docguard-cli 0.32.0 → 0.33.1
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/PHILOSOPHY.md +1 -0
- package/PRIVACY.md +45 -0
- package/README.md +68 -28
- package/cli/commands/ci.mjs +52 -13
- package/cli/commands/guard.mjs +80 -0
- package/cli/commands/mcp.mjs +16 -0
- package/cli/commands/report.mjs +200 -0
- package/cli/commands/score.mjs +55 -1
- package/cli/docguard.mjs +56 -11
- package/cli/shared-git.mjs +23 -0
- package/cli/validators/docs-coverage.mjs +5 -0
- package/cli/writers/baseline.mjs +84 -0
- package/cli/writers/history.mjs +82 -0
- package/cli/writers/junit.mjs +103 -0
- package/docs/commands.md +30 -2
- package/docs/configuration.md +14 -0
- package/docs/faq.md +31 -0
- package/extensions/spec-kit-docguard/extension.yml +1 -1
- package/extensions/spec-kit-docguard/skills/docguard-fix/SKILL.md +2 -2
- package/extensions/spec-kit-docguard/skills/docguard-guard/SKILL.md +2 -2
- package/extensions/spec-kit-docguard/skills/docguard-review/SKILL.md +2 -2
- package/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +2 -2
- package/extensions/spec-kit-docguard/skills/docguard-sync/SKILL.md +2 -2
- package/package.json +4 -3
- package/schemas/docguard-config.schema.json +5 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JUnit XML writer — `docguard guard --format junit`.
|
|
3
|
+
*
|
|
4
|
+
* SARIF covers GitHub Code Scanning; JUnit covers everything else an
|
|
5
|
+
* enterprise runs: GitLab CI (`artifacts:reports:junit`), Jenkins
|
|
6
|
+
* (`junit` step), Azure DevOps, CircleCI, Bamboo. One testcase per
|
|
7
|
+
* validator keeps the report readable in those UIs — a failed validator
|
|
8
|
+
* shows its findings (code + message + location) as the failure body.
|
|
9
|
+
*
|
|
10
|
+
* Mapping (deterministic):
|
|
11
|
+
* validator error findings → <failure> (red in every CI)
|
|
12
|
+
* validator crashed (fail, no
|
|
13
|
+
* structured findings) → <error> from its string errors (red)
|
|
14
|
+
* warn-only validator → passing testcase + findings in
|
|
15
|
+
* <system-out> (visible, non-gating)
|
|
16
|
+
* skipped / n/a → <skipped/>
|
|
17
|
+
*
|
|
18
|
+
* Zero npm dependencies — pure string assembly with strict XML escaping.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
function esc(s) {
|
|
22
|
+
return String(s ?? '')
|
|
23
|
+
.replace(/&/g, '&')
|
|
24
|
+
.replace(/</g, '<')
|
|
25
|
+
.replace(/>/g, '>')
|
|
26
|
+
.replace(/"/g, '"')
|
|
27
|
+
.replace(/'/g, ''');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function findingLine(f) {
|
|
31
|
+
const code = f.code ? `[${f.code}] ` : '';
|
|
32
|
+
const loc = f.location ? ` (${f.location})` : '';
|
|
33
|
+
return `${code}${f.message}${loc}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Build the JUnit XML document from runGuardInternal's data.
|
|
38
|
+
* `data.validators` entries: { name, status, findings? }; `data.findings`
|
|
39
|
+
* is the flat list with `validator` back-references — we group by the
|
|
40
|
+
* validator display name via each result's own findings when present,
|
|
41
|
+
* falling back to the flat list.
|
|
42
|
+
*/
|
|
43
|
+
export function toJUnit(data) {
|
|
44
|
+
const cases = [];
|
|
45
|
+
let failures = 0, errorCount = 0, skipped = 0;
|
|
46
|
+
|
|
47
|
+
for (const v of data.validators || []) {
|
|
48
|
+
const vFindings = Array.isArray(v.findings)
|
|
49
|
+
? v.findings
|
|
50
|
+
: (data.findings || []).filter(f => f.validator === v.key || f.validator === v.name);
|
|
51
|
+
const errors = vFindings.filter(f => f.severity === 'error');
|
|
52
|
+
const warns = vFindings.filter(f => f.severity !== 'error');
|
|
53
|
+
const attrs = `name="${esc(v.name)}" classname="docguard.guard"`;
|
|
54
|
+
|
|
55
|
+
if (v.status === 'skipped' || v.status === 'na') {
|
|
56
|
+
skipped++;
|
|
57
|
+
cases.push(` <testcase ${attrs}><skipped/></testcase>`);
|
|
58
|
+
} else if (errors.length > 0) {
|
|
59
|
+
failures++;
|
|
60
|
+
const body = errors.map(findingLine).join('\n');
|
|
61
|
+
cases.push(
|
|
62
|
+
` <testcase ${attrs}>\n` +
|
|
63
|
+
` <failure message="${esc(errors[0].message)}" type="${esc(errors[0].code || 'docguard')}">${esc(body)}</failure>\n` +
|
|
64
|
+
` </testcase>`
|
|
65
|
+
);
|
|
66
|
+
} else if (v.status === 'fail') {
|
|
67
|
+
// A validator that failed WITHOUT structured error findings — the
|
|
68
|
+
// crash path (guard catches the throw and records string errors only).
|
|
69
|
+
// This must go red in CI, not render as a passing testcase (M1).
|
|
70
|
+
errorCount++;
|
|
71
|
+
const body = (v.errors || []).join('\n') || 'validator failed without structured findings';
|
|
72
|
+
cases.push(
|
|
73
|
+
` <testcase ${attrs}>\n` +
|
|
74
|
+
` <error message="${esc((v.errors || [])[0] || 'validator failed')}" type="docguard.crash">${esc(body)}</error>\n` +
|
|
75
|
+
` </testcase>`
|
|
76
|
+
);
|
|
77
|
+
} else if (warns.length > 0) {
|
|
78
|
+
const body = warns.map(findingLine).join('\n');
|
|
79
|
+
cases.push(
|
|
80
|
+
` <testcase ${attrs}>\n` +
|
|
81
|
+
` <system-out>${esc(body)}</system-out>\n` +
|
|
82
|
+
` </testcase>`
|
|
83
|
+
);
|
|
84
|
+
} else {
|
|
85
|
+
cases.push(` <testcase ${attrs}/>`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const total = (data.validators || []).length;
|
|
90
|
+
const suiteAttrs =
|
|
91
|
+
`name="docguard guard — ${esc(data.project || 'project')}" ` +
|
|
92
|
+
`tests="${total}" failures="${failures}" errors="${errorCount}" skipped="${skipped}" ` +
|
|
93
|
+
`timestamp="${esc(data.timestamp || '')}"`;
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
`<?xml version="1.0" encoding="UTF-8"?>\n` +
|
|
97
|
+
`<testsuites tests="${total}" failures="${failures}" errors="${errorCount}">\n` +
|
|
98
|
+
` <testsuite ${suiteAttrs}>\n` +
|
|
99
|
+
cases.join('\n') + (cases.length ? '\n' : '') +
|
|
100
|
+
` </testsuite>\n` +
|
|
101
|
+
`</testsuites>`
|
|
102
|
+
);
|
|
103
|
+
}
|
package/docs/commands.md
CHANGED
|
@@ -38,6 +38,17 @@ npx docguard-cli diagnose --format prompt # Raw AI prompt (all issues combined)
|
|
|
38
38
|
npx docguard-cli guard # Text output
|
|
39
39
|
npx docguard-cli guard --format json # Structured JSON (the stable agent contract)
|
|
40
40
|
npx docguard-cli guard --format sarif # SARIF 2.1.0 for GitHub Code Scanning
|
|
41
|
+
npx docguard-cli guard --format junit # JUnit XML for GitLab/Jenkins/Azure DevOps
|
|
42
|
+
npx docguard-cli guard --update-baseline # Freeze current findings (brownfield adoption)
|
|
43
|
+
npx docguard-cli guard --no-baseline # Ignore the committed baseline this run
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Adoption baseline:** on a legacy repo, `--update-baseline` writes
|
|
47
|
+
`.docguard.baseline.json` (commit it). From then on guard/ci suppress those
|
|
48
|
+
frozen findings — visibly — and gate only new drift. Fingerprints are stable
|
|
49
|
+
across line-number churn and volatile counts, so the baseline doesn't rot.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
41
52
|
npx docguard-cli guard --verbose # Show all check details
|
|
42
53
|
npx docguard-cli guard --changed-only # Pre-commit lite mode (fast subset)
|
|
43
54
|
```
|
|
@@ -181,7 +192,7 @@ never touched without `--force`.
|
|
|
181
192
|
|
|
182
193
|
**MCP server over stdio** — DocGuard's read-only core as native agent tools
|
|
183
194
|
(`docguard_guard`, `docguard_score`, `docguard_explain`,
|
|
184
|
-
`docguard_verify_claims`, `docguard_diagnose`).
|
|
195
|
+
`docguard_verify_claims`, `docguard_report`, `docguard_diagnose`).
|
|
185
196
|
|
|
186
197
|
```bash
|
|
187
198
|
claude mcp add docguard -- npx docguard-cli mcp
|
|
@@ -211,15 +222,32 @@ npx docguard-cli memory --pack # .docguard/context-pack.md (session-start co
|
|
|
211
222
|
|
|
212
223
|
## DevOps Commands
|
|
213
224
|
|
|
225
|
+
### `docguard report`
|
|
226
|
+
|
|
227
|
+
**Compliance-evidence bundle for audits** — guard verdict, CDD score, ALCOA+
|
|
228
|
+
data-integrity attributes, findings grouped by code, and fix history, stamped
|
|
229
|
+
with the git commit and a tamper-evident sha256 integrity hash. Evidence, not
|
|
230
|
+
a gate: always exits 0 (`guard`/`ci` fail builds).
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
npx docguard-cli report # markdown to stdout
|
|
234
|
+
npx docguard-cli report --format json # machine bundle
|
|
235
|
+
npx docguard-cli report --out evidence.md # write to a file
|
|
236
|
+
```
|
|
237
|
+
|
|
214
238
|
### `docguard ci`
|
|
215
239
|
|
|
216
|
-
**Single command for CI/CD pipelines.** Runs guard + score internally (no
|
|
240
|
+
**Single command for CI/CD pipelines.** Runs guard + score internally (no
|
|
241
|
+
subprocess). Read-only and machine-clean: it never scaffolds or mutates the
|
|
242
|
+
workspace it validates. Each run appends one line to `.docguard/history.jsonl`
|
|
243
|
+
so `docguard score --trend` can show the trajectory (opt out: `--no-history`).
|
|
217
244
|
|
|
218
245
|
```bash
|
|
219
246
|
npx docguard-cli ci # Basic check
|
|
220
247
|
npx docguard-cli ci --threshold 70 # Fail below score 70
|
|
221
248
|
npx docguard-cli ci --threshold 80 --fail-on-warning # Strict mode
|
|
222
249
|
npx docguard-cli ci --format json # JSON for GitHub Actions
|
|
250
|
+
npx docguard-cli score --trend # Score history from past ci runs
|
|
223
251
|
```
|
|
224
252
|
|
|
225
253
|
### `docguard hooks`
|
package/docs/configuration.md
CHANGED
|
@@ -111,6 +111,20 @@ Conventional doc folders (`docs/`, `doc/`, `documentation/`, `guides/`,
|
|
|
111
111
|
that set with non-standard homes — it never replaces auto-detection. To exclude
|
|
112
112
|
a conventional dir, list it in `.docguardignore`.
|
|
113
113
|
|
|
114
|
+
## Adoption baseline — `baseline`
|
|
115
|
+
|
|
116
|
+
When a committed `.docguard.baseline.json` exists (written by
|
|
117
|
+
`docguard guard --update-baseline`), guard/ci suppress the frozen findings
|
|
118
|
+
and gate only new drift. Set `"baseline": false` in `.docguard.json` to
|
|
119
|
+
ignore the file entirely (same as always passing `--no-baseline`):
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{ "baseline": false }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Suppression is always visible in output and in the `baselineSuppressed`
|
|
126
|
+
JSON field — nothing is silently hidden.
|
|
127
|
+
|
|
114
128
|
## Muting a validator
|
|
115
129
|
|
|
116
130
|
Two ways to turn a validator off, for two different intents:
|
package/docs/faq.md
CHANGED
|
@@ -119,10 +119,41 @@ Exit code 0 = pass, 1 = fail. Use `--threshold` to set minimum score.
|
|
|
119
119
|
|
|
120
120
|
Yes — DocGuard ships a template at `templates/ci/github-actions.yml`. Copy it to `.github/workflows/` or use the reusable action in `action.yml`.
|
|
121
121
|
|
|
122
|
+
### Claude (or my AI agent) says DocGuard is "unknown" and wants a legitimacy check. Why?
|
|
123
|
+
|
|
124
|
+
That's the agent's default posture toward **any** third-party MCP server or
|
|
125
|
+
npx package — MCP servers run code with your permissions, so unknown ones get
|
|
126
|
+
a trust prompt. It's not a DocGuard-specific flag. What DocGuard provides so
|
|
127
|
+
the check can pass:
|
|
128
|
+
|
|
129
|
+
- **npm provenance** — releases are signed by GitHub Actions (Sigstore), so
|
|
130
|
+
the tarball is verifiably built from this repository.
|
|
131
|
+
- **Official MCP registry** — `io.github.raccioly/docguard` is a verified
|
|
132
|
+
namespace at registry.modelcontextprotocol.io.
|
|
133
|
+
- **Read-only annotations** — every MCP tool declares `readOnlyHint`; the
|
|
134
|
+
server never writes or reaches the network.
|
|
135
|
+
- **[PRIVACY.md](../PRIVACY.md)** — no telemetry, no data collection.
|
|
136
|
+
|
|
137
|
+
To stop the prompt on your own machines: approve with "Always allow", or
|
|
138
|
+
pre-trust it for a whole team via a project-scoped `.mcp.json` /
|
|
139
|
+
enterprise managed-settings allowlist.
|
|
140
|
+
|
|
122
141
|
### Does DocGuard block commits?
|
|
123
142
|
|
|
124
143
|
Only if you install hooks (`docguard hooks`). Without hooks, it's advisory only.
|
|
125
144
|
|
|
145
|
+
### I ran guard on our legacy repo and got dozens of findings. Now what?
|
|
146
|
+
|
|
147
|
+
Freeze them and move forward:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx docguard-cli guard --update-baseline # writes .docguard.baseline.json — commit it
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
From then on guard/ci pass, suppress the frozen findings **visibly**
|
|
154
|
+
("N pre-existing finding(s) suppressed"), and gate only NEW drift. Burn the
|
|
155
|
+
baseline down at your own pace; `--no-baseline` shows the full picture anytime.
|
|
156
|
+
|
|
126
157
|
---
|
|
127
158
|
|
|
128
159
|
## Technical
|
|
@@ -3,7 +3,7 @@ schema_version: "1.0"
|
|
|
3
3
|
extension:
|
|
4
4
|
id: "docguard"
|
|
5
5
|
name: "DocGuard — CDD Enforcement"
|
|
6
|
-
version: "0.
|
|
6
|
+
version: "0.33.1"
|
|
7
7
|
description: "Canonical-Driven Development enforcement as a true spec-kit extension. LLM-first design with automated validators, 4 AI behavior skills, spec-kit skill chaining, and workflow hooks. One pinned runtime dependency (@babel/parser); pure Node.js otherwise."
|
|
8
8
|
author: "Ricardo Accioly"
|
|
9
9
|
repository: "https://github.com/raccioly/docguard"
|
|
@@ -6,10 +6,10 @@ description: AI-driven documentation repair with structured research workflow, t
|
|
|
6
6
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
7
7
|
metadata:
|
|
8
8
|
author: docguard
|
|
9
|
-
version: 0.
|
|
9
|
+
version: 0.33.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-fix
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.33.1 -->
|
|
13
13
|
|
|
14
14
|
# DocGuard Fix Skill
|
|
15
15
|
|
|
@@ -7,10 +7,10 @@ description: Run DocGuard guard validation against Canonical-Driven Development
|
|
|
7
7
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
8
8
|
metadata:
|
|
9
9
|
author: docguard
|
|
10
|
-
version: 0.
|
|
10
|
+
version: 0.33.1
|
|
11
11
|
source: extensions/spec-kit-docguard/skills/docguard-guard
|
|
12
12
|
---
|
|
13
|
-
<!-- docguard:version: 0.
|
|
13
|
+
<!-- docguard:version: 0.33.1 -->
|
|
14
14
|
|
|
15
15
|
# DocGuard Guard Skill
|
|
16
16
|
|
|
@@ -6,10 +6,10 @@ description: Cross-document consistency analysis and quality assessment. Perform
|
|
|
6
6
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
7
7
|
metadata:
|
|
8
8
|
author: docguard
|
|
9
|
-
version: 0.
|
|
9
|
+
version: 0.33.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-review
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.33.1 -->
|
|
13
13
|
|
|
14
14
|
# DocGuard Review Skill
|
|
15
15
|
|
|
@@ -6,10 +6,10 @@ description: CDD maturity assessment with category-aware improvement roadmap. Ru
|
|
|
6
6
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
7
7
|
metadata:
|
|
8
8
|
author: docguard
|
|
9
|
-
version: 0.
|
|
9
|
+
version: 0.33.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-score
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.33.1 -->
|
|
13
13
|
|
|
14
14
|
# DocGuard Score Skill
|
|
15
15
|
|
|
@@ -4,10 +4,10 @@ description: Keep canonical documentation ALWAYS UP TO DATE. Refreshes code-trut
|
|
|
4
4
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
5
5
|
metadata:
|
|
6
6
|
author: docguard
|
|
7
|
-
version: 0.
|
|
7
|
+
version: 0.33.1
|
|
8
8
|
source: extensions/spec-kit-docguard/skills/docguard-sync
|
|
9
9
|
---
|
|
10
|
-
<!-- docguard:version: 0.
|
|
10
|
+
<!-- docguard:version: 0.33.1 -->
|
|
11
11
|
|
|
12
12
|
# DocGuard Sync Skill
|
|
13
13
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docguard-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.1",
|
|
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": {
|
|
7
|
-
"docguard": "
|
|
7
|
+
"docguard": "cli/docguard.mjs"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"docguard": "node cli/docguard.mjs",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"repository": {
|
|
38
38
|
"type": "git",
|
|
39
|
-
"url": "https://github.com/raccioly/docguard"
|
|
39
|
+
"url": "git+https://github.com/raccioly/docguard.git"
|
|
40
40
|
},
|
|
41
41
|
"homepage": "https://github.com/raccioly/docguard#readme",
|
|
42
42
|
"mcpName": "io.github.raccioly/docguard",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"docs/",
|
|
58
58
|
"schemas/",
|
|
59
59
|
"STANDARD.md",
|
|
60
|
+
"PRIVACY.md",
|
|
60
61
|
"PHILOSOPHY.md",
|
|
61
62
|
"README.md",
|
|
62
63
|
"LICENSE"
|
|
@@ -29,6 +29,11 @@
|
|
|
29
29
|
"enum": ["cli", "library", "webapp", "api", "unknown"],
|
|
30
30
|
"description": "Project shape. Affects which validators run (e.g. webapp + api need env vars; cli/library can skip)."
|
|
31
31
|
},
|
|
32
|
+
"baseline": {
|
|
33
|
+
"type": "boolean",
|
|
34
|
+
"description": "Set false to ignore a committed .docguard.baseline.json entirely (equivalent to always passing --no-baseline). Default: the baseline auto-applies when the file exists.",
|
|
35
|
+
"default": true
|
|
36
|
+
},
|
|
32
37
|
"projectTypeConfig": {
|
|
33
38
|
"type": "object",
|
|
34
39
|
"description": "Per-type behavior knobs that override profile defaults.",
|