docsanity 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 docsanity contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,181 @@
1
+ <div align="center">
2
+
3
+ # 🩺 docsanity
4
+
5
+ ### One command for docs-site health β€” broken links, orphan pages, SEO, readability & structure in a single score.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/docsanity.svg?color=success)](https://www.npmjs.com/package/docsanity)
8
+ [![CI](https://github.com/didrod205/docsanity/actions/workflows/ci.yml/badge.svg)](https://github.com/didrod205/docsanity/actions/workflows/ci.yml)
9
+ [![types](https://img.shields.io/npm/types/docsanity.svg)](https://www.npmjs.com/package/docsanity)
10
+ [![license](https://img.shields.io/npm/l/docsanity.svg)](./LICENSE)
11
+
12
+ </div>
13
+
14
+ Your docs site looks fine β€” until a reader hits a 404 from a link you moved, lands
15
+ on a page Google shows with a *duplicate* title, or bounces off a wall of
16
+ grad-school prose. These problems live **between** files (which page links where,
17
+ which titles repeat, what's orphaned), so single-file linters miss them and no one
18
+ notices until it ships.
19
+
20
+ **docsanity audits a whole docs directory in one pass** and unifies four health
21
+ dimensions into one score and one report β€” **100% locally, no API key:**
22
+
23
+ - πŸ”— **Links & references** β€” broken relative links, dead `#anchors`, missing
24
+ images, and **orphan pages** nothing links to.
25
+ - πŸ”Ž **SEO & frontmatter** β€” missing/oversized `title` & `description`, plus
26
+ **site-wide duplicate titles and descriptions** across every page.
27
+ - πŸ“– **Readability** β€” a per-page reading grade; flags pages that read too hard.
28
+ - β™Ώ **Structure & a11y** β€” single H1, no skipped heading levels, image alt text,
29
+ fenced code blocks that declare a language.
30
+
31
+ ```bash
32
+ npx docsanity scan ./docs
33
+ ```
34
+
35
+ ```
36
+ broken.md 50/100 (F)
37
+ βœ— L5 Link target not found: "./nope.md" links.broken-file-link
38
+ βœ— L5 Anchor "#does-not-exist" not found in index.md links.broken-cross-anchor
39
+ ⚠ L7 Image has no alt text: ./diagram.png structure.image-alt
40
+ orphan.md 88/100 (B)
41
+ ⚠ Orphan page β€” nothing links here links.orphan-document
42
+ ⚠ Duplicate title β€” also used by 1 other page(s) seo.duplicate-title
43
+
44
+ Overall 82/100 (B) Β· 5 page(s), 4 error(s), 10 warning(s)
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Why a suite (and not four separate tools)?
50
+
51
+ The valuable checks need the **whole-site view**, which only a unified pass can
52
+ give you:
53
+
54
+ - **Orphan pages** and **broken cross-file anchors** require the full page graph.
55
+ - **Duplicate titles/descriptions** require comparing every page to every other.
56
+ - A single **score + grade** you can gate in CI means one number to watch, not four
57
+ tools to wire up and reconcile.
58
+
59
+ docsanity builds the page graph once and runs every dimension over it, then folds
60
+ everything into a per-page and per-dimension report. Under the hood it leverages
61
+ the focused engines [`linklint`](https://www.npmjs.com/package/@didrod2539/linklint)
62
+ (link graph) and [`readlevel`](https://www.npmjs.com/package/@didrod2539/readlevel)
63
+ (readability), and adds the SEO-frontmatter and structure checks that tie them into
64
+ a docs-site audit.
65
+
66
+ Why not just ask an LLM to "check my docs"? It can't hold 300 interlinked files in
67
+ context, it can't run in CI deterministically, and "did this link break" is a graph
68
+ lookup, not a guess.
69
+
70
+ ## Install
71
+
72
+ ```bash
73
+ # run it now, no install
74
+ npx docsanity scan ./docs
75
+
76
+ # or add it
77
+ npm install -g docsanity # global CLI
78
+ npm install -D docsanity # CI dependency
79
+ ```
80
+
81
+ Node β‰₯ 18. Works with Docusaurus, Astro, Nextra, Hugo, Jekyll, VitePress β€” any
82
+ Markdown/MDX docs tree.
83
+
84
+ ## Quick start
85
+
86
+ ```bash
87
+ docsanity scan ./docs # audit a folder
88
+ docsanity scan ./docs --min-score 85 # CI gate: fail under 85
89
+ docsanity scan ./docs --md docs-report.md # write a Markdown report
90
+ docsanity scan ./docs --disable readability # turn a dimension off
91
+ docsanity init # write docsanity.config.json
92
+ ```
93
+
94
+ See [`examples/sample-report.md`](./examples/sample-report.md) and
95
+ [`examples/sample-report.json`](./examples/sample-report.json) for full reports.
96
+
97
+ ## Real scenarios
98
+
99
+ **1. CI gate for your docs.** A PR that moves a page and forgets to fix the inbound
100
+ links β€” or ships a new page with no description β€” fails the build:
101
+
102
+ ```yaml
103
+ # .github/workflows/docs.yml
104
+ - run: npx docsanity scan ./docs --min-score 90 --md docs-report.md
105
+ ```
106
+
107
+ **2. Pre-launch audit of an inherited site.** Point it at a docs tree you didn't
108
+ write and instantly see the orphans, duplicate titles and dead anchors that
109
+ accumulated over time β€” one report, ranked by page score.
110
+
111
+ **3. Keep AI answer engines happy.** Clear, well-structured, well-linked pages are
112
+ what answer engines quote. Fix the readability and structure findings to make your
113
+ docs the source they cite.
114
+
115
+ ## What each dimension checks
116
+
117
+ | Dimension | Checks |
118
+ | --------- | ------ |
119
+ | **Links & references** | broken relative links, dead `#anchors`, broken cross-file anchors, missing images, undefined references, **orphan pages** |
120
+ | **SEO & frontmatter** | required `title`/`description`, length windows, H1-as-title fallback, **site-wide duplicate titles & descriptions** |
121
+ | **Readability** | Flesch–Kincaid / Gunning Fog / SMOG average grade per page, flagged against a configurable ceiling |
122
+ | **Structure & a11y** | single H1, no skipped heading levels, image alt text, code-fence language tags |
123
+
124
+ Scoring is transparent: each finding is a weighted error / warning / info; pages
125
+ roll up to a 0–100 score and an A–F grade, averaged into the overall.
126
+
127
+ ## Configuration
128
+
129
+ `docsanity init` writes `docsanity.config.json`:
130
+
131
+ ```jsonc
132
+ {
133
+ "extensions": [".md", ".mdx", ".markdown"],
134
+ "requireFrontmatter": ["title", "description"],
135
+ "descriptionMin": 50,
136
+ "descriptionMax": 160,
137
+ "titleMax": 60,
138
+ "maxGrade": 14,
139
+ "minWordsForReadability": 80,
140
+ "disable": [], // e.g. ["readability"]
141
+ "ignore": [], // rule ids, e.g. ["structure.code-language"]
142
+ "minScore": 0 // CI gate threshold
143
+ }
144
+ ```
145
+
146
+ ## Library API
147
+
148
+ ```ts
149
+ import { analyzeDocs } from "docsanity";
150
+
151
+ const report = analyzeDocs(root, inputs, config, {
152
+ version: "1.0.0",
153
+ generatedAt: new Date().toISOString(),
154
+ });
155
+ for (const page of report.pages) {
156
+ console.log(page.path, page.score, page.findings.length);
157
+ }
158
+ ```
159
+
160
+ Also exported: `parsePage`, `parseFrontmatter`, `parseMarkdown`, `seoChecks`,
161
+ `structureChecks`, `readabilityCheck`, `linkFindings`, `DEFAULT_CONFIG`, and types.
162
+
163
+ ## Roadmap
164
+
165
+ - More frontmatter conventions (Hugo/Jekyll specifics, custom required schemas).
166
+ - HTML docs input (not just Markdown/MDX).
167
+ - Per-rule severity overrides and inline ignore comments.
168
+ - `--baseline` to fail only on *new* issues vs a committed snapshot.
169
+ - A web playground (drop a zip of docs, get the report β€” nothing uploaded).
170
+
171
+ ## πŸ’– Sponsor
172
+
173
+ docsanity is free and MIT-licensed, built and maintained in spare time. If it
174
+ caught a broken link before your readers did, please consider supporting it:
175
+
176
+ - ⭐ **Star this repo** β€” the simplest free way to help others find it.
177
+ - πŸ‹ **[Sponsor via Lemon Squeezy](https://elab-studio.lemonsqueezy.com/checkout/buy/5d059b89-51d0-456b-b33a-ed56994f7010)** β€” one-time or recurring.
178
+
179
+ ## License
180
+
181
+ [MIT](./LICENSE) Β© docsanity contributors