@vibecheckai/cli 3.2.2 → 3.2.4
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/bin/.generated +25 -25
- package/bin/dev/run-v2-torture.js +30 -30
- package/bin/runners/ENHANCEMENT_GUIDE.md +121 -121
- package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -295
- package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
- package/bin/runners/lib/agent-firewall/claims/extractor.js +117 -28
- package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +23 -14
- package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +72 -1
- package/bin/runners/lib/agent-firewall/interceptor/base.js +2 -2
- package/bin/runners/lib/agent-firewall/policy/default-policy.json +6 -0
- package/bin/runners/lib/agent-firewall/policy/engine.js +34 -3
- package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +29 -4
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +12 -0
- package/bin/runners/lib/agent-firewall/truthpack/loader.js +21 -0
- package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
- package/bin/runners/lib/analyzers.js +606 -325
- package/bin/runners/lib/auth-truth.js +193 -193
- package/bin/runners/lib/backup.js +62 -62
- package/bin/runners/lib/billing.js +107 -107
- package/bin/runners/lib/claims.js +118 -118
- package/bin/runners/lib/cli-ui.js +540 -540
- package/bin/runners/lib/contracts/auth-contract.js +202 -202
- package/bin/runners/lib/contracts/env-contract.js +181 -181
- package/bin/runners/lib/contracts/external-contract.js +206 -206
- package/bin/runners/lib/contracts/guard.js +168 -168
- package/bin/runners/lib/contracts/index.js +89 -89
- package/bin/runners/lib/contracts/plan-validator.js +311 -311
- package/bin/runners/lib/contracts/route-contract.js +199 -199
- package/bin/runners/lib/contracts.js +804 -804
- package/bin/runners/lib/detect.js +89 -89
- package/bin/runners/lib/doctor/autofix.js +254 -254
- package/bin/runners/lib/doctor/index.js +37 -37
- package/bin/runners/lib/doctor/modules/dependencies.js +325 -325
- package/bin/runners/lib/doctor/modules/index.js +46 -46
- package/bin/runners/lib/doctor/modules/network.js +250 -250
- package/bin/runners/lib/doctor/modules/project.js +312 -312
- package/bin/runners/lib/doctor/modules/runtime.js +224 -224
- package/bin/runners/lib/doctor/modules/security.js +348 -348
- package/bin/runners/lib/doctor/modules/system.js +213 -213
- package/bin/runners/lib/doctor/modules/vibecheck.js +394 -394
- package/bin/runners/lib/doctor/reporter.js +262 -262
- package/bin/runners/lib/doctor/service.js +262 -262
- package/bin/runners/lib/doctor/types.js +113 -113
- package/bin/runners/lib/doctor/ui.js +263 -263
- package/bin/runners/lib/doctor-v2.js +608 -608
- package/bin/runners/lib/drift.js +425 -425
- package/bin/runners/lib/enforcement.js +72 -72
- package/bin/runners/lib/engines/accessibility-engine.js +190 -0
- package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
- package/bin/runners/lib/engines/ast-cache.js +99 -0
- package/bin/runners/lib/engines/code-quality-engine.js +255 -0
- package/bin/runners/lib/engines/console-logs-engine.js +115 -0
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
- package/bin/runners/lib/engines/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
- package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
- package/bin/runners/lib/engines/file-filter.js +131 -0
- package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
- package/bin/runners/lib/engines/mock-data-engine.js +272 -0
- package/bin/runners/lib/engines/parallel-processor.js +71 -0
- package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
- package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
- package/bin/runners/lib/engines/type-aware-engine.js +152 -0
- package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
- package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
- package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
- package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -0
- package/bin/runners/lib/enterprise-detect.js +603 -603
- package/bin/runners/lib/enterprise-init.js +942 -942
- package/bin/runners/lib/env-resolver.js +417 -417
- package/bin/runners/lib/env-template.js +66 -66
- package/bin/runners/lib/env.js +189 -189
- package/bin/runners/lib/extractors/client-calls.js +990 -990
- package/bin/runners/lib/extractors/fastify-route-dump.js +573 -573
- package/bin/runners/lib/extractors/fastify-routes.js +426 -426
- package/bin/runners/lib/extractors/index.js +363 -363
- package/bin/runners/lib/extractors/next-routes.js +524 -524
- package/bin/runners/lib/extractors/proof-graph.js +431 -431
- package/bin/runners/lib/extractors/route-matcher.js +451 -451
- package/bin/runners/lib/extractors/truthpack-v2.js +377 -377
- package/bin/runners/lib/extractors/ui-bindings.js +547 -547
- package/bin/runners/lib/findings-schema.js +281 -281
- package/bin/runners/lib/firewall-prompt.js +50 -50
- package/bin/runners/lib/global-flags.js +213 -213
- package/bin/runners/lib/graph/graph-builder.js +265 -265
- package/bin/runners/lib/graph/html-renderer.js +413 -413
- package/bin/runners/lib/graph/index.js +32 -32
- package/bin/runners/lib/graph/runtime-collector.js +215 -215
- package/bin/runners/lib/graph/static-extractor.js +518 -518
- package/bin/runners/lib/html-report.js +650 -650
- package/bin/runners/lib/interactive-menu.js +1496 -1496
- package/bin/runners/lib/llm.js +75 -75
- package/bin/runners/lib/meter.js +61 -61
- package/bin/runners/lib/missions/evidence.js +126 -126
- package/bin/runners/lib/patch.js +40 -40
- package/bin/runners/lib/permissions/auth-model.js +213 -213
- package/bin/runners/lib/permissions/idor-prover.js +205 -205
- package/bin/runners/lib/permissions/index.js +45 -45
- package/bin/runners/lib/permissions/matrix-builder.js +198 -198
- package/bin/runners/lib/pkgjson.js +28 -28
- package/bin/runners/lib/policy.js +295 -295
- package/bin/runners/lib/preflight.js +142 -142
- package/bin/runners/lib/reality/correlation-detectors.js +359 -359
- package/bin/runners/lib/reality/index.js +318 -318
- package/bin/runners/lib/reality/request-hashing.js +416 -416
- package/bin/runners/lib/reality/request-mapper.js +453 -453
- package/bin/runners/lib/reality/safety-rails.js +463 -463
- package/bin/runners/lib/reality/semantic-snapshot.js +408 -408
- package/bin/runners/lib/reality/toast-detector.js +393 -393
- package/bin/runners/lib/reality-findings.js +84 -84
- package/bin/runners/lib/receipts.js +179 -179
- package/bin/runners/lib/redact.js +29 -29
- package/bin/runners/lib/replay/capsule-manager.js +154 -154
- package/bin/runners/lib/replay/index.js +263 -263
- package/bin/runners/lib/replay/player.js +348 -348
- package/bin/runners/lib/replay/recorder.js +331 -331
- package/bin/runners/lib/report-output.js +187 -187
- package/bin/runners/lib/report.js +135 -135
- package/bin/runners/lib/route-detection.js +1140 -1140
- package/bin/runners/lib/sandbox/index.js +59 -59
- package/bin/runners/lib/sandbox/proof-chain.js +399 -399
- package/bin/runners/lib/sandbox/sandbox-runner.js +205 -205
- package/bin/runners/lib/sandbox/worktree.js +174 -174
- package/bin/runners/lib/scan-output.js +525 -190
- package/bin/runners/lib/schema-validator.js +350 -350
- package/bin/runners/lib/schemas/contracts.schema.json +160 -160
- package/bin/runners/lib/schemas/finding.schema.json +100 -100
- package/bin/runners/lib/schemas/mission-pack.schema.json +206 -206
- package/bin/runners/lib/schemas/proof-graph.schema.json +176 -176
- package/bin/runners/lib/schemas/reality-report.schema.json +162 -162
- package/bin/runners/lib/schemas/share-pack.schema.json +180 -180
- package/bin/runners/lib/schemas/ship-report.schema.json +117 -117
- package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -303
- package/bin/runners/lib/schemas/validator.js +438 -438
- package/bin/runners/lib/score-history.js +282 -282
- package/bin/runners/lib/share-pack.js +239 -239
- package/bin/runners/lib/snippets.js +67 -67
- package/bin/runners/lib/status-output.js +253 -253
- package/bin/runners/lib/terminal-ui.js +351 -271
- package/bin/runners/lib/upsell.js +510 -510
- package/bin/runners/lib/usage.js +153 -153
- package/bin/runners/lib/validate-patch.js +156 -156
- package/bin/runners/lib/verdict-engine.js +628 -628
- package/bin/runners/reality/engine.js +917 -917
- package/bin/runners/reality/flows.js +122 -122
- package/bin/runners/reality/report.js +378 -378
- package/bin/runners/reality/session.js +193 -193
- package/bin/runners/runGuard.js +168 -168
- package/bin/runners/runProof.zip +0 -0
- package/bin/runners/runProve.js +8 -0
- package/bin/runners/runReality.js +14 -0
- package/bin/runners/runScan.js +17 -1
- package/bin/runners/runTruth.js +15 -3
- package/mcp-server/tier-auth.js +4 -4
- package/mcp-server/tools/index.js +72 -72
- package/package.json +1 -1
|
@@ -1,181 +1,181 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Env Contract Builder
|
|
3
|
-
* Builds env.json contract from truthpack
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
"use strict";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Build env contract from truthpack
|
|
10
|
-
*/
|
|
11
|
-
function buildEnvContract(truthpack) {
|
|
12
|
-
const contract = {
|
|
13
|
-
version: "1.0.0",
|
|
14
|
-
generatedAt: new Date().toISOString(),
|
|
15
|
-
vars: []
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const envVars = truthpack?.env?.vars || [];
|
|
19
|
-
const declared = new Set(truthpack?.env?.declared || []);
|
|
20
|
-
const declaredSources = truthpack?.env?.declaredSources || [];
|
|
21
|
-
|
|
22
|
-
for (const v of envVars) {
|
|
23
|
-
const varSpec = {
|
|
24
|
-
name: v.name,
|
|
25
|
-
required: inferRequired(v, declared),
|
|
26
|
-
usedIn: (v.references || []).map(r => r.file).filter(Boolean),
|
|
27
|
-
declaredIn: declaredSources.filter(s => isDeclaredInSource(v.name, s)),
|
|
28
|
-
description: inferDescription(v.name),
|
|
29
|
-
evidence: v.references || []
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
contract.vars.push(varSpec);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Add declared vars that aren't used (might be optional)
|
|
36
|
-
for (const name of declared) {
|
|
37
|
-
if (!envVars.find(v => v.name === name)) {
|
|
38
|
-
contract.vars.push({
|
|
39
|
-
name,
|
|
40
|
-
required: false,
|
|
41
|
-
usedIn: [],
|
|
42
|
-
declaredIn: declaredSources,
|
|
43
|
-
description: inferDescription(name),
|
|
44
|
-
evidence: []
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Deterministic output: sort vars by name
|
|
50
|
-
contract.vars.sort((a, b) => a.name.localeCompare(b.name));
|
|
51
|
-
|
|
52
|
-
return contract;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Infer if env var is required
|
|
57
|
-
*/
|
|
58
|
-
function inferRequired(envVar, declared) {
|
|
59
|
-
const name = envVar.name;
|
|
60
|
-
|
|
61
|
-
// Common required patterns
|
|
62
|
-
const requiredPatterns = [
|
|
63
|
-
/^DATABASE_URL$/i,
|
|
64
|
-
/^NEXTAUTH_SECRET$/i,
|
|
65
|
-
/^NEXTAUTH_URL$/i,
|
|
66
|
-
/^JWT_SECRET$/i,
|
|
67
|
-
/^API_KEY$/i,
|
|
68
|
-
/^STRIPE_SECRET_KEY$/i,
|
|
69
|
-
/^STRIPE_WEBHOOK_SECRET$/i,
|
|
70
|
-
/^AUTH0_/i,
|
|
71
|
-
/^CLERK_/i,
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
for (const pattern of requiredPatterns) {
|
|
75
|
-
if (pattern.test(name)) return true;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// If used but not declared, likely required
|
|
79
|
-
if (!declared.has(name) && envVar.references?.length > 0) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function isDeclaredInSource(name, source) {
|
|
87
|
-
// Simple heuristic - would need to parse files for accurate check
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function inferDescription(name) {
|
|
92
|
-
const descriptions = {
|
|
93
|
-
DATABASE_URL: "Database connection string",
|
|
94
|
-
NEXTAUTH_SECRET: "NextAuth.js encryption secret",
|
|
95
|
-
NEXTAUTH_URL: "NextAuth.js base URL",
|
|
96
|
-
JWT_SECRET: "JWT signing secret",
|
|
97
|
-
STRIPE_SECRET_KEY: "Stripe API secret key",
|
|
98
|
-
STRIPE_PUBLISHABLE_KEY: "Stripe publishable key",
|
|
99
|
-
STRIPE_WEBHOOK_SECRET: "Stripe webhook signing secret",
|
|
100
|
-
NODE_ENV: "Node environment (development/production)",
|
|
101
|
-
PORT: "Server port",
|
|
102
|
-
HOST: "Server host",
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
return descriptions[name] || undefined;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Validate code against env contract
|
|
110
|
-
*/
|
|
111
|
-
function validateAgainstEnvContract(contract, usedVars) {
|
|
112
|
-
const violations = [];
|
|
113
|
-
const contractVars = new Map(contract.vars.map(v => [v.name, v]));
|
|
114
|
-
|
|
115
|
-
for (const used of usedVars) {
|
|
116
|
-
if (!contractVars.has(used.name)) {
|
|
117
|
-
violations.push({
|
|
118
|
-
type: "undeclared_env",
|
|
119
|
-
severity: "WARN",
|
|
120
|
-
name: used.name,
|
|
121
|
-
usedIn: used.references?.map(r => r.file) || [],
|
|
122
|
-
message: `Env var ${used.name} used but not declared in contract`,
|
|
123
|
-
evidence: used.references || []
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Check for required vars that aren't used
|
|
129
|
-
for (const [name, spec] of contractVars) {
|
|
130
|
-
if (spec.required && spec.usedIn.length === 0) {
|
|
131
|
-
violations.push({
|
|
132
|
-
type: "unused_required",
|
|
133
|
-
severity: "WARN",
|
|
134
|
-
name,
|
|
135
|
-
message: `Required env var ${name} declared but not used`,
|
|
136
|
-
evidence: []
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return violations;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Diff two env contracts
|
|
146
|
-
*/
|
|
147
|
-
function diffEnvContracts(before, after) {
|
|
148
|
-
const diff = {
|
|
149
|
-
added: [],
|
|
150
|
-
removed: [],
|
|
151
|
-
changed: []
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const beforeMap = new Map(before.vars.map(v => [v.name, v]));
|
|
155
|
-
const afterMap = new Map(after.vars.map(v => [v.name, v]));
|
|
156
|
-
|
|
157
|
-
for (const [name, spec] of afterMap) {
|
|
158
|
-
if (!beforeMap.has(name)) {
|
|
159
|
-
diff.added.push(spec);
|
|
160
|
-
} else {
|
|
161
|
-
const prev = beforeMap.get(name);
|
|
162
|
-
if (prev.required !== spec.required) {
|
|
163
|
-
diff.changed.push({ before: prev, after: spec });
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
for (const [name, spec] of beforeMap) {
|
|
169
|
-
if (!afterMap.has(name)) {
|
|
170
|
-
diff.removed.push(spec);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return diff;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
module.exports = {
|
|
178
|
-
buildEnvContract,
|
|
179
|
-
validateAgainstEnvContract,
|
|
180
|
-
diffEnvContracts
|
|
181
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Env Contract Builder
|
|
3
|
+
* Builds env.json contract from truthpack
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Build env contract from truthpack
|
|
10
|
+
*/
|
|
11
|
+
function buildEnvContract(truthpack) {
|
|
12
|
+
const contract = {
|
|
13
|
+
version: "1.0.0",
|
|
14
|
+
generatedAt: new Date().toISOString(),
|
|
15
|
+
vars: []
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const envVars = truthpack?.env?.vars || [];
|
|
19
|
+
const declared = new Set(truthpack?.env?.declared || []);
|
|
20
|
+
const declaredSources = truthpack?.env?.declaredSources || [];
|
|
21
|
+
|
|
22
|
+
for (const v of envVars) {
|
|
23
|
+
const varSpec = {
|
|
24
|
+
name: v.name,
|
|
25
|
+
required: inferRequired(v, declared),
|
|
26
|
+
usedIn: (v.references || []).map(r => r.file).filter(Boolean),
|
|
27
|
+
declaredIn: declaredSources.filter(s => isDeclaredInSource(v.name, s)),
|
|
28
|
+
description: inferDescription(v.name),
|
|
29
|
+
evidence: v.references || []
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
contract.vars.push(varSpec);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Add declared vars that aren't used (might be optional)
|
|
36
|
+
for (const name of declared) {
|
|
37
|
+
if (!envVars.find(v => v.name === name)) {
|
|
38
|
+
contract.vars.push({
|
|
39
|
+
name,
|
|
40
|
+
required: false,
|
|
41
|
+
usedIn: [],
|
|
42
|
+
declaredIn: declaredSources,
|
|
43
|
+
description: inferDescription(name),
|
|
44
|
+
evidence: []
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Deterministic output: sort vars by name
|
|
50
|
+
contract.vars.sort((a, b) => a.name.localeCompare(b.name));
|
|
51
|
+
|
|
52
|
+
return contract;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Infer if env var is required
|
|
57
|
+
*/
|
|
58
|
+
function inferRequired(envVar, declared) {
|
|
59
|
+
const name = envVar.name;
|
|
60
|
+
|
|
61
|
+
// Common required patterns
|
|
62
|
+
const requiredPatterns = [
|
|
63
|
+
/^DATABASE_URL$/i,
|
|
64
|
+
/^NEXTAUTH_SECRET$/i,
|
|
65
|
+
/^NEXTAUTH_URL$/i,
|
|
66
|
+
/^JWT_SECRET$/i,
|
|
67
|
+
/^API_KEY$/i,
|
|
68
|
+
/^STRIPE_SECRET_KEY$/i,
|
|
69
|
+
/^STRIPE_WEBHOOK_SECRET$/i,
|
|
70
|
+
/^AUTH0_/i,
|
|
71
|
+
/^CLERK_/i,
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
for (const pattern of requiredPatterns) {
|
|
75
|
+
if (pattern.test(name)) return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// If used but not declared, likely required
|
|
79
|
+
if (!declared.has(name) && envVar.references?.length > 0) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function isDeclaredInSource(name, source) {
|
|
87
|
+
// Simple heuristic - would need to parse files for accurate check
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function inferDescription(name) {
|
|
92
|
+
const descriptions = {
|
|
93
|
+
DATABASE_URL: "Database connection string",
|
|
94
|
+
NEXTAUTH_SECRET: "NextAuth.js encryption secret",
|
|
95
|
+
NEXTAUTH_URL: "NextAuth.js base URL",
|
|
96
|
+
JWT_SECRET: "JWT signing secret",
|
|
97
|
+
STRIPE_SECRET_KEY: "Stripe API secret key",
|
|
98
|
+
STRIPE_PUBLISHABLE_KEY: "Stripe publishable key",
|
|
99
|
+
STRIPE_WEBHOOK_SECRET: "Stripe webhook signing secret",
|
|
100
|
+
NODE_ENV: "Node environment (development/production)",
|
|
101
|
+
PORT: "Server port",
|
|
102
|
+
HOST: "Server host",
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return descriptions[name] || undefined;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Validate code against env contract
|
|
110
|
+
*/
|
|
111
|
+
function validateAgainstEnvContract(contract, usedVars) {
|
|
112
|
+
const violations = [];
|
|
113
|
+
const contractVars = new Map(contract.vars.map(v => [v.name, v]));
|
|
114
|
+
|
|
115
|
+
for (const used of usedVars) {
|
|
116
|
+
if (!contractVars.has(used.name)) {
|
|
117
|
+
violations.push({
|
|
118
|
+
type: "undeclared_env",
|
|
119
|
+
severity: "WARN",
|
|
120
|
+
name: used.name,
|
|
121
|
+
usedIn: used.references?.map(r => r.file) || [],
|
|
122
|
+
message: `Env var ${used.name} used but not declared in contract`,
|
|
123
|
+
evidence: used.references || []
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Check for required vars that aren't used
|
|
129
|
+
for (const [name, spec] of contractVars) {
|
|
130
|
+
if (spec.required && spec.usedIn.length === 0) {
|
|
131
|
+
violations.push({
|
|
132
|
+
type: "unused_required",
|
|
133
|
+
severity: "WARN",
|
|
134
|
+
name,
|
|
135
|
+
message: `Required env var ${name} declared but not used`,
|
|
136
|
+
evidence: []
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return violations;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Diff two env contracts
|
|
146
|
+
*/
|
|
147
|
+
function diffEnvContracts(before, after) {
|
|
148
|
+
const diff = {
|
|
149
|
+
added: [],
|
|
150
|
+
removed: [],
|
|
151
|
+
changed: []
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const beforeMap = new Map(before.vars.map(v => [v.name, v]));
|
|
155
|
+
const afterMap = new Map(after.vars.map(v => [v.name, v]));
|
|
156
|
+
|
|
157
|
+
for (const [name, spec] of afterMap) {
|
|
158
|
+
if (!beforeMap.has(name)) {
|
|
159
|
+
diff.added.push(spec);
|
|
160
|
+
} else {
|
|
161
|
+
const prev = beforeMap.get(name);
|
|
162
|
+
if (prev.required !== spec.required) {
|
|
163
|
+
diff.changed.push({ before: prev, after: spec });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
for (const [name, spec] of beforeMap) {
|
|
169
|
+
if (!afterMap.has(name)) {
|
|
170
|
+
diff.removed.push(spec);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return diff;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
module.exports = {
|
|
178
|
+
buildEnvContract,
|
|
179
|
+
validateAgainstEnvContract,
|
|
180
|
+
diffEnvContracts
|
|
181
|
+
};
|