@aegis-scan/core 0.2.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.
@@ -0,0 +1,8 @@
1
+ import type { AegisConfig } from './types.js';
2
+ /**
3
+ * Shape of a user-provided config file (aegis.config.json).
4
+ * `projectPath` and `mode` are always set by CLI args, never from the file.
5
+ */
6
+ export type ConfigFileShape = Partial<Omit<AegisConfig, 'projectPath' | 'mode'>>;
7
+ export declare function loadConfig(projectPath: string, mode?: AegisConfig['mode']): Promise<AegisConfig>;
8
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AA8C7D;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC;AA8BjF,wBAAsB,UAAU,CAC9B,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,WAAW,CAAC,MAAM,CAAU,GACjC,OAAO,CAAC,WAAW,CAAC,CA0CtB"}
package/dist/config.js ADDED
@@ -0,0 +1,111 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { z } from 'zod';
4
+ import { detectStack } from './detect.js';
5
+ const ConfigFileSchema = z.object({
6
+ stack: z.object({
7
+ framework: z.string().optional(),
8
+ database: z.string().optional(),
9
+ auth: z.string().optional(),
10
+ ai: z.string().optional(),
11
+ payment: z.string().optional(),
12
+ deploy: z.string().optional(),
13
+ language: z.string().optional(),
14
+ hasI18n: z.boolean().optional(),
15
+ hasTests: z.boolean().optional(),
16
+ }).optional(),
17
+ locale: z.string().optional(),
18
+ compliance: z.array(z.string()).optional(),
19
+ scanners: z.record(z.record(z.unknown())).optional(),
20
+ rules: z.record(z.string()).optional(),
21
+ ignore: z.array(z.string()).optional(),
22
+ target: z.string().optional(),
23
+ }).strict();
24
+ const DEFAULT_IGNORE = [
25
+ 'node_modules',
26
+ '.git',
27
+ '.next',
28
+ '.nuxt',
29
+ 'dist',
30
+ 'build',
31
+ 'coverage',
32
+ '.turbo',
33
+ '.vercel',
34
+ '.cache',
35
+ 'out',
36
+ '.output',
37
+ '__pycache__',
38
+ '.pytest_cache',
39
+ '.venv',
40
+ 'venv',
41
+ 'vendor',
42
+ 'target',
43
+ '.gradle',
44
+ '.idea',
45
+ '.vscode',
46
+ ];
47
+ /**
48
+ * Attempt to load aegis.config.json from the project directory.
49
+ * Only JSON config is supported — JS config files are not loaded to avoid
50
+ * arbitrary code execution.
51
+ */
52
+ async function loadConfigFile(projectPath) {
53
+ const jsonPath = path.join(projectPath, 'aegis.config.json');
54
+ if (fs.existsSync(jsonPath)) {
55
+ try {
56
+ const raw = fs.readFileSync(jsonPath, 'utf-8');
57
+ const parsed = JSON.parse(raw);
58
+ const result = ConfigFileSchema.safeParse(parsed);
59
+ if (result.success) {
60
+ return result.data;
61
+ }
62
+ // Validation failed — log warning but don't crash, fall back to auto-detection
63
+ console.warn(`[aegis] Config validation warning in ${jsonPath}: ${result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join(', ')}. Falling back to auto-detection.`);
64
+ return null;
65
+ }
66
+ catch {
67
+ // Malformed JSON — fall through
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ export async function loadConfig(projectPath, mode = 'scan') {
73
+ if (!fs.existsSync(projectPath)) {
74
+ throw new Error(`Project path does not exist: ${projectPath}`);
75
+ }
76
+ const stack = detectStack(projectPath);
77
+ const config = {
78
+ projectPath,
79
+ stack,
80
+ mode,
81
+ ignore: [...DEFAULT_IGNORE],
82
+ };
83
+ // Load and merge user config file (values override auto-detected)
84
+ const fileConfig = await loadConfigFile(projectPath);
85
+ if (fileConfig) {
86
+ if (fileConfig.stack) {
87
+ config.stack = { ...stack, ...fileConfig.stack };
88
+ }
89
+ if (fileConfig.locale !== undefined) {
90
+ config.locale = fileConfig.locale;
91
+ }
92
+ if (fileConfig.compliance !== undefined) {
93
+ config.compliance = fileConfig.compliance;
94
+ }
95
+ if (fileConfig.scanners !== undefined) {
96
+ config.scanners = fileConfig.scanners;
97
+ }
98
+ if (fileConfig.rules !== undefined) {
99
+ config.rules = fileConfig.rules;
100
+ }
101
+ if (fileConfig.ignore !== undefined) {
102
+ // Merge with defaults — never lose node_modules/.git protection
103
+ config.ignore = [...new Set([...DEFAULT_IGNORE, ...fileConfig.ignore])];
104
+ }
105
+ if (fileConfig.target !== undefined) {
106
+ config.target = fileConfig.target;
107
+ }
108
+ }
109
+ return config;
110
+ }
111
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DetectedStack } from './types.js';
2
+ export declare function detectStack(projectPath: string): DetectedStack;
3
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAuBhD,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAoM9D"}
package/dist/detect.js ADDED
@@ -0,0 +1,250 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ function readJsonSafe(filePath) {
4
+ try {
5
+ const content = fs.readFileSync(filePath, 'utf-8');
6
+ return JSON.parse(content);
7
+ }
8
+ catch {
9
+ return {};
10
+ }
11
+ }
12
+ function readFileSafe(filePath) {
13
+ try {
14
+ return fs.readFileSync(filePath, 'utf-8');
15
+ }
16
+ catch {
17
+ return '';
18
+ }
19
+ }
20
+ function hasDep(deps, ...names) {
21
+ return names.some((n) => n in deps);
22
+ }
23
+ export function detectStack(projectPath) {
24
+ const pkgPath = path.join(projectPath, 'package.json');
25
+ const pkg = readJsonSafe(pkgPath);
26
+ const deps = {
27
+ ...(pkg['dependencies'] ?? {}),
28
+ ...(pkg['devDependencies'] ?? {}),
29
+ };
30
+ // ---- Language ----
31
+ let language = 'unknown';
32
+ if (fs.existsSync(path.join(projectPath, 'tsconfig.json')) || hasDep(deps, 'typescript')) {
33
+ language = 'typescript';
34
+ }
35
+ else if (fs.existsSync(path.join(projectPath, 'package.json'))) {
36
+ language = 'javascript';
37
+ }
38
+ else if (fs.existsSync(path.join(projectPath, 'requirements.txt')) || fs.existsSync(path.join(projectPath, 'pyproject.toml'))) {
39
+ language = 'python';
40
+ }
41
+ else if (fs.existsSync(path.join(projectPath, 'Gemfile'))) {
42
+ language = 'ruby';
43
+ }
44
+ else if (fs.existsSync(path.join(projectPath, 'go.mod'))) {
45
+ language = 'go';
46
+ }
47
+ else if (fs.existsSync(path.join(projectPath, 'Cargo.toml'))) {
48
+ language = 'rust';
49
+ }
50
+ else if (fs.existsSync(path.join(projectPath, 'composer.json'))) {
51
+ language = 'php';
52
+ }
53
+ else if (fs.existsSync(path.join(projectPath, 'pom.xml')) || fs.existsSync(path.join(projectPath, 'build.gradle'))) {
54
+ language = 'java';
55
+ }
56
+ // ---- Framework ----
57
+ let framework = 'unknown';
58
+ // Check Node/JS frameworks first
59
+ if (hasDep(deps, 'next')) {
60
+ framework = 'nextjs';
61
+ }
62
+ else if (hasDep(deps, 'nuxt', '@nuxt/core')) {
63
+ framework = 'nuxt';
64
+ }
65
+ else if (hasDep(deps, '@remix-run/react', '@remix-run/node', '@remix-run/serve')) {
66
+ framework = 'remix';
67
+ }
68
+ else if (hasDep(deps, 'astro')) {
69
+ framework = 'astro';
70
+ }
71
+ else if (hasDep(deps, 'svelte', '@sveltejs/kit')) {
72
+ framework = 'svelte';
73
+ }
74
+ else if (hasDep(deps, 'vue', '@vue/core')) {
75
+ framework = 'vue';
76
+ }
77
+ else if (hasDep(deps, 'react', 'react-dom')) {
78
+ framework = 'react';
79
+ }
80
+ else if (hasDep(deps, 'fastify')) {
81
+ framework = 'fastify';
82
+ }
83
+ else if (hasDep(deps, 'express')) {
84
+ framework = 'express';
85
+ }
86
+ else if (fs.existsSync(path.join(projectPath, 'go.mod'))) {
87
+ framework = 'go';
88
+ }
89
+ else if (fs.existsSync(path.join(projectPath, 'Cargo.toml'))) {
90
+ framework = 'rust';
91
+ }
92
+ else if (fs.existsSync(path.join(projectPath, 'requirements.txt')) || fs.existsSync(path.join(projectPath, 'pyproject.toml'))) {
93
+ const reqContent = readFileSafe(path.join(projectPath, 'requirements.txt'));
94
+ const pyprojectContent = readFileSafe(path.join(projectPath, 'pyproject.toml'));
95
+ const combined = reqContent + pyprojectContent;
96
+ if (/\bdjango\b/i.test(combined)) {
97
+ framework = 'django';
98
+ }
99
+ else if (/\bflask\b/i.test(combined)) {
100
+ framework = 'flask';
101
+ }
102
+ }
103
+ else if (fs.existsSync(path.join(projectPath, 'Gemfile'))) {
104
+ const gemfileContent = readFileSafe(path.join(projectPath, 'Gemfile'));
105
+ if (/\brails\b/i.test(gemfileContent)) {
106
+ framework = 'rails';
107
+ }
108
+ }
109
+ else if (fs.existsSync(path.join(projectPath, 'composer.json'))) {
110
+ const composer = readJsonSafe(path.join(projectPath, 'composer.json'));
111
+ const composerDeps = {
112
+ ...(composer['require'] ?? {}),
113
+ ...(composer['require-dev'] ?? {}),
114
+ };
115
+ if (hasDep(composerDeps, 'laravel/framework')) {
116
+ framework = 'laravel';
117
+ }
118
+ }
119
+ // ---- Database ----
120
+ let database = 'unknown';
121
+ if (hasDep(deps, '@supabase/supabase-js', '@supabase/ssr', '@supabase/auth-helpers-nextjs')) {
122
+ database = 'supabase';
123
+ }
124
+ else if (hasDep(deps, 'firebase', 'firebase-admin', '@firebase/firestore')) {
125
+ database = 'firebase';
126
+ }
127
+ else if (hasDep(deps, '@prisma/client', 'prisma')) {
128
+ database = 'prisma';
129
+ }
130
+ else if (hasDep(deps, 'drizzle-orm', 'drizzle-kit')) {
131
+ database = 'drizzle';
132
+ }
133
+ else if (hasDep(deps, 'mongoose')) {
134
+ database = 'mongoose';
135
+ }
136
+ else if (hasDep(deps, 'pg', 'postgres', 'node-postgres')) {
137
+ database = 'raw-pg';
138
+ }
139
+ else if (!fs.existsSync(path.join(projectPath, 'package.json')) &&
140
+ (fs.existsSync(path.join(projectPath, 'requirements.txt')) || fs.existsSync(path.join(projectPath, 'Gemfile')))) {
141
+ database = 'none';
142
+ }
143
+ // ---- Auth ----
144
+ let auth = 'unknown';
145
+ if (hasDep(deps, '@supabase/supabase-js', '@supabase/ssr', '@supabase/auth-helpers-nextjs')) {
146
+ auth = 'supabase-auth';
147
+ }
148
+ else if (hasDep(deps, 'next-auth', '@auth/core', '@auth/nextjs')) {
149
+ auth = 'next-auth';
150
+ }
151
+ else if (hasDep(deps, '@clerk/nextjs', '@clerk/clerk-react', '@clerk/clerk-sdk-node')) {
152
+ auth = 'clerk';
153
+ }
154
+ else if (hasDep(deps, 'lucia')) {
155
+ auth = 'lucia';
156
+ }
157
+ else if (hasDep(deps, 'passport', 'passport-local', 'passport-jwt')) {
158
+ auth = 'passport';
159
+ }
160
+ // ---- AI ----
161
+ let ai = 'unknown';
162
+ if (hasDep(deps, 'openai', '@openai/openai')) {
163
+ ai = 'openai';
164
+ }
165
+ else if (hasDep(deps, '@anthropic-ai/sdk', 'anthropic')) {
166
+ ai = 'anthropic';
167
+ }
168
+ else if (hasDep(deps, '@mistralai/mistralai', 'mistral', 'mistralai')) {
169
+ ai = 'mistral';
170
+ }
171
+ else if (hasDep(deps, 'ollama', '@ollama/ollama')) {
172
+ ai = 'ollama';
173
+ }
174
+ else {
175
+ // Check Python requirements for AI libs
176
+ const reqContent = readFileSafe(path.join(projectPath, 'requirements.txt'));
177
+ if (/\bopenai\b/i.test(reqContent)) {
178
+ ai = 'openai';
179
+ }
180
+ else if (/\banthropic\b/i.test(reqContent)) {
181
+ ai = 'anthropic';
182
+ }
183
+ else if (/\bmistral/i.test(reqContent)) {
184
+ ai = 'mistral';
185
+ }
186
+ else if (/\bollama\b/i.test(reqContent)) {
187
+ ai = 'ollama';
188
+ }
189
+ else {
190
+ ai = 'none';
191
+ }
192
+ }
193
+ // ---- Payment ----
194
+ let payment = 'unknown';
195
+ if (hasDep(deps, 'stripe', '@stripe/stripe-js', '@stripe/react-stripe-js')) {
196
+ payment = 'stripe';
197
+ }
198
+ else {
199
+ const reqContent = readFileSafe(path.join(projectPath, 'requirements.txt'));
200
+ if (/\bstripe\b/i.test(reqContent)) {
201
+ payment = 'stripe';
202
+ }
203
+ else {
204
+ payment = 'none';
205
+ }
206
+ }
207
+ // ---- Deploy ----
208
+ let deploy = 'unknown';
209
+ if (fs.existsSync(path.join(projectPath, 'vercel.json')) || fs.existsSync(path.join(projectPath, '.vercel'))) {
210
+ deploy = 'vercel';
211
+ }
212
+ else if (fs.existsSync(path.join(projectPath, 'Dockerfile')) || fs.existsSync(path.join(projectPath, 'docker-compose.yml')) || fs.existsSync(path.join(projectPath, 'docker-compose.yaml'))) {
213
+ deploy = 'docker';
214
+ }
215
+ else if (fs.existsSync(path.join(projectPath, 'railway.toml')) || fs.existsSync(path.join(projectPath, 'railway.json'))) {
216
+ deploy = 'railway';
217
+ }
218
+ else if (fs.existsSync(path.join(projectPath, 'fly.toml'))) {
219
+ deploy = 'fly';
220
+ }
221
+ else if (fs.existsSync(path.join(projectPath, 'netlify.toml'))) {
222
+ deploy = 'netlify';
223
+ }
224
+ else {
225
+ deploy = 'none';
226
+ }
227
+ // ---- i18n ----
228
+ const hasI18n = hasDep(deps, 'next-intl', 'react-i18next', 'i18next', 'vue-i18n', '@nuxtjs/i18n', 'react-intl', 'lingui') ||
229
+ fs.existsSync(path.join(projectPath, 'messages')) ||
230
+ fs.existsSync(path.join(projectPath, 'locales')) ||
231
+ fs.existsSync(path.join(projectPath, 'i18n'));
232
+ // ---- Tests ----
233
+ const hasTests = hasDep(deps, 'vitest', 'jest', '@jest/core', 'mocha', 'jasmine', 'playwright', '@playwright/test', 'cypress') ||
234
+ fs.existsSync(path.join(projectPath, '__tests__')) ||
235
+ fs.existsSync(path.join(projectPath, 'tests')) ||
236
+ fs.existsSync(path.join(projectPath, 'spec')) ||
237
+ fs.existsSync(path.join(projectPath, 'e2e'));
238
+ return {
239
+ framework,
240
+ database,
241
+ auth,
242
+ ai,
243
+ payment,
244
+ deploy,
245
+ language,
246
+ hasI18n,
247
+ hasTests,
248
+ };
249
+ }
250
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export * from './types.js';
2
+ export { detectStack } from './detect.js';
3
+ export { calculateScore, getGrade, getBadge, CATEGORY_WEIGHTS } from './scoring.js';
4
+ export { loadConfig, type ConfigFileShape } from './config.js';
5
+ export { Orchestrator } from './orchestrator.js';
6
+ export { exec, commandExists, walkFiles, readFileSafe, clearWalkFilesCache, type ExecResult, type ExecOptions } from './utils.js';
7
+ export { getVersion } from './version.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,mBAAmB,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAClI,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from './types.js';
2
+ export { detectStack } from './detect.js';
3
+ export { calculateScore, getGrade, getBadge, CATEGORY_WEIGHTS } from './scoring.js';
4
+ export { loadConfig } from './config.js';
5
+ export { Orchestrator } from './orchestrator.js';
6
+ export { exec, commandExists, walkFiles, readFileSafe, clearWalkFilesCache } from './utils.js';
7
+ export { getVersion } from './version.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,UAAU,EAAwB,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,mBAAmB,EAAqC,MAAM,YAAY,CAAC;AAClI,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Scanner, AegisConfig, AuditResult } from './types.js';
2
+ export declare class Orchestrator {
3
+ private scanners;
4
+ register(scanner: Scanner): void;
5
+ run(config: AegisConfig): Promise<AuditResult>;
6
+ }
7
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAmC,MAAM,YAAY,CAAC;AAcrG,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAiB;IAEjC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI1B,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;CAiGrD"}
@@ -0,0 +1,101 @@
1
+ import { calculateScore } from './scoring.js';
2
+ const SCANNER_TIMEOUT_MS = 120_000; // 2 minutes per scanner
3
+ function withTimeout(promise, ms, label) {
4
+ return new Promise((resolve, reject) => {
5
+ const timer = setTimeout(() => reject(new Error(`Scanner '${label}' timed out after ${ms / 1000}s`)), ms);
6
+ promise.then((val) => { clearTimeout(timer); resolve(val); }, (err) => { clearTimeout(timer); reject(err); });
7
+ });
8
+ }
9
+ export class Orchestrator {
10
+ scanners = [];
11
+ register(scanner) {
12
+ this.scanners.push(scanner);
13
+ }
14
+ async run(config) {
15
+ const startTime = Date.now();
16
+ // Check availability and run all scanners in parallel
17
+ const scanPromises = this.scanners.map(async (scanner) => {
18
+ let available;
19
+ try {
20
+ available = await scanner.isAvailable(config.projectPath);
21
+ }
22
+ catch {
23
+ available = false;
24
+ }
25
+ if (!available) {
26
+ return {
27
+ scanner: scanner.name,
28
+ category: scanner.category,
29
+ findings: [],
30
+ duration: 0,
31
+ available: false,
32
+ };
33
+ }
34
+ const scanStart = Date.now();
35
+ try {
36
+ const result = await withTimeout(scanner.scan(config.projectPath, config), SCANNER_TIMEOUT_MS, scanner.name);
37
+ return {
38
+ ...result,
39
+ available: true,
40
+ duration: result.duration ?? Date.now() - scanStart,
41
+ };
42
+ }
43
+ catch (err) {
44
+ return {
45
+ scanner: scanner.name,
46
+ category: scanner.category,
47
+ findings: [],
48
+ duration: Date.now() - scanStart,
49
+ available: true,
50
+ error: err instanceof Error ? err.message : String(err),
51
+ };
52
+ }
53
+ });
54
+ const scanResults = await Promise.all(scanPromises);
55
+ // Aggregate and deduplicate findings (same file + line + title = duplicate)
56
+ const rawFindings = scanResults.flatMap((r) => r.findings);
57
+ const seen = new Set();
58
+ const allFindings = [];
59
+ for (const f of rawFindings) {
60
+ const key = `${f.file ?? ''}:${f.line ?? 0}:${f.title}`;
61
+ if (!seen.has(key)) {
62
+ seen.add(key);
63
+ allFindings.push(f);
64
+ }
65
+ }
66
+ // Calculate confidence based on SECURITY-focused external tools.
67
+ // npm-audit, react-doctor, license-checker are always available (built-in node tools)
68
+ // and don't indicate real external security tool installation.
69
+ const SECURITY_EXTERNAL_NAMES = ['semgrep', 'gitleaks', 'nuclei', 'trivy', 'testssl', 'zap', 'trufflehog'];
70
+ const securityExternals = scanResults.filter((r) => SECURITY_EXTERNAL_NAMES.includes(r.scanner));
71
+ const securityAvailable = securityExternals.filter((r) => r.available).length;
72
+ let confidence;
73
+ if (securityAvailable >= 2) {
74
+ confidence = 'high';
75
+ }
76
+ else if (securityAvailable >= 1) {
77
+ confidence = 'medium';
78
+ }
79
+ else {
80
+ confidence = 'low';
81
+ }
82
+ // Calculate score (confidence is passed so scoring can cap grade when low)
83
+ const scoreResult = calculateScore(allFindings, confidence);
84
+ const duration = Date.now() - startTime;
85
+ return {
86
+ score: scoreResult.score,
87
+ grade: scoreResult.grade,
88
+ badge: scoreResult.badge,
89
+ blocked: scoreResult.blocked,
90
+ blockerReason: scoreResult.blockerReason,
91
+ breakdown: scoreResult.breakdown,
92
+ findings: allFindings,
93
+ scanResults,
94
+ stack: config.stack,
95
+ duration,
96
+ timestamp: new Date().toISOString(),
97
+ confidence,
98
+ };
99
+ }
100
+ }
101
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,kBAAkB,GAAG,OAAO,CAAC,CAAC,wBAAwB;AAE5D,SAAS,WAAW,CAAI,OAAmB,EAAE,EAAU,EAAE,KAAa;IACpE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,KAAK,qBAAqB,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1G,OAAO,CAAC,IAAI,CACV,CAAC,GAAG,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAC/C,CAAC,GAAG,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAC/C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,YAAY;IACf,QAAQ,GAAc,EAAE,CAAC;IAEjC,QAAQ,CAAC,OAAgB;QACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,MAAmB;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,sDAAsD;QACtD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAuB,EAAE;YAC5E,IAAI,SAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,SAAS,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,GAAG,KAAK,CAAC;YACpB,CAAC;YAED,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO;oBACL,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE,EAAE;oBACZ,QAAQ,EAAE,CAAC;oBACX,SAAS,EAAE,KAAK;iBACjB,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,EACxC,kBAAkB,EAClB,OAAO,CAAC,IAAI,CACb,CAAC;gBACF,OAAO;oBACL,GAAG,MAAM;oBACT,SAAS,EAAE,IAAI;oBACf,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;iBACpD,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO;oBACL,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE,EAAE;oBACZ,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;oBAChC,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACxD,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEpD,4EAA4E;QAC5E,MAAM,WAAW,GAAc,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,WAAW,GAAc,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QAED,iEAAiE;QACjE,sFAAsF;QACtF,+DAA+D;QAC/D,MAAM,uBAAuB,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QAC3G,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CACnD,CAAC;QACF,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;QAC9E,IAAI,UAAsB,CAAC;QAC3B,IAAI,iBAAiB,IAAI,CAAC,EAAE,CAAC;YAC3B,UAAU,GAAG,MAAM,CAAC;QACtB,CAAC;aAAM,IAAI,iBAAiB,IAAI,CAAC,EAAE,CAAC;YAClC,UAAU,GAAG,QAAQ,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,KAAK,CAAC;QACrB,CAAC;QAED,2EAA2E;QAC3E,MAAM,WAAW,GAAG,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAE5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAExC,OAAO;YACL,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,aAAa,EAAE,WAAW,CAAC,aAAa;YACxC,SAAS,EAAE,WAAW,CAAC,SAAS;YAChC,QAAQ,EAAE,WAAW;YACrB,WAAW;YACX,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ;YACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,UAAU;SACX,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { Finding, ScanCategory, Grade, Badge, AuditResult, Confidence } from './types.js';
2
+ export declare const CATEGORY_WEIGHTS: Record<ScanCategory, number>;
3
+ export declare function getGrade(score: number): Grade;
4
+ export declare function getBadge(grade: Grade): Badge;
5
+ export interface ScoreResult {
6
+ score: number;
7
+ grade: Grade;
8
+ badge: Badge;
9
+ blocked: boolean;
10
+ blockerReason?: string;
11
+ breakdown: AuditResult['breakdown'];
12
+ confidence: Confidence;
13
+ }
14
+ export declare function calculateScore(findings: Finding[], confidence?: Confidence): ScoreResult;
15
+ //# sourceMappingURL=scoring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK/F,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAazD,CAAC;AAYF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAO7C;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAU5C;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACpC,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,GAAE,UAAmB,GAAG,WAAW,CAuDhG"}
@@ -0,0 +1,130 @@
1
+ // Spec-specified relative weights. These do NOT need to sum to 1.0 here;
2
+ // calculateScore normalizes by dividing each weight by the sum so the
3
+ // final score is always on a 0–1000 scale regardless.
4
+ export const CATEGORY_WEIGHTS = {
5
+ security: 0.20,
6
+ dast: 0.10,
7
+ dependencies: 0.10,
8
+ compliance: 0.10,
9
+ quality: 0.075,
10
+ infrastructure: 0.075,
11
+ accessibility: 0.05,
12
+ performance: 0.05,
13
+ 'ai-llm': 0.05,
14
+ i18n: 0.025,
15
+ runtime: 0.025,
16
+ attack: 0.05,
17
+ };
18
+ /** Base deduction per finding severity. Actual deduction uses diminishing returns. */
19
+ const SEVERITY_BASE_DEDUCTIONS = {
20
+ blocker: Infinity,
21
+ critical: 40,
22
+ high: 15,
23
+ medium: 5,
24
+ low: 1,
25
+ info: 0,
26
+ };
27
+ export function getGrade(score) {
28
+ if (score >= 950)
29
+ return 'S';
30
+ if (score >= 850)
31
+ return 'A';
32
+ if (score >= 700)
33
+ return 'B';
34
+ if (score >= 500)
35
+ return 'C';
36
+ if (score >= 300)
37
+ return 'D';
38
+ return 'F';
39
+ }
40
+ export function getBadge(grade) {
41
+ const map = {
42
+ S: 'FORTRESS',
43
+ A: 'HARDENED',
44
+ B: 'SOLID',
45
+ C: 'NEEDS_WORK',
46
+ D: 'AT_RISK',
47
+ F: 'CRITICAL',
48
+ };
49
+ return map[grade];
50
+ }
51
+ export function calculateScore(findings, confidence = 'high') {
52
+ // Check for blockers first — scanners are responsible for emitting severity: 'blocker'
53
+ const blockerFinding = findings.find((f) => f.severity === 'blocker');
54
+ if (blockerFinding) {
55
+ const breakdown = buildBreakdown(findings);
56
+ // Force all scores to 0
57
+ for (const cat of Object.keys(breakdown)) {
58
+ breakdown[cat].score = 0;
59
+ }
60
+ return {
61
+ score: 0,
62
+ grade: 'F',
63
+ badge: 'CRITICAL',
64
+ blocked: true,
65
+ blockerReason: `Blocker finding: ${blockerFinding.title} (${blockerFinding.id})`,
66
+ breakdown,
67
+ confidence,
68
+ };
69
+ }
70
+ const breakdown = buildBreakdown(findings);
71
+ // Normalize weights so they sum to 1.0, preserving relative ratios
72
+ const weightSum = Object.values(CATEGORY_WEIGHTS).reduce((a, b) => a + b, 0);
73
+ // Calculate weighted total score (0–1000)
74
+ let totalScore = 0;
75
+ for (const [cat, weight] of Object.entries(CATEGORY_WEIGHTS)) {
76
+ const catData = breakdown[cat];
77
+ const catScore = catData.score; // already 0–1000 for this category
78
+ totalScore += catScore * (weight / weightSum);
79
+ }
80
+ // Round to nearest integer
81
+ const score = Math.round(totalScore);
82
+ let grade = getGrade(score);
83
+ let badge = getBadge(grade);
84
+ // Cap grade when confidence is low — S requires comprehensive scanning
85
+ // A is still achievable with low confidence, but S (FORTRESS) requires proof
86
+ if (confidence === 'low' && grade === 'S') {
87
+ grade = 'A';
88
+ badge = getBadge(grade);
89
+ }
90
+ return {
91
+ score,
92
+ grade,
93
+ badge,
94
+ blocked: false,
95
+ breakdown,
96
+ confidence,
97
+ };
98
+ }
99
+ function buildBreakdown(findings) {
100
+ // Initialize breakdown with full scores per category
101
+ const breakdown = {};
102
+ for (const cat of Object.keys(CATEGORY_WEIGHTS)) {
103
+ breakdown[cat] = { score: 1000, maxScore: 1000, findings: 0 };
104
+ }
105
+ // Apply deductions per category with diminishing returns.
106
+ // Each subsequent finding of the same category deducts less (1/sqrt(n) scaling).
107
+ // This prevents 40 HIGH findings from completely zeroing a category while
108
+ // still penalizing projects with more findings.
109
+ const categoryFindingCount = {};
110
+ for (const finding of findings) {
111
+ const cat = finding.category;
112
+ if (!(cat in breakdown))
113
+ continue;
114
+ breakdown[cat].findings += 1;
115
+ const baseDeduction = SEVERITY_BASE_DEDUCTIONS[finding.severity] ?? 0;
116
+ if (baseDeduction === Infinity) {
117
+ breakdown[cat].score = 0;
118
+ continue;
119
+ }
120
+ if (baseDeduction === 0)
121
+ continue;
122
+ // Diminishing returns: nth finding deducts base / sqrt(n)
123
+ categoryFindingCount[cat] = (categoryFindingCount[cat] ?? 0) + 1;
124
+ const n = categoryFindingCount[cat];
125
+ const actualDeduction = baseDeduction / Math.sqrt(n);
126
+ breakdown[cat].score = Math.max(0, breakdown[cat].score - actualDeduction);
127
+ }
128
+ return breakdown;
129
+ }
130
+ //# sourceMappingURL=scoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ export type Severity = 'blocker' | 'critical' | 'high' | 'medium' | 'low' | 'info';
2
+ export type ScanCategory = 'security' | 'dast' | 'dependencies' | 'compliance' | 'quality' | 'accessibility' | 'performance' | 'infrastructure' | 'i18n' | 'ai-llm' | 'runtime' | 'attack';
3
+ export interface Finding {
4
+ id: string;
5
+ scanner: string;
6
+ category: ScanCategory;
7
+ severity: Severity;
8
+ title: string;
9
+ description: string;
10
+ file?: string;
11
+ line?: number;
12
+ column?: number;
13
+ fix?: string;
14
+ owasp?: string;
15
+ cwe?: number;
16
+ reference?: string;
17
+ }
18
+ export interface ScanResult {
19
+ scanner: string;
20
+ category: ScanCategory;
21
+ findings: Finding[];
22
+ score?: number;
23
+ duration: number;
24
+ available: boolean;
25
+ error?: string;
26
+ }
27
+ export interface Scanner {
28
+ name: string;
29
+ description: string;
30
+ category: ScanCategory;
31
+ isAvailable(projectPath: string): Promise<boolean>;
32
+ scan(projectPath: string, config: AegisConfig): Promise<ScanResult>;
33
+ }
34
+ export interface DetectedStack {
35
+ framework: 'nextjs' | 'react' | 'vue' | 'svelte' | 'nuxt' | 'astro' | 'remix' | 'express' | 'fastify' | 'django' | 'flask' | 'rails' | 'laravel' | 'spring' | 'go' | 'rust' | 'unknown';
36
+ database: 'supabase' | 'firebase' | 'prisma' | 'drizzle' | 'mongoose' | 'raw-pg' | 'none' | 'unknown';
37
+ auth: 'supabase-auth' | 'next-auth' | 'clerk' | 'lucia' | 'passport' | 'none' | 'unknown';
38
+ ai: 'openai' | 'anthropic' | 'mistral' | 'ollama' | 'none' | 'unknown';
39
+ payment: 'stripe' | 'none' | 'unknown';
40
+ deploy: 'vercel' | 'docker' | 'railway' | 'fly' | 'netlify' | 'none' | 'unknown';
41
+ language: 'typescript' | 'javascript' | 'python' | 'ruby' | 'go' | 'rust' | 'php' | 'java' | 'unknown';
42
+ hasI18n: boolean;
43
+ hasTests: boolean;
44
+ }
45
+ export interface AegisConfig {
46
+ projectPath: string;
47
+ stack: DetectedStack;
48
+ locale?: string;
49
+ compliance?: string[];
50
+ scanners?: Record<string, Record<string, unknown>>;
51
+ rules?: Record<string, Severity>;
52
+ ignore?: string[];
53
+ target?: string;
54
+ mode: 'scan' | 'audit' | 'pentest' | 'siege' | 'fortress';
55
+ }
56
+ export type Grade = 'S' | 'A' | 'B' | 'C' | 'D' | 'F';
57
+ export type Badge = 'FORTRESS' | 'HARDENED' | 'SOLID' | 'NEEDS_WORK' | 'AT_RISK' | 'CRITICAL';
58
+ export type Confidence = 'low' | 'medium' | 'high';
59
+ export interface AuditResult {
60
+ score: number;
61
+ grade: Grade;
62
+ badge: Badge;
63
+ blocked: boolean;
64
+ blockerReason?: string;
65
+ breakdown: Record<ScanCategory, {
66
+ score: number;
67
+ maxScore: number;
68
+ findings: number;
69
+ }>;
70
+ findings: Finding[];
71
+ scanResults: ScanResult[];
72
+ stack: DetectedStack;
73
+ duration: number;
74
+ timestamp: string;
75
+ confidence: Confidence;
76
+ }
77
+ export interface Reporter {
78
+ name: string;
79
+ format(result: AuditResult): string;
80
+ }
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ export interface ExecOptions {
2
+ cwd?: string;
3
+ timeout?: number;
4
+ env?: NodeJS.ProcessEnv;
5
+ }
6
+ export interface ExecResult {
7
+ stdout: string;
8
+ stderr: string;
9
+ exitCode: number;
10
+ }
11
+ /**
12
+ * Safe child_process.execFile wrapper.
13
+ * ALWAYS resolves — even on non-zero exit codes — so callers can read stdout/stderr
14
+ * from tools that exit 1 when findings exist (gitleaks, semgrep, npm audit, etc.).
15
+ * Only rejects on timeout or signal kill.
16
+ */
17
+ export declare function exec(command: string, args?: string[], options?: ExecOptions): Promise<ExecResult>;
18
+ /**
19
+ * Checks if a command exists on PATH.
20
+ */
21
+ export declare function commandExists(command: string): Promise<boolean>;
22
+ /**
23
+ * Clears the walkFiles result cache. Useful in tests or between audit runs.
24
+ */
25
+ export declare function clearWalkFilesCache(): void;
26
+ /**
27
+ * Recursive file walker returning ABSOLUTE paths.
28
+ * Filters by ignored directory names and optional file extensions (without dot).
29
+ * Results are memoized by (dir, ignore, extensions) key for the lifetime of the process
30
+ * or until clearWalkFilesCache() is called.
31
+ */
32
+ export declare function walkFiles(dir: string, ignore?: string[], extensions?: string[]): string[];
33
+ /**
34
+ * Reads a file, returning null on any failure (file not found, permission denied, etc.).
35
+ */
36
+ export declare function readFileSafe(filePath: string): string | null;
37
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAClB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CA2BrB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQrE;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,MAAM,EAAO,EACrB,UAAU,GAAE,MAAM,EAAO,GACxB,MAAM,EAAE,CAmDV;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM5D"}
package/dist/utils.js ADDED
@@ -0,0 +1,123 @@
1
+ import * as childProcess from 'node:child_process';
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ /**
5
+ * Safe child_process.execFile wrapper.
6
+ * ALWAYS resolves — even on non-zero exit codes — so callers can read stdout/stderr
7
+ * from tools that exit 1 when findings exist (gitleaks, semgrep, npm audit, etc.).
8
+ * Only rejects on timeout or signal kill.
9
+ */
10
+ export function exec(command, args = [], options = {}) {
11
+ const { cwd, timeout = 120_000, env } = options;
12
+ return new Promise((resolve, reject) => {
13
+ childProcess.execFile(command, args, {
14
+ cwd,
15
+ timeout,
16
+ maxBuffer: 50 * 1024 * 1024, // 50 MB
17
+ env: env ?? process.env,
18
+ }, (error, stdout, stderr) => {
19
+ if (error && error.killed) {
20
+ reject(new Error(`Command timed out: ${command} ${args.join(' ')}`));
21
+ return;
22
+ }
23
+ // Always resolve — non-zero exit is normal for many security tools
24
+ resolve({
25
+ stdout: stdout ?? '',
26
+ stderr: stderr ?? '',
27
+ exitCode: error ? error.code ?? 1 : 0,
28
+ });
29
+ });
30
+ });
31
+ }
32
+ /**
33
+ * Checks if a command exists on PATH.
34
+ */
35
+ export async function commandExists(command) {
36
+ try {
37
+ const whichCmd = process.platform === 'win32' ? 'where.exe' : 'which';
38
+ const result = await exec(whichCmd, [command], { timeout: 5000 });
39
+ return result.exitCode === 0;
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ }
45
+ /** Module-level cache for walkFiles results — avoids redundant directory traversals
46
+ * when multiple scanners walk the same directories in a single audit run. */
47
+ const _walkFilesCache = new Map();
48
+ /**
49
+ * Clears the walkFiles result cache. Useful in tests or between audit runs.
50
+ */
51
+ export function clearWalkFilesCache() {
52
+ _walkFilesCache.clear();
53
+ }
54
+ /**
55
+ * Recursive file walker returning ABSOLUTE paths.
56
+ * Filters by ignored directory names and optional file extensions (without dot).
57
+ * Results are memoized by (dir, ignore, extensions) key for the lifetime of the process
58
+ * or until clearWalkFilesCache() is called.
59
+ */
60
+ export function walkFiles(dir, ignore = [], extensions = []) {
61
+ const resolvedDir = path.resolve(dir);
62
+ const cacheKey = `${resolvedDir}:${ignore.join(',')}:${extensions.join(',')}`;
63
+ const cached = _walkFilesCache.get(cacheKey);
64
+ if (cached)
65
+ return cached;
66
+ const results = [];
67
+ const visited = new Set();
68
+ function walk(current) {
69
+ // Resolve symlinks to detect cycles
70
+ let realPath;
71
+ try {
72
+ realPath = fs.realpathSync(current);
73
+ }
74
+ catch {
75
+ return;
76
+ }
77
+ if (visited.has(realPath))
78
+ return;
79
+ visited.add(realPath);
80
+ let entries;
81
+ try {
82
+ entries = fs.readdirSync(current, { withFileTypes: true });
83
+ }
84
+ catch {
85
+ return;
86
+ }
87
+ for (const entry of entries) {
88
+ const fullPath = path.join(current, entry.name);
89
+ if (entry.isDirectory()) {
90
+ if (ignore.includes(entry.name))
91
+ continue;
92
+ walk(fullPath);
93
+ }
94
+ else if (entry.isFile()) {
95
+ if (extensions.length === 0) {
96
+ results.push(fullPath);
97
+ }
98
+ else {
99
+ // Fix: path.extname returns '.ts' — slice(1) removes the dot to match ['ts', 'js']
100
+ const ext = path.extname(entry.name).slice(1);
101
+ if (extensions.includes(ext)) {
102
+ results.push(fullPath);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ walk(resolvedDir);
109
+ _walkFilesCache.set(cacheKey, results);
110
+ return results;
111
+ }
112
+ /**
113
+ * Reads a file, returning null on any failure (file not found, permission denied, etc.).
114
+ */
115
+ export function readFileSafe(filePath) {
116
+ try {
117
+ return fs.readFileSync(filePath, 'utf-8');
118
+ }
119
+ catch {
120
+ return null;
121
+ }
122
+ }
123
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAclC;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAClB,OAAe,EACf,OAAiB,EAAE,EACnB,UAAuB,EAAE;IAEzB,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAEhD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,YAAY,CAAC,QAAQ,CACnB,OAAO,EACP,IAAI,EACJ;YACE,GAAG;YACH,OAAO;YACP,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,QAAQ;YACrC,GAAG,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG;SACxB,EACD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,IAAK,KAAsC,CAAC,MAAM,EAAE,CAAC;gBAC5D,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrE,OAAO;YACT,CAAC;YACD,mEAAmE;YACnE,OAAO,CAAC;gBACN,MAAM,EAAE,MAAM,IAAI,EAAE;gBACpB,MAAM,EAAE,MAAM,IAAI,EAAE;gBACpB,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAE,KAAmC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;aACrE,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;QACtE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;8EAC8E;AAC9E,MAAM,eAAe,GAAG,IAAI,GAAG,EAAoB,CAAC;AAEpD;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,eAAe,CAAC,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACvB,GAAW,EACX,SAAmB,EAAE,EACrB,aAAuB,EAAE;IAEzB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,GAAG,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAE9E,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,SAAS,IAAI,CAAC,OAAe;QAC3B,oCAAoC;QACpC,IAAI,QAAgB,CAAC;QACrB,IAAI,CAAC;YACH,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO;QAClC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEtB,IAAI,OAAoB,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAEhD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAC1C,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjB,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC5B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACN,mFAAmF;oBACnF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC9C,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC7B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,CAAC;IAClB,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACvC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function getVersion(): string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAMA,wBAAgB,UAAU,IAAI,MAAM,CAYnC"}
@@ -0,0 +1,20 @@
1
+ import { readFileSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ let cachedVersion;
5
+ export function getVersion() {
6
+ if (cachedVersion !== undefined)
7
+ return cachedVersion;
8
+ try {
9
+ // Read from cli package.json (the main published package)
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+ const pkgPath = join(__dirname, '../../cli/package.json');
12
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
13
+ cachedVersion = pkg.version ?? '0.0.0';
14
+ }
15
+ catch {
16
+ cachedVersion = '0.0.0';
17
+ }
18
+ return cachedVersion;
19
+ }
20
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,IAAI,aAAiC,CAAC;AAEtC,MAAM,UAAU,UAAU;IACxB,IAAI,aAAa,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC;IACtD,IAAI,CAAC;QACH,0DAA0D;QAC1D,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,wBAAwB,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,aAAa,GAAI,GAAG,CAAC,OAAkB,IAAI,OAAO,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,aAAa,GAAG,OAAO,CAAC;IAC1B,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@aegis-scan/core",
3
+ "version": "0.2.0",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/RideMatch1/a.e.g.i.s.git",
8
+ "directory": "core"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "keywords": [
17
+ "security",
18
+ "audit",
19
+ "scoring",
20
+ "scanner"
21
+ ],
22
+ "description": "AEGIS core engine \u2014 orchestrator, scoring, config",
23
+ "type": "module",
24
+ "main": "dist/index.js",
25
+ "types": "dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "import": "./dist/index.js",
29
+ "types": "./dist/index.d.ts"
30
+ }
31
+ },
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "test": "vitest run",
35
+ "clean": "rm -rf dist"
36
+ },
37
+ "dependencies": {
38
+ "zod": "^3.23.0"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^22.0.0",
42
+ "typescript": "^5.8.0",
43
+ "vitest": "^3.1.0"
44
+ }
45
+ }