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.
- package/LICENSE +21 -0
- package/README.md +466 -0
- package/bin/devbooks.js +987 -0
- package/package.json +43 -0
- package/skills/Skills/344/275/277/347/224/250/350/257/264/346/230/216.md +446 -0
- package/skills/Skill/345/274/200/345/217/221/346/214/207/345/215/227.md +248 -0
- package/skills/_shared/context-detection-template.md +315 -0
- package/skills/_shared/mcp-enhancement-template.md +144 -0
- 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
- package/skills/_template/config-discovery-template.md +126 -0
- package/skills/devbooks-brownfield-bootstrap/SKILL.md +167 -0
- 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
- 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
- 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
- package/skills/devbooks-brownfield-bootstrap/references//346/234/257/350/257/255/350/241/250/346/250/241/346/235/277.md +42 -0
- package/skills/devbooks-brownfield-bootstrap/scripts/cod-update.sh +357 -0
- package/skills/devbooks-brownfield-bootstrap/templates/project-profile-template.md +172 -0
- package/skills/devbooks-c4-map/SKILL.md +151 -0
- 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
- 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
- package/skills/devbooks-code-review/SKILL.md +175 -0
- 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
- 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
- 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
- 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
- package/skills/devbooks-coder/SKILL.md +219 -0
- 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
- 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
- package/skills/devbooks-coder/references//346/227/245/345/277/227/350/247/204/350/214/203.md +329 -0
- 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
- package/skills/devbooks-coder/references//351/224/231/350/257/257/347/240/201/350/247/204/350/214/203.md +463 -0
- package/skills/devbooks-delivery-workflow/SKILL.md +217 -0
- 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
- 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
- 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
- package/skills/devbooks-delivery-workflow/scripts/ac-trace-check.sh +330 -0
- package/skills/devbooks-delivery-workflow/scripts/audit-scope.sh +262 -0
- package/skills/devbooks-delivery-workflow/scripts/change-check.sh +1040 -0
- package/skills/devbooks-delivery-workflow/scripts/change-codemod-scaffold.sh +135 -0
- package/skills/devbooks-delivery-workflow/scripts/change-evidence.sh +152 -0
- package/skills/devbooks-delivery-workflow/scripts/change-scaffold.sh +442 -0
- package/skills/devbooks-delivery-workflow/scripts/change-spec-delta-scaffold.sh +136 -0
- package/skills/devbooks-delivery-workflow/scripts/constitution-check.sh +237 -0
- package/skills/devbooks-delivery-workflow/scripts/env-match-check.sh +128 -0
- package/skills/devbooks-delivery-workflow/scripts/fitness-check.sh +387 -0
- package/skills/devbooks-delivery-workflow/scripts/guardrail-check.sh +519 -0
- package/skills/devbooks-delivery-workflow/scripts/handoff-check.sh +141 -0
- package/skills/devbooks-delivery-workflow/scripts/hygiene-check.sh +340 -0
- package/skills/devbooks-delivery-workflow/scripts/migrate-from-openspec.sh +385 -0
- package/skills/devbooks-delivery-workflow/scripts/migrate-to-v2-gates.sh +202 -0
- package/skills/devbooks-delivery-workflow/scripts/progress-dashboard.sh +319 -0
- package/skills/devbooks-delivery-workflow/scripts/prototype-promote.sh +341 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-preview.sh +203 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-promote.sh +118 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-rollback.sh +124 -0
- package/skills/devbooks-delivery-workflow/scripts/spec-stage.sh +117 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-all.sh +78 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-npm-package.sh +123 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-openspec-free.sh +81 -0
- package/skills/devbooks-delivery-workflow/scripts/verify-slash-commands.sh +146 -0
- package/skills/devbooks-delivery-workflow/templates/handoff.md +50 -0
- package/skills/devbooks-design-backport/SKILL.md +73 -0
- 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
- package/skills/devbooks-design-doc/SKILL.md +121 -0
- 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
- 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
- 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
- package/skills/devbooks-entropy-monitor/SKILL.md +188 -0
- 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
- package/skills/devbooks-entropy-monitor/scripts/entropy-measure.sh +449 -0
- package/skills/devbooks-entropy-monitor/scripts/entropy-report.sh +303 -0
- package/skills/devbooks-entropy-monitor/templates/thresholds.json +99 -0
- package/skills/devbooks-federation/SKILL.md +264 -0
- package/skills/devbooks-federation/scripts/federation-check.sh +144 -0
- package/skills/devbooks-federation/templates/federation.yaml +89 -0
- package/skills/devbooks-impact-analysis/SKILL.md +135 -0
- 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
- package/skills/devbooks-impact-analysis/scripts/graph-cache.sh +214 -0
- package/skills/devbooks-implementation-plan/SKILL.md +83 -0
- 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
- package/skills/devbooks-index-bootstrap/SKILL.md +240 -0
- package/skills/devbooks-proposal-author/SKILL.md +83 -0
- 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
- package/skills/devbooks-proposal-challenger/SKILL.md +86 -0
- 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
- 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
- package/skills/devbooks-proposal-debate-workflow/SKILL.md +78 -0
- 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
- 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
- package/skills/devbooks-proposal-debate-workflow/scripts/proposal-debate-check.sh +102 -0
- package/skills/devbooks-proposal-judge/SKILL.md +78 -0
- 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
- package/skills/devbooks-router/SKILL.md +346 -0
- package/skills/devbooks-spec-contract/SKILL.md +191 -0
- package/skills/devbooks-spec-contract/references/API/350/256/276/350/256/241/346/214/207/345/215/227.md +349 -0
- 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
- 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
- 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
- package/skills/devbooks-spec-contract/scripts/implicit-change-detect.sh +378 -0
- package/skills/devbooks-spec-gardener/SKILL.md +72 -0
- 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
- package/skills/devbooks-test-owner/SKILL.md +172 -0
- 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
- 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
- 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
- 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
- package/skills/devbooks-test-owner/references//346/265/213/350/257/225/351/251/261/345/212/250.md +394 -0
- 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
- package/skills/devbooks-test-reviewer/SKILL.md +189 -0
- package/templates/.devbooks/config.yaml +88 -0
- package/templates/claude-commands/devbooks/apply.md +38 -0
- package/templates/claude-commands/devbooks/archive.md +33 -0
- package/templates/claude-commands/devbooks/backport.md +19 -0
- package/templates/claude-commands/devbooks/bootstrap.md +19 -0
- package/templates/claude-commands/devbooks/c4.md +19 -0
- package/templates/claude-commands/devbooks/challenger.md +19 -0
- package/templates/claude-commands/devbooks/code.md +19 -0
- package/templates/claude-commands/devbooks/debate.md +19 -0
- package/templates/claude-commands/devbooks/delivery.md +19 -0
- package/templates/claude-commands/devbooks/design.md +19 -0
- package/templates/claude-commands/devbooks/entropy.md +19 -0
- package/templates/claude-commands/devbooks/federation.md +19 -0
- package/templates/claude-commands/devbooks/gardener.md +19 -0
- package/templates/claude-commands/devbooks/impact.md +19 -0
- package/templates/claude-commands/devbooks/index.md +19 -0
- package/templates/claude-commands/devbooks/judge.md +19 -0
- package/templates/claude-commands/devbooks/plan.md +19 -0
- package/templates/claude-commands/devbooks/proposal.md +19 -0
- package/templates/claude-commands/devbooks/quick.md +42 -0
- package/templates/claude-commands/devbooks/review.md +19 -0
- package/templates/claude-commands/devbooks/router.md +19 -0
- package/templates/claude-commands/devbooks/spec.md +19 -0
- package/templates/claude-commands/devbooks/test-review.md +19 -0
- package/templates/claude-commands/devbooks/test.md +19 -0
- package/templates/dev-playbooks/README.md +458 -0
- package/templates/dev-playbooks/changes/.gitkeep +1 -0
- package/templates/dev-playbooks/constitution.md +116 -0
- package/templates/dev-playbooks/project.md +96 -0
- package/templates/dev-playbooks/scripts/.gitkeep +1 -0
- package/templates/dev-playbooks/specs/_meta/anti-patterns/.gitkeep +2 -0
- package/templates/dev-playbooks/specs/_meta/glossary.md +47 -0
- package/templates/dev-playbooks/specs/_meta/project-profile.md +79 -0
- package/templates/dev-playbooks/specs/architecture/fitness-rules.md +95 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# skills/devbooks-delivery-workflow/scripts/fitness-check.sh
|
|
3
|
+
# Architecture Fitness Check Script
|
|
4
|
+
#
|
|
5
|
+
# Executes architecture fitness function checks to verify code conforms to architectural rules.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# ./fitness-check.sh [options]
|
|
9
|
+
# ./fitness-check.sh --help
|
|
10
|
+
#
|
|
11
|
+
# Options:
|
|
12
|
+
# --mode MODE Check mode: warn (warning) | error (blocking)
|
|
13
|
+
# --rules FILE Rules file path
|
|
14
|
+
# --project-root DIR Project root directory
|
|
15
|
+
# --file FILE Check a single file (for testing)
|
|
16
|
+
#
|
|
17
|
+
# Exit codes:
|
|
18
|
+
# 0 - Check passed (or warnings in warn mode)
|
|
19
|
+
# 1 - Check failed (violations in error mode)
|
|
20
|
+
# 2 - Usage error
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
# Version
|
|
25
|
+
VERSION="1.0.0"
|
|
26
|
+
|
|
27
|
+
# Defaults
|
|
28
|
+
mode="warn"
|
|
29
|
+
rules_file=""
|
|
30
|
+
project_root="."
|
|
31
|
+
single_file=""
|
|
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
|
+
# Counters
|
|
41
|
+
errors=0
|
|
42
|
+
warnings=0
|
|
43
|
+
|
|
44
|
+
# Show help
|
|
45
|
+
show_help() {
|
|
46
|
+
cat << 'EOF'
|
|
47
|
+
Architecture Fitness Check Script (fitness-check.sh)
|
|
48
|
+
|
|
49
|
+
Usage:
|
|
50
|
+
./fitness-check.sh [options]
|
|
51
|
+
|
|
52
|
+
Options:
|
|
53
|
+
--mode MODE Check mode: warn (warning only) | error (blocking)
|
|
54
|
+
--rules FILE Rules file path (default: specs/architecture/fitness-rules.md)
|
|
55
|
+
--project-root DIR Project root directory, default is current directory
|
|
56
|
+
--file FILE Check a single file (for testing)
|
|
57
|
+
--help, -h Show this help message
|
|
58
|
+
--version, -v Show version information
|
|
59
|
+
|
|
60
|
+
Supported rule types:
|
|
61
|
+
FR-001: Layered architecture check (Controller -> Service -> Repository)
|
|
62
|
+
FR-002: Circular dependency check (basic version)
|
|
63
|
+
FR-003: Sensitive file protection
|
|
64
|
+
|
|
65
|
+
Exit codes:
|
|
66
|
+
0 - Check passed (or warnings in warn mode)
|
|
67
|
+
1 - Check failed (violations in error mode)
|
|
68
|
+
2 - Usage error
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
./fitness-check.sh # Default check
|
|
72
|
+
./fitness-check.sh --mode error # Strict mode
|
|
73
|
+
./fitness-check.sh --rules custom-rules.md # Custom rules file
|
|
74
|
+
./fitness-check.sh --file src/test.js # Check a single file
|
|
75
|
+
|
|
76
|
+
EOF
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# Show version
|
|
80
|
+
show_version() {
|
|
81
|
+
echo "fitness-check.sh v${VERSION}"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# Log functions
|
|
85
|
+
log_info() {
|
|
86
|
+
echo -e "${BLUE}[INFO]${NC} $*" >&2
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
log_pass() {
|
|
90
|
+
echo -e "${GREEN}[PASS]${NC} $*"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
log_fail() {
|
|
94
|
+
echo -e "${RED}[FAIL]${NC} $*" >&2
|
|
95
|
+
if [[ "$mode" == "error" ]]; then
|
|
96
|
+
errors=$((errors + 1))
|
|
97
|
+
else
|
|
98
|
+
warnings=$((warnings + 1))
|
|
99
|
+
fi
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
log_warn() {
|
|
103
|
+
echo -e "${YELLOW}[WARN]${NC} $*" >&2
|
|
104
|
+
warnings=$((warnings + 1))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
# ============================================================================
|
|
108
|
+
# FR-001: Layered Architecture Check
|
|
109
|
+
# Controller should not call Repository directly
|
|
110
|
+
# ============================================================================
|
|
111
|
+
check_layered_architecture() {
|
|
112
|
+
log_info "FR-001: Checking layered architecture..."
|
|
113
|
+
|
|
114
|
+
local src_dir="${project_root}/src"
|
|
115
|
+
local controllers_dir="${src_dir}/controllers"
|
|
116
|
+
|
|
117
|
+
if [[ ! -d "$controllers_dir" ]]; then
|
|
118
|
+
# Try other common paths
|
|
119
|
+
controllers_dir="${src_dir}/controller"
|
|
120
|
+
if [[ ! -d "$controllers_dir" ]]; then
|
|
121
|
+
log_info " No controllers directory found, skipping"
|
|
122
|
+
return 0
|
|
123
|
+
fi
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
local violations=""
|
|
127
|
+
|
|
128
|
+
# Find Controller code that directly calls Repository
|
|
129
|
+
# Pattern: Repository.xxx or import ... from '...repository'
|
|
130
|
+
while IFS= read -r file; do
|
|
131
|
+
[[ -z "$file" ]] && continue
|
|
132
|
+
|
|
133
|
+
# Check direct Repository method calls
|
|
134
|
+
local matches
|
|
135
|
+
matches=$(grep -nE "Repository\.(find|save|delete|update|create|get)|new [A-Z][a-zA-Z]*Repository" "$file" 2>/dev/null || true)
|
|
136
|
+
|
|
137
|
+
if [[ -n "$matches" ]]; then
|
|
138
|
+
violations="${violations}${file}:\n${matches}\n\n"
|
|
139
|
+
fi
|
|
140
|
+
done < <(find "$controllers_dir" -type f \( -name "*.ts" -o -name "*.js" \) 2>/dev/null)
|
|
141
|
+
|
|
142
|
+
if [[ -n "$violations" ]]; then
|
|
143
|
+
log_fail "FR-001: Layered architecture violation - Controller directly accesses Repository"
|
|
144
|
+
echo -e " Violation details:\n$violations" >&2
|
|
145
|
+
return 1
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
log_pass "FR-001: Layered architecture check passed"
|
|
149
|
+
return 0
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
# ============================================================================
|
|
153
|
+
# FR-002: Circular Dependency Check (basic version)
|
|
154
|
+
# Detect obvious circular imports
|
|
155
|
+
# ============================================================================
|
|
156
|
+
check_circular_dependencies() {
|
|
157
|
+
log_info "FR-002: Checking circular dependencies..."
|
|
158
|
+
|
|
159
|
+
local src_dir="${project_root}/src"
|
|
160
|
+
|
|
161
|
+
if [[ ! -d "$src_dir" ]]; then
|
|
162
|
+
log_info " No src directory found, skipping"
|
|
163
|
+
return 0
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Basic check: mutual references within the same directory
|
|
167
|
+
# This is a simplified version, full detection requires more complex graph analysis
|
|
168
|
+
|
|
169
|
+
local circular_count=0
|
|
170
|
+
|
|
171
|
+
# Find potential circular reference patterns
|
|
172
|
+
# Example: a.ts import from './b' and b.ts import from './a'
|
|
173
|
+
while IFS= read -r file; do
|
|
174
|
+
[[ -z "$file" ]] && continue
|
|
175
|
+
|
|
176
|
+
local dir
|
|
177
|
+
dir=$(dirname "$file")
|
|
178
|
+
local base
|
|
179
|
+
base=$(basename "$file" | sed 's/\.\(ts\|js\|tsx\|jsx\)$//')
|
|
180
|
+
|
|
181
|
+
# Get relative imports from this file
|
|
182
|
+
local imports
|
|
183
|
+
imports=$(grep -oE "from ['\"]\.\/[a-zA-Z0-9_-]+['\"]" "$file" 2>/dev/null | sed "s/from ['\"]\.\\///g; s/['\"]//g" || true)
|
|
184
|
+
|
|
185
|
+
for imported in $imports; do
|
|
186
|
+
local imported_file="${dir}/${imported}.ts"
|
|
187
|
+
[[ ! -f "$imported_file" ]] && imported_file="${dir}/${imported}.js"
|
|
188
|
+
[[ ! -f "$imported_file" ]] && continue
|
|
189
|
+
|
|
190
|
+
# Check if imported file imports back
|
|
191
|
+
if grep -qE "from ['\"]\./${base}['\"]" "$imported_file" 2>/dev/null; then
|
|
192
|
+
log_warn "FR-002: Possible circular dependency: ${file} <-> ${imported_file}"
|
|
193
|
+
circular_count=$((circular_count + 1))
|
|
194
|
+
fi
|
|
195
|
+
done
|
|
196
|
+
done < <(find "$src_dir" -type f \( -name "*.ts" -o -name "*.js" \) 2>/dev/null | head -100)
|
|
197
|
+
|
|
198
|
+
if [[ $circular_count -gt 0 ]]; then
|
|
199
|
+
log_warn "FR-002: Detected ${circular_count} possible circular dependencies"
|
|
200
|
+
return 0 # Only warn, do not block
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
log_pass "FR-002: Circular dependency check passed"
|
|
204
|
+
return 0
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
# ============================================================================
|
|
208
|
+
# FR-003: Sensitive File Protection
|
|
209
|
+
# Prevent sensitive files from being accidentally modified or committed
|
|
210
|
+
# ============================================================================
|
|
211
|
+
check_sensitive_files() {
|
|
212
|
+
log_info "FR-003: Checking sensitive files..."
|
|
213
|
+
|
|
214
|
+
# Sensitive file patterns
|
|
215
|
+
local sensitive_patterns=(
|
|
216
|
+
".env"
|
|
217
|
+
".env.local"
|
|
218
|
+
".env.production"
|
|
219
|
+
"credentials.json"
|
|
220
|
+
"secrets.yaml"
|
|
221
|
+
"*.pem"
|
|
222
|
+
"*.key"
|
|
223
|
+
"id_rsa"
|
|
224
|
+
"id_ed25519"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
local violations=0
|
|
228
|
+
|
|
229
|
+
for pattern in "${sensitive_patterns[@]}"; do
|
|
230
|
+
# Check if sensitive files are being tracked
|
|
231
|
+
if command -v git >/dev/null 2>&1 && git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
232
|
+
local tracked
|
|
233
|
+
tracked=$(git -C "$project_root" ls-files "$pattern" 2>/dev/null || true)
|
|
234
|
+
if [[ -n "$tracked" ]]; then
|
|
235
|
+
log_fail "FR-003: Sensitive file tracked by Git: ${tracked}"
|
|
236
|
+
violations=$((violations + 1))
|
|
237
|
+
fi
|
|
238
|
+
fi
|
|
239
|
+
done
|
|
240
|
+
|
|
241
|
+
# Check if .gitignore contains sensitive patterns
|
|
242
|
+
local gitignore="${project_root}/.gitignore"
|
|
243
|
+
if [[ -f "$gitignore" ]]; then
|
|
244
|
+
local missing_patterns=()
|
|
245
|
+
for pattern in ".env" "*.key" "*.pem"; do
|
|
246
|
+
if ! grep -qE "^${pattern}$|^\\*${pattern}$" "$gitignore" 2>/dev/null; then
|
|
247
|
+
missing_patterns+=("$pattern")
|
|
248
|
+
fi
|
|
249
|
+
done
|
|
250
|
+
|
|
251
|
+
if [[ ${#missing_patterns[@]} -gt 0 ]]; then
|
|
252
|
+
log_warn "FR-003: .gitignore should add sensitive file patterns: ${missing_patterns[*]}"
|
|
253
|
+
fi
|
|
254
|
+
fi
|
|
255
|
+
|
|
256
|
+
if [[ $violations -eq 0 ]]; then
|
|
257
|
+
log_pass "FR-003: Sensitive file check passed"
|
|
258
|
+
return 0
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
return 1
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
# ============================================================================
|
|
265
|
+
# Check a single file (for testing)
|
|
266
|
+
# ============================================================================
|
|
267
|
+
check_single_file() {
|
|
268
|
+
local file="$1"
|
|
269
|
+
|
|
270
|
+
log_info "Checking file: $file"
|
|
271
|
+
|
|
272
|
+
if [[ ! -f "$file" ]]; then
|
|
273
|
+
log_fail "File does not exist: $file"
|
|
274
|
+
return 1
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
# FR-001: Layered architecture check
|
|
278
|
+
if [[ "$file" =~ controller ]]; then
|
|
279
|
+
local matches
|
|
280
|
+
matches=$(grep -nE "Repository\.(find|save|delete|update|create|get)" "$file" 2>/dev/null || true)
|
|
281
|
+
if [[ -n "$matches" ]]; then
|
|
282
|
+
log_fail "FR-001: Controller directly accesses Repository"
|
|
283
|
+
echo " $matches" >&2
|
|
284
|
+
return 1
|
|
285
|
+
fi
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
log_pass "File check passed: $file"
|
|
289
|
+
return 0
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
# ============================================================================
|
|
293
|
+
# Main function
|
|
294
|
+
# ============================================================================
|
|
295
|
+
main() {
|
|
296
|
+
# Parse arguments
|
|
297
|
+
while [[ $# -gt 0 ]]; do
|
|
298
|
+
case "$1" in
|
|
299
|
+
--help|-h)
|
|
300
|
+
show_help
|
|
301
|
+
exit 0
|
|
302
|
+
;;
|
|
303
|
+
--version|-v)
|
|
304
|
+
show_version
|
|
305
|
+
exit 0
|
|
306
|
+
;;
|
|
307
|
+
--mode)
|
|
308
|
+
mode="${2:-warn}"
|
|
309
|
+
shift 2
|
|
310
|
+
;;
|
|
311
|
+
--rules)
|
|
312
|
+
rules_file="${2:-}"
|
|
313
|
+
shift 2
|
|
314
|
+
;;
|
|
315
|
+
--project-root)
|
|
316
|
+
project_root="${2:-.}"
|
|
317
|
+
shift 2
|
|
318
|
+
;;
|
|
319
|
+
--file)
|
|
320
|
+
single_file="${2:-}"
|
|
321
|
+
shift 2
|
|
322
|
+
;;
|
|
323
|
+
-*)
|
|
324
|
+
echo "error: unknown option: $1" >&2
|
|
325
|
+
echo "Use --help for usage" >&2
|
|
326
|
+
exit 2
|
|
327
|
+
;;
|
|
328
|
+
*)
|
|
329
|
+
shift
|
|
330
|
+
;;
|
|
331
|
+
esac
|
|
332
|
+
done
|
|
333
|
+
|
|
334
|
+
# Validate mode
|
|
335
|
+
case "$mode" in
|
|
336
|
+
warn|error) ;;
|
|
337
|
+
*)
|
|
338
|
+
echo "error: invalid --mode: $mode (must be warn or error)" >&2
|
|
339
|
+
exit 2
|
|
340
|
+
;;
|
|
341
|
+
esac
|
|
342
|
+
|
|
343
|
+
echo "=========================================="
|
|
344
|
+
echo "Architecture Fitness Check (fitness-check.sh)"
|
|
345
|
+
echo "Mode: $mode"
|
|
346
|
+
echo "Project: $project_root"
|
|
347
|
+
echo "=========================================="
|
|
348
|
+
echo ""
|
|
349
|
+
|
|
350
|
+
# Single file check mode
|
|
351
|
+
if [[ -n "$single_file" ]]; then
|
|
352
|
+
check_single_file "$single_file"
|
|
353
|
+
exit $?
|
|
354
|
+
fi
|
|
355
|
+
|
|
356
|
+
# Run all checks
|
|
357
|
+
check_layered_architecture || true
|
|
358
|
+
check_circular_dependencies || true
|
|
359
|
+
check_sensitive_files || true
|
|
360
|
+
|
|
361
|
+
# Output summary
|
|
362
|
+
echo ""
|
|
363
|
+
echo "=========================================="
|
|
364
|
+
echo "Check Complete"
|
|
365
|
+
echo " Errors: $errors"
|
|
366
|
+
echo " Warnings: $warnings"
|
|
367
|
+
echo "=========================================="
|
|
368
|
+
|
|
369
|
+
if [[ $errors -gt 0 ]]; then
|
|
370
|
+
echo ""
|
|
371
|
+
log_fail "Check failed: ${errors} error(s)"
|
|
372
|
+
exit 1
|
|
373
|
+
fi
|
|
374
|
+
|
|
375
|
+
if [[ $warnings -gt 0 ]]; then
|
|
376
|
+
echo ""
|
|
377
|
+
log_warn "Check passed: ${warnings} warning(s)"
|
|
378
|
+
exit 0
|
|
379
|
+
fi
|
|
380
|
+
|
|
381
|
+
echo ""
|
|
382
|
+
log_pass "Check passed: no violations"
|
|
383
|
+
exit 0
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
# Run main function
|
|
387
|
+
main "$@"
|