micro-contracts 0.9.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 +22 -0
- package/README.md +351 -0
- package/dist/cli/templates.d.ts +16 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +377 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +978 -0
- package/dist/cli.js.map +1 -0
- package/dist/generator/dependencyGenerator.d.ts +43 -0
- package/dist/generator/dependencyGenerator.d.ts.map +1 -0
- package/dist/generator/dependencyGenerator.js +159 -0
- package/dist/generator/dependencyGenerator.js.map +1 -0
- package/dist/generator/domainGenerator.d.ts +16 -0
- package/dist/generator/domainGenerator.d.ts.map +1 -0
- package/dist/generator/domainGenerator.js +212 -0
- package/dist/generator/domainGenerator.js.map +1 -0
- package/dist/generator/index.d.ts +37 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +747 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/linter.d.ts +24 -0
- package/dist/generator/linter.d.ts.map +1 -0
- package/dist/generator/linter.js +202 -0
- package/dist/generator/linter.js.map +1 -0
- package/dist/generator/overlayProcessor.d.ts +90 -0
- package/dist/generator/overlayProcessor.d.ts.map +1 -0
- package/dist/generator/overlayProcessor.js +532 -0
- package/dist/generator/overlayProcessor.js.map +1 -0
- package/dist/generator/schemaGenerator.d.ts +10 -0
- package/dist/generator/schemaGenerator.d.ts.map +1 -0
- package/dist/generator/schemaGenerator.js +299 -0
- package/dist/generator/schemaGenerator.js.map +1 -0
- package/dist/generator/templateProcessor.d.ts +178 -0
- package/dist/generator/templateProcessor.d.ts.map +1 -0
- package/dist/generator/templateProcessor.js +607 -0
- package/dist/generator/templateProcessor.js.map +1 -0
- package/dist/generator/typeGenerator.d.ts +9 -0
- package/dist/generator/typeGenerator.d.ts.map +1 -0
- package/dist/generator/typeGenerator.js +395 -0
- package/dist/generator/typeGenerator.js.map +1 -0
- package/dist/guardrails/allowlist.d.ts +45 -0
- package/dist/guardrails/allowlist.d.ts.map +1 -0
- package/dist/guardrails/allowlist.js +261 -0
- package/dist/guardrails/allowlist.js.map +1 -0
- package/dist/guardrails/config.d.ts +40 -0
- package/dist/guardrails/config.d.ts.map +1 -0
- package/dist/guardrails/config.js +174 -0
- package/dist/guardrails/config.js.map +1 -0
- package/dist/guardrails/docs.d.ts +24 -0
- package/dist/guardrails/docs.d.ts.map +1 -0
- package/dist/guardrails/docs.js +138 -0
- package/dist/guardrails/docs.js.map +1 -0
- package/dist/guardrails/drift.d.ts +23 -0
- package/dist/guardrails/drift.d.ts.map +1 -0
- package/dist/guardrails/drift.js +127 -0
- package/dist/guardrails/drift.js.map +1 -0
- package/dist/guardrails/index.d.ts +19 -0
- package/dist/guardrails/index.d.ts.map +1 -0
- package/dist/guardrails/index.js +25 -0
- package/dist/guardrails/index.js.map +1 -0
- package/dist/guardrails/lint.d.ts +20 -0
- package/dist/guardrails/lint.d.ts.map +1 -0
- package/dist/guardrails/lint.js +274 -0
- package/dist/guardrails/lint.js.map +1 -0
- package/dist/guardrails/manifest.d.ts +43 -0
- package/dist/guardrails/manifest.d.ts.map +1 -0
- package/dist/guardrails/manifest.js +231 -0
- package/dist/guardrails/manifest.js.map +1 -0
- package/dist/guardrails/runner.d.ts +31 -0
- package/dist/guardrails/runner.d.ts.map +1 -0
- package/dist/guardrails/runner.js +268 -0
- package/dist/guardrails/runner.js.map +1 -0
- package/dist/guardrails/security.d.ts +31 -0
- package/dist/guardrails/security.d.ts.map +1 -0
- package/dist/guardrails/security.js +181 -0
- package/dist/guardrails/security.js.map +1 -0
- package/dist/guardrails/typecheck.d.ts +15 -0
- package/dist/guardrails/typecheck.d.ts.map +1 -0
- package/dist/guardrails/typecheck.js +104 -0
- package/dist/guardrails/typecheck.js.map +1 -0
- package/dist/guardrails/types.d.ts +196 -0
- package/dist/guardrails/types.d.ts.map +1 -0
- package/dist/guardrails/types.js +8 -0
- package/dist/guardrails/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +489 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +297 -0
- package/dist/types.js.map +1 -0
- package/docs/architecture.svg +226 -0
- package/docs/development-guardrails.md +541 -0
- package/docs/guardrails-concept.svg +252 -0
- package/docs/overlays-deep-dive.md +298 -0
- package/package.json +66 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated artifact manifest management
|
|
3
|
+
*
|
|
4
|
+
* Creates and verifies manifests for generated files to detect tampering.
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import crypto from 'crypto';
|
|
9
|
+
import { glob } from 'glob';
|
|
10
|
+
/** Current manifest format version */
|
|
11
|
+
const MANIFEST_VERSION = '1.0';
|
|
12
|
+
/** Manifest file name */
|
|
13
|
+
const MANIFEST_FILENAME = '.generated-manifest.json';
|
|
14
|
+
/**
|
|
15
|
+
* Calculate SHA-256 hash of file content
|
|
16
|
+
*/
|
|
17
|
+
export function hashFile(filePath) {
|
|
18
|
+
const content = fs.readFileSync(filePath);
|
|
19
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get all generated files in a directory
|
|
23
|
+
*/
|
|
24
|
+
export async function getGeneratedFiles(baseDir, patterns = ['**/*']) {
|
|
25
|
+
const files = [];
|
|
26
|
+
for (const pattern of patterns) {
|
|
27
|
+
const matches = await glob(pattern, {
|
|
28
|
+
cwd: baseDir,
|
|
29
|
+
nodir: true,
|
|
30
|
+
ignore: [
|
|
31
|
+
'**/node_modules/**',
|
|
32
|
+
'**/.git/**',
|
|
33
|
+
MANIFEST_FILENAME,
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
files.push(...matches);
|
|
37
|
+
}
|
|
38
|
+
// Deduplicate and sort
|
|
39
|
+
return [...new Set(files)].sort();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generate manifest for a directory of generated files
|
|
43
|
+
*/
|
|
44
|
+
export async function generateManifest(baseDir, options = {}) {
|
|
45
|
+
const { generatorVersion = '1.0.0', sourceMap = new Map(), patterns = ['**/*'], } = options;
|
|
46
|
+
const files = await getGeneratedFiles(baseDir, patterns);
|
|
47
|
+
const fileInfos = {};
|
|
48
|
+
for (const relPath of files) {
|
|
49
|
+
const fullPath = path.join(baseDir, relPath);
|
|
50
|
+
if (!fs.existsSync(fullPath))
|
|
51
|
+
continue;
|
|
52
|
+
if (fs.statSync(fullPath).isDirectory())
|
|
53
|
+
continue;
|
|
54
|
+
const info = {
|
|
55
|
+
sha256: hashFile(fullPath),
|
|
56
|
+
};
|
|
57
|
+
// Add source if available
|
|
58
|
+
const source = sourceMap.get(relPath);
|
|
59
|
+
if (source) {
|
|
60
|
+
info.source = source;
|
|
61
|
+
}
|
|
62
|
+
fileInfos[relPath] = info;
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
version: MANIFEST_VERSION,
|
|
66
|
+
generatedAt: new Date().toISOString(),
|
|
67
|
+
generatorVersion,
|
|
68
|
+
files: fileInfos,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Write manifest to file
|
|
73
|
+
*/
|
|
74
|
+
export function writeManifest(manifest, baseDir) {
|
|
75
|
+
const manifestPath = path.join(baseDir, MANIFEST_FILENAME);
|
|
76
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
77
|
+
return manifestPath;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Load manifest from file
|
|
81
|
+
*/
|
|
82
|
+
export function loadManifest(baseDir) {
|
|
83
|
+
const manifestPath = path.join(baseDir, MANIFEST_FILENAME);
|
|
84
|
+
if (!fs.existsSync(manifestPath)) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const content = fs.readFileSync(manifestPath, 'utf-8');
|
|
89
|
+
return JSON.parse(content);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Verify generated files against manifest
|
|
97
|
+
*/
|
|
98
|
+
export async function verifyManifest(baseDir) {
|
|
99
|
+
const manifest = loadManifest(baseDir);
|
|
100
|
+
if (!manifest) {
|
|
101
|
+
return {
|
|
102
|
+
valid: false,
|
|
103
|
+
mismatches: [{
|
|
104
|
+
file: MANIFEST_FILENAME,
|
|
105
|
+
reason: 'missing',
|
|
106
|
+
}],
|
|
107
|
+
manifestPath: path.join(baseDir, MANIFEST_FILENAME),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const mismatches = [];
|
|
111
|
+
// Check files in manifest
|
|
112
|
+
for (const [relPath, meta] of Object.entries(manifest.files)) {
|
|
113
|
+
const fullPath = path.join(baseDir, relPath);
|
|
114
|
+
if (!fs.existsSync(fullPath)) {
|
|
115
|
+
mismatches.push({
|
|
116
|
+
file: relPath,
|
|
117
|
+
reason: 'missing',
|
|
118
|
+
});
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const actualHash = hashFile(fullPath);
|
|
122
|
+
if (actualHash !== meta.sha256) {
|
|
123
|
+
mismatches.push({
|
|
124
|
+
file: relPath,
|
|
125
|
+
reason: 'hash-mismatch',
|
|
126
|
+
expected: meta.sha256.slice(0, 16) + '...',
|
|
127
|
+
actual: actualHash.slice(0, 16) + '...',
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Check for extra files not in manifest
|
|
132
|
+
const currentFiles = await getGeneratedFiles(baseDir);
|
|
133
|
+
const manifestFiles = new Set(Object.keys(manifest.files));
|
|
134
|
+
for (const file of currentFiles) {
|
|
135
|
+
if (!manifestFiles.has(file)) {
|
|
136
|
+
mismatches.push({
|
|
137
|
+
file,
|
|
138
|
+
reason: 'extra',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
valid: mismatches.length === 0,
|
|
144
|
+
mismatches,
|
|
145
|
+
manifestPath: path.join(baseDir, MANIFEST_FILENAME),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Run manifest verification check
|
|
150
|
+
*/
|
|
151
|
+
export async function runManifestCheck(options) {
|
|
152
|
+
const start = Date.now();
|
|
153
|
+
const generatedDir = options.generatedDir || 'packages/';
|
|
154
|
+
try {
|
|
155
|
+
// Check if directory exists
|
|
156
|
+
if (!fs.existsSync(generatedDir)) {
|
|
157
|
+
return {
|
|
158
|
+
name: 'manifest',
|
|
159
|
+
status: 'skip',
|
|
160
|
+
duration: Date.now() - start,
|
|
161
|
+
message: `Generated directory not found: ${generatedDir}`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const result = await verifyManifest(generatedDir);
|
|
165
|
+
if (result.valid) {
|
|
166
|
+
const manifest = loadManifest(generatedDir);
|
|
167
|
+
const fileCount = manifest ? Object.keys(manifest.files).length : 0;
|
|
168
|
+
return {
|
|
169
|
+
name: 'manifest',
|
|
170
|
+
status: 'pass',
|
|
171
|
+
duration: Date.now() - start,
|
|
172
|
+
message: `All ${fileCount} generated files match manifest`,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const details = result.mismatches.map(m => {
|
|
176
|
+
if (m.reason === 'missing') {
|
|
177
|
+
return ` - ${m.file}: FILE MISSING`;
|
|
178
|
+
}
|
|
179
|
+
else if (m.reason === 'hash-mismatch') {
|
|
180
|
+
return ` - ${m.file}: HASH MISMATCH\n Expected: ${m.expected}\n Actual: ${m.actual}`;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return ` - ${m.file}: EXTRA FILE (not in manifest)`;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
return {
|
|
187
|
+
name: 'manifest',
|
|
188
|
+
status: 'fail',
|
|
189
|
+
duration: Date.now() - start,
|
|
190
|
+
message: `${result.mismatches.length} file(s) failed integrity check`,
|
|
191
|
+
details,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
return {
|
|
196
|
+
name: 'manifest',
|
|
197
|
+
status: 'fail',
|
|
198
|
+
duration: Date.now() - start,
|
|
199
|
+
message: error instanceof Error ? error.message : String(error),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Format manifest result for CLI output
|
|
205
|
+
*/
|
|
206
|
+
export function formatManifestResult(result) {
|
|
207
|
+
const lines = [];
|
|
208
|
+
if (result.valid) {
|
|
209
|
+
lines.push('✅ All generated files match manifest');
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
lines.push('❌ Generated artifact integrity check failed:\n');
|
|
213
|
+
for (const m of result.mismatches) {
|
|
214
|
+
if (m.reason === 'missing') {
|
|
215
|
+
lines.push(` - ${m.file}: FILE MISSING`);
|
|
216
|
+
}
|
|
217
|
+
else if (m.reason === 'hash-mismatch') {
|
|
218
|
+
lines.push(` - ${m.file}: HASH MISMATCH`);
|
|
219
|
+
lines.push(` Expected: ${m.expected}`);
|
|
220
|
+
lines.push(` Actual: ${m.actual}`);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
lines.push(` - ${m.file}: EXTRA FILE (not in manifest)`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
lines.push('\n💡 Run `micro-contracts generate` to regenerate all artifacts.');
|
|
227
|
+
lines.push('💡 Do NOT edit files in packages/ directly.');
|
|
228
|
+
}
|
|
229
|
+
return lines.join('\n');
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/guardrails/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check runner for guardrails
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates running multiple guardrail checks.
|
|
5
|
+
* Supports both built-in checks and custom checks from guardrails.yaml.
|
|
6
|
+
*/
|
|
7
|
+
import type { CheckOptions, CheckSummary, CheckDefinition, GateNumber } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Gate descriptions for display
|
|
10
|
+
*/
|
|
11
|
+
export declare const GATE_DESCRIPTIONS: Record<GateNumber, string>;
|
|
12
|
+
/**
|
|
13
|
+
* Get list of available checks
|
|
14
|
+
*/
|
|
15
|
+
export declare function getAvailableChecks(options?: CheckOptions): CheckDefinition[];
|
|
16
|
+
/**
|
|
17
|
+
* Extended check summary with gate info
|
|
18
|
+
*/
|
|
19
|
+
export interface CheckSummaryWithGates extends CheckSummary {
|
|
20
|
+
/** All checks with their gate assignments */
|
|
21
|
+
checks: CheckDefinition[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Run all guardrail checks
|
|
25
|
+
*/
|
|
26
|
+
export declare function runAllChecks(options?: CheckOptions): Promise<CheckSummaryWithGates>;
|
|
27
|
+
/**
|
|
28
|
+
* Format check results for CLI output
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatCheckResults(summary: CheckSummary, verbose?: boolean, checksWithGates?: CheckDefinition[]): string;
|
|
31
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/guardrails/runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAe,YAAY,EAAE,eAAe,EAAsB,UAAU,EAAE,MAAM,YAAY,CAAC;AAU3H;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAMxD,CAAC;AA0FF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,YAAiB,GAAG,eAAe,EAAE,CAEhF;AA0BD;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IACzD,6CAA6C;IAC7C,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA2C7F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,OAAe,EACxB,eAAe,CAAC,EAAE,eAAe,EAAE,GAClC,MAAM,CA0GR"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check runner for guardrails
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates running multiple guardrail checks.
|
|
5
|
+
* Supports both built-in checks and custom checks from guardrails.yaml.
|
|
6
|
+
*/
|
|
7
|
+
import { runAllowlistCheck } from './allowlist.js';
|
|
8
|
+
import { runDriftCheck } from './drift.js';
|
|
9
|
+
import { runManifestCheck } from './manifest.js';
|
|
10
|
+
import { runCustomCommandCheck } from './lint.js';
|
|
11
|
+
import { runSecurityCheck } from './security.js';
|
|
12
|
+
import { loadGuardrailsConfigWithPath } from './config.js';
|
|
13
|
+
/**
|
|
14
|
+
* Gate descriptions for display
|
|
15
|
+
*/
|
|
16
|
+
export const GATE_DESCRIPTIONS = {
|
|
17
|
+
1: 'Change Allowlist',
|
|
18
|
+
2: 'OpenAPI Contract Validation',
|
|
19
|
+
3: 'Generated Artifact Integrity',
|
|
20
|
+
4: 'Code Quality',
|
|
21
|
+
5: 'Doc Consistency & Static Analysis',
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Built-in checks (always available)
|
|
25
|
+
*/
|
|
26
|
+
const builtinChecks = [
|
|
27
|
+
{
|
|
28
|
+
name: 'allowlist',
|
|
29
|
+
description: 'Verify changes are within allowed paths',
|
|
30
|
+
gate: 1,
|
|
31
|
+
run: runAllowlistCheck,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'drift',
|
|
35
|
+
description: 'Check for uncommitted generated file changes',
|
|
36
|
+
gate: 3,
|
|
37
|
+
run: runDriftCheck,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'manifest',
|
|
41
|
+
description: 'Verify generated artifact integrity',
|
|
42
|
+
gate: 3,
|
|
43
|
+
run: runManifestCheck,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'security',
|
|
47
|
+
description: 'Verify security declarations match implementations',
|
|
48
|
+
gate: 5,
|
|
49
|
+
run: runSecurityCheck,
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Legacy built-in checks (deprecated - use guardrails.yaml checks instead)
|
|
54
|
+
* These are only included if no custom checks are defined in guardrails.yaml
|
|
55
|
+
*/
|
|
56
|
+
const legacyChecks = [
|
|
57
|
+
// Removed: use spec-lint in guardrails.yaml instead
|
|
58
|
+
// Removed: use code-typecheck in guardrails.yaml instead
|
|
59
|
+
// Removed: use docs-sync, docs-links in guardrails.yaml instead
|
|
60
|
+
];
|
|
61
|
+
/**
|
|
62
|
+
* Load custom checks from guardrails.yaml
|
|
63
|
+
*/
|
|
64
|
+
function loadCustomChecks(options) {
|
|
65
|
+
const { config } = loadGuardrailsConfigWithPath(options.guardrailsPath);
|
|
66
|
+
const customChecks = [];
|
|
67
|
+
if (config?.checks) {
|
|
68
|
+
for (const [name, checkConfig] of Object.entries(config.checks)) {
|
|
69
|
+
if (!checkConfig || checkConfig.enabled === false) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
customChecks.push({
|
|
73
|
+
name,
|
|
74
|
+
description: `Custom check: ${name}`,
|
|
75
|
+
gate: checkConfig.gate,
|
|
76
|
+
run: (opts) => runCustomCommandCheck(name, checkConfig.command, opts),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return customChecks;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get all available checks (built-in + custom)
|
|
84
|
+
*/
|
|
85
|
+
function getAllChecks(options) {
|
|
86
|
+
const customChecks = loadCustomChecks(options);
|
|
87
|
+
const customNames = new Set(customChecks.map(c => c.name));
|
|
88
|
+
// Start with built-in checks
|
|
89
|
+
const allChecks = [...builtinChecks];
|
|
90
|
+
// Add legacy checks only if not overridden by custom checks
|
|
91
|
+
for (const legacyCheck of legacyChecks) {
|
|
92
|
+
if (!customNames.has(legacyCheck.name)) {
|
|
93
|
+
allChecks.push(legacyCheck);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Add custom checks
|
|
97
|
+
allChecks.push(...customChecks);
|
|
98
|
+
return allChecks;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get list of available checks
|
|
102
|
+
*/
|
|
103
|
+
export function getAvailableChecks(options = {}) {
|
|
104
|
+
return getAllChecks(options);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Filter checks based on options
|
|
108
|
+
*/
|
|
109
|
+
function filterChecks(allChecks, options) {
|
|
110
|
+
let filtered = [...allChecks];
|
|
111
|
+
// Filter by --gate (highest priority)
|
|
112
|
+
if (options.gates && options.gates.length > 0) {
|
|
113
|
+
filtered = filtered.filter(c => c.gate !== undefined && options.gates.includes(c.gate));
|
|
114
|
+
}
|
|
115
|
+
// Filter by --only
|
|
116
|
+
if (options.only && options.only.length > 0) {
|
|
117
|
+
filtered = filtered.filter(c => options.only.includes(c.name));
|
|
118
|
+
}
|
|
119
|
+
// Filter by --skip
|
|
120
|
+
if (options.skip && options.skip.length > 0) {
|
|
121
|
+
filtered = filtered.filter(c => !options.skip.includes(c.name));
|
|
122
|
+
}
|
|
123
|
+
return filtered;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Run all guardrail checks
|
|
127
|
+
*/
|
|
128
|
+
export async function runAllChecks(options = {}) {
|
|
129
|
+
const results = [];
|
|
130
|
+
const allChecks = getAllChecks(options);
|
|
131
|
+
const checksToRun = filterChecks(allChecks, options);
|
|
132
|
+
const skippedChecks = allChecks.filter(c => !checksToRun.includes(c));
|
|
133
|
+
// Add skipped results
|
|
134
|
+
for (const check of skippedChecks) {
|
|
135
|
+
results.push({
|
|
136
|
+
name: check.name,
|
|
137
|
+
status: 'skip',
|
|
138
|
+
duration: 0,
|
|
139
|
+
message: 'Skipped by filter',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// Run enabled checks
|
|
143
|
+
for (const check of checksToRun) {
|
|
144
|
+
try {
|
|
145
|
+
const result = await check.run(options);
|
|
146
|
+
results.push(result);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
results.push({
|
|
150
|
+
name: check.name,
|
|
151
|
+
status: 'fail',
|
|
152
|
+
duration: 0,
|
|
153
|
+
message: error instanceof Error ? error.message : String(error),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Calculate summary
|
|
158
|
+
const passed = results.filter(r => r.status === 'pass').length;
|
|
159
|
+
const failed = results.filter(r => r.status === 'fail').length;
|
|
160
|
+
const skipped = results.filter(r => r.status === 'skip').length;
|
|
161
|
+
return {
|
|
162
|
+
passed,
|
|
163
|
+
failed,
|
|
164
|
+
skipped,
|
|
165
|
+
results,
|
|
166
|
+
checks: allChecks,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Format check results for CLI output
|
|
171
|
+
*/
|
|
172
|
+
export function formatCheckResults(summary, verbose = false, checksWithGates) {
|
|
173
|
+
const lines = [];
|
|
174
|
+
lines.push('');
|
|
175
|
+
lines.push('🔍 AI Guardrail Check Results');
|
|
176
|
+
lines.push('═'.repeat(50));
|
|
177
|
+
lines.push('');
|
|
178
|
+
// Build a map of check name -> gate for display
|
|
179
|
+
const gateMap = new Map();
|
|
180
|
+
if (checksWithGates) {
|
|
181
|
+
for (const check of checksWithGates) {
|
|
182
|
+
gateMap.set(check.name, check.gate);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Group results by gate if gate info is available
|
|
186
|
+
const hasGateInfo = checksWithGates && checksWithGates.some(c => c.gate !== undefined);
|
|
187
|
+
if (hasGateInfo && verbose) {
|
|
188
|
+
// Group by gate for verbose output
|
|
189
|
+
const byGate = new Map();
|
|
190
|
+
for (const result of summary.results) {
|
|
191
|
+
const gate = gateMap.get(result.name);
|
|
192
|
+
if (!byGate.has(gate)) {
|
|
193
|
+
byGate.set(gate, []);
|
|
194
|
+
}
|
|
195
|
+
byGate.get(gate).push(result);
|
|
196
|
+
}
|
|
197
|
+
// Output by gate
|
|
198
|
+
const sortedGates = [...byGate.keys()].sort((a, b) => {
|
|
199
|
+
if (a === undefined)
|
|
200
|
+
return 1;
|
|
201
|
+
if (b === undefined)
|
|
202
|
+
return -1;
|
|
203
|
+
return a - b;
|
|
204
|
+
});
|
|
205
|
+
for (const gate of sortedGates) {
|
|
206
|
+
const results = byGate.get(gate);
|
|
207
|
+
if (gate !== undefined) {
|
|
208
|
+
lines.push(` Gate ${gate}: ${GATE_DESCRIPTIONS[gate]}`);
|
|
209
|
+
lines.push(' ' + '─'.repeat(40));
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
lines.push(` Other Checks:`);
|
|
213
|
+
lines.push(' ' + '─'.repeat(40));
|
|
214
|
+
}
|
|
215
|
+
for (const result of results) {
|
|
216
|
+
const icon = result.status === 'pass' ? '✓' : result.status === 'fail' ? '✗' : '○';
|
|
217
|
+
const status = result.status.toUpperCase().padEnd(4);
|
|
218
|
+
lines.push(` ${icon} ${result.name.padEnd(20)} ${status} (${result.duration}ms)`);
|
|
219
|
+
if (result.message && (verbose || result.status !== 'pass')) {
|
|
220
|
+
lines.push(` ${result.message}`);
|
|
221
|
+
}
|
|
222
|
+
if (verbose && result.details) {
|
|
223
|
+
for (const detail of result.details) {
|
|
224
|
+
lines.push(` ${detail}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
lines.push('');
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
// Flat output
|
|
233
|
+
for (const result of summary.results) {
|
|
234
|
+
const icon = result.status === 'pass' ? '✓' : result.status === 'fail' ? '✗' : '○';
|
|
235
|
+
const status = result.status.toUpperCase().padEnd(4);
|
|
236
|
+
const gate = gateMap.get(result.name);
|
|
237
|
+
const gateStr = gate !== undefined ? `[G${gate}] ` : '';
|
|
238
|
+
lines.push(` ${icon} ${gateStr}${result.name.padEnd(20)} ${status} (${result.duration}ms)`);
|
|
239
|
+
if (result.message && (verbose || result.status !== 'pass')) {
|
|
240
|
+
lines.push(` ${result.message}`);
|
|
241
|
+
}
|
|
242
|
+
if (verbose && result.details) {
|
|
243
|
+
for (const detail of result.details) {
|
|
244
|
+
lines.push(` ${detail}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Summary
|
|
250
|
+
lines.push('');
|
|
251
|
+
lines.push('─'.repeat(50));
|
|
252
|
+
lines.push('');
|
|
253
|
+
lines.push(` Passed: ${summary.passed}`);
|
|
254
|
+
lines.push(` Failed: ${summary.failed}`);
|
|
255
|
+
if (summary.skipped > 0) {
|
|
256
|
+
lines.push(` Skipped: ${summary.skipped}`);
|
|
257
|
+
}
|
|
258
|
+
lines.push('');
|
|
259
|
+
if (summary.failed > 0) {
|
|
260
|
+
lines.push('❌ Some checks failed. Fix issues before committing.');
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
lines.push('✅ All checks passed!');
|
|
264
|
+
}
|
|
265
|
+
lines.push('');
|
|
266
|
+
return lines.join('\n');
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/guardrails/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security consistency check for guardrails
|
|
3
|
+
*
|
|
4
|
+
* Verifies that security declarations in OpenAPI specs (x-auth, x-authz, x-middleware)
|
|
5
|
+
* have corresponding implementations.
|
|
6
|
+
*/
|
|
7
|
+
import type { CheckResult, CheckOptions } from './types.js';
|
|
8
|
+
import type { OpenAPISpec } from '../types.js';
|
|
9
|
+
export interface SecurityIssue {
|
|
10
|
+
spec: string;
|
|
11
|
+
path: string;
|
|
12
|
+
method: string;
|
|
13
|
+
issue: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Extract exported function names from TypeScript files
|
|
17
|
+
*/
|
|
18
|
+
export declare function getImplementedOverlays(overlayDir: string): Promise<Set<string>>;
|
|
19
|
+
/**
|
|
20
|
+
* Check a single OpenAPI spec for security consistency
|
|
21
|
+
*/
|
|
22
|
+
export declare function checkSecurityConsistency(specPath: string, spec: OpenAPISpec, implementedOverlays: Set<string>): SecurityIssue[];
|
|
23
|
+
/**
|
|
24
|
+
* Find overlay implementation directories
|
|
25
|
+
*/
|
|
26
|
+
export declare function findOverlayDirs(): Promise<string[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Run security consistency check
|
|
29
|
+
*/
|
|
30
|
+
export declare function runSecurityCheck(options: CheckOptions): Promise<CheckResult>;
|
|
31
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/guardrails/security.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CA2BrF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC/B,aAAa,EAAE,CAoDjB;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAsBzD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAmFlF"}
|