docguard-cli 0.9.4 → 0.9.6
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 +281 -203
- package/cli/commands/init.mjs +1 -0
- package/cli/scanners/speckit.mjs +318 -87
- package/cli/validators/metrics-consistency.mjs +2 -1
- package/cli/validators/traceability.mjs +17 -9
- package/commands/docguard.fix.md +65 -0
- package/commands/docguard.guard.md +60 -0
- package/commands/docguard.review.md +53 -0
- package/commands/docguard.score.md +61 -0
- package/docs/installation.md +37 -19
- package/docs/quickstart.md +21 -6
- package/extensions/spec-kit-docguard/LICENSE +21 -0
- package/extensions/spec-kit-docguard/README.md +105 -0
- package/extensions/spec-kit-docguard/commands/diagnose.md +43 -0
- package/extensions/spec-kit-docguard/commands/generate.md +50 -0
- package/extensions/spec-kit-docguard/commands/guard.md +73 -0
- package/extensions/spec-kit-docguard/commands/init.md +38 -0
- package/extensions/spec-kit-docguard/commands/score.md +53 -0
- package/extensions/spec-kit-docguard/commands/trace.md +56 -0
- package/extensions/spec-kit-docguard/extension.yml +109 -0
- package/extensions/spec-kit-docguard/scripts/bash/common.sh +106 -0
- package/extensions/spec-kit-docguard/scripts/bash/docguard-check-docs.sh +153 -0
- package/extensions/spec-kit-docguard/scripts/bash/docguard-init-doc.sh +153 -0
- package/extensions/spec-kit-docguard/scripts/bash/docguard-suggest-fix.sh +107 -0
- package/extensions/spec-kit-docguard/skills/docguard-fix/SKILL.md +218 -0
- package/extensions/spec-kit-docguard/skills/docguard-guard/SKILL.md +167 -0
- package/extensions/spec-kit-docguard/skills/docguard-review/SKILL.md +182 -0
- package/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +178 -0
- package/extensions/spec-kit-docguard/templates/extensions.yml +39 -0
- package/package.json +5 -2
- package/templates/REQUIREMENTS.md.template +68 -0
- package/templates/commands/docguard.fix.md +35 -39
- package/templates/commands/docguard.guard.md +26 -13
- package/templates/commands/docguard.init.md +35 -28
- package/templates/commands/docguard.review.md +33 -23
- package/templates/commands/docguard.update.md +15 -4
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Calculate CDD maturity score with multi-signal quality breakdown"
|
|
3
|
+
handoffs:
|
|
4
|
+
- label: Improve Score
|
|
5
|
+
agent: docguard.fix
|
|
6
|
+
prompt: Fix highest-ROI documentation issues to improve score
|
|
7
|
+
- label: Deep Review
|
|
8
|
+
agent: docguard.review
|
|
9
|
+
prompt: Perform semantic analysis for accuracy verification
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# DocGuard Score
|
|
13
|
+
|
|
14
|
+
Calculate your project's Canonical-Driven Development maturity score (0-100) across 8 weighted categories.
|
|
15
|
+
|
|
16
|
+
## User Input
|
|
17
|
+
|
|
18
|
+
$ARGUMENTS
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
1. Run DocGuard score on the current project:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx --yes docguard-cli@latest score $ARGUMENTS
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Review the breakdown:
|
|
29
|
+
- **Structure** (25%) — required files present
|
|
30
|
+
- **Doc Quality** (20%) — docs have required sections
|
|
31
|
+
- **Testing** (15%) — test spec alignment
|
|
32
|
+
- **Security** (10%) — no hardcoded secrets
|
|
33
|
+
- **Environment** (10%) — env docs configured
|
|
34
|
+
- **Drift** (10%) — drift tracking discipline
|
|
35
|
+
- **Changelog** (5%) — changelog maintenance
|
|
36
|
+
- **Architecture** (5%) — layer boundary compliance
|
|
37
|
+
|
|
38
|
+
3. For per-signal quality labels, add `--signals`.
|
|
39
|
+
|
|
40
|
+
## Grading
|
|
41
|
+
|
|
42
|
+
| Score | Grade | Status |
|
|
43
|
+
|-------|-------|--------|
|
|
44
|
+
| 90-100 | A | Strong CDD compliance |
|
|
45
|
+
| 75-89 | B | Good, some gaps |
|
|
46
|
+
| 50-74 | C | Needs work |
|
|
47
|
+
| < 50 | D | Significant gaps |
|
|
48
|
+
|
|
49
|
+
## Flags
|
|
50
|
+
|
|
51
|
+
- `--signals` — Show multi-signal CJE composite breakdown with quality labels
|
|
52
|
+
- `--tax` — Show estimated maintenance effort
|
|
53
|
+
- `--format json` — Output as JSON
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Generate requirements traceability matrix"
|
|
3
|
+
handoffs:
|
|
4
|
+
- label: Fix Coverage Gaps
|
|
5
|
+
agent: docguard.fix
|
|
6
|
+
prompt: Fix traceability gaps found in the matrix
|
|
7
|
+
- label: Run Guard
|
|
8
|
+
agent: docguard.guard
|
|
9
|
+
prompt: Validate traceability checks pass
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# DocGuard Trace
|
|
13
|
+
|
|
14
|
+
Generate a requirements traceability matrix mapping canonical docs ↔ source code ↔ tests. Config-aware — respects `.docguard.json` exclusions and detects orphaned files.
|
|
15
|
+
|
|
16
|
+
## User Input
|
|
17
|
+
|
|
18
|
+
$ARGUMENTS
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
1. Run DocGuard trace on the current project:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx --yes docguard-cli@latest trace $ARGUMENTS
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Review the matrix. Each canonical doc gets a coverage signal:
|
|
29
|
+
- **TRACED** — doc + source code + tests all linked
|
|
30
|
+
- **PARTIAL** — doc exists, source found, no test coverage
|
|
31
|
+
- **UNLINKED** — doc exists but no matching source code
|
|
32
|
+
- **MISSING** — doc not found
|
|
33
|
+
|
|
34
|
+
3. Orphaned files (exist but excluded from config) are flagged with cleanup instructions.
|
|
35
|
+
|
|
36
|
+
## Standards
|
|
37
|
+
|
|
38
|
+
Maps against industry standards per document type:
|
|
39
|
+
|
|
40
|
+
| Document | Standard |
|
|
41
|
+
|----------|----------|
|
|
42
|
+
| ARCHITECTURE.md | arc42 / C4 Model |
|
|
43
|
+
| DATA-MODEL.md | C4 Component / ER (Chen) |
|
|
44
|
+
| TEST-SPEC.md | ISO/IEC/IEEE 29119-3 |
|
|
45
|
+
| SECURITY.md | OWASP ASVS v4.0 |
|
|
46
|
+
| ENVIRONMENT.md | 12-Factor App |
|
|
47
|
+
| API-REFERENCE.md | OpenAPI 3.1 |
|
|
48
|
+
|
|
49
|
+
## Flags
|
|
50
|
+
|
|
51
|
+
- `--format json` — Output as JSON
|
|
52
|
+
- `--dir <path>` — Run on a different directory
|
|
53
|
+
|
|
54
|
+
## Research
|
|
55
|
+
|
|
56
|
+
Inspired by ISO/IEC/IEEE 29119 traceability requirements (Lopez et al., AITPG, IEEE TSE 2026).
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
schema_version: "1.0"
|
|
2
|
+
|
|
3
|
+
extension:
|
|
4
|
+
id: "docguard"
|
|
5
|
+
name: "DocGuard — CDD Enforcement"
|
|
6
|
+
version: "0.9.6"
|
|
7
|
+
description: "Canonical-Driven Development enforcement with enterprise-grade AI skills. 19 automated validators, structured research workflows, quality validation loops, and spec-kit integration hooks. Zero dependencies."
|
|
8
|
+
author: "Ricardo Accioly"
|
|
9
|
+
repository: "https://github.com/raccioly/docguard"
|
|
10
|
+
license: "MIT"
|
|
11
|
+
homepage: "https://www.npmjs.com/package/docguard-cli"
|
|
12
|
+
|
|
13
|
+
requires:
|
|
14
|
+
speckit_version: ">=0.1.0"
|
|
15
|
+
tools:
|
|
16
|
+
- name: "node"
|
|
17
|
+
required: true
|
|
18
|
+
version: ">=18.0.0"
|
|
19
|
+
- name: "npx"
|
|
20
|
+
required: true
|
|
21
|
+
|
|
22
|
+
provides:
|
|
23
|
+
commands:
|
|
24
|
+
- name: "docguard.guard"
|
|
25
|
+
file: "commands/guard.md"
|
|
26
|
+
description: "Run 19-validator quality gate with severity triage and remediation plan"
|
|
27
|
+
aliases: ["speckit.docguard.guard"]
|
|
28
|
+
|
|
29
|
+
- name: "docguard.fix"
|
|
30
|
+
file: "commands/fix.md"
|
|
31
|
+
description: "AI-driven documentation repair with codebase research and validation loops"
|
|
32
|
+
aliases: ["speckit.docguard.fix"]
|
|
33
|
+
|
|
34
|
+
- name: "docguard.review"
|
|
35
|
+
file: "commands/review.md"
|
|
36
|
+
description: "Cross-document semantic consistency analysis (read-only)"
|
|
37
|
+
aliases: ["speckit.docguard.review"]
|
|
38
|
+
|
|
39
|
+
- name: "docguard.score"
|
|
40
|
+
file: "commands/score.md"
|
|
41
|
+
description: "CDD maturity score with ROI-based improvement roadmap"
|
|
42
|
+
aliases: ["speckit.docguard.score"]
|
|
43
|
+
|
|
44
|
+
- name: "speckit.docguard.diagnose"
|
|
45
|
+
file: "commands/review.md"
|
|
46
|
+
description: "Diagnose all issues and generate a complete AI remediation plan"
|
|
47
|
+
|
|
48
|
+
- name: "speckit.docguard.generate"
|
|
49
|
+
file: "commands/fix.md"
|
|
50
|
+
description: "Reverse-engineer canonical docs from existing codebase"
|
|
51
|
+
|
|
52
|
+
skills:
|
|
53
|
+
- name: "docguard-guard"
|
|
54
|
+
path: "skills/docguard-guard/SKILL.md"
|
|
55
|
+
description: "19-validator quality gate with severity triage and structured reporting"
|
|
56
|
+
|
|
57
|
+
- name: "docguard-fix"
|
|
58
|
+
path: "skills/docguard-fix/SKILL.md"
|
|
59
|
+
description: "AI-driven documentation repair with research workflow and validation loops"
|
|
60
|
+
|
|
61
|
+
- name: "docguard-review"
|
|
62
|
+
path: "skills/docguard-review/SKILL.md"
|
|
63
|
+
description: "Cross-document semantic consistency analysis with quality scoring"
|
|
64
|
+
|
|
65
|
+
- name: "docguard-score"
|
|
66
|
+
path: "skills/docguard-score/SKILL.md"
|
|
67
|
+
description: "CDD maturity assessment with ROI-based improvement roadmap"
|
|
68
|
+
|
|
69
|
+
scripts:
|
|
70
|
+
- name: "docguard-check-docs"
|
|
71
|
+
path: "scripts/bash/docguard-check-docs.sh"
|
|
72
|
+
description: "Discover project docs, return JSON inventory with metadata"
|
|
73
|
+
|
|
74
|
+
- name: "docguard-suggest-fix"
|
|
75
|
+
path: "scripts/bash/docguard-suggest-fix.sh"
|
|
76
|
+
description: "Run guard, parse results, output prioritized fix suggestions"
|
|
77
|
+
|
|
78
|
+
- name: "docguard-init-doc"
|
|
79
|
+
path: "scripts/bash/docguard-init-doc.sh"
|
|
80
|
+
description: "Initialize a new canonical document with metadata header"
|
|
81
|
+
|
|
82
|
+
hooks:
|
|
83
|
+
after_implement:
|
|
84
|
+
command: "docguard.guard"
|
|
85
|
+
optional: false
|
|
86
|
+
prompt: "Run DocGuard validation after implementation"
|
|
87
|
+
description: "Mandatory quality gate — ensures docs stay in sync with code"
|
|
88
|
+
|
|
89
|
+
before_tasks:
|
|
90
|
+
command: "docguard.review"
|
|
91
|
+
optional: true
|
|
92
|
+
prompt: "Review documentation consistency before generating tasks?"
|
|
93
|
+
|
|
94
|
+
after_tasks:
|
|
95
|
+
command: "docguard.score"
|
|
96
|
+
optional: true
|
|
97
|
+
prompt: "Show CDD maturity score after task generation?"
|
|
98
|
+
|
|
99
|
+
tags:
|
|
100
|
+
- "documentation"
|
|
101
|
+
- "validation"
|
|
102
|
+
- "quality"
|
|
103
|
+
- "cdd"
|
|
104
|
+
- "spec-driven"
|
|
105
|
+
- "traceability"
|
|
106
|
+
- "ai-agents"
|
|
107
|
+
- "enforcement"
|
|
108
|
+
- "spec-kit"
|
|
109
|
+
- "skills"
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# DocGuard — Shared utilities for bash scripts
|
|
3
|
+
# Used by all DocGuard orchestration scripts
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
# ── Project Root Detection ─────────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
find_docguard_root() {
|
|
10
|
+
local dir="${1:-$(pwd)}"
|
|
11
|
+
while [ "$dir" != "/" ]; do
|
|
12
|
+
# Check for DocGuard project markers
|
|
13
|
+
if [ -d "$dir/docs-canonical" ] || [ -f "$dir/.docguard.json" ] || [ -f "$dir/CHANGELOG.md" ]; then
|
|
14
|
+
echo "$dir"
|
|
15
|
+
return 0
|
|
16
|
+
fi
|
|
17
|
+
dir="$(dirname "$dir")"
|
|
18
|
+
done
|
|
19
|
+
return 1
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# ── DocGuard CLI Detection ─────────────────────────────────────────────────
|
|
23
|
+
|
|
24
|
+
find_docguard_cli() {
|
|
25
|
+
local root="${1:-$(pwd)}"
|
|
26
|
+
|
|
27
|
+
# Check for local dev mode first
|
|
28
|
+
if [ -f "$root/cli/docguard.mjs" ]; then
|
|
29
|
+
echo "node $root/cli/docguard.mjs"
|
|
30
|
+
return 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Check for global install
|
|
34
|
+
if command -v docguard-cli >/dev/null 2>&1; then
|
|
35
|
+
echo "docguard-cli"
|
|
36
|
+
return 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Fall back to npx
|
|
40
|
+
if command -v npx >/dev/null 2>&1; then
|
|
41
|
+
echo "npx docguard-cli"
|
|
42
|
+
return 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
return 1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# ── JSON Escape ────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
json_escape() {
|
|
51
|
+
local s="$1"
|
|
52
|
+
s="${s//\\/\\\\}"
|
|
53
|
+
s="${s//\"/\\\"}"
|
|
54
|
+
s="${s//$'\n'/\\n}"
|
|
55
|
+
s="${s//$'\t'/\\t}"
|
|
56
|
+
s="${s//$'\r'/\\r}"
|
|
57
|
+
printf '%s' "$s"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# ── JSON Output Helper ────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
json_output() {
|
|
63
|
+
# Build JSON from key=value pairs
|
|
64
|
+
# Usage: json_output key1 "value1" key2 "value2"
|
|
65
|
+
local result="{"
|
|
66
|
+
local first=true
|
|
67
|
+
while [ $# -ge 2 ]; do
|
|
68
|
+
if [ "$first" = true ]; then
|
|
69
|
+
first=false
|
|
70
|
+
else
|
|
71
|
+
result="$result,"
|
|
72
|
+
fi
|
|
73
|
+
result="$result\"$1\":\"$(json_escape "$2")\""
|
|
74
|
+
shift 2
|
|
75
|
+
done
|
|
76
|
+
result="$result}"
|
|
77
|
+
echo "$result"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# ── Date Helpers ───────────────────────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
today_iso() {
|
|
83
|
+
date +%Y-%m-%d
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# ── File Helpers ───────────────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
file_exists() {
|
|
89
|
+
[ -f "$1" ]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
dir_exists() {
|
|
93
|
+
[ -d "$1" ]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
ensure_dir() {
|
|
97
|
+
mkdir -p "$1"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# ── Metadata Helpers ──────────────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
extract_metadata() {
|
|
103
|
+
local file="$1"
|
|
104
|
+
local key="$2"
|
|
105
|
+
grep "docguard:${key}" "$file" 2>/dev/null | sed "s/.*docguard:${key} //" | sed 's/ -->//' | tr -d '\r'
|
|
106
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# DocGuard — Check project documentation status
|
|
3
|
+
# Returns JSON with document inventory and health status
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./docguard-check-docs.sh [--json] [--verbose]
|
|
7
|
+
#
|
|
8
|
+
# JSON output fields:
|
|
9
|
+
# PROJECT_ROOT — absolute path to project root
|
|
10
|
+
# CLI_CMD — command to run DocGuard CLI
|
|
11
|
+
# DOCS — array of {name, path, exists, version, status, lastReviewed}
|
|
12
|
+
# SCORE — CDD maturity score (if --verbose)
|
|
13
|
+
# GUARD_PASS — number of passing guard checks (if --verbose)
|
|
14
|
+
# GUARD_TOTAL — total guard checks (if --verbose)
|
|
15
|
+
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
19
|
+
source "$SCRIPT_DIR/common.sh"
|
|
20
|
+
|
|
21
|
+
JSON_MODE=false
|
|
22
|
+
VERBOSE=false
|
|
23
|
+
|
|
24
|
+
while [ $# -gt 0 ]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
--json) JSON_MODE=true ;;
|
|
27
|
+
--verbose) VERBOSE=true ;;
|
|
28
|
+
--help|-h)
|
|
29
|
+
echo "Usage: $0 [--json] [--verbose]"
|
|
30
|
+
echo ""
|
|
31
|
+
echo "Options:"
|
|
32
|
+
echo " --json Output in JSON format for AI consumption"
|
|
33
|
+
echo " --verbose Include score and guard results"
|
|
34
|
+
echo " --help Show this help message"
|
|
35
|
+
exit 0
|
|
36
|
+
;;
|
|
37
|
+
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
|
38
|
+
esac
|
|
39
|
+
shift
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
# Find project root
|
|
43
|
+
PROJECT_ROOT=$(find_docguard_root "$(pwd)") || {
|
|
44
|
+
echo "Error: No DocGuard project found. Run 'docguard init' first." >&2
|
|
45
|
+
exit 1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Find CLI command
|
|
49
|
+
CLI_CMD=$(find_docguard_cli "$PROJECT_ROOT") || {
|
|
50
|
+
echo "Error: DocGuard CLI not found. Install with: npm i -g docguard-cli" >&2
|
|
51
|
+
exit 1
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
cd "$PROJECT_ROOT"
|
|
55
|
+
|
|
56
|
+
# Canonical documents to check
|
|
57
|
+
CANONICAL_DOCS=(
|
|
58
|
+
"docs-canonical/ARCHITECTURE.md"
|
|
59
|
+
"docs-canonical/DATA-MODEL.md"
|
|
60
|
+
"docs-canonical/SECURITY.md"
|
|
61
|
+
"docs-canonical/TEST-SPEC.md"
|
|
62
|
+
"docs-canonical/ENVIRONMENT.md"
|
|
63
|
+
"docs-canonical/REQUIREMENTS.md"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Support documents
|
|
67
|
+
SUPPORT_DOCS=(
|
|
68
|
+
"CHANGELOG.md"
|
|
69
|
+
"DRIFT-LOG.md"
|
|
70
|
+
"AGENTS.md"
|
|
71
|
+
"README.md"
|
|
72
|
+
"ROADMAP.md"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if $JSON_MODE; then
|
|
76
|
+
# Build canonical docs JSON array
|
|
77
|
+
DOCS_JSON="["
|
|
78
|
+
first=true
|
|
79
|
+
for doc in "${CANONICAL_DOCS[@]}" "${SUPPORT_DOCS[@]}"; do
|
|
80
|
+
if [ "$first" = true ]; then first=false; else DOCS_JSON="$DOCS_JSON,"; fi
|
|
81
|
+
|
|
82
|
+
doc_name=$(basename "$doc" .md)
|
|
83
|
+
doc_path="$PROJECT_ROOT/$doc"
|
|
84
|
+
doc_exists="false"
|
|
85
|
+
doc_version=""
|
|
86
|
+
doc_status=""
|
|
87
|
+
doc_reviewed=""
|
|
88
|
+
|
|
89
|
+
if [ -f "$doc_path" ]; then
|
|
90
|
+
doc_exists="true"
|
|
91
|
+
doc_version=$(extract_metadata "$doc_path" "version" 2>/dev/null || echo "")
|
|
92
|
+
doc_status=$(extract_metadata "$doc_path" "status" 2>/dev/null || echo "")
|
|
93
|
+
doc_reviewed=$(extract_metadata "$doc_path" "last-reviewed" 2>/dev/null || echo "")
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
DOCS_JSON="$DOCS_JSON{\"name\":\"$(json_escape "$doc_name")\",\"path\":\"$(json_escape "$doc")\",\"exists\":$doc_exists"
|
|
97
|
+
[ -n "$doc_version" ] && DOCS_JSON="$DOCS_JSON,\"version\":\"$(json_escape "$doc_version")\""
|
|
98
|
+
[ -n "$doc_status" ] && DOCS_JSON="$DOCS_JSON,\"status\":\"$(json_escape "$doc_status")\""
|
|
99
|
+
[ -n "$doc_reviewed" ] && DOCS_JSON="$DOCS_JSON,\"lastReviewed\":\"$(json_escape "$doc_reviewed")\""
|
|
100
|
+
DOCS_JSON="$DOCS_JSON}"
|
|
101
|
+
done
|
|
102
|
+
DOCS_JSON="$DOCS_JSON]"
|
|
103
|
+
|
|
104
|
+
# Optionally include score and guard
|
|
105
|
+
EXTRAS=""
|
|
106
|
+
if $VERBOSE; then
|
|
107
|
+
SCORE_OUTPUT=$(eval $CLI_CMD score --format json 2>/dev/null || echo "")
|
|
108
|
+
GUARD_OUTPUT=$(eval $CLI_CMD guard 2>&1 || true)
|
|
109
|
+
|
|
110
|
+
# Extract score
|
|
111
|
+
SCORE=$(echo "$SCORE_OUTPUT" | grep -o '"total":[0-9]*' | head -1 | sed 's/"total"://' || echo "0")
|
|
112
|
+
|
|
113
|
+
# Extract guard pass/total from output like "156/160 passed"
|
|
114
|
+
GUARD_PASS=$(echo "$GUARD_OUTPUT" | grep -o '[0-9]*/[0-9]* passed' | sed 's|/.*||' || echo "0")
|
|
115
|
+
GUARD_TOTAL=$(echo "$GUARD_OUTPUT" | grep -o '[0-9]*/[0-9]* passed' | sed 's|.*/||; s| .*||' || echo "0")
|
|
116
|
+
|
|
117
|
+
EXTRAS=",\"score\":$SCORE,\"guardPass\":$GUARD_PASS,\"guardTotal\":$GUARD_TOTAL"
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
# Check for spec-kit
|
|
121
|
+
HAS_SPECKIT="false"
|
|
122
|
+
[ -d "$PROJECT_ROOT/.specify" ] && HAS_SPECKIT="true"
|
|
123
|
+
|
|
124
|
+
echo "{\"projectRoot\":\"$(json_escape "$PROJECT_ROOT")\",\"cliCommand\":\"$(json_escape "$CLI_CMD")\",\"hasSpecKit\":$HAS_SPECKIT,\"docs\":$DOCS_JSON$EXTRAS}"
|
|
125
|
+
else
|
|
126
|
+
echo "DocGuard Project: $PROJECT_ROOT"
|
|
127
|
+
echo "CLI: $CLI_CMD"
|
|
128
|
+
echo ""
|
|
129
|
+
echo "Canonical Documents:"
|
|
130
|
+
for doc in "${CANONICAL_DOCS[@]}"; do
|
|
131
|
+
if [ -f "$PROJECT_ROOT/$doc" ]; then
|
|
132
|
+
version=$(extract_metadata "$PROJECT_ROOT/$doc" "version" 2>/dev/null || echo "?")
|
|
133
|
+
reviewed=$(extract_metadata "$PROJECT_ROOT/$doc" "last-reviewed" 2>/dev/null || echo "?")
|
|
134
|
+
echo " ✅ $doc (v$version, reviewed: $reviewed)"
|
|
135
|
+
else
|
|
136
|
+
echo " ❌ $doc (MISSING)"
|
|
137
|
+
fi
|
|
138
|
+
done
|
|
139
|
+
echo ""
|
|
140
|
+
echo "Support Documents:"
|
|
141
|
+
for doc in "${SUPPORT_DOCS[@]}"; do
|
|
142
|
+
if [ -f "$PROJECT_ROOT/$doc" ]; then
|
|
143
|
+
echo " ✅ $doc"
|
|
144
|
+
else
|
|
145
|
+
echo " ❌ $doc (MISSING)"
|
|
146
|
+
fi
|
|
147
|
+
done
|
|
148
|
+
|
|
149
|
+
if $VERBOSE; then
|
|
150
|
+
echo ""
|
|
151
|
+
eval $CLI_CMD score 2>&1 || true
|
|
152
|
+
fi
|
|
153
|
+
fi
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# DocGuard — Initialize a new canonical document with metadata header
|
|
3
|
+
# Copies template and adds DocGuard metadata scaffolding
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./docguard-init-doc.sh <doc-name> [--json] [--version X.X.X]
|
|
7
|
+
#
|
|
8
|
+
# Examples:
|
|
9
|
+
# ./docguard-init-doc.sh architecture
|
|
10
|
+
# ./docguard-init-doc.sh security --json --version 0.5.0
|
|
11
|
+
#
|
|
12
|
+
# JSON output fields:
|
|
13
|
+
# DOC_PATH — absolute path to created document
|
|
14
|
+
# DOC_NAME — canonical document name
|
|
15
|
+
# TEMPLATE — template used (if any)
|
|
16
|
+
# CREATED — whether file was created (true/false)
|
|
17
|
+
|
|
18
|
+
set -e
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
source "$SCRIPT_DIR/common.sh"
|
|
22
|
+
|
|
23
|
+
JSON_MODE=false
|
|
24
|
+
DOC_VERSION="0.1.0"
|
|
25
|
+
DOC_NAME=""
|
|
26
|
+
|
|
27
|
+
while [ $# -gt 0 ]; do
|
|
28
|
+
case "$1" in
|
|
29
|
+
--json) JSON_MODE=true ;;
|
|
30
|
+
--version)
|
|
31
|
+
shift
|
|
32
|
+
DOC_VERSION="${1:-0.1.0}"
|
|
33
|
+
;;
|
|
34
|
+
--help|-h)
|
|
35
|
+
echo "Usage: $0 <doc-name> [--json] [--version X.X.X]"
|
|
36
|
+
echo ""
|
|
37
|
+
echo "Document names: architecture, data-model, security, test-spec, environment, requirements"
|
|
38
|
+
echo ""
|
|
39
|
+
echo "Options:"
|
|
40
|
+
echo " --json Output in JSON format"
|
|
41
|
+
echo " --version X.X.X Set initial version (default: 0.1.0)"
|
|
42
|
+
echo " --help Show this help"
|
|
43
|
+
exit 0
|
|
44
|
+
;;
|
|
45
|
+
*)
|
|
46
|
+
if [ -z "$DOC_NAME" ]; then
|
|
47
|
+
DOC_NAME="$1"
|
|
48
|
+
else
|
|
49
|
+
echo "Error: Unexpected argument: $1" >&2
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
;;
|
|
53
|
+
esac
|
|
54
|
+
shift
|
|
55
|
+
done
|
|
56
|
+
|
|
57
|
+
if [ -z "$DOC_NAME" ]; then
|
|
58
|
+
echo "Error: Document name required" >&2
|
|
59
|
+
echo "Usage: $0 <doc-name> [--json] [--version X.X.X]" >&2
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Normalize document name
|
|
64
|
+
DOC_NAME_UPPER=$(echo "$DOC_NAME" | tr '[:lower:]' '[:upper:]' | tr '-' '-')
|
|
65
|
+
DOC_FILE="docs-canonical/${DOC_NAME_UPPER}.md"
|
|
66
|
+
|
|
67
|
+
# Find project root
|
|
68
|
+
PROJECT_ROOT=$(find_docguard_root "$(pwd)") || {
|
|
69
|
+
echo "Error: No DocGuard project found." >&2
|
|
70
|
+
exit 1
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
cd "$PROJECT_ROOT"
|
|
74
|
+
|
|
75
|
+
DOC_PATH="$PROJECT_ROOT/$DOC_FILE"
|
|
76
|
+
CREATED=false
|
|
77
|
+
TEMPLATE_USED=""
|
|
78
|
+
|
|
79
|
+
# Check if file already exists
|
|
80
|
+
if [ -f "$DOC_PATH" ]; then
|
|
81
|
+
if $JSON_MODE; then
|
|
82
|
+
echo "{\"docPath\":\"$(json_escape "$DOC_PATH")\",\"docName\":\"$(json_escape "$DOC_NAME_UPPER")\",\"created\":false,\"reason\":\"File already exists\"}"
|
|
83
|
+
else
|
|
84
|
+
echo "⚠ $DOC_FILE already exists. Use docguard fix to update it."
|
|
85
|
+
fi
|
|
86
|
+
exit 0
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# Ensure docs-canonical directory exists
|
|
90
|
+
ensure_dir "$PROJECT_ROOT/docs-canonical"
|
|
91
|
+
|
|
92
|
+
# Check for template
|
|
93
|
+
TEMPLATE_DIR="$PROJECT_ROOT/templates"
|
|
94
|
+
TEMPLATE_FILE="$TEMPLATE_DIR/${DOC_NAME_UPPER}.md"
|
|
95
|
+
|
|
96
|
+
# Generate metadata header
|
|
97
|
+
TODAY=$(today_iso)
|
|
98
|
+
HEADER="# ${DOC_NAME_UPPER}
|
|
99
|
+
|
|
100
|
+
<!-- docguard:version ${DOC_VERSION} -->
|
|
101
|
+
<!-- docguard:status active -->
|
|
102
|
+
<!-- docguard:last-reviewed ${TODAY} -->
|
|
103
|
+
"
|
|
104
|
+
|
|
105
|
+
if [ -f "$TEMPLATE_FILE" ]; then
|
|
106
|
+
# Use template, but replace/add metadata header
|
|
107
|
+
cp "$TEMPLATE_FILE" "$DOC_PATH"
|
|
108
|
+
TEMPLATE_USED="$TEMPLATE_FILE"
|
|
109
|
+
|
|
110
|
+
# Ensure metadata header exists
|
|
111
|
+
if ! grep -q "docguard:version" "$DOC_PATH"; then
|
|
112
|
+
# Prepend metadata after first heading
|
|
113
|
+
tmp_file=$(mktemp)
|
|
114
|
+
head -1 "$DOC_PATH" > "$tmp_file"
|
|
115
|
+
echo "" >> "$tmp_file"
|
|
116
|
+
echo "<!-- docguard:version ${DOC_VERSION} -->" >> "$tmp_file"
|
|
117
|
+
echo "<!-- docguard:status active -->" >> "$tmp_file"
|
|
118
|
+
echo "<!-- docguard:last-reviewed ${TODAY} -->" >> "$tmp_file"
|
|
119
|
+
tail -n +2 "$DOC_PATH" >> "$tmp_file"
|
|
120
|
+
mv "$tmp_file" "$DOC_PATH"
|
|
121
|
+
fi
|
|
122
|
+
CREATED=true
|
|
123
|
+
else
|
|
124
|
+
# Generate from scratch with skeleton
|
|
125
|
+
cat > "$DOC_PATH" << EOF
|
|
126
|
+
${HEADER}
|
|
127
|
+
<!-- ACTION REQUIRED: This is a skeleton document. Fill each section with
|
|
128
|
+
real project-specific content. Run 'docguard fix --doc ${DOC_NAME}' for
|
|
129
|
+
AI-generated guidance on what to write. -->
|
|
130
|
+
|
|
131
|
+
## Overview
|
|
132
|
+
|
|
133
|
+
[Describe the purpose of this document and what it covers]
|
|
134
|
+
|
|
135
|
+
## Details
|
|
136
|
+
|
|
137
|
+
[Add project-specific content here]
|
|
138
|
+
|
|
139
|
+
## References
|
|
140
|
+
|
|
141
|
+
- [Link to related documents or resources]
|
|
142
|
+
EOF
|
|
143
|
+
CREATED=true
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
if $JSON_MODE; then
|
|
147
|
+
echo "{\"docPath\":\"$(json_escape "$DOC_PATH")\",\"docName\":\"$(json_escape "$DOC_NAME_UPPER")\",\"template\":\"$(json_escape "$TEMPLATE_USED")\",\"created\":$CREATED,\"version\":\"$(json_escape "$DOC_VERSION")\"}"
|
|
148
|
+
else
|
|
149
|
+
echo "✅ Created $DOC_FILE"
|
|
150
|
+
[ -n "$TEMPLATE_USED" ] && echo " Template: $TEMPLATE_USED"
|
|
151
|
+
echo " Version: $DOC_VERSION"
|
|
152
|
+
echo " Next: Run 'docguard fix --doc $DOC_NAME' for content guidance"
|
|
153
|
+
fi
|