{"id":50472424,"url":"https://github.com/semcod/docval","last_synced_at":"2026-06-01T11:03:34.047Z","repository":{"id":351253083,"uuid":"1209494424","full_name":"semcod/docval","owner":"semcod","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-14T07:32:26.000Z","size":167,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T09:28:56.901Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/semcod.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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}},"created_at":"2026-04-13T13:38:01.000Z","updated_at":"2026-04-14T07:32:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/semcod/docval","commit_stats":null,"previous_names":["semcod/docval"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/semcod/docval","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fdocval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fdocval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fdocval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fdocval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/semcod","download_url":"https://codeload.github.com/semcod/docval/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semcod%2Fdocval/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33771630,"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-01T02:00:06.963Z","response_time":115,"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":[],"created_at":"2026-06-01T11:03:33.936Z","updated_at":"2026-06-01T11:03:34.033Z","avatar_url":"https://github.com/semcod.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# docval\n\n[![Python](https://img.shields.io/badge/python-3.10+-3776AB)](https://python.org)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Tests](https://img.shields.io/badge/tests-37%20passed-brightgreen)](tests/)\n\n\n## AI Cost Tracking\n\n![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.1.31-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)\n![AI Cost](https://img.shields.io/badge/AI%20Cost-$0.51-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-4.2h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)\n\n- 🤖 **LLM usage:** $0.5083 (6 commits)\n- 👤 **Human dev:** ~$424 (4.2h @ $100/h, 30min dedup)\n\nGenerated on 2026-04-20 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)\n\n---\n\nValidate and refactor Markdown documentation against source code — detect outdated, orphaned, duplicate, and invalid docs using heuristics + optional LLM.\n\n![docval_architecture.svg](../../../Downloads/docval_architecture.svg)\n\n## How it works\n\n```\ndocs/  ──→  chunk by heading  ──→  heuristic checks  ──→  cross-ref with code  ──→  (optional) LLM  ──→  report/fix\n```\n\n**Three validation layers**, each progressively deeper:\n\n1. **Heuristic validator** (fast, free) — empty sections, broken internal links, TODO/FIXME markers, duplicate detection via `difflib`, stale version references, archive path detection, explicit deprecation markers\n2. **Cross-reference validator** (fast, free) — checks that backtick-quoted symbols (`ClassName`, `function_name`), import paths in code blocks, and CLI commands actually exist in the project source\n3. **LLM validator** (optional, paid) — semantic validation via `litellm` for chunks that heuristics couldn't resolve with high confidence\n\n## Installation\n\n```bash\npip install docval\n```\n\nWith LLM support:\n\n```bash\npip install docval[llm]\n```\n\nFrom source:\n\n```bash\ngit clone https://github.com/wronai/docval.git\ncd docval\npip install -e \".[dev]\"\n```\n\n## CLI Usage\n\n### Scan and report issues\n\n```bash\ndocval scan docs/\ndocval scan docs/ --project /path/to/repo -v\ndocval scan docs/ -o report.md\ndocval scan docs/ -o report.json\n```\n\n### Fix documentation (dry-run by default)\n\n```bash\ndocval fix docs/                           # preview changes\ndocval fix docs/ --no-dry-run              # apply fixes\ndocval fix docs/ --no-dry-run --llm        # with LLM validation\n```\n\n### Generate a patch file\n\n```bash\ndocval patch docs/ -o fixes.txt\ndocval patch docs/ --llm --model gpt-4o -o fixes.txt\n```\n\n### View documentation statistics\n\n```bash\ndocval stats docs/\n```\n\n### LLM validation\n\n```bash\nexport OPENAI_API_KEY=sk-...\ndocval scan docs/ --llm --model gpt-4o-mini\ndocval scan docs/ --llm --model anthropic/claude-sonnet-4-20250514\ndocval scan docs/ --llm --model groq/llama-3.3-70b-versatile\n```\n\nAny model supported by [litellm](https://docs.litellm.ai/) works.\n\n## Python API\n\n```python\nfrom pathlib import Path\nfrom docval.pipeline import scan\nfrom docval.reporters import ConsoleReporter, MarkdownReporter\n\n# Run validation\nresult = scan(\n    docs_dir=Path(\"docs/\"),\n    project_root=Path(\".\"),\n    use_llm=False,\n)\n\n# Print to console\nConsoleReporter(verbose=True).report(result)\n\n# Write markdown report\nMarkdownReporter().report(result, Path(\"validation-report.md\"))\n```\n\n### Using individual validators\n\n```python\nfrom docval.chunker import chunk_directory\nfrom docval.context import build_context\nfrom docval.validators import HeuristicValidator, CrossRefValidator\n\n# Chunk docs\ndoc_files = chunk_directory(Path(\"docs/\"))\n\n# Build project context\nctx = build_context(Path(\".\"))\n\n# Run heuristics\nheuristic = HeuristicValidator(ctx=ctx)\nheuristic.validate(doc_files)\n\n# Cross-reference check\ncrossref = CrossRefValidator(ctx=ctx)\ncrossref.validate(doc_files)\n\n# Inspect results\nfor f in doc_files:\n    for chunk in f.chunks:\n        if chunk.issues:\n            print(f\"{f.relative_path}:{chunk.line_start} [{chunk.status.value}] {chunk.heading}\")\n            for issue in chunk.issues:\n                print(f\"  {issue.severity.value}: {issue.message}\")\n```\n\n## What it detects\n\n| Check | Layer | Example |\n|-------|-------|---------|\n| Empty sections | Heuristic | Heading with no body text |\n| Broken internal links | Heuristic | `[guide](./deleted-file.md)` |\n| Deprecated markers | Heuristic | `DEPRECATED`, `OBSOLETE`, `DO NOT USE` |\n| Archive path | Heuristic | Files in `docs/archive/` directories |\n| Stale versions | Heuristic | References to v1.x when project is v3.x |\n| Duplicates | Heuristic | \u003e80% similar content across files |\n| TODO/FIXME | Heuristic | Unfinished documentation markers |\n| Orphaned code refs | CrossRef | `` `NonExistentClass` `` in backticks |\n| Broken imports | CrossRef | `from mypackage.deleted import X` in code blocks |\n| Semantic accuracy | LLM | Content that doesn't match actual project behavior |\n\n## Architecture\n\n```\nsrc/docval/\n├── cli.py                  # Click CLI: scan, fix, patch, stats\n├── pipeline.py             # Orchestrates: discover → chunk → validate → report\n├── models.py               # Data models: DocChunk, DocFile, ValidationResult\n├── chunker.py              # MD → heading-based semantic chunks\n├── context.py              # Build project context (AST, git, .toon files)\n├── validators/\n│   ├── heuristic.py        # Rule-based checks (free, fast)\n│   ├── crossref.py         # Code ↔ docs cross-reference\n│   └── llm_validator.py    # Semantic validation via litellm\n├── actions/\n│   └── executor.py         # Apply fixes: delete, archive, patch\n└── reporters/\n    ├── console.py           # Rich CLI output\n    ├── markdown_report.py   # .md report\n    └── json_report.py       # .json for CI/CD\n```\n\n## Integration with .toon files\n\ndocval understands `.toon.yaml` files from the [code2llm](https://github.com/wronai/code2llm) ecosystem. When present, it extracts module names, class names, and exported functions for cross-referencing, giving more accurate orphaned-reference detection.\n\n## License\n\nLicensed under Apache-2.0.\n\n\u003c!-- taskill:status:start --\u003e\n\n## Status\n\n_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 13:37 UTC_\n\n| Metric | Value |\n|---|---|\n| HEAD | `4fba32f` |\n| Coverage | — |\n| Failing tests | — |\n| Commits in last cycle | 6 |\n\n\u003e Add markdown output for documentation generation (docs feature). Commit also added inclusion of commit messages in the markdown output.\n\n\u003c!-- taskill:status:end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fdocval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsemcod%2Fdocval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemcod%2Fdocval/lists"}