cerber-core 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 (67) hide show
  1. package/.cerber-example/BIBLE.md +132 -0
  2. package/.cerber-example/CERBER_LAW.md +200 -0
  3. package/.cerber-example/connections/contracts/booking-to-pricing.json +44 -0
  4. package/.cerber-example/connections/contracts/pricing-to-booking.json +37 -0
  5. package/.cerber-example/modules/booking-calendar/MODULE.md +225 -0
  6. package/.cerber-example/modules/booking-calendar/contract.json +106 -0
  7. package/.cerber-example/modules/booking-calendar/dependencies.json +8 -0
  8. package/.cerber-example/modules/pricing-engine/MODULE.md +160 -0
  9. package/.cerber-example/modules/pricing-engine/contract.json +64 -0
  10. package/.cerber-example/modules/pricing-engine/dependencies.json +8 -0
  11. package/CHANGELOG.md +68 -0
  12. package/LICENSE +21 -0
  13. package/README.md +1379 -0
  14. package/bin/cerber +105 -0
  15. package/bin/cerber-focus +31 -0
  16. package/bin/cerber-guardian +90 -0
  17. package/bin/cerber-health +113 -0
  18. package/bin/cerber-morning +19 -0
  19. package/bin/cerber-repair +21 -0
  20. package/dist/cerber/index.d.ts +47 -0
  21. package/dist/cerber/index.d.ts.map +1 -0
  22. package/dist/cerber/index.js +154 -0
  23. package/dist/cerber/index.js.map +1 -0
  24. package/dist/guardian/index.d.ts +70 -0
  25. package/dist/guardian/index.d.ts.map +1 -0
  26. package/dist/guardian/index.js +271 -0
  27. package/dist/guardian/index.js.map +1 -0
  28. package/dist/index.d.ts +9 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +9 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/types.d.ts +76 -0
  33. package/dist/types.d.ts.map +1 -0
  34. package/dist/types.js +5 -0
  35. package/dist/types.js.map +1 -0
  36. package/examples/backend-schema.ts +72 -0
  37. package/examples/frontend-schema.ts +67 -0
  38. package/examples/health-checks.ts +196 -0
  39. package/examples/solo-integration/README.md +457 -0
  40. package/examples/solo-integration/package.json +47 -0
  41. package/examples/team-integration/README.md +347 -0
  42. package/examples/team-integration/package.json +23 -0
  43. package/package.json +104 -0
  44. package/solo/README.md +258 -0
  45. package/solo/config/performance-budget.json +53 -0
  46. package/solo/config/solo-contract.json +71 -0
  47. package/solo/lib/feature-flags.ts +177 -0
  48. package/solo/scripts/cerber-auto-repair.js +260 -0
  49. package/solo/scripts/cerber-daily-check.js +282 -0
  50. package/solo/scripts/cerber-dashboard.js +191 -0
  51. package/solo/scripts/cerber-deps-health.js +247 -0
  52. package/solo/scripts/cerber-docs-sync.js +304 -0
  53. package/solo/scripts/cerber-flags-check.js +229 -0
  54. package/solo/scripts/cerber-performance-budget.js +271 -0
  55. package/solo/scripts/cerber-rollback.js +229 -0
  56. package/solo/scripts/cerber-snapshot.js +319 -0
  57. package/team/README.md +327 -0
  58. package/team/config/team-contract.json +27 -0
  59. package/team/lib/module-system.ts +157 -0
  60. package/team/scripts/cerber-add-module.sh +195 -0
  61. package/team/scripts/cerber-connections-check.sh +186 -0
  62. package/team/scripts/cerber-focus.sh +170 -0
  63. package/team/scripts/cerber-module-check.sh +165 -0
  64. package/team/scripts/cerber-team-morning.sh +210 -0
  65. package/team/templates/BIBLE_TEMPLATE.md +52 -0
  66. package/team/templates/CONNECTION_TEMPLATE.json +20 -0
  67. package/team/templates/MODULE_TEMPLATE.md +60 -0
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Cerber SOLO - Dashboard
5
+ *
6
+ * Extends Cerber Core with automation for solo developers
7
+ *
8
+ * Features:
9
+ * - Colored terminal output
10
+ * - System health summary
11
+ * - Quick actions menu
12
+ *
13
+ * @author Stefan Pitek
14
+ * @copyright 2026 Stefan Pitek
15
+ * @license MIT
16
+ */
17
+
18
+ const { execSync } = require('child_process');
19
+
20
+ // Terminal colors
21
+ const colors = {
22
+ reset: '\x1b[0m',
23
+ bright: '\x1b[1m',
24
+ dim: '\x1b[2m',
25
+ red: '\x1b[31m',
26
+ green: '\x1b[32m',
27
+ yellow: '\x1b[33m',
28
+ blue: '\x1b[34m',
29
+ magenta: '\x1b[35m',
30
+ cyan: '\x1b[36m',
31
+ white: '\x1b[37m',
32
+ bgRed: '\x1b[41m',
33
+ bgGreen: '\x1b[42m',
34
+ bgYellow: '\x1b[43m',
35
+ bgBlue: '\x1b[44m'
36
+ };
37
+
38
+ function colorize(text, color) {
39
+ return `${colors[color] || ''}${text}${colors.reset}`;
40
+ }
41
+
42
+ function header(text) {
43
+ console.log();
44
+ console.log(colorize('='.repeat(60), 'cyan'));
45
+ console.log(colorize(text, 'bright'));
46
+ console.log(colorize('='.repeat(60), 'cyan'));
47
+ console.log();
48
+ }
49
+
50
+ function section(title) {
51
+ console.log(colorize(`\n${title}`, 'yellow'));
52
+ console.log(colorize('-'.repeat(40), 'dim'));
53
+ }
54
+
55
+ function success(text) {
56
+ console.log(colorize(`✅ ${text}`, 'green'));
57
+ }
58
+
59
+ function warning(text) {
60
+ console.log(colorize(`⚠️ ${text}`, 'yellow'));
61
+ }
62
+
63
+ function error(text) {
64
+ console.log(colorize(`❌ ${text}`, 'red'));
65
+ }
66
+
67
+ function info(text) {
68
+ console.log(colorize(`ℹ️ ${text}`, 'blue'));
69
+ }
70
+
71
+ function metric(label, value, status = 'normal') {
72
+ const statusColor = status === 'good' ? 'green' :
73
+ status === 'warning' ? 'yellow' :
74
+ status === 'error' ? 'red' : 'white';
75
+ console.log(` ${colorize(label + ':', 'dim')} ${colorize(value, statusColor)}`);
76
+ }
77
+
78
+ // Main dashboard
79
+ header('🛡️ Cerber SOLO Dashboard');
80
+
81
+ // System status
82
+ section('📊 System Status');
83
+
84
+ try {
85
+ const packagePath = require('path').join(process.cwd(), 'package.json');
86
+ const fs = require('fs');
87
+
88
+ if (fs.existsSync(packagePath)) {
89
+ const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
90
+ metric('Project', pkg.name || 'unknown');
91
+ metric('Version', pkg.version || '0.0.0');
92
+ success('Package configuration found');
93
+ } else {
94
+ warning('No package.json found');
95
+ }
96
+ } catch (err) {
97
+ error('Could not read package.json');
98
+ }
99
+
100
+ // Git status
101
+ section('📂 Git Status');
102
+
103
+ try {
104
+ const branch = execSync('git rev-parse --abbrev-ref HEAD', {
105
+ encoding: 'utf8',
106
+ stdio: 'pipe'
107
+ }).trim();
108
+
109
+ metric('Branch', branch);
110
+
111
+ const status = execSync('git status --short', { encoding: 'utf8', stdio: 'pipe' }).trim();
112
+
113
+ if (status) {
114
+ const lines = status.split('\n').length;
115
+ warning(`${lines} file(s) with changes`);
116
+ } else {
117
+ success('Working directory clean');
118
+ }
119
+
120
+ // Check for unpushed commits
121
+ try {
122
+ const unpushed = execSync('git log @{u}.. --oneline 2>/dev/null || true', {
123
+ encoding: 'utf8',
124
+ stdio: 'pipe'
125
+ }).trim();
126
+
127
+ if (unpushed) {
128
+ const count = unpushed.split('\n').filter(l => l.trim()).length;
129
+ info(`${count} unpushed commit(s)`);
130
+ }
131
+ } catch (err) {
132
+ // No upstream
133
+ }
134
+ } catch (err) {
135
+ info('Not a git repository');
136
+ }
137
+
138
+ // Guardian status
139
+ section('🛡️ Guardian Status');
140
+
141
+ const guardianPaths = [
142
+ 'scripts/validate-schema.mjs',
143
+ 'scripts/validate-schema.js',
144
+ '.husky/pre-commit'
145
+ ];
146
+
147
+ const guardianExists = guardianPaths.some(p => {
148
+ const fs = require('fs');
149
+ const path = require('path');
150
+ return fs.existsSync(path.join(process.cwd(), p));
151
+ });
152
+
153
+ if (guardianExists) {
154
+ success('Guardian installed and active');
155
+ } else {
156
+ warning('Guardian not detected');
157
+ }
158
+
159
+ // SOLO tools
160
+ section('⚡ SOLO Tools');
161
+
162
+ const tools = [
163
+ { name: 'Auto-repair', cmd: 'cerber:repair' },
164
+ { name: 'Deps health', cmd: 'cerber:deps' },
165
+ { name: 'Performance', cmd: 'cerber:perf' },
166
+ { name: 'Docs sync', cmd: 'cerber:docs' },
167
+ { name: 'Feature flags', cmd: 'cerber:flags' },
168
+ { name: 'Snapshot', cmd: 'cerber:snapshot' }
169
+ ];
170
+
171
+ console.log();
172
+ tools.forEach(tool => {
173
+ console.log(` ${colorize('•', 'cyan')} ${tool.name}: ${colorize(`npm run ${tool.cmd}`, 'dim')}`);
174
+ });
175
+
176
+ // Quick actions
177
+ section('🚀 Quick Actions');
178
+
179
+ console.log();
180
+ console.log(colorize(' 1.', 'bright') + ' Run morning check: ' + colorize('npm run cerber:morning', 'cyan'));
181
+ console.log(colorize(' 2.', 'bright') + ' Auto-fix issues: ' + colorize('npm run cerber:repair', 'cyan'));
182
+ console.log(colorize(' 3.', 'bright') + ' Check dependencies: ' + colorize('npm run cerber:deps', 'cyan'));
183
+ console.log(colorize(' 4.', 'bright') + ' Before pushing: ' + colorize('npm run cerber:pre-push', 'cyan'));
184
+ console.log(colorize(' 5.', 'bright') + ' End of day snapshot: ' + colorize('npm run cerber:snapshot', 'cyan'));
185
+
186
+ // Footer
187
+ console.log();
188
+ console.log(colorize('='.repeat(60), 'cyan'));
189
+ console.log(colorize('\n✨ Cerber SOLO - Built by Stefan Pitek\n', 'magenta'));
190
+
191
+ process.exit(0);
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Cerber SOLO - Dependency Health Checker
5
+ *
6
+ * Extends Cerber Core with automation for solo developers
7
+ *
8
+ * Checks:
9
+ * - npm audit (vulnerabilities)
10
+ * - Outdated packages
11
+ * - Deprecated packages
12
+ * - Unmaintained packages (no updates 2+ years)
13
+ *
14
+ * @author Stefan Pitek
15
+ * @copyright 2026 Stefan Pitek
16
+ * @license MIT
17
+ */
18
+
19
+ const { execSync } = require('child_process');
20
+ const fs = require('fs');
21
+ const path = require('path');
22
+
23
+ console.log('🏥 Cerber SOLO - Dependency Health Check\n');
24
+
25
+ let healthScore = 100;
26
+ const issues = [];
27
+
28
+ /**
29
+ * Check for security vulnerabilities
30
+ */
31
+ function checkVulnerabilities() {
32
+ console.log('🔒 Checking security vulnerabilities...');
33
+
34
+ try {
35
+ execSync('npm audit --json > /tmp/audit-result.json 2>/dev/null', {
36
+ stdio: 'pipe',
37
+ encoding: 'utf8'
38
+ });
39
+
40
+ const auditData = JSON.parse(fs.readFileSync('/tmp/audit-result.json', 'utf8'));
41
+
42
+ const critical = auditData.metadata?.vulnerabilities?.critical || 0;
43
+ const high = auditData.metadata?.vulnerabilities?.high || 0;
44
+ const moderate = auditData.metadata?.vulnerabilities?.moderate || 0;
45
+ const low = auditData.metadata?.vulnerabilities?.low || 0;
46
+
47
+ if (critical > 0 || high > 0 || moderate > 0 || low > 0) {
48
+ console.log(` ⚠️ Found vulnerabilities:`);
49
+ if (critical > 0) console.log(` 🔴 Critical: ${critical}`);
50
+ if (high > 0) console.log(` 🟠 High: ${high}`);
51
+ if (moderate > 0) console.log(` 🟡 Moderate: ${moderate}`);
52
+ if (low > 0) console.log(` 🟢 Low: ${low}`);
53
+
54
+ healthScore -= (critical * 20) + (high * 10) + (moderate * 5) + (low * 2);
55
+ issues.push({
56
+ type: 'security',
57
+ severity: critical > 0 ? 'critical' : high > 0 ? 'high' : 'moderate',
58
+ message: `${critical + high + moderate + low} vulnerabilities found`,
59
+ action: 'Run: npm audit fix'
60
+ });
61
+ } else {
62
+ console.log(' ✅ No vulnerabilities found');
63
+ }
64
+ } catch (error) {
65
+ console.log(' ℹ️ npm audit check skipped (may not be available)');
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Check for outdated packages
71
+ */
72
+ function checkOutdated() {
73
+ console.log('\n📦 Checking outdated packages...');
74
+
75
+ try {
76
+ const outdated = execSync('npm outdated --json 2>/dev/null', {
77
+ encoding: 'utf8',
78
+ stdio: 'pipe'
79
+ });
80
+
81
+ if (!outdated) {
82
+ console.log(' ✅ All packages are up to date');
83
+ return;
84
+ }
85
+
86
+ const packages = JSON.parse(outdated);
87
+ const count = Object.keys(packages).length;
88
+
89
+ if (count > 0) {
90
+ console.log(` ⚠️ ${count} outdated packages found`);
91
+
92
+ // Show top 5 outdated packages
93
+ const entries = Object.entries(packages).slice(0, 5);
94
+ entries.forEach(([name, info]) => {
95
+ console.log(` ${name}: ${info.current} → ${info.latest}`);
96
+ });
97
+
98
+ if (count > 5) {
99
+ console.log(` ... and ${count - 5} more`);
100
+ }
101
+
102
+ healthScore -= Math.min(count * 2, 30);
103
+ issues.push({
104
+ type: 'outdated',
105
+ severity: 'low',
106
+ message: `${count} packages are outdated`,
107
+ action: 'Run: npm update'
108
+ });
109
+ }
110
+ } catch (error) {
111
+ // npm outdated exits with code 1 when packages are outdated
112
+ console.log(' ℹ️ Could not check outdated packages');
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Check for deprecated packages
118
+ */
119
+ function checkDeprecated() {
120
+ console.log('\n⚠️ Checking for deprecated packages...');
121
+
122
+ const packagePath = path.join(process.cwd(), 'package.json');
123
+
124
+ if (!fs.existsSync(packagePath)) {
125
+ console.log(' ⚠️ No package.json found');
126
+ return;
127
+ }
128
+
129
+ try {
130
+ const packageData = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
131
+ const allDeps = {
132
+ ...packageData.dependencies || {},
133
+ ...packageData.devDependencies || {}
134
+ };
135
+
136
+ // Known deprecated packages (example list)
137
+ const knownDeprecated = [
138
+ 'request',
139
+ 'node-uuid',
140
+ 'babel-preset-es2015',
141
+ 'gulp-util',
142
+ 'coffee-script'
143
+ ];
144
+
145
+ const deprecated = Object.keys(allDeps).filter(dep =>
146
+ knownDeprecated.some(d => dep.includes(d))
147
+ );
148
+
149
+ if (deprecated.length > 0) {
150
+ console.log(` ⚠️ ${deprecated.length} deprecated packages found:`);
151
+ deprecated.forEach(pkg => {
152
+ console.log(` - ${pkg}`);
153
+ });
154
+
155
+ healthScore -= deprecated.length * 10;
156
+ issues.push({
157
+ type: 'deprecated',
158
+ severity: 'moderate',
159
+ message: `${deprecated.length} deprecated packages in use`,
160
+ action: 'Replace with maintained alternatives'
161
+ });
162
+ } else {
163
+ console.log(' ✅ No known deprecated packages');
164
+ }
165
+ } catch (error) {
166
+ console.log(` ❌ Error checking deprecated packages: ${error.message}`);
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Check package-lock.json health
172
+ */
173
+ function checkLockFile() {
174
+ console.log('\n🔒 Checking package-lock.json...');
175
+
176
+ const lockPath = path.join(process.cwd(), 'package-lock.json');
177
+ const packagePath = path.join(process.cwd(), 'package.json');
178
+
179
+ if (!fs.existsSync(lockPath)) {
180
+ console.log(' ⚠️ No package-lock.json found');
181
+ issues.push({
182
+ type: 'lock-file',
183
+ severity: 'moderate',
184
+ message: 'Missing package-lock.json',
185
+ action: 'Run: npm install'
186
+ });
187
+ healthScore -= 10;
188
+ return;
189
+ }
190
+
191
+ try {
192
+ const lockStat = fs.statSync(lockPath);
193
+ const packageStat = fs.statSync(packagePath);
194
+
195
+ if (packageStat.mtime > lockStat.mtime) {
196
+ console.log(' ⚠️ package.json is newer than package-lock.json');
197
+ issues.push({
198
+ type: 'lock-file',
199
+ severity: 'low',
200
+ message: 'package-lock.json may be out of sync',
201
+ action: 'Run: npm install'
202
+ });
203
+ healthScore -= 5;
204
+ } else {
205
+ console.log(' ✅ package-lock.json is up to date');
206
+ }
207
+ } catch (error) {
208
+ console.log(` ❌ Error checking lock file: ${error.message}`);
209
+ }
210
+ }
211
+
212
+ // Run all checks
213
+ checkVulnerabilities();
214
+ checkOutdated();
215
+ checkDeprecated();
216
+ checkLockFile();
217
+
218
+ // Generate report
219
+ console.log('\n' + '='.repeat(60));
220
+ console.log('\n📊 Dependency Health Report\n');
221
+
222
+ healthScore = Math.max(0, healthScore);
223
+ const grade = healthScore >= 90 ? 'A' :
224
+ healthScore >= 75 ? 'B' :
225
+ healthScore >= 60 ? 'C' :
226
+ healthScore >= 40 ? 'D' : 'F';
227
+
228
+ const gradeEmoji = grade === 'A' ? '✅' :
229
+ grade === 'B' ? '👍' :
230
+ grade === 'C' ? '⚠️' :
231
+ grade === 'D' ? '🔴' : '💀';
232
+
233
+ console.log(`${gradeEmoji} Health Score: ${healthScore}/100 (Grade: ${grade})`);
234
+ console.log(` Issues Found: ${issues.length}`);
235
+
236
+ if (issues.length > 0) {
237
+ console.log('\n🔧 Recommended Actions:\n');
238
+ issues.forEach((issue, idx) => {
239
+ console.log(`${idx + 1}. [${issue.severity.toUpperCase()}] ${issue.message}`);
240
+ console.log(` → ${issue.action}\n`);
241
+ });
242
+ }
243
+
244
+ console.log('='.repeat(60));
245
+
246
+ // Exit with appropriate code
247
+ process.exit(healthScore < 60 ? 1 : 0);