{"id":51306283,"url":"https://github.com/phlx0/living-docs","last_synced_at":"2026-07-01T00:01:25.090Z","repository":{"id":352432998,"uuid":"1215128731","full_name":"phlx0/living-docs","owner":"phlx0","description":"Keep documentation alive — Claude Code plugin that auto-detects and fixes stale docs after code changes","archived":false,"fork":false,"pushed_at":"2026-04-19T15:09:41.000Z","size":33,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-19T16:27:54.642Z","etag":null,"topics":["ai","automation","claude-code","claude-code-plugin","developer-tools","documentation","dx","jsdoc","markdown","openapi"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phlx0.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["phlx0"]}},"created_at":"2026-04-19T14:17:58.000Z","updated_at":"2026-04-19T15:09:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/phlx0/living-docs","commit_stats":null,"previous_names":["phlx0/living-docs"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/phlx0/living-docs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlx0%2Fliving-docs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlx0%2Fliving-docs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlx0%2Fliving-docs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlx0%2Fliving-docs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phlx0","download_url":"https://codeload.github.com/phlx0/living-docs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phlx0%2Fliving-docs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34987611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","automation","claude-code","claude-code-plugin","developer-tools","documentation","dx","jsdoc","markdown","openapi"],"created_at":"2026-07-01T00:01:24.180Z","updated_at":"2026-07-01T00:01:25.077Z","avatar_url":"https://github.com/phlx0.png","language":"Shell","funding_links":["https://github.com/sponsors/phlx0"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# living-docs\n\n### Documentation that keeps up with your code.\n\n[![CI](https://github.com/phlx0/living-docs/actions/workflows/ci.yml/badge.svg)](https://github.com/phlx0/living-docs/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Claude Code](https://img.shields.io/badge/Claude%20Code-plugin-blueviolet)](https://code.claude.ai)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/phlx0/living-docs/pulls)\n\n\u003c/div\u003e\n\n---\n\nYou renamed a function. You added a required parameter. You retired an env var.\n\nSomewhere in your docs, the old name is still there. The old signature. The old example that no longer runs. It will stay there until a confused colleague files a bug, or a new hire wastes a morning following instructions that stopped being true six months ago.\n\n**living-docs** finds every doc that references what you just changed, tells you exactly what's wrong, and fixes only that — without touching anything else.\n\n---\n\n## What it looks like\n\nYou've been editing `src/auth.ts`. Claude Code's hook fires quietly:\n\n```\n⚠ living-docs: code changed in auth.ts — docs may be stale. Run /living-docs to check.\n```\n\nYou run `/living-docs`:\n\n```\nScanning docs against changes since HEAD~1...\n\n  STALE  docs/api.md            2 issues\n  STALE  docs/configuration.md  1 issue\n  STALE  src/auth.ts (JSDoc)    1 issue\n  OK     README.md\n  OK     docs/architecture.md\n\n─────────────────────────────────────────────────────────────────\ndocs/api.md · line 112\n─────────────────────────────────────────────────────────────────\nTYPE     outdated signature\nCHANGED  authenticate(token) → authenticate(token, options?)\n\nWAS:\n  authenticate(token)\n  Validates a JWT and returns the decoded payload.\n\nNOW:\n  authenticate(token, options?)\n  Validates a JWT and returns the decoded payload.\n  options.strict — boolean  Reject tokens missing `exp`. Default: false.\n  options.audience — string  Validate `aud` claim. Default: not checked.\n\n─────────────────────────────────────────────────────────────────\ndocs/configuration.md · line 58\n─────────────────────────────────────────────────────────────────\nTYPE     renamed env var\nCHANGED  AUTH_SECRET → AUTH_SIGNING_KEY\n\nWAS:\n  AUTH_SECRET — Secret used to sign tokens.\n\nNOW:\n  AUTH_SIGNING_KEY — Secret used to sign tokens.\n\n─────────────────────────────────────────────────────────────────\nsrc/auth.ts · JSDoc\n─────────────────────────────────────────────────────────────────\nTYPE     missing param\nCHANGED  new options parameter not documented in JSDoc\n\nWAS:\n  * @param {string} token - JWT to validate\n\nNOW:\n  * @param {string} token - JWT to validate\n  * @param {Object} [options] - Validation options\n  * @param {boolean} [options.strict=false] - Reject tokens missing `exp`\n  * @param {string} [options.audience] - Validate `aud` claim\n\n─────────────────────────────────────────────────────────────────\n\nApply all 4 fixes? [Y/n/select]\n```\n\nType `Y`. Done. Every doc is accurate again.\n\n---\n\n## Install\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/phlx0/living-docs/main/scripts/install.sh | sh\n```\n\nOr manually:\n\n```bash\ngit clone https://github.com/phlx0/living-docs ~/.claude/plugins/living-docs\nchmod +x ~/.claude/plugins/living-docs/hooks/*.sh\n```\n\nAdd to `~/.claude/settings.json`:\n\n```json\n{\n  \"plugins\": [\"~/.claude/plugins/living-docs\"]\n}\n```\n\n---\n\n## Usage\n\n```\n/living-docs                   scan everything changed since last commit\n/living-docs --dry-run         preview fixes, change nothing\n/living-docs --all             scan all docs, not just recent changes\n/living-docs --since main      diff against a branch instead of HEAD~1\n/living-docs docs/api.md       check one file only\n/living-docs --format openapi  focus on a specific doc format\n```\n\n---\n\n## What it catches\n\n| Code change | What gets flagged |\n|---|---|\n| Function signature changed | Every doc, example, and JSDoc showing the old signature |\n| Parameter added or removed | README usage sections, API references, docstrings |\n| Env var renamed | Every mention of the old name across all doc files |\n| CLI flag renamed | Help text, quickstart guides, deployment docs |\n| API endpoint moved | OpenAPI specs, integration guides, curl examples |\n| Config key renamed | Configuration references, environment setup guides |\n| New public export | Missing documentation for newly exposed API surface |\n| File path changed | Cross-references, import examples |\n\n**Supported doc formats:** Markdown, JSDoc/TSDoc, Python docstrings, Go doc comments, OpenAPI/Swagger, reStructuredText.\n\n---\n\n## How it works\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│  git diff HEAD~1                                            │\n│    → changed code files                                     │\n└──────────────────────────┬──────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────┐\n│  extract semantic markers                                   │\n│    → function names, param changes, env vars, endpoints,   │\n│      config keys, exports, file paths                       │\n└──────────────────────────┬──────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────┐\n│  glob doc files                                             │\n│    → markdown, rst, jsdoc, docstrings, openapi             │\n│    → skip: CHANGELOG, auto-generated, .living-docs-ignore  │\n└──────────────────────────┬──────────────────────────────────┘\n                           │\n                   ┌───────┴───────┐\n                   │               │\n                   ▼               ▼\n            references?        no references\n            → analyze          → skip (fast)\n                   │\n                   ▼\n┌─────────────────────────────────────────────────────────────┐\n│  staleness-detector subagent (per file)                     │\n│    → compare doc content vs current code                    │\n│    → classify: outdated / missing / broken-link / wrong-eg  │\n│    → confidence: high / medium / low                        │\n└──────────────────────────┬──────────────────────────────────┘\n                           │\n                           ▼\n┌─────────────────────────────────────────────────────────────┐\n│  surgical fix                                               │\n│    → edit only the stale lines                             │\n│    → preserve author's style, tone, structure              │\n│    → low-confidence: flag only, never auto-fix             │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Configuration\n\nDrop a `.living-docs.json` in your project root to override defaults:\n\n```bash\ncp ~/.claude/plugins/living-docs/.living-docs.example.json .living-docs.json\n```\n\n```json\n{\n  \"docs\": {\n    \"include\": [\"**/*.md\", \"docs/**/*\", \"README*\"],\n    \"exclude\": [\"CHANGELOG.md\", \"node_modules/**\", \"dist/**\"]\n  },\n  \"code\": {\n    \"include\": [\"src/**\", \"lib/**\"],\n    \"exclude\": [\"**/*.test.*\", \"**/*.spec.*\"]\n  },\n  \"hooks\": {\n    \"enabled\": true,\n    \"debounceSeconds\": 30\n  },\n  \"behavior\": {\n    \"autoFix\": false,\n    \"requireConfirmation\": true\n  }\n}\n```\n\nTo permanently exclude files, create `.living-docs-ignore`:\n\n```\nCHANGELOG.md\ndocs/archive/\nsrc/generated/\nvendor/\n```\n\n---\n\n## CI integration\n\nFail the build if docs would be stale after a merge:\n\n```yaml\n# .github/workflows/docs-check.yml\n- name: Check for stale docs\n  run: |\n    claude --print \"/living-docs --dry-run --since origin/main\" \\\n      | grep -q \"All docs up to date\" || exit 1\n```\n\nOr as a pre-push hook:\n\n```bash\n# .git/hooks/pre-push\nclaude --print \"/living-docs --dry-run\" | grep -q \"All docs up to date\" || {\n  echo \"Stale docs detected. Run /living-docs to fix.\"\n  exit 1\n}\n```\n\n---\n\n## FAQ\n\n**Will it rewrite my whole README?**\nNo. It edits exactly the lines that are wrong. The rest is untouched — including your formatting, whitespace, and wording.\n\n**My docs are intentionally different from the code. Will it break them?**\nUse `--dry-run` to review before applying. Add the file to `.living-docs-ignore` to exclude it permanently.\n\n**No git history?**\nUse `--all` to scan all docs without diffing.\n\n**Monorepo?**\nYes. Point `code.include` and `docs.include` at the subdirectories you want.\n\n**Works without Claude Code?**\nNo. living-docs is a Claude Code plugin. The analysis is done by an LLM — that's what makes it semantic instead of just a text search.\n\n**Will it touch auto-generated files?**\nNo. Files with `# DO NOT EDIT`, `@generated`, or `Code generated` headers are skipped automatically.\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](.github/CONTRIBUTING.md).\n\nIssues and PRs at [github.com/phlx0/living-docs](https://github.com/phlx0/living-docs/issues). Bug reports are most useful with a code snippet and doc snippet showing what wasn't caught (or was wrongly flagged).\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\nMIT — [LICENSE](LICENSE)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphlx0%2Fliving-docs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphlx0%2Fliving-docs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphlx0%2Fliving-docs/lists"}