docguard-cli 0.18.1 → 0.20.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/README.md CHANGED
@@ -15,6 +15,7 @@
15
15
  ## Table of Contents
16
16
 
17
17
  - [What is DocGuard?](#what-is-docguard)
18
+ - [What's New](#-whats-new)
18
19
  - [Quick Start](#-quick-start)
19
20
  - [Spec Kit Integration](#-spec-kit-integration)
20
21
  - [Usage](#usage)
@@ -50,15 +51,15 @@ DocGuard is an official [GitHub Spec Kit](https://github.com/github/spec-kit) co
50
51
 
51
52
  ```mermaid
52
53
  graph TD
53
- CLI["CLI Entry<br/>docguard.mjs"] --> Commands["Commands (15)"]
54
+ CLI["CLI Entry<br/>docguard.mjs"] --> Commands["Commands (13)"]
54
55
  Commands --> guard["guard"]
55
56
  Commands --> generate["generate"]
56
57
  Commands --> score["score"]
57
58
  Commands --> diagnose["diagnose"]
58
59
  Commands --> setup["setup wizard"]
59
- Commands --> other["diff · init · fix · trace<br/>agents · hooks · badge · ci · watch"]
60
+ Commands --> other["diff · init · fix · trace · impact · sync<br/>explain · memory · upgrade · agents · hooks · badge · ci · watch"]
60
61
 
61
- guard --> Validators["Validators (19)"]
62
+ guard --> Validators["Validators (23)"]
62
63
  generate --> Scanners["Scanners (4)<br/>routes · schemas · doc-tools · speckit"]
63
64
  score --> Scoring["Weighted Scoring<br/>8 categories"]
64
65
  diagnose --> Validators
@@ -81,6 +82,37 @@ graph TD
81
82
 
82
83
  ---
83
84
 
85
+ ## ✨ What's New
86
+
87
+ Recent highlights across the v0.16 → v0.19 line:
88
+
89
+ - **`docguard explain <validator>`** — `docguard explain freshness` prints purpose, rules, common
90
+ failures, and fix recipes for any of the 23 validators. No need to dig into source.
91
+ - **`docguard memory --diff`** — surface what changed in your canonical docs between two refs
92
+ (`HEAD~10..HEAD` by default). Great for code review and changelog drafting.
93
+ - **`docguard score --diff`** — see exactly which validators moved the score up or down between
94
+ two commits. Pinpoints regressions without re-running the full suite by hand.
95
+ - **`docguard upgrade --apply --pr`** — when the config schema bumps, DocGuard migrates
96
+ `.docguard.json` for you and (optionally) opens a PR with the change.
97
+ - **Language-aware patterns** — test discovery and trace mapping now understand Python, Rust, Go,
98
+ Java, Ruby, and PHP layouts in addition to JS/TS. Sensible defaults, override via config.
99
+ - **Per-validator severity overrides** — escalate `freshness` to `high` for production repos,
100
+ demote `doc-quality` to `low` for prototypes. Configurable per-project.
101
+ - **JSON Schema for `.docguard.json`** — IDE autocomplete, in-line docs, and validation via
102
+ `$schema`. Shipped in the package at `schemas/docguard-config.schema.json`.
103
+ - **Version pin (`docguardVersion` + `--pin`)** — pin the CLI version your project supports so
104
+ CI fails loudly if someone bumps DocGuard without re-running the suite.
105
+ - **Cross-process plan cache** — repeated runs reuse the validator plan across processes when
106
+ the working tree hasn't changed. ~30% faster guard runs on typical repos.
107
+ - **Headless-aware banner** — `--quiet`, `--format json`, `--write`, and `--changed-only`
108
+ automatically suppress the banner so JSON output stays parse-clean.
109
+ - **npm-pack smoke gate** — every release now extracts the actual tarball and runs the CLI
110
+ end-to-end before publish, catching missing-file regressions.
111
+
112
+ See [CHANGELOG.md](CHANGELOG.md) for the full history.
113
+
114
+ ---
115
+
84
116
  ## ⚡ Quick Start
85
117
 
86
118
  ### Node.js (npm)
@@ -203,24 +235,49 @@ This installs DocGuard's slash commands (`/docguard.guard`, `/docguard.review`,
203
235
 
204
236
  ## Usage
205
237
 
206
- DocGuard ships **13 commands**:
238
+ DocGuard ships **13 commands** (the "Daily 5" + 8 situational tools). Six additional one-shot scaffolders are accessed via `docguard init --with <name>`. Eight v0.19 commands continue to work as deprecation aliases through v0.20.x — see [MIGRATION-v0.20.md](docs-implementation/MIGRATION-v0.20.md).
239
+
240
+ **The Daily 5** — what you'll reach for 95% of the time:
241
+
242
+ | Command | What It Does |
243
+ |:--------|:-------------|
244
+ | `init` | Bootstrap a project (`--wizard` for interactive · `--with <name>` for scaffolders) |
245
+ | `guard` | Validate against canonical docs — 23 validators |
246
+ | `diff` | Show gaps between docs and code (`--since <ref>` for impact mode) |
247
+ | `sync` | Refresh code-truth doc sections — keeps memory always up to date |
248
+ | `score` | CDD maturity score (0-100; `--diff` for delta between refs) |
249
+
250
+ **Tools (situational, but day-to-day useful):**
207
251
 
208
252
  | Command | Purpose |
209
253
  |:--------|:--------|
210
- | `diagnose` | **Primary**identify every issue + generate AI fix prompts |
211
- | `guard` | Validate project against canonical docs (CI gate) |
212
- | `generate` | Reverse-engineer docs from existing codebase |
213
- | `init` | Initialize CDD docs from templates (interactive) |
214
- | `score` | CDD maturity score (0–100) with weighted breakdown |
215
- | `fix --doc <name>` | Generate AI prompt for a specific document |
216
- | `fix --write` | Apply deterministic fixes (remove stale documented endpoints) no AI |
217
- | `diff` | Compare canonical docs vs actual code artifacts |
218
- | `agents` | Generate agent-specific config files |
219
- | `trace` | Requirements traceability matrix |
220
- | `ci` | CI/CD pipeline check with threshold |
221
- | `watch` | Live watch mode with auto-fix |
222
- | `hooks` | Install git hooks (pre-commit, pre-push) |
223
- | `llms` | Generate `llms.txt` (AI-friendly project summary) |
254
+ | `diagnose` | AI orchestrator guard emit fix prompts in one command |
255
+ | `fix` | Generate AI fix instructions for specific docs (`--doc <name> --format prompt`) |
256
+ | `fix --write` | Apply deterministic fixes (no AI — version bumps, counts, anchors, sections) |
257
+ | `fix --history` | Audit log of every mechanical fix applied (from `.docguard/fixed.json`) |
258
+ | `generate` | Reverse-engineer docs from existing codebase (`--plan` for AI scan) |
259
+ | `explain <warning>` | Paste any warning get the validator's docstring + fix path |
260
+ | `memory` | Per-domain accuracy headline (endpoints / entities / env / tech) |
261
+ | `memory --diff` | Drill into which specific claims don't match code |
262
+ | `score --diff` | Drill into which checks pulled each category down |
263
+ | `trace` / `trace --reverse <file>` | Requirements traceability forward AND reverse |
264
+ | `upgrade [--apply] [--pr]` | Check + migrate `.docguard.json` schema; `--pr` opens a PR |
265
+ | `watch` | Live mode: re-run guard on file changes |
266
+
267
+ **`init --with <name>` scaffolders** picked at init time:
268
+
269
+ | Scaffolder | What It Generates |
270
+ |:-----------|:------------------|
271
+ | `agents` | `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/`, `.github/copilot-instructions.md` |
272
+ | `hooks` | Git pre-commit / pre-push hooks |
273
+ | `ci` | GitHub Actions / pipeline YAML |
274
+ | `badge` | Shields.io score badges for README |
275
+ | `llms` | `llms.txt` (AI-friendly summary) |
276
+ | `publish` | External doc-site config (Mintlify) — experimental |
277
+
278
+ Run them solo (`docguard init --with hooks`) or stacked (`docguard init --with agents,hooks,badge,ci`).
279
+
280
+ **Deprecation aliases** — `setup` · `agents` · `hooks` · `ci` · `badge` · `llms` · `publish` · `impact` keep working in v0.20.x with a yellow stderr warning. `audit → guard` is permanent (no warning). See [MIGRATION-v0.20.md](docs-implementation/MIGRATION-v0.20.md).
224
281
 
225
282
  ### CLI Flags
226
283
 
@@ -228,10 +285,22 @@ DocGuard ships **13 commands**:
228
285
  |:-----|:------------|:---------|
229
286
  | `--dir <path>` | Project directory (default: `.`) | All |
230
287
  | `--verbose` | Show detailed output | All |
231
- | `--format json` | Machine-readable output for CI/CD | score, guard, diff |
288
+ | `--quiet` / `-q` | Suppress banner for hooks, CI loops, scripts | All |
289
+ | `--format json` | Machine-readable output (clean JSON, no ANSI bleed) | guard, score, diff, trace, diagnose, memory, impact, explain |
232
290
  | `--force` | Overwrite existing files (creates `.bak` backups) | generate, agents, init |
233
- | `--profile <name>` | Starter, standard, or enterprise | init |
234
- | `--agent <name>` | Target specific AI agent | agents |
291
+ | `--force-redo` | Bypass ping-pong suppression in `.docguard/fixed.json` | fix --write |
292
+ | `--profile <name>` | Starter / standard / enterprise | init |
293
+ | `--no-spec-kit` | Skip auto-init of `.specify/` / `.agent/` scaffolding | init |
294
+ | `--changed-only [--since <ref>]` | Pre-commit lite mode (5 fast validators on changed files only) | guard |
295
+ | `--timings` | Per-validator wall-time profile (slowest first) | guard |
296
+ | `--show-failing` | Show warnings/errors even when status is PASS | guard |
297
+ | `--pin` | Record running CLI version into `.docguard.json` (reproducibility) | guard |
298
+ | `--diff` | Per-category drill-down | score, memory |
299
+ | `--check-only` | Exit 1 if behind (for CI) | upgrade |
300
+ | `--apply` | Actually run the migration | upgrade |
301
+ | `--pr` | Open a PR with the migration | upgrade |
302
+ | `--reverse <file>` | Reverse traceability (code → docs) | trace |
303
+ | `--history` | Show fix audit log | fix |
235
304
 
236
305
  ### Example Output
237
306
 
@@ -266,30 +335,47 @@ $ npx docguard-cli generate
266
335
 
267
336
  ## 🔍 Validators
268
337
 
269
- DocGuard runs **19 automated validators** on every `guard` check:
338
+ DocGuard runs **23 automated validators** on every `guard` check. Every one is **language-aware** as of v0.16 — patterns for Python (`test_*.py`), Rust (`tests/*.rs`), Go (`*_test.go`), Java (`*Test.java`), Ruby (`*_spec.rb`), PHP, and JS/TS all match.
270
339
 
271
340
  | # | Validator | What It Checks | Default |
272
341
  |:--|:----------|:--------------|:--------|
273
342
  | 1 | **Structure** | Required CDD files exist | ✅ On |
274
- | 2 | **Doc Sections** | Canonical docs have required sections | ✅ On |
343
+ | 2 | **Doc Sections** | Canonical docs have required sections (or N/A markers) | ✅ On |
275
344
  | 3 | **Docs-Sync** | Routes/services referenced in docs + OpenAPI cross-check | ✅ On |
276
- | 4 | **Drift-Comments** | `// DRIFT:` comments logged in DRIFT-LOG.md | ✅ On |
345
+ | 4 | **Drift-Comments** | `// DRIFT:` comments logged in DRIFT-LOG.md (skips test files by default) | ✅ On |
277
346
  | 5 | **Changelog** | CHANGELOG.md has [Unreleased] section | ✅ On |
278
347
  | 6 | **Test-Spec** | Tests exist per TEST-SPEC.md rules | ✅ On |
279
- | 7 | **Environment** | Env vars documented, .env.example exists | ✅ On |
348
+ | 7 | **Environment** | Env vars documented, `.env.example` exists | ✅ On |
280
349
  | 8 | **Security** | No hardcoded secrets in source code | ✅ On |
281
- | 9 | **Architecture** | Imports follow layer boundaries | ✅ On |
282
- | 10 | **Freshness** | Docs not stale relative to code changes | ✅ On |
350
+ | 9 | **Architecture** | Imports follow layer boundaries (honors `config.ignore`) | ✅ On |
351
+ | 10 | **Freshness** | Docs not stale relative to code changes (rename-aware via `git log --follow`) | ✅ On |
283
352
  | 11 | **Traceability** | Requirement IDs (FR, SC, NFR, US, AC, T) trace to tests | ✅ On |
284
353
  | 12 | **Docs-Diff** | Code artifacts match documented entities | ✅ On |
285
- | 13 | **Metadata-Sync** | Version refs consistent across docs | ✅ On |
286
- | 14 | **Docs-Coverage** | Code features referenced in documentation | ✅ On |
287
- | 15 | **Metrics-Consistency** | Hardcoded numbers match actual counts | ✅ On |
288
- | 16 | **Doc-Quality** | Writing quality (readability, passive voice, atomicity) | ✅ On |
289
- | 17 | **TODO-Tracking** | Untracked TODOs/FIXMEs and skipped tests | ✅ On |
354
+ | 13 | **API-Surface** | API-REFERENCE.md endpoints match real routes (OpenAPI cross-check) | ✅ On |
355
+ | 14 | **Metadata-Sync** | Version refs consistent across docs | ✅ On |
356
+ | 15 | **Docs-Coverage** | Code features referenced in documentation | ✅ On |
357
+ | 16 | **Doc-Quality** | Writing quality (readability, passive voice, atomicity, IEEE 830) | ✅ On |
358
+ | 17 | **TODO-Tracking** | Untracked TODOs/FIXMEs and skipped tests (skips test files by default) | ✅ On |
290
359
  | 18 | **Schema-Sync** | Database models documented in DATA-MODEL.md | ✅ On |
291
360
  | 19 | **Spec-Kit** | Spec quality validation (FR-IDs, mandatory sections, phased tasks) | ✅ On |
292
- | 20 | **API-Surface** | API-REFERENCE.md endpoints match the real API surface (OpenAPI spec / routes); flags documented-but-deleted endpoints | ✅ On |
361
+ | 20 | **Cross-Reference** | Internal markdown links + anchors resolve (with "did you mean?" hints) | ✅ On |
362
+ | 21 | **Generated-Staleness** | `source=code` sections match scanner output; `status: draft` doc age | ✅ On |
363
+ | 22 | **Canonical-Sync** | DocGuard's own README count claims match code-truth (DocGuard repo only — N/A elsewhere) | ✅ On |
364
+ | 23 | **Metrics-Consistency** | Hardcoded numbers match actual counts | ✅ On |
365
+
366
+ **Per-validator controls** (in `.docguard.json`):
367
+ ```json
368
+ {
369
+ "validators": {
370
+ "test-spec": false, // disable (kebab-case OR camelCase both accepted)
371
+ "freshness": true
372
+ },
373
+ "severity": {
374
+ "todoTracking": "high", // warnings fail CI
375
+ "freshness": "low" // warnings ignored for exit code
376
+ }
377
+ }
378
+ ```
293
379
 
294
380
  ---
295
381
 
@@ -343,7 +429,7 @@ DocGuard provides AI agent slash commands for integrated workflows. Installed au
343
429
 
344
430
  | Command | What It Does |
345
431
  |:--------|:-------------|
346
- | `/docguard.guard` | Run quality validation — check all 22 validators |
432
+ | `/docguard.guard` | Run quality validation — check all 23 validators |
347
433
  | `/docguard.review` | Analyze doc quality and suggest improvements |
348
434
  | `/docguard.fix` | Generate targeted fix prompts for specific issues |
349
435
  | `/docguard.score` | Show CDD maturity score with category breakdown |
@@ -139,7 +139,8 @@ import { validateCrossReferences } from '../validators/cross-reference.mjs';
139
139
  import { validateGeneratedStaleness } from '../validators/generated-staleness.mjs';
140
140
  import { validateTodoTracking } from '../validators/todo-tracking.mjs';
141
141
  import { validateSchemaSync } from '../validators/schema-sync.mjs';
142
- import { validateSpecKitIntegration } from '../scanners/speckit.mjs';
142
+ import { validateSpecKitIntegration } from '../validators/spec-kit.mjs';
143
+ import { validateCanonicalSync } from '../validators/canonical-sync.mjs';
143
144
 
144
145
  /**
145
146
  * Internal guard — returns structured data, no console output, no process.exit.
@@ -237,6 +238,22 @@ export function runGuardInternal(projectDir, config) {
237
238
  }
238
239
  }
239
240
 
241
+ // ── Canonical-Sync runs AFTER main loop, BEFORE metrics-consistency.
242
+ // Needs the live validator results to count "real" validators that ran.
243
+ // (Pre-canonical-sync ordering — comes before metrics-consistency so the
244
+ // metrics validator sees a stable surface count.)
245
+ if (validators.canonicalSync !== false) {
246
+ const start = performance.now();
247
+ try {
248
+ const result = validateCanonicalSync(projectDir, config, results);
249
+ const durationMs = Math.round((performance.now() - start) * 100) / 100;
250
+ results.push({ ...result, name: 'Canonical-Sync', key: 'canonicalSync', durationMs, ...classifyResult(result) });
251
+ } catch (err) {
252
+ const durationMs = Math.round((performance.now() - start) * 100) / 100;
253
+ results.push({ name: 'Canonical-Sync', key: 'canonicalSync', status: 'fail', quality: 'LOW', errors: [err.message], warnings: [], passed: 0, total: 1, durationMs });
254
+ }
255
+ }
256
+
240
257
  // ── Metrics-Consistency runs AFTER all other validators (needs their results) ──
241
258
  if (validators.metricsConsistency !== false) {
242
259
  const start = performance.now();
@@ -317,7 +334,8 @@ function liteValidatorsConfig() {
317
334
  'structure', 'docsSync', 'drift', 'changelog', 'testSpec', 'environment',
318
335
  'security', 'architecture', 'freshness', 'traceability', 'docsDiff',
319
336
  'apiSurface', 'metadataSync', 'docsCoverage', 'docQuality', 'todoTracking',
320
- 'schemaSync', 'specKit', 'crossReference', 'generatedStaleness', 'metricsConsistency',
337
+ 'schemaSync', 'specKit', 'crossReference', 'generatedStaleness',
338
+ 'canonicalSync', 'metricsConsistency',
321
339
  ];
322
340
  const out = {};
323
341
  for (const k of all) out[k] = CHANGED_ONLY_VALIDATORS.includes(k);
@@ -17,6 +17,45 @@ import { execSync } from 'node:child_process';
17
17
  import { c, PROFILES } from '../shared.mjs';
18
18
  import { ensureSkills, detectAgentMode, detectAIAgent, isSpecKitAvailable, isSpecKitInitialized, getDetectedAgent } from '../ensure-skills.mjs';
19
19
 
20
+ // v0.20: scaffolder names that can be passed via `init --with <name>` and
21
+ // dispatched to the corresponding standalone runner. Each name maps to its
22
+ // canonical command module. Keep in sync with cli/docguard.mjs router.
23
+ const SCAFFOLDER_DISPATCH = {
24
+ agents: async (dir, cfg, flags) => (await import('./agents.mjs')).runAgents(dir, cfg, flags),
25
+ hooks: async (dir, cfg, flags) => (await import('./hooks.mjs')).runHooks(dir, cfg, flags),
26
+ ci: async (dir, cfg, flags) => (await import('./ci.mjs')).runCI(dir, cfg, flags),
27
+ badge: async (dir, cfg, flags) => (await import('./badge.mjs')).runBadge(dir, cfg, flags),
28
+ llms: async (dir, cfg, flags) => (await import('./llms.mjs')).runLlms(dir, cfg, flags),
29
+ publish: async (dir, cfg, flags) => (await import('./publish.mjs')).runPublish(dir, cfg, flags),
30
+ };
31
+
32
+ /**
33
+ * Run one or more scaffolders after init has completed.
34
+ * Called when `docguard init --with agents,hooks,ci` is invoked.
35
+ * Each scaffolder runs in sequence; if one throws, the rest are skipped
36
+ * (matches the standalone command's failure semantics).
37
+ */
38
+ async function runScaffolders(projectDir, config, flags, names) {
39
+ const unknown = names.filter(n => !SCAFFOLDER_DISPATCH[n]);
40
+ if (unknown.length > 0) {
41
+ console.error(`${c.red}Unknown --with target(s): ${unknown.join(', ')}${c.reset}`);
42
+ console.log(`${c.dim}Valid: ${Object.keys(SCAFFOLDER_DISPATCH).join(', ')}${c.reset}`);
43
+ process.exit(1);
44
+ }
45
+
46
+ console.log(`\n${c.bold}🧰 Scaffolders:${c.reset} ${c.cyan}${names.join(', ')}${c.reset}\n`);
47
+
48
+ for (const name of names) {
49
+ console.log(`${c.dim}── ${name} ───────────────────────────────────────${c.reset}`);
50
+ try {
51
+ await SCAFFOLDER_DISPATCH[name](projectDir, config, flags);
52
+ } catch (err) {
53
+ console.error(`${c.red}✗ ${name} failed: ${err.message}${c.reset}`);
54
+ process.exit(1);
55
+ }
56
+ }
57
+ }
58
+
20
59
  function detectProjectType(dir) {
21
60
  const pkgPath = resolve(dir, 'package.json');
22
61
  if (existsSync(pkgPath)) {
@@ -54,6 +93,14 @@ function askQuestion(prompt) {
54
93
  // ── Init Command ─────────────────────────────────────────────────────────
55
94
 
56
95
  export async function runInit(projectDir, config, flags) {
96
+ // v0.20: `--wizard` dispatches to the full interactive onboarding (formerly
97
+ // `docguard setup`). Done before profile validation so the wizard can ask
98
+ // for the profile itself if needed.
99
+ if (flags.wizard) {
100
+ const { runSetup } = await import('./setup.mjs');
101
+ return runSetup(projectDir, config, flags);
102
+ }
103
+
57
104
  const profileName = flags.profile || 'standard';
58
105
  const profile = PROFILES[profileName];
59
106
 
@@ -369,4 +416,11 @@ poetry.lock
369
416
 
370
417
  // Auto-install DocGuard skills and commands (spec-kit skills handled by specify init)
371
418
  ensureSkills(projectDir, flags);
419
+
420
+ // v0.20: `docguard init --with agents,hooks,ci,badge,llms,publish` runs
421
+ // the named scaffolders after init has finished. Each one runs in sequence
422
+ // and uses the same flags object (so --force / --skip-prompts propagate).
423
+ if (Array.isArray(flags.with) && flags.with.length > 0) {
424
+ await runScaffolders(projectDir, config, flags, flags.with);
425
+ }
372
426
  }
package/cli/docguard.mjs CHANGED
@@ -282,36 +282,37 @@ function printHelp() {
282
282
  console.log(`${c.bold}Usage:${c.reset}
283
283
  docguard <command> [options]
284
284
 
285
- ${c.bold}Getting Started:${c.reset}
286
- ${c.green}init${c.reset} Initialize CDD docs (interactive setup)
287
- ${c.green}setup${c.reset} Full onboarding wizard (skills, integrations, hooks)
288
- ${c.green}generate${c.reset} Reverse-engineer canonical docs from existing code
289
-
290
- ${c.bold}Enforcement:${c.reset}
291
- ${c.green}guard${c.reset} Validate project against canonical docs (51+ checks)
292
- ${c.green}diagnose${c.reset} AI orchestrator — guard → fix in one command
293
-
294
- ${c.bold}Memory (build & maintain docs):${c.reset}
295
- ${c.green}generate --plan${c.reset} AI-powered: scan any project, emit agent task manifest + skeleton
296
- ${c.green}sync${c.reset} Refresh code-truth doc sections to match current code (always up to date)
297
-
298
- ${c.bold}Analysis:${c.reset}
299
- ${c.green}score${c.reset} CDD maturity score (0-100)
300
- ${c.green}trace${c.reset} Requirements traceability matrix
301
- ${c.green}diff${c.reset} Show gaps between docs and code (detailed view)
302
-
303
- ${c.bold}CI/CD & Automation:${c.reset}
304
- ${c.green}ci${c.reset} Pipeline gate (guard + score, exit codes)
305
- ${c.green}hooks${c.reset} Install/manage git hooks
306
- ${c.green}watch${c.reset} Watch for changes, re-run guard
307
-
308
- ${c.bold}Utilities:${c.reset}
285
+ ${c.bold}The Daily 5${c.reset} ${c.dim}— what you'll reach for 95% of the time${c.reset}
286
+ ${c.green}init${c.reset} Bootstrap a project (use ${c.cyan}--wizard${c.reset} for guided / ${c.cyan}--with <name>${c.reset} for scaffolders)
287
+ ${c.green}guard${c.reset} Validate against canonical docs (23 validators)
288
+ ${c.green}diff${c.reset} Show gaps between docs and code (add ${c.cyan}--since <ref>${c.reset} for changed-file impact)
289
+ ${c.green}sync${c.reset} Refresh code-truth doc sections — keeps memory always up to date
290
+ ${c.green}score${c.reset} CDD maturity score (0-100; ${c.cyan}--diff${c.reset} for delta between refs)
291
+
292
+ ${c.bold}Tools (situational, but day-to-day useful)${c.reset}
293
+ ${c.green}diagnose${c.reset} AI orchestrator — guard → emit fix prompts in one command
309
294
  ${c.green}fix${c.reset} Generate AI fix instructions for specific docs
310
- ${c.green}agents${c.reset} Generate agent config files (AGENTS.md, CLAUDE.md)
311
- ${c.green}badge${c.reset} Generate CDD score badges for README
312
-
313
- ${c.bold}Experimental:${c.reset}
314
- ${c.dim}publish${c.reset} Scaffold external doc sites (Mintlify)
295
+ ${c.green}generate${c.reset} Reverse-engineer canonical docs from existing code (${c.cyan}--plan${c.reset} for AI scan)
296
+ ${c.green}explain${c.reset} Explain a validator key or warning text
297
+ ${c.green}memory${c.reset} Show what DocGuard remembers (${c.cyan}--diff${c.reset} drills into drift)
298
+ ${c.green}trace${c.reset} Requirements traceability matrix (${c.cyan}--reverse${c.reset} for code→doc map)
299
+ ${c.green}upgrade${c.reset} Migrate ${c.cyan}.docguard.json${c.reset} schema + CLI (${c.cyan}--apply --pr${c.reset} for team-wide PR)
300
+ ${c.green}watch${c.reset} Live mode: re-run guard on file changes
301
+
302
+ ${c.bold}init --with <name>${c.reset} ${c.dim}— optional scaffolders, picked at init time${c.reset}
303
+ ${c.dim}agents${c.reset} AGENTS.md / CLAUDE.md / .cursor/rules / Copilot instructions
304
+ ${c.dim}hooks${c.reset} Git pre-commit / pre-push hooks
305
+ ${c.dim}ci${c.reset} GitHub Actions / pipeline config
306
+ ${c.dim}badge${c.reset} Shields.io score badges for README
307
+ ${c.dim}llms${c.reset} llms.txt generation
308
+ ${c.dim}publish${c.reset} External doc-site scaffold (Mintlify) ${c.dim}— experimental${c.reset}
309
+
310
+ ${c.bold}Deprecation aliases${c.reset} ${c.dim}— still work in v0.20.x with a yellow warning${c.reset}
311
+ ${c.dim}setup${c.reset} → ${c.cyan}init --wizard${c.reset}
312
+ ${c.dim}agents · hooks · ci · badge · llms · publish${c.reset} → ${c.cyan}init --with <name>${c.reset}
313
+ ${c.dim}impact${c.reset} → ${c.cyan}diff --since <ref>${c.reset}
314
+ ${c.dim}audit${c.reset} → ${c.green}guard${c.reset} ${c.dim}(permanent — no warning, no removal planned)${c.reset}
315
+ ${c.dim}See docs-implementation/MIGRATION-v0.20.md for the full timeline.${c.reset}
315
316
 
316
317
  ${c.bold}Options:${c.reset}
317
318
  --dir <path> Project directory (default: current directory)
@@ -459,6 +460,17 @@ async function main() {
459
460
  // v0.17-P2: `docguard memory --diff` drills into accuracy mismatches.
460
461
  // Distinct from the `diff` command itself (which is a top-level cmd).
461
462
  flags.diff = true;
463
+ } else if (args[i] === '--with' && args[i + 1]) {
464
+ // v0.20: `docguard init --with agents,hooks,ci,badge,llms,publish`
465
+ // folds the six standalone scaffolders into init. Comma-separated
466
+ // names, each dispatched to the matching runner after init finishes.
467
+ flags.with = args[i + 1].split(',').map(s => s.trim()).filter(Boolean);
468
+ i++;
469
+ } else if (args[i] === '--wizard') {
470
+ // v0.20: `docguard init --wizard` runs the 7-step interactive
471
+ // onboarding flow (previously `docguard setup`). `setup` keeps
472
+ // working as a deprecation alias.
473
+ flags.wizard = true;
462
474
  } else if (!args[i].startsWith('--') && i > 0) {
463
475
  // Positional args go into flags.args for commands that take them (e.g.
464
476
  // `docguard trace --reverse <path>`). Skip the command itself (i === 0).
@@ -522,17 +534,61 @@ async function main() {
522
534
  ensureSkills(projectDir, flags);
523
535
  }
524
536
 
537
+ // v0.20: deprecation aliases. The legacy command keeps working through v0.20
538
+ // and emits a yellow stderr warning suggesting the new shape. Quiet mode
539
+ // (e.g. inside hooks) suppresses the warning so CI output stays clean.
540
+ // The full deprecation timeline is in docs-implementation/MIGRATION-v0.20.md.
541
+ const DEPRECATED_COMMANDS = {
542
+ setup: { since: '0.20', replacement: 'docguard init --wizard' },
543
+ agents: { since: '0.20', replacement: 'docguard init --with agents' },
544
+ hooks: { since: '0.20', replacement: 'docguard init --with hooks' },
545
+ ci: { since: '0.20', replacement: 'docguard init --with ci' },
546
+ badge: { since: '0.20', replacement: 'docguard init --with badge' },
547
+ llms: { since: '0.20', replacement: 'docguard init --with llms' },
548
+ publish: { since: '0.20', replacement: 'docguard init --with publish' },
549
+ impact: { since: '0.20', replacement: 'docguard diff --since <ref>' },
550
+ };
551
+
552
+ // v0.20: dropped aliases — the 10 cute variants the audit identified.
553
+ // `audit` is intentionally NOT here; it remains a permanent silent alias
554
+ // for `guard` (per SURFACE-AUDIT §8.1 — older CI scripts depend on it).
555
+ const DROPPED_ALIASES = {
556
+ onboard: 'setup (deprecated) — try `docguard init --wizard`',
557
+ gen: 'generate',
558
+ badges: 'badge (deprecated) — try `docguard init --with badge`',
559
+ pipeline: 'ci (deprecated) — try `docguard init --with ci`',
560
+ repair: 'fix',
561
+ dx: 'diagnose',
562
+ pub: 'publish (deprecated) — try `docguard init --with publish`',
563
+ traceability: 'trace',
564
+ 'help-warning': 'explain',
565
+ update: 'upgrade',
566
+ };
567
+
568
+ if (DROPPED_ALIASES[command]) {
569
+ console.error(`${c.red}Unknown command: ${command}${c.reset}`);
570
+ console.error(`${c.yellow}Hint: this alias was removed in v0.20. Try ${c.cyan}docguard ${DROPPED_ALIASES[command]}${c.yellow}.${c.reset}`);
571
+ console.error(`${c.dim}See docs-implementation/MIGRATION-v0.20.md for the full list.${c.reset}`);
572
+ process.exit(1);
573
+ }
574
+
575
+ if (DEPRECATED_COMMANDS[command] && !flags.quiet) {
576
+ const { since, replacement } = DEPRECATED_COMMANDS[command];
577
+ console.error(`${c.yellow}⚠ Deprecated since v${since}:${c.reset} ${c.cyan}docguard ${command}${c.reset} → use ${c.cyan}${replacement}${c.reset}`);
578
+ console.error(`${c.dim} The old form still works in v0.20.x but will be removed in v1.0. See MIGRATION-v0.20.md.${c.reset}`);
579
+ }
580
+
525
581
  switch (command) {
526
582
  case 'audit':
527
- // audit is an alias for guard guard does everything the old audit did + 50 more checks
583
+ // Permanent silent alias for guard (SURFACE-AUDIT §8.1).
528
584
  runGuard(projectDir, config, flags);
529
585
  break;
530
586
  case 'init':
531
587
  await runInit(projectDir, config, flags);
532
588
  break;
533
589
  case 'setup':
534
- case 'onboard':
535
- await runSetup(projectDir, config, flags);
590
+ // v0.20: deprecated → dispatches to init --wizard
591
+ await runInit(projectDir, config, { ...flags, wizard: true });
536
592
  break;
537
593
  case 'guard':
538
594
  runGuard(projectDir, config, flags);
@@ -541,32 +597,35 @@ async function main() {
541
597
  runScore(projectDir, config, flags);
542
598
  break;
543
599
  case 'diff':
544
- runDiff(projectDir, config, flags);
600
+ // v0.20: `docguard diff --since <ref>` dispatches to the impact-mode
601
+ // analyzer (post-commit "which docs reference files changed since X").
602
+ // Without --since it's the standard current-state drift report.
603
+ if (flags.since) {
604
+ runImpact(projectDir, config, flags);
605
+ } else {
606
+ runDiff(projectDir, config, flags);
607
+ }
545
608
  break;
546
609
  case 'agents':
547
- runAgents(projectDir, config, flags);
610
+ // v0.20: deprecated → dispatches through init --with
611
+ await runInit(projectDir, config, { ...flags, with: ['agents'], skipPrompts: true });
548
612
  break;
549
613
  case 'generate':
550
- case 'gen':
551
614
  runGenerate(projectDir, config, flags);
552
615
  break;
553
616
  case 'hooks':
554
- runHooks(projectDir, config, flags);
617
+ await runInit(projectDir, config, { ...flags, with: ['hooks'], skipPrompts: true });
555
618
  break;
556
619
  case 'badge':
557
- case 'badges':
558
- runBadge(projectDir, config, flags);
620
+ await runInit(projectDir, config, { ...flags, with: ['badge'], skipPrompts: true });
559
621
  break;
560
622
  case 'ci':
561
- case 'pipeline':
562
- runCI(projectDir, config, flags);
623
+ await runInit(projectDir, config, { ...flags, with: ['ci'], skipPrompts: true });
563
624
  break;
564
625
  case 'fix':
565
- case 'repair':
566
626
  runFix(projectDir, config, flags);
567
627
  break;
568
628
  case 'diagnose':
569
- case 'dx':
570
629
  runDiagnose(projectDir, config, flags);
571
630
  break;
572
631
  case 'watch':
@@ -576,25 +635,23 @@ async function main() {
576
635
  runSync(projectDir, config, flags);
577
636
  break;
578
637
  case 'publish':
579
- case 'pub':
580
- runPublish(projectDir, config, flags);
638
+ await runInit(projectDir, config, { ...flags, with: ['publish'], skipPrompts: true });
581
639
  break;
582
640
  case 'trace':
583
- case 'traceability':
584
641
  runTrace(projectDir, config, flags);
585
642
  break;
586
643
  case 'llms':
587
- runLlms(projectDir, config, flags);
644
+ await runInit(projectDir, config, { ...flags, with: ['llms'], skipPrompts: true });
588
645
  break;
589
646
  case 'upgrade':
590
- case 'update':
591
647
  await runUpgrade(projectDir, config, flags);
592
648
  break;
593
649
  case 'impact':
594
- runImpact(projectDir, config, flags);
650
+ // v0.20: deprecated alias for `diff --since`. Default --since HEAD~1
651
+ // matches impact's historical behavior.
652
+ runImpact(projectDir, config, { ...flags, since: flags.since || 'HEAD~1' });
595
653
  break;
596
654
  case 'explain':
597
- case 'help-warning':
598
655
  runExplain(projectDir, config, flags);
599
656
  break;
600
657
  case 'memory':
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Canonical-Sync Validator — v0.19-A.
3
+ *
4
+ * The missing self-check. Until this validator existed, `guard` could not
5
+ * see when the docs lied about DocGuard's own surface. README claimed
6
+ * "ships 19 commands" while 21 files existed in `cli/commands/`; the
7
+ * architecture diagram drifted across 5 releases (15 → 19 → still wrong)
8
+ * because no validator was checking. SURFACE-AUDIT.md §7 specifies the
9
+ * rules; this is the implementation.
10
+ *
11
+ * Scope: DocGuard's own repository only. Gated by `package.json` name ===
12
+ * "docguard-cli". For every other project, this validator returns N/A —
13
+ * the "ships N commands" pattern is meaningless in a generic project's
14
+ * docs (their N refers to their own product, not DocGuard's surface).
15
+ *
16
+ * What it checks:
17
+ * 1. README "ships N commands" matches `cli/commands/*.mjs` file count
18
+ * 2. README "N validators" matches `runGuardInternal()` output length
19
+ * (or, if no guardResults passed, falls back to file count + the 2
20
+ * inlined validators: Doc Sections in structure.mjs + Spec-Kit)
21
+ * 3. Validator names enumerated inline in README appear in guard output
22
+ *
23
+ * What it explicitly skips:
24
+ * - ROADMAP.md (historical phase logs — "Built with 9 validators" is
25
+ * legitimately about v0.7, not today)
26
+ * - CHANGELOG.md (same — entries describe what shipped, not current state)
27
+ * - docs-implementation/ (snapshots of past state)
28
+ * - `<!-- docguard:section source=human -->` blocks (prose, not inventory)
29
+ *
30
+ * Self-counting: per SURFACE-AUDIT §8.5, this validator counts itself.
31
+ * After v0.19 ships, README claims "23 validators" (the previous 22 +
32
+ * canonical-sync). The check passes only if the README matches reality
33
+ * INCLUDING the new validator.
34
+ *
35
+ * Severity: HIGH — a doc lying about the basic surface is a credibility
36
+ * killer for a documentation-quality tool.
37
+ *
38
+ * Zero NPM runtime dependencies — pure Node.js built-ins only.
39
+ */
40
+
41
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
42
+ import { resolve, join } from 'node:path';
43
+
44
+ /**
45
+ * Validate that README count claims about DocGuard's surface match code-truth.
46
+ * Returns N/A for non-DocGuard projects.
47
+ *
48
+ * @param {string} projectDir - Project root directory
49
+ * @param {object} config - DocGuard config (unused but required by validator interface)
50
+ * @param {Array} [guardResults] - Results array from runGuardInternal (optional but recommended)
51
+ * @returns {{ errors: string[], warnings: string[], fixes: object[], passed: number, total: number, na?: boolean, naReason?: string }}
52
+ */
53
+ export function validateCanonicalSync(projectDir, config, guardResults) {
54
+ const result = { errors: [], warnings: [], fixes: [], passed: 0, total: 0 };
55
+
56
+ // ── Gate: only run in DocGuard's own repo ─────────────────────────────
57
+ const pkgPath = resolve(projectDir, 'package.json');
58
+ if (!existsSync(pkgPath)) {
59
+ return { ...result, na: true, naReason: 'no package.json' };
60
+ }
61
+
62
+ let pkg;
63
+ try {
64
+ pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
65
+ } catch {
66
+ return { ...result, na: true, naReason: 'unreadable package.json' };
67
+ }
68
+
69
+ if (pkg.name !== 'docguard-cli') {
70
+ return {
71
+ ...result,
72
+ na: true,
73
+ naReason: 'canonical-sync only runs in the docguard-cli repo (it polices DocGuard\'s own surface)',
74
+ };
75
+ }
76
+
77
+ // ── Gather code-truth ────────────────────────────────────────────────
78
+ const cliDir = resolve(projectDir, 'cli');
79
+ const commandsDir = resolve(cliDir, 'commands');
80
+ const validatorsDir = resolve(cliDir, 'validators');
81
+
82
+ if (!existsSync(commandsDir) || !existsSync(validatorsDir)) {
83
+ return { ...result, na: true, naReason: 'cli/commands or cli/validators not found' };
84
+ }
85
+
86
+ const commandFiles = readdirSync(commandsDir).filter(f => f.endsWith('.mjs'));
87
+ const actualCommandFileCount = commandFiles.length;
88
+
89
+ // v0.20: the user-facing command count is what shows up in --help's "Daily 5"
90
+ // and "Tools" sections — NOT the file count, since deprecation aliases dispatch
91
+ // through the same files. Parse cli/docguard.mjs to find names in those
92
+ // sections so the README claim and code-truth stay in lockstep across renames.
93
+ const cliEntry = resolve(cliDir, 'docguard.mjs');
94
+ let actualUserFacingCount = actualCommandFileCount; // fallback if parse fails
95
+ if (existsSync(cliEntry)) {
96
+ try {
97
+ const cliSrc = readFileSync(cliEntry, 'utf-8');
98
+ // Match `${c.green}<name>${c.reset}` inside the Daily 5 / Tools blocks.
99
+ // Anything in init --with / Deprecation aliases sections uses c.dim, so
100
+ // they're naturally excluded.
101
+ const helpBlock = cliSrc.match(/The Daily 5[\s\S]*?Deprecation aliases/);
102
+ if (helpBlock) {
103
+ const greenNames = [...helpBlock[0].matchAll(/\$\{c\.green\}(\w+)\$\{c\.reset\}/g)]
104
+ .map(m => m[1]);
105
+ // Unique names (init shows up only once)
106
+ actualUserFacingCount = [...new Set(greenNames)].length;
107
+ }
108
+ } catch { /* fall through to file-count fallback */ }
109
+ }
110
+ const actualCommandCount = actualUserFacingCount;
111
+
112
+ // Validator count: always use the file-count truth source. It's run-order
113
+ // independent (canonical-sync runs BEFORE metrics-consistency at guard time,
114
+ // so guardResults.length would undercount by 1). File count + 1 for the
115
+ // single inlined validator (Doc Sections, exported alongside Structure from
116
+ // structure.mjs).
117
+ const validatorFiles = readdirSync(validatorsDir).filter(f => f.endsWith('.mjs'));
118
+ const actualValidatorCount = validatorFiles.length + 1; // +1 for Doc Sections inlined in structure.mjs
119
+
120
+ // Names list (currently unused for warnings, but kept for future Check 3
121
+ // where the README enumerates validator names inline).
122
+ let actualValidatorNames = [];
123
+ if (Array.isArray(guardResults) && guardResults.length > 0) {
124
+ actualValidatorNames = guardResults.map(r => r.name).filter(Boolean);
125
+ }
126
+
127
+ // ── Read README ─────────────────────────────────────────────────────
128
+ const readmePath = resolve(projectDir, 'README.md');
129
+ if (!existsSync(readmePath)) {
130
+ result.warnings.push('canonical-sync: README.md not found — cannot check surface claims');
131
+ result.total = 1;
132
+ return result;
133
+ }
134
+
135
+ let readme;
136
+ try {
137
+ readme = readFileSync(readmePath, 'utf-8');
138
+ } catch {
139
+ result.warnings.push('canonical-sync: README.md unreadable');
140
+ result.total = 1;
141
+ return result;
142
+ }
143
+
144
+ // ── Check 1: "ships N commands" ─────────────────────────────────────
145
+ result.total++;
146
+ const shipsCommandsRe = /ships\s+\*{0,2}(\d+)\s+commands?\*{0,2}/i;
147
+ const m1 = readme.match(shipsCommandsRe);
148
+ if (m1) {
149
+ const claimed = Number(m1[1]);
150
+ if (claimed === actualCommandCount) {
151
+ result.passed++;
152
+ } else {
153
+ const detail = actualUserFacingCount !== actualCommandFileCount
154
+ ? `${actualCommandCount} user-facing commands in --help (${actualCommandFileCount} files including deprecation aliases)`
155
+ : `${actualCommandCount} command file(s)`;
156
+ result.warnings.push(
157
+ `README.md claims "ships ${claimed} commands" but the real count is ${detail}. Update the README.`
158
+ );
159
+ }
160
+ } else {
161
+ // No claim found — that's OK, just don't check this one
162
+ result.passed++;
163
+ }
164
+
165
+ // ── Check 2: "N validators" in surface context ──────────────────────
166
+ // Match phrases like "22 validators", "all 22 validators", "the 22 validators"
167
+ // but NOT phase-log entries like "Built with 9 validators" (those are
168
+ // historical, and ROADMAP.md/CHANGELOG.md are skipped at the file level).
169
+ result.total++;
170
+ const validatorMatches = [...readme.matchAll(/(?:all|the|with|across|ships?)\s+\*{0,2}(\d+)\s+validators?\*{0,2}/gi)];
171
+ if (validatorMatches.length > 0) {
172
+ const wrongClaims = validatorMatches
173
+ .map(m => Number(m[1]))
174
+ .filter(n => n !== actualValidatorCount);
175
+ if (wrongClaims.length === 0) {
176
+ result.passed++;
177
+ } else {
178
+ const uniqueWrong = [...new Set(wrongClaims)];
179
+ result.warnings.push(
180
+ `README.md claims ${uniqueWrong.map(n => `"${n} validators"`).join(' / ')} but guard reports ${actualValidatorCount}. Update the README.`
181
+ );
182
+ }
183
+ } else {
184
+ result.passed++;
185
+ }
186
+
187
+ // ── Check 3: architecture-diagram counts ────────────────────────────
188
+ // Catches the specific "Commands (N)" and "Validators (N)" patterns in
189
+ // the mermaid block that drifted across 5 releases.
190
+ result.total++;
191
+ const archMatches = [
192
+ { re: /Commands\s*\((\d+)\)/, label: 'Commands', expected: actualCommandCount },
193
+ { re: /Validators\s*\((\d+)\)/, label: 'Validators', expected: actualValidatorCount },
194
+ ];
195
+ const archWrong = [];
196
+ for (const { re, label, expected } of archMatches) {
197
+ const m = readme.match(re);
198
+ if (m && Number(m[1]) !== expected) {
199
+ archWrong.push(`${label} (${m[1]}) → should be (${expected})`);
200
+ }
201
+ }
202
+ if (archWrong.length === 0) {
203
+ result.passed++;
204
+ } else {
205
+ result.warnings.push(
206
+ `README.md architecture diagram has stale counts: ${archWrong.join('; ')}. Update the mermaid block.`
207
+ );
208
+ }
209
+
210
+ return result;
211
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Spec-Kit Validator — Validates Spec Kit artifacts (specs/, plans/, tasks/, constitution).
3
+ *
4
+ * v0.19-D: Architectural move. The validation logic still lives in
5
+ * `scanners/speckit.mjs` (where the spec-kit data is scanned), but the
6
+ * validator entry-point now lives here in `validators/` so the file count
7
+ * matches the validator count. This also makes the canonical-sync validator's
8
+ * truth source (`ls cli/validators/*.mjs`) align with what `guard` reports.
9
+ *
10
+ * Re-exports `validateSpecKitIntegration` from the scanner. Importers should
11
+ * use this path (`validators/spec-kit.mjs`) going forward.
12
+ */
13
+
14
+ export { validateSpecKitIntegration } from '../scanners/speckit.mjs';
@@ -68,7 +68,7 @@ diagnose → AI reads prompts → AI fixes docs → guard verifies
68
68
  ## Verify
69
69
 
70
70
  ```bash
71
- npx docguard-cli guard # Pass/fail check (22 validators)
71
+ npx docguard-cli guard # Pass/fail check (23 validators)
72
72
  npx docguard-cli score # 0-100 maturity score
73
73
  ```
74
74
 
@@ -4,7 +4,7 @@ Enterprise-grade Canonical-Driven Development (CDD) enforcement and **AI-readabl
4
4
 
5
5
  ## Features
6
6
 
7
- - **22 Validators** — Structure, Security, Doc Quality, Test-Spec, Drift-Comments, API-Surface, Freshness, Cross-Reference, and 13 more
7
+ - **23 Validators** — Structure, Security, Doc Quality, Test-Spec, Drift-Comments, API-Surface, Freshness, Cross-Reference, and 13 more
8
8
  - **Language-agnostic** — JS/TS, Python, Rust, Go, Java/Kotlin, Ruby, PHP, C#. Polyglot/monorepo-aware.
9
9
  - **AI-powered Generate** — `generate --plan` builds the code-truth skeleton in `<!-- docguard:section -->` markers and emits a structured agent task manifest; the AI writes the prose.
10
10
  - **Always up to date** — `sync` surgically refreshes code-truth doc sections in place, **preserves human prose**, flags prose for agent review.
@@ -3,7 +3,7 @@ schema_version: "1.0"
3
3
  extension:
4
4
  id: "docguard"
5
5
  name: "DocGuard — CDD Enforcement"
6
- version: "0.18.1"
6
+ version: "0.20.0"
7
7
  description: "Canonical-Driven Development enforcement as a true spec-kit extension. LLM-first design with 19 automated validators, 4 AI behavior skills, spec-kit skill chaining, and workflow hooks. Zero NPM runtime dependencies."
8
8
  author: "Ricardo Accioly"
9
9
  repository: "https://github.com/raccioly/docguard"
@@ -28,22 +28,22 @@ provides:
28
28
  - name: "speckit.docguard.guard"
29
29
  file: "commands/guard.md"
30
30
  description: "Run 19-validator quality gate with severity triage and remediation plan"
31
- aliases: ["docguard.guard"]
31
+ aliases: ["speckit.docguard.guard"]
32
32
 
33
33
  - name: "speckit.docguard.fix"
34
34
  file: "commands/generate.md"
35
35
  description: "AI-driven documentation repair with codebase research and validation loops"
36
- aliases: ["docguard.fix"]
36
+ aliases: ["speckit.docguard.fix"]
37
37
 
38
38
  - name: "speckit.docguard.review"
39
39
  file: "commands/diagnose.md"
40
40
  description: "Cross-document semantic consistency analysis (read-only)"
41
- aliases: ["docguard.review"]
41
+ aliases: ["speckit.docguard.review"]
42
42
 
43
43
  - name: "speckit.docguard.score"
44
44
  file: "commands/score.md"
45
45
  description: "CDD maturity score with ROI-based improvement roadmap"
46
- aliases: ["docguard.score"]
46
+ aliases: ["speckit.docguard.score"]
47
47
 
48
48
  - name: "speckit.docguard.diagnose"
49
49
  file: "commands/diagnose.md"
@@ -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.18.1
9
+ version: 0.20.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-fix
11
11
  ---
12
- <!-- docguard:version: 0.18.1 -->
12
+ <!-- docguard:version: 0.20.0 -->
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.18.1
10
+ version: 0.20.0
11
11
  source: extensions/spec-kit-docguard/skills/docguard-guard
12
12
  ---
13
- <!-- docguard:version: 0.18.1 -->
13
+ <!-- docguard:version: 0.20.0 -->
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.18.1
9
+ version: 0.20.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-review
11
11
  ---
12
- <!-- docguard:version: 0.18.1 -->
12
+ <!-- docguard:version: 0.20.0 -->
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.18.1
9
+ version: 0.20.0
10
10
  source: extensions/spec-kit-docguard/skills/docguard-score
11
11
  ---
12
- <!-- docguard:version: 0.18.1 -->
12
+ <!-- docguard:version: 0.20.0 -->
13
13
 
14
14
  # DocGuard Score Skill
15
15
 
@@ -4,7 +4,7 @@ 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.18.1
7
+ version: 0.20.0
8
8
  source: extensions/spec-kit-docguard/skills/docguard-sync
9
9
  ---
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docguard-cli",
3
- "version": "0.18.1",
3
+ "version": "0.20.0",
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": {