docguard-cli 0.9.1 → 0.9.2

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/README.md CHANGED
@@ -223,7 +223,7 @@ $ npx docguard-cli guard
223
223
 
224
224
  ---
225
225
 
226
- ## 19 Validators
226
+ ## 18 Validators
227
227
 
228
228
  | # | Validator | What It Checks | Default |
229
229
  |---|-----------|---------------|---------|
@@ -16,7 +16,7 @@
16
16
  import { c } from '../shared.mjs';
17
17
  import { runGuardInternal } from './guard.mjs';
18
18
  import { runScoreInternal } from './score.mjs';
19
- import { existsSync, readFileSync, mkdirSync } from 'node:fs';
19
+ import { existsSync, readFileSync } from 'node:fs';
20
20
  import { resolve, dirname } from 'node:path';
21
21
  import { fileURLToPath } from 'node:url';
22
22
  import { execSync } from 'node:child_process';
@@ -28,7 +28,7 @@ const THRESHOLDS = {
28
28
  passiveVoiceRatio: { warn: 0.20, label: 'Passive voice ratio' }, // >20% passive = warn
29
29
  ambiguousPronounRatio: { warn: 0.15, label: 'Ambiguous pronoun ratio' }, // >15% ambiguous pronouns = warn
30
30
  atomicityScore: { warn: 0.30, label: 'Non-atomic sentence ratio' }, // >30% compound sentences = warn
31
- fleschReadingEase: { warn: 30, label: 'Flesch reading ease' }, // <30 = very hard to read
31
+ fleschReadingEase: { warn: 20, label: 'Flesch reading ease' }, // <20 = very hard to read (lowered from 30 for technical markdown)
32
32
  fleschKincaidGrade: { warn: 16, label: 'Flesch-Kincaid grade' }, // >16 = graduate level+
33
33
  avgSentenceLength: { warn: 25, label: 'Avg sentence length' }, // >25 words = too long
34
34
  negationLoad: { warn: 0.15, label: 'Negation load' }, // >15% sentences with negation = warn
@@ -49,18 +49,28 @@ function stripMarkdown(content) {
49
49
  text = text.replace(/````[\s\S]*?````/g, '');
50
50
  text = text.replace(/```[\s\S]*?```/g, '');
51
51
 
52
+ // Remove mermaid diagrams
53
+ text = text.replace(/```mermaid[\s\S]*?```/g, '');
54
+
52
55
  // Remove HTML comments (<!-- ... -->)
53
56
  text = text.replace(/<!--[\s\S]*?-->/g, '');
54
57
 
58
+ // Remove HTML tags
59
+ text = text.replace(/<[^>]+>/g, '');
60
+
55
61
  // Remove YAML frontmatter (---...---)
56
62
  text = text.replace(/^---[\s\S]*?---\n/m, '');
57
63
 
58
- // Remove table rows (lines starting with |)
64
+ // Remove table rows (lines starting with |) and table separators
59
65
  text = text.replace(/^\|.*$/gm, '');
66
+ text = text.replace(/^[|:\-\s]+$/gm, '');
60
67
 
61
68
  // Remove horizontal rules
62
69
  text = text.replace(/^[-*_]{3,}\s*$/gm, '');
63
70
 
71
+ // Remove badge images (shield.io etc.) — before generic image removal
72
+ text = text.replace(/!\[.*?\]\(https?:\/\/[^)]+\)/g, '');
73
+
64
74
  // Remove images: ![alt](url)
65
75
  text = text.replace(/!\[.*?\]\(.*?\)/g, '');
66
76
 
@@ -81,8 +91,21 @@ function stripMarkdown(content) {
81
91
  text = text.replace(/\*{1,3}([^*]+)\*{1,3}/g, '$1');
82
92
  text = text.replace(/_{1,3}([^_]+)_{1,3}/g, '$1');
83
93
 
84
- // Remove badge images (shield.io etc.)
85
- text = text.replace(/!\[.*?\]\(https:\/\/img\.shields\.io\/.*?\)/g, '');
94
+ // Remove definition-style lines (key: value or key | value)
95
+ text = text.replace(/^\s*\w[\w\s]*\s*[:|]\s*.*$/gm, (match) => {
96
+ // Only strip if it looks like a key-value pair, not a sentence
97
+ if (match.includes('.') || match.split(/\s+/).length > 8) return match;
98
+ return '';
99
+ });
100
+
101
+ // Remove lines that are mostly non-prose (>60% special characters)
102
+ text = text.replace(/^.+$/gm, (line) => {
103
+ const trimmed = line.trim();
104
+ if (trimmed.length < 5) return '';
105
+ const alphaCount = (trimmed.match(/[a-zA-Z]/g) || []).length;
106
+ const ratio = alphaCount / trimmed.length;
107
+ return ratio < 0.4 ? '' : line; // If <40% letters, it's not prose
108
+ });
86
109
 
87
110
  // Collapse multiple blank lines
88
111
  text = text.replace(/\n{3,}/g, '\n\n');
@@ -397,7 +420,9 @@ function getGradeLabel(grade) {
397
420
  */
398
421
  function findUnderstandingCli() {
399
422
  try {
400
- const result = execSync('which understanding 2>/dev/null || where understanding 2>NUL', {
423
+ // Use 'which' on Unix/Mac, 'where' on Windows — never redirect to NUL (creates file on Mac)
424
+ const cmd = process.platform === 'win32' ? 'where understanding' : 'which understanding';
425
+ const result = execSync(`${cmd} 2>/dev/null`, {
401
426
  encoding: 'utf-8',
402
427
  timeout: 3000,
403
428
  }).trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docguard-cli",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "The enforcement tool for Canonical-Driven Development (CDD). Audit, generate, and guard your project documentation.",
5
5
  "type": "module",
6
6
  "bin": {