@oculum/cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,323 @@
1
+ "use strict";
2
+ /**
3
+ * Scan Command
4
+ * Main scanning functionality for the CLI
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.scanCommand = void 0;
11
+ exports.runScan = runScan;
12
+ const commander_1 = require("commander");
13
+ const path_1 = require("path");
14
+ const fs_1 = require("fs");
15
+ const glob_1 = require("glob");
16
+ const chalk_1 = __importDefault(require("chalk"));
17
+ const ora_1 = __importDefault(require("ora"));
18
+ const scanner_1 = require("@oculum/scanner");
19
+ const formatters_1 = require("@oculum/scanner/formatters");
20
+ const config_js_1 = require("../utils/config.js");
21
+ const api_js_1 = require("../utils/api.js");
22
+ /**
23
+ * Check if file should be scanned
24
+ */
25
+ function isScannableFile(filePath) {
26
+ const ext = (0, path_1.extname)(filePath).toLowerCase();
27
+ const fileName = (0, path_1.basename)(filePath);
28
+ // Check special files first
29
+ if (scanner_1.SPECIAL_FILES.includes(fileName)) {
30
+ return true;
31
+ }
32
+ // Check extensions
33
+ return scanner_1.SCANNABLE_EXTENSIONS.includes(ext);
34
+ }
35
+ /**
36
+ * Map file extension to language
37
+ */
38
+ function getLanguage(filePath) {
39
+ const ext = (0, path_1.extname)(filePath).toLowerCase();
40
+ const langMap = {
41
+ '.js': 'javascript',
42
+ '.jsx': 'javascript',
43
+ '.mjs': 'javascript',
44
+ '.cjs': 'javascript',
45
+ '.ts': 'typescript',
46
+ '.tsx': 'typescript',
47
+ '.py': 'python',
48
+ '.go': 'go',
49
+ '.java': 'java',
50
+ '.rb': 'ruby',
51
+ '.php': 'php',
52
+ '.cs': 'csharp',
53
+ '.yaml': 'yaml',
54
+ '.yml': 'yaml',
55
+ '.json': 'json',
56
+ '.toml': 'toml',
57
+ '.env': 'dotenv',
58
+ '.sh': 'shell',
59
+ '.bash': 'shell',
60
+ };
61
+ return langMap[ext] || 'text';
62
+ }
63
+ /**
64
+ * Collect files to scan from a directory
65
+ */
66
+ async function collectFiles(targetPath) {
67
+ const absolutePath = (0, path_1.resolve)(targetPath);
68
+ const stats = (0, fs_1.statSync)(absolutePath);
69
+ const files = [];
70
+ if (stats.isFile()) {
71
+ // Single file scan
72
+ if (isScannableFile(absolutePath)) {
73
+ const content = (0, fs_1.readFileSync)(absolutePath, 'utf-8');
74
+ if (content.length <= scanner_1.MAX_FILE_SIZE) {
75
+ files.push({
76
+ path: (0, path_1.relative)(process.cwd(), absolutePath),
77
+ content,
78
+ language: getLanguage(absolutePath),
79
+ size: content.length,
80
+ });
81
+ }
82
+ }
83
+ }
84
+ else if (stats.isDirectory()) {
85
+ // Directory scan - use glob to find all files
86
+ const patterns = [
87
+ '**/*.js',
88
+ '**/*.jsx',
89
+ '**/*.ts',
90
+ '**/*.tsx',
91
+ '**/*.py',
92
+ '**/*.go',
93
+ '**/*.java',
94
+ '**/*.rb',
95
+ '**/*.php',
96
+ '**/*.cs',
97
+ '**/*.yaml',
98
+ '**/*.yml',
99
+ '**/*.json',
100
+ '**/*.toml',
101
+ '**/*.env*',
102
+ '**/Dockerfile*',
103
+ '**/docker-compose*.yml',
104
+ '**/package.json',
105
+ '**/.env*',
106
+ ];
107
+ const ignorePatterns = [
108
+ '**/node_modules/**',
109
+ '**/dist/**',
110
+ '**/build/**',
111
+ '**/.git/**',
112
+ '**/vendor/**',
113
+ '**/__pycache__/**',
114
+ '**/venv/**',
115
+ '**/.venv/**',
116
+ '**/coverage/**',
117
+ '**/.next/**',
118
+ '**/.nuxt/**',
119
+ ];
120
+ const foundFiles = await (0, glob_1.glob)(patterns, {
121
+ cwd: absolutePath,
122
+ ignore: ignorePatterns,
123
+ nodir: true,
124
+ absolute: true,
125
+ });
126
+ for (const filePath of foundFiles) {
127
+ try {
128
+ const fileStats = (0, fs_1.statSync)(filePath);
129
+ if (fileStats.size > scanner_1.MAX_FILE_SIZE)
130
+ continue;
131
+ const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
132
+ files.push({
133
+ path: (0, path_1.relative)(process.cwd(), filePath),
134
+ content,
135
+ language: getLanguage(filePath),
136
+ size: content.length,
137
+ });
138
+ }
139
+ catch {
140
+ // Skip files that can't be read
141
+ }
142
+ }
143
+ }
144
+ return files;
145
+ }
146
+ /**
147
+ * Format result based on output format
148
+ */
149
+ function formatOutput(result, format, noColor) {
150
+ switch (format) {
151
+ case 'json':
152
+ return (0, formatters_1.formatJSON)(result, true);
153
+ case 'sarif':
154
+ return JSON.stringify((0, formatters_1.formatSARIF)(result), null, 2);
155
+ case 'markdown':
156
+ return formatMarkdown(result);
157
+ case 'terminal':
158
+ default:
159
+ return (0, formatters_1.formatTerminalOutput)(result, { noColor });
160
+ }
161
+ }
162
+ /**
163
+ * Format as markdown (for docs/reports)
164
+ */
165
+ function formatMarkdown(result) {
166
+ const { vulnerabilities, severityCounts, filesScanned, scanDuration } = result;
167
+ let md = `# Oculum Security Scan Report\n\n`;
168
+ md += `**Scanned:** ${filesScanned} files in ${(scanDuration / 1000).toFixed(1)}s\n\n`;
169
+ // Summary table
170
+ md += `## Summary\n\n`;
171
+ md += `| Severity | Count |\n`;
172
+ md += `|----------|-------|\n`;
173
+ md += `| Critical | ${severityCounts.critical} |\n`;
174
+ md += `| High | ${severityCounts.high} |\n`;
175
+ md += `| Medium | ${severityCounts.medium} |\n`;
176
+ md += `| Low | ${severityCounts.low} |\n`;
177
+ md += `| Info | ${severityCounts.info} |\n\n`;
178
+ if (vulnerabilities.length === 0) {
179
+ md += `## Findings\n\n`;
180
+ md += `No security issues found.\n`;
181
+ return md;
182
+ }
183
+ // Findings by severity
184
+ md += `## Findings\n\n`;
185
+ for (const severity of ['critical', 'high', 'medium', 'low', 'info']) {
186
+ const findings = vulnerabilities.filter(v => v.severity === severity);
187
+ if (findings.length === 0)
188
+ continue;
189
+ md += `### ${severity.charAt(0).toUpperCase() + severity.slice(1)} (${findings.length})\n\n`;
190
+ for (const finding of findings) {
191
+ md += `#### ${finding.title}\n\n`;
192
+ md += `- **File:** \`${finding.filePath}:${finding.lineNumber}\`\n`;
193
+ md += `- **Category:** ${finding.category}\n`;
194
+ md += `- **Description:** ${finding.description}\n`;
195
+ if (finding.suggestedFix) {
196
+ md += `- **Fix:** ${finding.suggestedFix}\n`;
197
+ }
198
+ md += `\n`;
199
+ }
200
+ }
201
+ return md;
202
+ }
203
+ /**
204
+ * Get severity rank for comparison
205
+ */
206
+ function severityRank(severity) {
207
+ const ranks = {
208
+ critical: 5,
209
+ high: 4,
210
+ medium: 3,
211
+ low: 2,
212
+ info: 1,
213
+ none: 0,
214
+ };
215
+ return ranks[severity] || 0;
216
+ }
217
+ /**
218
+ * Main scan function
219
+ */
220
+ async function runScan(targetPath, options) {
221
+ const spinner = (0, ora_1.default)();
222
+ const config = (0, config_js_1.getConfig)();
223
+ const noColor = options.color === false;
224
+ // Validate depth against auth
225
+ if ((options.depth === 'validated' || options.depth === 'deep') && !(0, config_js_1.isAuthenticated)()) {
226
+ console.log(chalk_1.default.yellow('\nNote: validated and deep scans require authentication.'));
227
+ console.log(chalk_1.default.dim('Run `oculum login` to authenticate, or use `--depth cheap` for free local scans.\n'));
228
+ console.log(chalk_1.default.dim('Falling back to cheap scan...\n'));
229
+ options.depth = 'cheap';
230
+ }
231
+ // Collect files
232
+ spinner.start('Collecting files to scan...');
233
+ let files;
234
+ try {
235
+ files = await collectFiles(targetPath);
236
+ }
237
+ catch (err) {
238
+ spinner.fail(`Failed to collect files: ${err}`);
239
+ process.exit(1);
240
+ }
241
+ if (files.length === 0) {
242
+ spinner.fail('No scannable files found');
243
+ process.exit(1);
244
+ }
245
+ spinner.succeed(`Found ${files.length} files to scan`);
246
+ // Progress callback
247
+ const onProgress = (progress) => {
248
+ switch (progress.status) {
249
+ case 'layer1':
250
+ spinner.text = `Layer 1: Pattern matching... (${progress.vulnerabilitiesFound} findings)`;
251
+ break;
252
+ case 'layer2':
253
+ spinner.text = `Layer 2: Structural analysis... (${progress.vulnerabilitiesFound} findings)`;
254
+ break;
255
+ case 'validating':
256
+ spinner.text = `AI validation... (${progress.vulnerabilitiesFound} candidates)`;
257
+ break;
258
+ case 'layer3':
259
+ spinner.text = `Layer 3: AI semantic analysis...`;
260
+ break;
261
+ case 'complete':
262
+ spinner.succeed(`Scan complete: ${progress.vulnerabilitiesFound} issues found`);
263
+ break;
264
+ case 'failed':
265
+ spinner.fail(progress.message);
266
+ break;
267
+ }
268
+ };
269
+ // Run scan
270
+ let result;
271
+ try {
272
+ spinner.start('Starting scan...');
273
+ // For validated/deep scans, call the backend API
274
+ if (options.depth !== 'cheap' && (0, config_js_1.isAuthenticated)()) {
275
+ result = await (0, api_js_1.callBackendAPI)(files, options.depth, config.apiKey);
276
+ }
277
+ else {
278
+ // Local scan for cheap depth
279
+ result = await (0, scanner_1.runScan)(files, {
280
+ name: (0, path_1.basename)((0, path_1.resolve)(targetPath)),
281
+ url: '',
282
+ branch: 'local',
283
+ }, {
284
+ enableAI: false, // Cheap mode = no AI
285
+ scanDepth: 'cheap',
286
+ }, onProgress);
287
+ }
288
+ }
289
+ catch (err) {
290
+ spinner.fail(`Scan failed: ${err}`);
291
+ process.exit(1);
292
+ }
293
+ // Output results
294
+ const output = formatOutput(result, options.format, noColor);
295
+ console.log(output);
296
+ // Write to file if specified
297
+ if (options.output) {
298
+ const { writeFileSync } = await import('fs');
299
+ writeFileSync(options.output, output);
300
+ console.log(chalk_1.default.dim(`\nResults written to ${options.output}`));
301
+ }
302
+ // Exit code based on findings
303
+ const failThreshold = severityRank(options.failOn);
304
+ const highestSeverity = result.vulnerabilities.reduce((max, v) => Math.max(max, severityRank(v.severity)), 0);
305
+ if (highestSeverity >= failThreshold) {
306
+ process.exit(1);
307
+ }
308
+ }
309
+ /**
310
+ * Scan command definition
311
+ */
312
+ exports.scanCommand = new commander_1.Command('scan')
313
+ .description('Scan a directory or file for security vulnerabilities')
314
+ .argument('[path]', 'path to scan', '.')
315
+ .option('-d, --depth <depth>', 'scan depth: cheap (free), validated, deep', 'cheap')
316
+ .option('-f, --format <format>', 'output format: terminal, json, sarif, markdown', 'terminal')
317
+ .option('--fail-on <severity>', 'exit with error code if findings at severity', 'high')
318
+ .option('--no-color', 'disable colored output')
319
+ .option('-o, --output <file>', 'write output to file')
320
+ .option('--incremental', 'only scan changed files (requires git)')
321
+ .option('--diff <ref>', 'diff against branch/commit for incremental scan')
322
+ .action(runScan);
323
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Watch Command
3
+ * File watcher for continuous scanning during development
4
+ */
5
+ import { Command } from 'commander';
6
+ /**
7
+ * Watch command definition
8
+ */
9
+ export declare const watchCommand: Command;
10
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAmPnC;;GAEG;AACH,eAAO,MAAM,YAAY,SAYrB,CAAA"}
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ /**
3
+ * Watch Command
4
+ * File watcher for continuous scanning during development
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.watchCommand = void 0;
11
+ const commander_1 = require("commander");
12
+ const path_1 = require("path");
13
+ const fs_1 = require("fs");
14
+ const chalk_1 = __importDefault(require("chalk"));
15
+ const chokidar_1 = __importDefault(require("chokidar"));
16
+ const scanner_1 = require("@oculum/scanner");
17
+ const formatters_1 = require("@oculum/scanner/formatters");
18
+ const config_js_1 = require("../utils/config.js");
19
+ /**
20
+ * Check if file should be scanned
21
+ */
22
+ function isScannableFile(filePath) {
23
+ const ext = (0, path_1.extname)(filePath).toLowerCase();
24
+ const fileName = (0, path_1.basename)(filePath);
25
+ if (scanner_1.SPECIAL_FILES.includes(fileName))
26
+ return true;
27
+ return scanner_1.SCANNABLE_EXTENSIONS.includes(ext);
28
+ }
29
+ /**
30
+ * Map file extension to language
31
+ */
32
+ function getLanguage(filePath) {
33
+ const ext = (0, path_1.extname)(filePath).toLowerCase();
34
+ const langMap = {
35
+ '.js': 'javascript',
36
+ '.jsx': 'javascript',
37
+ '.ts': 'typescript',
38
+ '.tsx': 'typescript',
39
+ '.py': 'python',
40
+ '.go': 'go',
41
+ '.java': 'java',
42
+ '.rb': 'ruby',
43
+ '.php': 'php',
44
+ '.yaml': 'yaml',
45
+ '.yml': 'yaml',
46
+ '.json': 'json',
47
+ };
48
+ return langMap[ext] || 'text';
49
+ }
50
+ /**
51
+ * Read file as ScanFile
52
+ */
53
+ function readScanFile(filePath) {
54
+ try {
55
+ const stats = (0, fs_1.statSync)(filePath);
56
+ if (stats.size > scanner_1.MAX_FILE_SIZE)
57
+ return null;
58
+ const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
59
+ return {
60
+ path: (0, path_1.relative)(process.cwd(), filePath),
61
+ content,
62
+ language: getLanguage(filePath),
63
+ size: content.length,
64
+ };
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ /**
71
+ * Debounce function
72
+ */
73
+ function debounce(fn, delay) {
74
+ let timeoutId = null;
75
+ return (...args) => {
76
+ if (timeoutId)
77
+ clearTimeout(timeoutId);
78
+ timeoutId = setTimeout(() => fn(...args), delay);
79
+ };
80
+ }
81
+ /**
82
+ * Watch command
83
+ */
84
+ async function watch(targetPath, options) {
85
+ const absolutePath = (0, path_1.resolve)(targetPath);
86
+ const config = (0, config_js_1.getConfig)();
87
+ // Validate depth against auth
88
+ if ((options.depth === 'validated' || options.depth === 'deep') && !(0, config_js_1.isAuthenticated)()) {
89
+ console.log(chalk_1.default.yellow('\nNote: validated and deep scans require authentication.'));
90
+ console.log(chalk_1.default.dim('Run `oculum login` to authenticate.\n'));
91
+ options.depth = 'cheap';
92
+ }
93
+ console.log(chalk_1.default.bold('\nOculum Watch Mode'));
94
+ console.log(chalk_1.default.dim('─'.repeat(40)));
95
+ console.log(chalk_1.default.dim(`Watching: ${absolutePath}`));
96
+ console.log(chalk_1.default.dim(`Depth: ${options.depth}`));
97
+ console.log(chalk_1.default.dim(`Debounce: ${options.debounce}ms`));
98
+ console.log(chalk_1.default.dim('\nPress Ctrl+C to stop\n'));
99
+ // Track changed files for incremental scanning
100
+ const changedFiles = new Set();
101
+ let isScanning = false;
102
+ // Scan function (debounced)
103
+ const runScanOnChanges = debounce(async () => {
104
+ if (isScanning || changedFiles.size === 0)
105
+ return;
106
+ isScanning = true;
107
+ const filesToScan = Array.from(changedFiles);
108
+ changedFiles.clear();
109
+ // Clear console if requested
110
+ if (options.clearOnScan) {
111
+ console.clear();
112
+ }
113
+ console.log(chalk_1.default.cyan(`\n[${new Date().toLocaleTimeString()}] Scanning ${filesToScan.length} changed file(s)...`));
114
+ // Read files
115
+ const scanFiles = [];
116
+ for (const filePath of filesToScan) {
117
+ const file = readScanFile(filePath);
118
+ if (file)
119
+ scanFiles.push(file);
120
+ }
121
+ if (scanFiles.length === 0) {
122
+ console.log(chalk_1.default.dim('No scannable files found.'));
123
+ isScanning = false;
124
+ return;
125
+ }
126
+ try {
127
+ const result = await (0, scanner_1.runScan)(scanFiles, {
128
+ name: (0, path_1.basename)(absolutePath),
129
+ url: '',
130
+ branch: 'watch',
131
+ }, {
132
+ enableAI: options.depth !== 'cheap' && (0, config_js_1.isAuthenticated)(),
133
+ scanDepth: options.depth,
134
+ scanMode: 'incremental',
135
+ });
136
+ // Output results
137
+ if (result.vulnerabilities.length === 0) {
138
+ console.log(chalk_1.default.green('No issues found.'));
139
+ }
140
+ else {
141
+ console.log((0, formatters_1.formatTerminalOutput)(result, {
142
+ maxFindingsPerGroup: 5,
143
+ }));
144
+ }
145
+ }
146
+ catch (err) {
147
+ console.error(chalk_1.default.red(`Scan error: ${err}`));
148
+ }
149
+ isScanning = false;
150
+ }, options.debounce);
151
+ // Set up watcher
152
+ const watcher = chokidar_1.default.watch(absolutePath, {
153
+ ignored: [
154
+ '**/node_modules/**',
155
+ '**/dist/**',
156
+ '**/build/**',
157
+ '**/.git/**',
158
+ '**/vendor/**',
159
+ '**/__pycache__/**',
160
+ '**/venv/**',
161
+ '**/.venv/**',
162
+ '**/coverage/**',
163
+ '**/.next/**',
164
+ '**/.nuxt/**',
165
+ ],
166
+ persistent: true,
167
+ ignoreInitial: true,
168
+ });
169
+ watcher.on('change', (filePath) => {
170
+ if (!isScannableFile(filePath))
171
+ return;
172
+ changedFiles.add((0, path_1.resolve)(filePath));
173
+ console.log(chalk_1.default.dim(`Changed: ${(0, path_1.relative)(process.cwd(), filePath)}`));
174
+ runScanOnChanges();
175
+ });
176
+ watcher.on('add', (filePath) => {
177
+ if (!isScannableFile(filePath))
178
+ return;
179
+ changedFiles.add((0, path_1.resolve)(filePath));
180
+ console.log(chalk_1.default.dim(`Added: ${(0, path_1.relative)(process.cwd(), filePath)}`));
181
+ runScanOnChanges();
182
+ });
183
+ watcher.on('error', (error) => {
184
+ console.error(chalk_1.default.red(`Watcher error: ${error}`));
185
+ });
186
+ // Handle shutdown
187
+ process.on('SIGINT', () => {
188
+ console.log(chalk_1.default.dim('\n\nStopping watch mode...'));
189
+ watcher.close();
190
+ process.exit(0);
191
+ });
192
+ // Initial scan
193
+ console.log(chalk_1.default.dim('Performing initial scan...'));
194
+ const { glob } = await import('glob');
195
+ const patterns = [
196
+ '**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx',
197
+ '**/*.py', '**/*.go', '**/*.java', '**/*.rb',
198
+ '**/*.php', '**/*.cs', '**/package.json',
199
+ ];
200
+ const ignorePatterns = [
201
+ '**/node_modules/**', '**/dist/**', '**/build/**',
202
+ '**/.git/**', '**/vendor/**', '**/__pycache__/**',
203
+ ];
204
+ const allFiles = await glob(patterns, {
205
+ cwd: absolutePath,
206
+ ignore: ignorePatterns,
207
+ nodir: true,
208
+ absolute: true,
209
+ });
210
+ for (const filePath of allFiles) {
211
+ changedFiles.add(filePath);
212
+ }
213
+ runScanOnChanges();
214
+ }
215
+ /**
216
+ * Watch command definition
217
+ */
218
+ exports.watchCommand = new commander_1.Command('watch')
219
+ .description('Watch files and scan on changes')
220
+ .argument('[path]', 'path to watch', '.')
221
+ .option('-d, --depth <depth>', 'scan depth: cheap, validated, deep', 'cheap')
222
+ .option('--debounce <ms>', 'debounce time in milliseconds', '500')
223
+ .option('--clear', 'clear console before each scan', false)
224
+ .action((path, options) => {
225
+ watch(path, {
226
+ depth: options.depth,
227
+ debounce: parseInt(options.debounce, 10),
228
+ clearOnScan: options.clear,
229
+ });
230
+ });
231
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Oculum CLI
4
+ * AI-native security scanner for your codebase
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}