cerber-core 1.1.1 → 1.1.3

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
@@ -50,7 +50,7 @@ ROI: Break-even on Day 1
50
50
  **For CTOs & Engineering Managers:**
51
51
  - **Reduce production incidents** - 95% bugs caught pre-production (vs 60-70% manual reviews)
52
52
  - **Cut debugging costs** - 4.5 hours saved per developer per session
53
- - **Speed up onboarding** - BIBLE.md = instant project understanding for new hires
53
+ - **Speed up onboarding** - CERBER.md = instant project understanding for new hires
54
54
  - **Enforce architecture** - Prevent technical debt before it enters codebase
55
55
 
56
56
  **Cost Comparison:**
@@ -91,7 +91,7 @@ Cerber guards → enforces your decisions
91
91
 
92
92
  **Cerber Core solution:**
93
93
  ```
94
- ✅ Architect defines rules once (BIBLE.md + Guardian schema)
94
+ ✅ Architect defines rules once (CERBER.md contract)
95
95
  ✅ Cerber enforces automatically forever
96
96
  ✅ Every commit validates against your roadmap (<1 second)
97
97
  ✅ Architecture stays intact as team scales
@@ -141,7 +141,7 @@ export const BACKEND_SCHEMA = {
141
141
  - **Focus Mode** - Generate 500 LOC context (vs 10K LOC) ⭐
142
142
  - Module boundaries enforcement
143
143
  - Connection contracts between modules
144
- - BIBLE.md project mapping
144
+ - CERBER.md project mapping
145
145
 
146
146
  ---
147
147
 
@@ -1143,88 +1143,6 @@ git commit # Guardian validates
1143
1143
 
1144
1144
  ---
1145
1145
 
1146
- ## 📖 BIBLE.md - Your Project's Single Source of Truth
1147
-
1148
- **BIBLE.md** is your project's master map - the ONE place where everything is documented.
1149
-
1150
- ### Why BIBLE.md?
1151
-
1152
- With AI coding, teams can diverge quickly. Everyone works fast, but in different directions. BIBLE.md keeps everyone aligned:
1153
-
1154
- - **All modules documented** - What exists, who owns it, what it does
1155
- - **All connections mapped** - How modules talk to each other
1156
- - **Team responsibilities clear** - Who works on what
1157
- - **Architecture decisions recorded** - Why things are built this way
1158
-
1159
- ### How It Works
1160
-
1161
- ```bash
1162
- # 1. Copy template
1163
- cp node_modules/cerber-core/team/templates/BIBLE_TEMPLATE.md .cerber/BIBLE.md
1164
-
1165
- # 2. Describe your architecture
1166
- nano .cerber/BIBLE.md
1167
-
1168
- # 3. Keep it updated when adding modules
1169
- # 4. Reference in code reviews
1170
- ```
1171
-
1172
- ### What's Inside BIBLE.md?
1173
-
1174
- ```markdown
1175
- # PROJECT BIBLE - Master Map
1176
-
1177
- ## Architecture Overview
1178
- [Visual diagram of your system]
1179
-
1180
- ## Modules Index
1181
- 1. **auth-service** - Authentication & JWT
1182
- - Owner: Alice
1183
- - Files: `src/modules/auth/`
1184
-
1185
- 2. **payment-service** - Stripe integration
1186
- - Owner: Bob
1187
- - Files: `src/modules/payment/`
1188
-
1189
- ## Connections Map
1190
- - `auth-service` → `user-service`: validateToken()
1191
- - `payment-service` → `notification-service`: sendReceipt()
1192
-
1193
- ## Team Responsibilities
1194
- - Alice: auth, user management
1195
- - Bob: payments, billing
1196
- ```
1197
-
1198
- ### Integration with Cerber
1199
-
1200
- Cerber automatically reads BIBLE.md from `.cerber/BIBLE.md` when running health checks:
1201
-
1202
- ```typescript
1203
- // server.ts
1204
- import { createHealthEndpoint } from 'cerber-core';
1205
-
1206
- const healthChecks = {
1207
- // Cerber automatically validates against .cerber/BIBLE.md
1208
- architecture: async () => {
1209
- // Checks if actual modules match BIBLE structure
1210
- return await validateArchitectureAgainstBible();
1211
- }
1212
- };
1213
-
1214
- app.get('/api/health', createHealthEndpoint(healthChecks));
1215
- ```
1216
-
1217
- **What Cerber checks:**
1218
- - **Guardian** validates modules match BIBLE structure (pre-commit)
1219
- - **Focus Mode** uses BIBLE to isolate context (500 LOC vs 10K LOC)
1220
- - **Module checks** ensure boundaries defined in BIBLE are respected
1221
- - **Morning checks** verify BIBLE is up-to-date with codebase
1222
- - **Runtime health** checks architecture drift from BIBLE
1223
-
1224
- **Result:** Your team stays aligned even when coding at AI speed! 🚀
1225
-
1226
- ---
1227
-
1228
1146
  ## 🏆 Why Cerber Core?
1229
1147
 
1230
1148
  ### Unique Innovations
@@ -20,12 +20,14 @@ export const BACKEND_SCHEMA = {
20
20
  forbiddenPatterns: [
21
21
  // Uncomment and customize based on your tech stack:
22
22
  // {
23
- // pattern: /password\s*=\s*['"][^'"]+['"]/i,
23
+ // pattern: "password\\s*=\\s*['\"][^'\"]+['\"]",
24
+ // flags: "i",
24
25
  // name: "Hardcoded passwords",
25
26
  // severity: "error"
26
27
  // },
27
28
  // {
28
- // pattern: /api[_-]?key\s*=\s*['"][^'"]+['"]/i,
29
+ // pattern: "api[_-]?key\\s*=\\s*['\"][^'\"]+['\"]",
30
+ // flags: "i",
29
31
  // name: "Hardcoded API keys",
30
32
  // severity: "error"
31
33
  // }
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { execSync } from 'child_process';
6
6
  import fs from 'fs';
7
+ import { join } from 'path';
7
8
 
8
9
  const SCHEMA_FILE = '{{SCHEMA_FILE}}';
9
10
  const APPROVALS_TAG = '{{APPROVALS_TAG}}';
@@ -13,10 +14,23 @@ async function main() {
13
14
 
14
15
  if (!fs.existsSync(SCHEMA_FILE)) {
15
16
  console.error(`❌ Schema file not found: ${SCHEMA_FILE}`);
16
- console.error('Guardian MVP: schema missing. Add your rules to proceed.');
17
+ console.error('Create your schema file to enable validation.');
18
+ console.error(`Example: npx cerber init --print-schema-template > ${SCHEMA_FILE}`);
17
19
  process.exit(1);
18
20
  }
19
21
 
22
+ // Import schema
23
+ let schema;
24
+ try {
25
+ const schemaPath = join(process.cwd(), SCHEMA_FILE);
26
+ const schemaModule = await import(`file://${schemaPath}`);
27
+ schema = schemaModule.BACKEND_SCHEMA || schemaModule.default || schemaModule;
28
+ } catch (err) {
29
+ console.error(`❌ Failed to load schema from ${SCHEMA_FILE}:`, err.message);
30
+ process.exit(1);
31
+ }
32
+
33
+ // Get staged files
20
34
  let stagedFiles;
21
35
  try {
22
36
  stagedFiles = execSync('git diff --cached --name-only', { encoding: 'utf-8' })
@@ -34,7 +48,97 @@ async function main() {
34
48
  }
35
49
 
36
50
  console.log(`Checking ${stagedFiles.length} file(s)...`);
37
- console.log('Guardian MVP: schema detected. Add validation rules to enforce imports/forbidden patterns.');
51
+
52
+ const violations = [];
53
+
54
+ // Validate each staged file
55
+ for (const file of stagedFiles) {
56
+ if (!fs.existsSync(file)) continue;
57
+
58
+ const content = fs.readFileSync(file, 'utf-8');
59
+
60
+ // Check forbidden patterns
61
+ if (schema.forbiddenPatterns && Array.isArray(schema.forbiddenPatterns)) {
62
+ for (const rule of schema.forbiddenPatterns) {
63
+ if (!rule.pattern) continue;
64
+
65
+ const pattern = typeof rule.pattern === 'string'
66
+ ? new RegExp(rule.pattern, rule.flags || 'i')
67
+ : rule.pattern;
68
+
69
+ // Check if file is in exceptions
70
+ if (rule.exceptions && rule.exceptions.some(ex => file.includes(ex))) {
71
+ continue;
72
+ }
73
+
74
+ if (pattern.test(content)) {
75
+ // Check for architect approval
76
+ const hasApproval = content.includes(APPROVALS_TAG);
77
+
78
+ if (!hasApproval) {
79
+ violations.push({
80
+ file,
81
+ rule: rule.name || 'Unnamed rule',
82
+ severity: rule.severity || 'error'
83
+ });
84
+ }
85
+ }
86
+ }
87
+ }
88
+
89
+ // Check required imports (rules)
90
+ if (schema.rules && Array.isArray(schema.rules)) {
91
+ for (const rule of schema.rules) {
92
+ if (!rule.pattern || !rule.requiredImports) continue;
93
+
94
+ const filePattern = typeof rule.pattern === 'string' ? new RegExp(rule.pattern) : rule.pattern;
95
+
96
+ if (!filePattern.test(file)) continue;
97
+
98
+ // Check if file is in exceptions
99
+ if (rule.exceptions && rule.exceptions.some(ex => file.includes(ex))) {
100
+ continue;
101
+ }
102
+
103
+ // Check each required import
104
+ for (const requiredImport of rule.requiredImports) {
105
+ const importPattern = new RegExp(`import.*${requiredImport}`, 'i');
106
+
107
+ if (!importPattern.test(content)) {
108
+ // Check for architect approval
109
+ const hasApproval = content.includes(APPROVALS_TAG);
110
+
111
+ if (!hasApproval) {
112
+ violations.push({
113
+ file,
114
+ rule: `${rule.name || 'Unnamed rule'}: missing import '${requiredImport}'`,
115
+ severity: rule.severity || 'error'
116
+ });
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ // Report violations
125
+ if (violations.length > 0) {
126
+ console.error('\n❌ Architecture violations detected:\n');
127
+
128
+ for (const v of violations) {
129
+ const icon = v.severity === 'error' ? '🔴' : '⚠️';
130
+ console.error(`${icon} [${v.severity.toUpperCase()}] ${v.file}`);
131
+ console.error(` ${v.rule}`);
132
+ console.error(` Add ${APPROVALS_TAG} comment to override\n`);
133
+ }
134
+
135
+ const errorCount = violations.filter(v => v.severity === 'error').length;
136
+ if (errorCount > 0) {
137
+ console.error(`\n❌ Commit blocked: ${errorCount} error(s) found`);
138
+ process.exit(1);
139
+ }
140
+ }
141
+
38
142
  console.log('✅ All checks passed');
39
143
  }
40
144