dev-playbooks-cn 1.0.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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +466 -0
  3. package/bin/devbooks.js +987 -0
  4. package/package.json +43 -0
  5. package/skills/Skills/344/275/277/347/224/250/350/257/264/346/230/216.md +446 -0
  6. package/skills/Skill/345/274/200/345/217/221/346/214/207/345/215/227.md +248 -0
  7. package/skills/_shared/context-detection-template.md +315 -0
  8. package/skills/_shared/mcp-enhancement-template.md +144 -0
  9. package/skills/_shared/references//351/200/232/347/224/250/345/256/210/351/227/250/345/215/217/350/256/256.md +114 -0
  10. package/skills/_template/config-discovery-template.md +126 -0
  11. package/skills/devbooks-brownfield-bootstrap/SKILL.md +167 -0
  12. package/skills/devbooks-brownfield-bootstrap/references//344/273/243/347/240/201/345/257/274/350/210/252/347/255/226/347/225/245.md +203 -0
  13. package/skills/devbooks-brownfield-bootstrap/references//345/255/230/351/207/217/351/241/271/347/233/256/345/210/235/345/247/213/345/214/226.md +96 -0
  14. package/skills/devbooks-brownfield-bootstrap/references//345/255/230/351/207/217/351/241/271/347/233/256/345/210/235/345/247/213/345/214/226/346/217/220/347/244/272/350/257/215.md +115 -0
  15. package/skills/devbooks-brownfield-bootstrap/references//346/234/257/350/257/255/350/241/250/346/250/241/346/235/277.md +42 -0
  16. package/skills/devbooks-brownfield-bootstrap/scripts/cod-update.sh +357 -0
  17. package/skills/devbooks-brownfield-bootstrap/templates/project-profile-template.md +172 -0
  18. package/skills/devbooks-c4-map/SKILL.md +151 -0
  19. package/skills/devbooks-c4-map/references/C4/346/236/266/346/236/204/345/234/260/345/233/276/346/217/220/347/244/272/350/257/215.md +33 -0
  20. package/skills/devbooks-c4-map/references//345/210/206/345/261/202/347/272/246/346/235/237/346/243/200/346/237/245/346/270/205/345/215/225.md +185 -0
  21. package/skills/devbooks-code-review/SKILL.md +175 -0
  22. package/skills/devbooks-code-review/references/PR/346/250/241/346/235/277/344/270/216/346/214/207/345/215/227.md +321 -0
  23. package/skills/devbooks-code-review/references//344/273/243/347/240/201/350/257/204/345/256/241/346/217/220/347/244/272/350/257/215.md +100 -0
  24. package/skills/devbooks-code-review/references//345/235/217/345/221/263/351/201/223/351/200/237/346/237/245/350/241/250.md +495 -0
  25. package/skills/devbooks-code-review/references//350/265/204/346/272/220/347/256/241/347/220/206/345/256/241/346/237/245/346/270/205/345/215/225.md +311 -0
  26. package/skills/devbooks-coder/SKILL.md +219 -0
  27. package/skills/devbooks-coder/references//344/273/243/347/240/201/345/256/236/347/216/260/346/217/220/347/244/272/350/257/215.md +70 -0
  28. package/skills/devbooks-coder/references//344/275/216/351/243/216/351/231/251/346/224/271/345/212/250/346/212/200/346/234/257.md +275 -0
  29. package/skills/devbooks-coder/references//346/227/245/345/277/227/350/247/204/350/214/203.md +329 -0
  30. package/skills/devbooks-coder/references//347/274/226/347/240/201/351/243/216/346/240/274/347/273/206/345/210/231.md +351 -0
  31. package/skills/devbooks-coder/references//351/224/231/350/257/257/347/240/201/350/247/204/350/214/203.md +463 -0
  32. package/skills/devbooks-delivery-workflow/SKILL.md +217 -0
  33. package/skills/devbooks-delivery-workflow/references//344/272/244/344/273/230/351/252/214/346/224/266/345/267/245/344/275/234/346/265/201.md +256 -0
  34. package/skills/devbooks-delivery-workflow/references//345/216/237/345/236/213-/347/224/237/344/272/247/345/217/214/350/275/250/346/250/241/345/274/217.md +168 -0
  35. package/skills/devbooks-delivery-workflow/references//345/217/230/346/233/264/351/252/214/350/257/201/344/270/216/350/277/275/346/272/257/346/250/241/346/235/277.md +133 -0
  36. package/skills/devbooks-delivery-workflow/scripts/ac-trace-check.sh +330 -0
  37. package/skills/devbooks-delivery-workflow/scripts/audit-scope.sh +262 -0
  38. package/skills/devbooks-delivery-workflow/scripts/change-check.sh +1040 -0
  39. package/skills/devbooks-delivery-workflow/scripts/change-codemod-scaffold.sh +135 -0
  40. package/skills/devbooks-delivery-workflow/scripts/change-evidence.sh +152 -0
  41. package/skills/devbooks-delivery-workflow/scripts/change-scaffold.sh +442 -0
  42. package/skills/devbooks-delivery-workflow/scripts/change-spec-delta-scaffold.sh +136 -0
  43. package/skills/devbooks-delivery-workflow/scripts/constitution-check.sh +237 -0
  44. package/skills/devbooks-delivery-workflow/scripts/env-match-check.sh +128 -0
  45. package/skills/devbooks-delivery-workflow/scripts/fitness-check.sh +387 -0
  46. package/skills/devbooks-delivery-workflow/scripts/guardrail-check.sh +519 -0
  47. package/skills/devbooks-delivery-workflow/scripts/handoff-check.sh +141 -0
  48. package/skills/devbooks-delivery-workflow/scripts/hygiene-check.sh +340 -0
  49. package/skills/devbooks-delivery-workflow/scripts/migrate-from-openspec.sh +385 -0
  50. package/skills/devbooks-delivery-workflow/scripts/migrate-to-v2-gates.sh +202 -0
  51. package/skills/devbooks-delivery-workflow/scripts/progress-dashboard.sh +319 -0
  52. package/skills/devbooks-delivery-workflow/scripts/prototype-promote.sh +341 -0
  53. package/skills/devbooks-delivery-workflow/scripts/spec-preview.sh +203 -0
  54. package/skills/devbooks-delivery-workflow/scripts/spec-promote.sh +118 -0
  55. package/skills/devbooks-delivery-workflow/scripts/spec-rollback.sh +124 -0
  56. package/skills/devbooks-delivery-workflow/scripts/spec-stage.sh +117 -0
  57. package/skills/devbooks-delivery-workflow/scripts/verify-all.sh +78 -0
  58. package/skills/devbooks-delivery-workflow/scripts/verify-npm-package.sh +123 -0
  59. package/skills/devbooks-delivery-workflow/scripts/verify-openspec-free.sh +81 -0
  60. package/skills/devbooks-delivery-workflow/scripts/verify-slash-commands.sh +146 -0
  61. package/skills/devbooks-delivery-workflow/templates/handoff.md +50 -0
  62. package/skills/devbooks-design-backport/SKILL.md +73 -0
  63. package/skills/devbooks-design-backport/references//345/233/236/345/206/231/350/256/276/350/256/241/346/226/207/346/241/243/346/217/220/347/244/272/350/257/215.md +196 -0
  64. package/skills/devbooks-design-doc/SKILL.md +121 -0
  65. package/skills/devbooks-design-doc/references//345/276/256/346/234/215/345/212/241/350/256/276/350/256/241/346/270/205/345/215/225.md +149 -0
  66. package/skills/devbooks-design-doc/references//350/256/276/350/256/241/346/226/207/346/241/243/346/217/220/347/244/272/350/257/215.md +189 -0
  67. package/skills/devbooks-design-doc/references//351/232/220/347/247/201/345/220/210/350/247/204/346/243/200/346/237/245/346/270/205/345/215/225.md +240 -0
  68. package/skills/devbooks-entropy-monitor/SKILL.md +188 -0
  69. package/skills/devbooks-entropy-monitor/references//347/206/265/345/272/246/351/207/217/346/226/271/346/263/225/350/256/272.md +223 -0
  70. package/skills/devbooks-entropy-monitor/scripts/entropy-measure.sh +449 -0
  71. package/skills/devbooks-entropy-monitor/scripts/entropy-report.sh +303 -0
  72. package/skills/devbooks-entropy-monitor/templates/thresholds.json +99 -0
  73. package/skills/devbooks-federation/SKILL.md +264 -0
  74. package/skills/devbooks-federation/scripts/federation-check.sh +144 -0
  75. package/skills/devbooks-federation/templates/federation.yaml +89 -0
  76. package/skills/devbooks-impact-analysis/SKILL.md +135 -0
  77. package/skills/devbooks-impact-analysis/references//345/275/261/345/223/215/345/210/206/346/236/220/346/217/220/347/244/272/350/257/215.md +82 -0
  78. package/skills/devbooks-impact-analysis/scripts/graph-cache.sh +214 -0
  79. package/skills/devbooks-implementation-plan/SKILL.md +83 -0
  80. package/skills/devbooks-implementation-plan/references//347/274/226/347/240/201/350/256/241/345/210/222/346/217/220/347/244/272/350/257/215.md +99 -0
  81. package/skills/devbooks-index-bootstrap/SKILL.md +240 -0
  82. package/skills/devbooks-proposal-author/SKILL.md +83 -0
  83. package/skills/devbooks-proposal-author/references//346/217/220/346/241/210/346/222/260/345/206/231/346/217/220/347/244/272/350/257/215.md +66 -0
  84. package/skills/devbooks-proposal-challenger/SKILL.md +86 -0
  85. package/skills/devbooks-proposal-challenger/references//344/274/246/347/220/206/344/270/216/345/220/210/350/247/204/346/243/200/346/237/245/346/270/205/345/215/225.md +176 -0
  86. package/skills/devbooks-proposal-challenger/references//346/217/220/346/241/210/350/264/250/347/226/221/346/217/220/347/244/272/350/257/215.md +57 -0
  87. package/skills/devbooks-proposal-debate-workflow/SKILL.md +78 -0
  88. package/skills/devbooks-proposal-debate-workflow/references//346/217/220/346/241/210/345/257/271/350/276/251/345/267/245/344/275/234/346/265/201.md +24 -0
  89. package/skills/devbooks-proposal-debate-workflow/references//346/217/220/346/241/210/345/257/271/350/276/251/346/250/241/346/235/277.md +35 -0
  90. package/skills/devbooks-proposal-debate-workflow/scripts/proposal-debate-check.sh +102 -0
  91. package/skills/devbooks-proposal-judge/SKILL.md +78 -0
  92. package/skills/devbooks-proposal-judge/references//346/217/220/346/241/210/350/243/201/345/206/263/346/217/220/347/244/272/350/257/215.md +37 -0
  93. package/skills/devbooks-router/SKILL.md +346 -0
  94. package/skills/devbooks-spec-contract/SKILL.md +191 -0
  95. package/skills/devbooks-spec-contract/references/API/350/256/276/350/256/241/346/214/207/345/215/227.md +349 -0
  96. package/skills/devbooks-spec-contract/references//345/245/221/347/272/246/344/270/216/346/225/260/346/215/256/345/256/232/344/271/211/346/217/220/347/244/272/350/257/215.md +85 -0
  97. package/skills/devbooks-spec-contract/references//350/247/204/346/240/274/345/217/230/346/233/264/346/217/220/347/244/272/350/257/215.md +63 -0
  98. package/skills/devbooks-spec-contract/references//351/232/220/345/274/217/345/217/230/346/233/264/346/243/200/346/265/213/346/217/220/347/244/272/350/257/215.md +183 -0
  99. package/skills/devbooks-spec-contract/scripts/implicit-change-detect.sh +378 -0
  100. package/skills/devbooks-spec-gardener/SKILL.md +72 -0
  101. package/skills/devbooks-spec-gardener/references//350/247/204/346/240/274/345/233/255/344/270/201/346/217/220/347/244/272/350/257/215.md +41 -0
  102. package/skills/devbooks-test-owner/SKILL.md +172 -0
  103. package/skills/devbooks-test-owner/references//345/217/230/346/233/264/351/252/214/350/257/201/344/270/216/350/277/275/346/272/257/346/250/241/346/235/277.md +228 -0
  104. package/skills/devbooks-test-owner/references//345/274/202/346/255/245/347/263/273/347/273/237/346/265/213/350/257/225/347/255/226/347/225/245.md +316 -0
  105. package/skills/devbooks-test-owner/references//346/265/213/350/257/225/344/273/243/347/240/201/346/217/220/347/244/272/350/257/215.md +208 -0
  106. package/skills/devbooks-test-owner/references//346/265/213/350/257/225/345/210/206/345/261/202/347/255/226/347/225/245.md +281 -0
  107. package/skills/devbooks-test-owner/references//346/265/213/350/257/225/351/251/261/345/212/250.md +394 -0
  108. package/skills/devbooks-test-owner/references//350/247/243/344/276/235/350/265/226/346/212/200/346/234/257/351/200/237/346/237/245/350/241/250.md +432 -0
  109. package/skills/devbooks-test-reviewer/SKILL.md +189 -0
  110. package/templates/.devbooks/config.yaml +88 -0
  111. package/templates/claude-commands/devbooks/apply.md +38 -0
  112. package/templates/claude-commands/devbooks/archive.md +33 -0
  113. package/templates/claude-commands/devbooks/backport.md +19 -0
  114. package/templates/claude-commands/devbooks/bootstrap.md +19 -0
  115. package/templates/claude-commands/devbooks/c4.md +19 -0
  116. package/templates/claude-commands/devbooks/challenger.md +19 -0
  117. package/templates/claude-commands/devbooks/code.md +19 -0
  118. package/templates/claude-commands/devbooks/debate.md +19 -0
  119. package/templates/claude-commands/devbooks/delivery.md +19 -0
  120. package/templates/claude-commands/devbooks/design.md +19 -0
  121. package/templates/claude-commands/devbooks/entropy.md +19 -0
  122. package/templates/claude-commands/devbooks/federation.md +19 -0
  123. package/templates/claude-commands/devbooks/gardener.md +19 -0
  124. package/templates/claude-commands/devbooks/impact.md +19 -0
  125. package/templates/claude-commands/devbooks/index.md +19 -0
  126. package/templates/claude-commands/devbooks/judge.md +19 -0
  127. package/templates/claude-commands/devbooks/plan.md +19 -0
  128. package/templates/claude-commands/devbooks/proposal.md +19 -0
  129. package/templates/claude-commands/devbooks/quick.md +42 -0
  130. package/templates/claude-commands/devbooks/review.md +19 -0
  131. package/templates/claude-commands/devbooks/router.md +19 -0
  132. package/templates/claude-commands/devbooks/spec.md +19 -0
  133. package/templates/claude-commands/devbooks/test-review.md +19 -0
  134. package/templates/claude-commands/devbooks/test.md +19 -0
  135. package/templates/dev-playbooks/README.md +458 -0
  136. package/templates/dev-playbooks/changes/.gitkeep +1 -0
  137. package/templates/dev-playbooks/constitution.md +116 -0
  138. package/templates/dev-playbooks/project.md +96 -0
  139. package/templates/dev-playbooks/scripts/.gitkeep +1 -0
  140. package/templates/dev-playbooks/specs/_meta/anti-patterns/.gitkeep +2 -0
  141. package/templates/dev-playbooks/specs/_meta/glossary.md +47 -0
  142. package/templates/dev-playbooks/specs/_meta/project-profile.md +79 -0
  143. package/templates/dev-playbooks/specs/architecture/fitness-rules.md +95 -0
@@ -0,0 +1,330 @@
1
+ #!/bin/bash
2
+ # skills/devbooks-delivery-workflow/scripts/ac-trace-check.sh
3
+ # AC-ID Traceability Coverage Check Script
4
+ #
5
+ # Checks the traceability coverage of AC-IDs from design to tests.
6
+ #
7
+ # Usage:
8
+ # ./ac-trace-check.sh <change-id> [options]
9
+ # ./ac-trace-check.sh --help
10
+ #
11
+ # Options:
12
+ # --threshold N Coverage threshold (default 80)
13
+ # --output FORMAT Output format (text|json, default text)
14
+ # --project-root DIR Project root directory
15
+ # --change-root DIR Change package directory
16
+ #
17
+ # Exit codes:
18
+ # 0 - Coverage meets threshold
19
+ # 1 - Coverage below threshold
20
+ # 2 - Usage error
21
+
22
+ set -euo pipefail
23
+
24
+ # Version
25
+ VERSION="1.0.0"
26
+
27
+ # Defaults
28
+ threshold=80
29
+ output_format="text"
30
+ project_root="."
31
+ change_root="changes"
32
+
33
+ # Color output
34
+ RED='\033[0;31m'
35
+ GREEN='\033[0;32m'
36
+ YELLOW='\033[0;33m'
37
+ BLUE='\033[0;34m'
38
+ NC='\033[0m'
39
+
40
+ # Show help
41
+ show_help() {
42
+ cat << 'EOF'
43
+ AC-ID Traceability Coverage Check Script (ac-trace-check.sh)
44
+
45
+ Usage:
46
+ ./ac-trace-check.sh <change-id> [options]
47
+
48
+ Options:
49
+ --threshold N Coverage threshold, default 80 (percentage)
50
+ --output FORMAT Output format: text | json, default text
51
+ --project-root DIR Project root directory, default is current directory
52
+ --change-root DIR Change package directory, default is changes
53
+ --help, -h Show this help message
54
+ --version, -v Show version information
55
+
56
+ Algorithm:
57
+ 1. Extract all AC-xxx from design.md
58
+ 2. Extract AC-xxx referenced in tasks.md
59
+ 3. Extract AC-xxx marked in tests/
60
+ 4. Calculate: Coverage = (traced AC count) / (total AC count) x 100%
61
+ 5. Compare against threshold, return exit code
62
+
63
+ Exit codes:
64
+ 0 - Coverage meets threshold
65
+ 1 - Coverage below threshold
66
+ 2 - Usage error
67
+
68
+ Examples:
69
+ ./ac-trace-check.sh my-feature # Default check
70
+ ./ac-trace-check.sh my-feature --threshold 90 # 90% threshold
71
+ ./ac-trace-check.sh my-feature --output json # JSON output
72
+ ./ac-trace-check.sh my-feature --change-root dev-playbooks/changes
73
+
74
+ EOF
75
+ }
76
+
77
+ # Show version
78
+ show_version() {
79
+ echo "ac-trace-check.sh v${VERSION}"
80
+ }
81
+
82
+ # Log functions
83
+ log_info() {
84
+ [[ "$output_format" == "text" ]] && echo -e "${BLUE}[INFO]${NC} $*" >&2
85
+ }
86
+
87
+ log_pass() {
88
+ [[ "$output_format" == "text" ]] && echo -e "${GREEN}[PASS]${NC} $*"
89
+ }
90
+
91
+ log_fail() {
92
+ [[ "$output_format" == "text" ]] && echo -e "${RED}[FAIL]${NC} $*"
93
+ }
94
+
95
+ log_warn() {
96
+ [[ "$output_format" == "text" ]] && echo -e "${YELLOW}[WARN]${NC} $*"
97
+ }
98
+
99
+ # Extract AC-IDs
100
+ extract_ac_ids() {
101
+ local file="$1"
102
+ grep -oE "AC-[A-Z0-9]+" "$file" 2>/dev/null | sort -u || true
103
+ }
104
+
105
+ # Extract AC-IDs from directory
106
+ extract_ac_ids_from_dir() {
107
+ local dir="$1"
108
+ local pattern="${2:-*.test.*}"
109
+ find "$dir" -type f \( -name "*.test.ts" -o -name "*.test.js" -o -name "*.spec.ts" -o -name "*.spec.js" -o -name "*.bats" -o -name "*_test.py" -o -name "*_test.go" \) 2>/dev/null | while read -r file; do
110
+ grep -oE "AC-[A-Z0-9]+" "$file" 2>/dev/null || true
111
+ done | sort -u
112
+ }
113
+
114
+ # Calculate coverage
115
+ calculate_coverage() {
116
+ local design_acs="$1"
117
+ local tasks_acs="$2"
118
+ local test_acs="$3"
119
+
120
+ # Get AC lists
121
+ local design_list=()
122
+ local tasks_list=()
123
+ local test_list=()
124
+ local covered_list=()
125
+ local uncovered_list=()
126
+
127
+ while IFS= read -r ac; do
128
+ [[ -n "$ac" ]] && design_list+=("$ac")
129
+ done <<< "$design_acs"
130
+
131
+ while IFS= read -r ac; do
132
+ [[ -n "$ac" ]] && tasks_list+=("$ac")
133
+ done <<< "$tasks_acs"
134
+
135
+ while IFS= read -r ac; do
136
+ [[ -n "$ac" ]] && test_list+=("$ac")
137
+ done <<< "$test_acs"
138
+
139
+ local total=${#design_list[@]}
140
+
141
+ if [[ $total -eq 0 ]]; then
142
+ # No ACs, count as 100% coverage
143
+ echo "100 0 0"
144
+ return
145
+ fi
146
+
147
+ # Calculate covered ACs
148
+ local covered=0
149
+ for ac in "${design_list[@]}"; do
150
+ local in_test=false
151
+ for test_ac in "${test_list[@]}"; do
152
+ if [[ "$ac" == "$test_ac" ]]; then
153
+ in_test=true
154
+ covered_list+=("$ac")
155
+ break
156
+ fi
157
+ done
158
+ if [[ "$in_test" == false ]]; then
159
+ uncovered_list+=("$ac")
160
+ else
161
+ covered=$((covered + 1))
162
+ fi
163
+ done
164
+
165
+ local rate=0
166
+ if [[ $total -gt 0 ]]; then
167
+ rate=$((covered * 100 / total))
168
+ fi
169
+
170
+ echo "$rate $covered $total"
171
+
172
+ # Output uncovered list to stderr
173
+ if [[ ${#uncovered_list[@]} -gt 0 && "$output_format" == "text" ]]; then
174
+ echo "uncovered: ${uncovered_list[*]}" >&2
175
+ fi
176
+ }
177
+
178
+ # Main function
179
+ main() {
180
+ local change_id=""
181
+
182
+ # Parse arguments
183
+ while [[ $# -gt 0 ]]; do
184
+ case "$1" in
185
+ --help|-h)
186
+ show_help
187
+ exit 0
188
+ ;;
189
+ --version|-v)
190
+ show_version
191
+ exit 0
192
+ ;;
193
+ --threshold)
194
+ threshold="${2:-80}"
195
+ shift 2
196
+ ;;
197
+ --output)
198
+ output_format="${2:-text}"
199
+ shift 2
200
+ ;;
201
+ --project-root)
202
+ project_root="${2:-.}"
203
+ shift 2
204
+ ;;
205
+ --change-root)
206
+ change_root="${2:-changes}"
207
+ shift 2
208
+ ;;
209
+ -*)
210
+ echo "error: unknown option: $1" >&2
211
+ echo "Use --help for usage" >&2
212
+ exit 2
213
+ ;;
214
+ *)
215
+ change_id="$1"
216
+ shift
217
+ ;;
218
+ esac
219
+ done
220
+
221
+ # Validate arguments
222
+ if [[ -z "$change_id" ]]; then
223
+ echo "error: missing change-id" >&2
224
+ echo "Use --help for usage" >&2
225
+ exit 2
226
+ fi
227
+
228
+ # Build paths
229
+ local change_dir
230
+ if [[ "$change_root" = /* ]]; then
231
+ change_dir="${change_root}/${change_id}"
232
+ else
233
+ change_dir="${project_root}/${change_root}/${change_id}"
234
+ fi
235
+
236
+ local design_file="${change_dir}/design.md"
237
+ local tasks_file="${change_dir}/tasks.md"
238
+ local tests_dir="${project_root}/tests"
239
+
240
+ log_info "Checking change package: ${change_id}"
241
+ log_info "Design file: ${design_file}"
242
+ log_info "Tasks file: ${tasks_file}"
243
+ log_info "Tests directory: ${tests_dir}"
244
+
245
+ # Check file exists
246
+ if [[ ! -f "$design_file" ]]; then
247
+ if [[ "$output_format" == "json" ]]; then
248
+ echo '{"error": "design.md not found", "coverage": 0}'
249
+ else
250
+ log_fail "design.md does not exist: ${design_file}"
251
+ fi
252
+ exit 1
253
+ fi
254
+
255
+ # Extract AC-IDs
256
+ local design_acs tasks_acs test_acs
257
+
258
+ design_acs=$(extract_ac_ids "$design_file")
259
+ tasks_acs=""
260
+ if [[ -f "$tasks_file" ]]; then
261
+ tasks_acs=$(extract_ac_ids "$tasks_file")
262
+ fi
263
+
264
+ test_acs=""
265
+ if [[ -d "$tests_dir" ]]; then
266
+ test_acs=$(extract_ac_ids_from_dir "$tests_dir")
267
+ fi
268
+
269
+ # Calculate coverage
270
+ local result
271
+ result=$(calculate_coverage "$design_acs" "$tasks_acs" "$test_acs")
272
+ read -r rate covered total <<< "$result"
273
+
274
+ # Output results
275
+ if [[ "$output_format" == "json" ]]; then
276
+ local uncovered_json="[]"
277
+ # Recalculate uncovered list
278
+ local uncovered_acs=""
279
+ while IFS= read -r ac; do
280
+ [[ -z "$ac" ]] && continue
281
+ if ! echo "$test_acs" | grep -qx "$ac"; then
282
+ if [[ -z "$uncovered_acs" ]]; then
283
+ uncovered_acs="\"$ac\""
284
+ else
285
+ uncovered_acs="${uncovered_acs},\"$ac\""
286
+ fi
287
+ fi
288
+ done <<< "$design_acs"
289
+
290
+ cat << EOF
291
+ {
292
+ "change_id": "${change_id}",
293
+ "coverage": ${rate},
294
+ "threshold": ${threshold},
295
+ "covered": ${covered},
296
+ "total": ${total},
297
+ "uncovered": [${uncovered_acs}],
298
+ "pass": $([ "$rate" -ge "$threshold" ] && echo "true" || echo "false")
299
+ }
300
+ EOF
301
+ else
302
+ echo ""
303
+ echo "AC Traceability Coverage Report"
304
+ echo "================================"
305
+ echo "Change package: ${change_id}"
306
+ echo "Total ACs: ${total}"
307
+ echo "Covered: ${covered}"
308
+ echo "Coverage: ${rate}%"
309
+ echo "Threshold: ${threshold}%"
310
+ echo ""
311
+
312
+ if [[ $rate -ge $threshold ]]; then
313
+ log_pass "Coverage ${rate}% >= ${threshold}%, check passed"
314
+ exit 0
315
+ else
316
+ log_fail "Coverage ${rate}% < ${threshold}%, check failed"
317
+ exit 1
318
+ fi
319
+ fi
320
+
321
+ # Exit code for JSON mode
322
+ if [[ $rate -ge $threshold ]]; then
323
+ exit 0
324
+ else
325
+ exit 1
326
+ fi
327
+ }
328
+
329
+ # Run main function
330
+ main "$@"
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env bash
2
+ # audit-scope.sh - Provide full-scope audit scanning for precision improvement
3
+ #
4
+ # This script scans a directory and outputs metrics for audit purposes:
5
+ # - File count by type
6
+ # - Line count
7
+ # - Complexity metrics (if available)
8
+ # - Hotspot file list (high churn + high complexity)
9
+ #
10
+ # Reference: harden-devbooks-quality-gates design.md AC-011
11
+
12
+ set -euo pipefail
13
+
14
+ usage() {
15
+ cat <<'EOF' >&2
16
+ usage: audit-scope.sh <directory> [options]
17
+
18
+ Provide full-scope audit scanning for a directory:
19
+ - File count by type
20
+ - Total line count
21
+ - Complexity metrics (if tools available)
22
+ - Hotspot identification
23
+
24
+ Options:
25
+ --format <fmt> Output format: text (default), markdown, json
26
+ --exclude <pat> Exclude pattern (can be used multiple times)
27
+ -h, --help Show this help message
28
+
29
+ Exit Codes:
30
+ 0 - Scan completed successfully
31
+ 1 - Scan error or directory not found
32
+ 2 - Usage error
33
+
34
+ Examples:
35
+ audit-scope.sh src/
36
+ audit-scope.sh src/ --format markdown
37
+ audit-scope.sh src/ --format json --exclude node_modules
38
+ EOF
39
+ }
40
+
41
+ if [[ $# -eq 0 ]]; then
42
+ usage
43
+ exit 2
44
+ fi
45
+
46
+ if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
47
+ usage
48
+ exit 0
49
+ fi
50
+
51
+ target_dir="$1"
52
+ shift
53
+
54
+ output_format="text"
55
+ declare -a exclude_patterns=()
56
+
57
+ while [[ $# -gt 0 ]]; do
58
+ case "$1" in
59
+ -h|--help)
60
+ usage
61
+ exit 0
62
+ ;;
63
+ --format)
64
+ output_format="${2:-text}"
65
+ shift 2
66
+ ;;
67
+ --exclude)
68
+ exclude_patterns+=("${2:-}")
69
+ shift 2
70
+ ;;
71
+ *)
72
+ echo "error: unknown option: $1" >&2
73
+ usage
74
+ exit 2
75
+ ;;
76
+ esac
77
+ done
78
+
79
+ # Validate format
80
+ case "$output_format" in
81
+ text|markdown|json) ;;
82
+ *)
83
+ echo "error: invalid --format: '$output_format' (use: text, markdown, json)" >&2
84
+ exit 2
85
+ ;;
86
+ esac
87
+
88
+ # Check directory exists
89
+ if [[ ! -d "$target_dir" ]]; then
90
+ echo "error: directory not found: ${target_dir}" >&2
91
+ exit 1
92
+ fi
93
+
94
+ # Build find exclude arguments as array
95
+ declare -a find_exclude_args=()
96
+ if [[ ${#exclude_patterns[@]} -gt 0 ]]; then
97
+ for pat in "${exclude_patterns[@]}"; do
98
+ find_exclude_args+=(-not -path "*/${pat}/*")
99
+ done
100
+ fi
101
+
102
+ # =============================================================================
103
+ # Collect Metrics
104
+ # =============================================================================
105
+
106
+ # Count files by type
107
+ count_files() {
108
+ local ext="$1"
109
+ find "$target_dir" -type f -name "*.$ext" ${find_exclude_args[@]+"${find_exclude_args[@]}"} 2>/dev/null | wc -l | tr -d ' '
110
+ }
111
+
112
+ # Count total lines
113
+ count_lines() {
114
+ local ext="$1"
115
+ find "$target_dir" -type f -name "*.$ext" ${find_exclude_args[@]+"${find_exclude_args[@]}"} -exec cat {} \; 2>/dev/null | wc -l | tr -d ' '
116
+ }
117
+
118
+ # Total file count
119
+ total_files=$(find "$target_dir" -type f ${find_exclude_args[@]+"${find_exclude_args[@]}"} 2>/dev/null | wc -l | tr -d ' ')
120
+
121
+ # Count by common types
122
+ sh_count=$(count_files "sh")
123
+ ts_count=$(count_files "ts")
124
+ js_count=$(count_files "js")
125
+ md_count=$(count_files "md")
126
+ yml_count=$(count_files "yml")
127
+ yaml_count=$(count_files "yaml")
128
+ json_count=$(count_files "json")
129
+ py_count=$(count_files "py")
130
+
131
+ # Line counts
132
+ sh_lines=$(count_lines "sh")
133
+ ts_lines=$(count_lines "ts")
134
+ js_lines=$(count_lines "js")
135
+
136
+ # Total lines (for major code types)
137
+ total_lines=$((sh_lines + ts_lines + js_lines))
138
+
139
+ # Identify potential hotspots (largest files)
140
+ hotspots=""
141
+ if command -v wc >/dev/null 2>&1; then
142
+ hotspots=$(find "$target_dir" -type f \( -name "*.sh" -o -name "*.ts" -o -name "*.js" -o -name "*.py" \) ${find_exclude_args[@]+"${find_exclude_args[@]}"} -exec wc -l {} \; 2>/dev/null | sort -rn | head -10)
143
+ fi
144
+
145
+ # =============================================================================
146
+ # Output
147
+ # =============================================================================
148
+
149
+ case "$output_format" in
150
+ text)
151
+ echo "=================================================="
152
+ echo "Audit Scope: ${target_dir}"
153
+ echo "=================================================="
154
+ echo ""
155
+ echo "## File Count Summary"
156
+ echo " Total files: ${total_files}"
157
+ echo " Shell (.sh): ${sh_count}"
158
+ echo " TypeScript (.ts): ${ts_count}"
159
+ echo " JavaScript (.js): ${js_count}"
160
+ echo " Markdown (.md): ${md_count}"
161
+ echo " YAML (.yml/.yaml): $((yml_count + yaml_count))"
162
+ echo " JSON (.json): ${json_count}"
163
+ echo " Python (.py): ${py_count}"
164
+ echo ""
165
+ echo "## Line Count (Code)"
166
+ echo " Shell: ${sh_lines}"
167
+ echo " TypeScript: ${ts_lines}"
168
+ echo " JavaScript: ${js_lines}"
169
+ echo " Total: ${total_lines}"
170
+ echo ""
171
+ echo "## Potential Hotspots (Top 10 by line count)"
172
+ if [[ -n "$hotspots" ]]; then
173
+ echo "$hotspots" | while read -r line; do
174
+ echo " $line"
175
+ done
176
+ else
177
+ echo " (no code files found)"
178
+ fi
179
+ echo ""
180
+ ;;
181
+
182
+ markdown)
183
+ echo "# Audit Scope: ${target_dir}"
184
+ echo ""
185
+ echo "## File Count Summary"
186
+ echo ""
187
+ echo "| Type | Count |"
188
+ echo "|------|-------|"
189
+ echo "| Total | ${total_files} |"
190
+ echo "| Shell (.sh) | ${sh_count} |"
191
+ echo "| TypeScript (.ts) | ${ts_count} |"
192
+ echo "| JavaScript (.js) | ${js_count} |"
193
+ echo "| Markdown (.md) | ${md_count} |"
194
+ echo "| YAML | $((yml_count + yaml_count)) |"
195
+ echo "| JSON | ${json_count} |"
196
+ echo "| Python (.py) | ${py_count} |"
197
+ echo ""
198
+ echo "## Line Count (Code)"
199
+ echo ""
200
+ echo "| Type | Lines |"
201
+ echo "|------|-------|"
202
+ echo "| Shell | ${sh_lines} |"
203
+ echo "| TypeScript | ${ts_lines} |"
204
+ echo "| JavaScript | ${js_lines} |"
205
+ echo "| **Total** | **${total_lines}** |"
206
+ echo ""
207
+ echo "## Potential Hotspots"
208
+ echo ""
209
+ if [[ -n "$hotspots" ]]; then
210
+ echo "| Lines | File |"
211
+ echo "|-------|------|"
212
+ echo "$hotspots" | while read -r lines file; do
213
+ echo "| ${lines} | ${file} |"
214
+ done
215
+ else
216
+ echo "(no code files found)"
217
+ fi
218
+ ;;
219
+
220
+ json)
221
+ # Build hotspots JSON array
222
+ hotspots_json="[]"
223
+ if [[ -n "$hotspots" ]]; then
224
+ hotspots_json="["
225
+ first=true
226
+ while read -r lines file; do
227
+ if [[ "$first" == true ]]; then
228
+ first=false
229
+ else
230
+ hotspots_json+=","
231
+ fi
232
+ hotspots_json+="{\"lines\":${lines},\"file\":\"${file}\"}"
233
+ done <<< "$hotspots"
234
+ hotspots_json+="]"
235
+ fi
236
+
237
+ cat << EOF
238
+ {
239
+ "directory": "${target_dir}",
240
+ "fileCount": {
241
+ "total": ${total_files},
242
+ "shell": ${sh_count},
243
+ "typescript": ${ts_count},
244
+ "javascript": ${js_count},
245
+ "markdown": ${md_count},
246
+ "yaml": $((yml_count + yaml_count)),
247
+ "json": ${json_count},
248
+ "python": ${py_count}
249
+ },
250
+ "lineCount": {
251
+ "shell": ${sh_lines},
252
+ "typescript": ${ts_lines},
253
+ "javascript": ${js_lines},
254
+ "total": ${total_lines}
255
+ },
256
+ "hotspots": ${hotspots_json}
257
+ }
258
+ EOF
259
+ ;;
260
+ esac
261
+
262
+ exit 0