fivosense 0.1.3 → 0.1.5

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,94 @@
1
+ {
2
+ "name": "fivosense-vscode",
3
+ "displayName": "FivoSense Security Scanner",
4
+ "description": "Real-time security vulnerability detection with AI-powered taint analysis",
5
+ "version": "0.1.0",
6
+ "publisher": "fivosense",
7
+ "engines": {
8
+ "vscode": "^1.80.0"
9
+ },
10
+ "categories": [
11
+ "Linters",
12
+ "Programming Languages",
13
+ "Other"
14
+ ],
15
+ "keywords": [
16
+ "security",
17
+ "vulnerability",
18
+ "sql injection",
19
+ "xss",
20
+ "taint analysis",
21
+ "code scanner"
22
+ ],
23
+ "activationEvents": [
24
+ "onLanguage:javascript",
25
+ "onLanguage:typescript",
26
+ "onLanguage:javascriptreact",
27
+ "onLanguage:typescriptreact"
28
+ ],
29
+ "main": "./dist/extension.js",
30
+ "contributes": {
31
+ "commands": [
32
+ {
33
+ "command": "fivosense.scanFile",
34
+ "title": "FivoSense: Scan Current File"
35
+ },
36
+ {
37
+ "command": "fivosense.scanWorkspace",
38
+ "title": "FivoSense: Scan Workspace"
39
+ },
40
+ {
41
+ "command": "fivosense.roast",
42
+ "title": "FivoSense: Roast Mode 🔥"
43
+ },
44
+ {
45
+ "command": "fivosense.badge",
46
+ "title": "FivoSense: Get Security Badge"
47
+ }
48
+ ],
49
+ "configuration": {
50
+ "title": "FivoSense",
51
+ "properties": {
52
+ "fivosense.enableRealTime": {
53
+ "type": "boolean",
54
+ "default": true,
55
+ "description": "Enable real-time security scanning as you type"
56
+ },
57
+ "fivosense.scanOnSave": {
58
+ "type": "boolean",
59
+ "default": true,
60
+ "description": "Automatically scan files on save"
61
+ },
62
+ "fivosense.severity": {
63
+ "type": "string",
64
+ "enum": ["all", "critical", "high", "medium"],
65
+ "default": "all",
66
+ "description": "Minimum severity level to report"
67
+ }
68
+ }
69
+ }
70
+ },
71
+ "scripts": {
72
+ "vscode:prepublish": "npm run compile",
73
+ "compile": "tsc -p ./",
74
+ "watch": "tsc -watch -p ./",
75
+ "package": "vsce package"
76
+ },
77
+ "devDependencies": {
78
+ "@types/node": "^20.11.0",
79
+ "@types/vscode": "^1.80.0",
80
+ "@vscode/vsce": "^2.22.0",
81
+ "typescript": "^5.3.3"
82
+ },
83
+ "dependencies": {
84
+ "fivosense": "^0.1.3"
85
+ },
86
+ "repository": {
87
+ "type": "git",
88
+ "url": "https://github.com/itsvinsoni/sense.git"
89
+ },
90
+ "bugs": {
91
+ "url": "https://github.com/itsvinsoni/sense/issues"
92
+ },
93
+ "license": "MIT"
94
+ }
@@ -0,0 +1,289 @@
1
+ import * as vscode from 'vscode';
2
+ import { auditFile } from 'fivosense';
3
+
4
+ let diagnosticCollection: vscode.DiagnosticCollection;
5
+ let statusBarItem: vscode.StatusBarItem;
6
+
7
+ /**
8
+ * Extension activation
9
+ */
10
+ export function activate(context: vscode.ExtensionContext) {
11
+ console.log('FivoSense extension activated');
12
+
13
+ // Create diagnostic collection
14
+ diagnosticCollection = vscode.languages.createDiagnosticCollection('fivosense');
15
+ context.subscriptions.push(diagnosticCollection);
16
+
17
+ // Create status bar item
18
+ statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100);
19
+ statusBarItem.text = '$(shield) FivoSense';
20
+ statusBarItem.tooltip = 'FivoSense Security Scanner';
21
+ statusBarItem.show();
22
+ context.subscriptions.push(statusBarItem);
23
+
24
+ // Register commands
25
+ context.subscriptions.push(
26
+ vscode.commands.registerCommand('fivosense.scanFile', scanCurrentFile),
27
+ vscode.commands.registerCommand('fivosense.scanWorkspace', scanWorkspace),
28
+ vscode.commands.registerCommand('fivosense.roast', roastMode),
29
+ vscode.commands.registerCommand('fivosense.badge', showBadge)
30
+ );
31
+
32
+ // Register event handlers
33
+ const config = vscode.workspace.getConfiguration('fivosense');
34
+
35
+ if (config.get('scanOnSave')) {
36
+ context.subscriptions.push(
37
+ vscode.workspace.onDidSaveTextDocument(document => {
38
+ if (shouldScanDocument(document)) {
39
+ scanDocument(document);
40
+ }
41
+ })
42
+ );
43
+ }
44
+
45
+ if (config.get('enableRealTime')) {
46
+ context.subscriptions.push(
47
+ vscode.workspace.onDidChangeTextDocument(event => {
48
+ if (shouldScanDocument(event.document)) {
49
+ // Debounce real-time scanning
50
+ debounce(() => scanDocument(event.document), 1000);
51
+ }
52
+ })
53
+ );
54
+ }
55
+
56
+ // Scan active editor on start
57
+ if (vscode.window.activeTextEditor) {
58
+ scanDocument(vscode.window.activeTextEditor.document);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Extension deactivation
64
+ */
65
+ export function deactivate() {
66
+ if (diagnosticCollection) {
67
+ diagnosticCollection.dispose();
68
+ }
69
+ if (statusBarItem) {
70
+ statusBarItem.dispose();
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Check if document should be scanned
76
+ */
77
+ function shouldScanDocument(document: vscode.TextDocument): boolean {
78
+ const supportedLanguages = ['javascript', 'typescript', 'javascriptreact', 'typescriptreact'];
79
+ return supportedLanguages.includes(document.languageId) &&
80
+ document.uri.scheme === 'file';
81
+ }
82
+
83
+ /**
84
+ * Scan a document
85
+ */
86
+ async function scanDocument(document: vscode.TextDocument) {
87
+ try {
88
+ statusBarItem.text = '$(sync~spin) Scanning...';
89
+
90
+ const result = await auditFile(document.uri.fsPath);
91
+ const diagnostics: vscode.Diagnostic[] = [];
92
+
93
+ // Convert findings to VS Code diagnostics
94
+ const allFindings = [...result.vulnerabilities, ...result.secrets, ...result.destructive];
95
+ for (const finding of allFindings) {
96
+ const severity = getSeverity(finding.severity);
97
+ const range = new vscode.Range(
98
+ finding.line - 1, 0,
99
+ finding.line - 1, 1000
100
+ );
101
+
102
+ const diagnostic = new vscode.Diagnostic(
103
+ range,
104
+ `[${finding.type}] ${finding.message}\n${finding.evidence}`,
105
+ severity
106
+ );
107
+
108
+ diagnostic.code = finding.cwe;
109
+ diagnostic.source = 'FivoSense';
110
+
111
+ // Add fix as code action
112
+ if (finding.fix) {
113
+ diagnostic.relatedInformation = [
114
+ new vscode.DiagnosticRelatedInformation(
115
+ new vscode.Location(document.uri, range),
116
+ `Fix: ${finding.fix}`
117
+ )
118
+ ];
119
+ }
120
+
121
+ diagnostics.push(diagnostic);
122
+ }
123
+
124
+ diagnosticCollection.set(document.uri, diagnostics);
125
+
126
+ // Update status bar
127
+ const { critical, high, medium } = result.summary;
128
+ if (result.summary.total === 0) {
129
+ statusBarItem.text = '$(shield-check) FivoSense: Clean';
130
+ statusBarItem.backgroundColor = undefined;
131
+ } else if (critical > 0) {
132
+ statusBarItem.text = `$(shield-x) FivoSense: ${critical} Critical`;
133
+ statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.errorBackground');
134
+ } else if (high > 0) {
135
+ statusBarItem.text = `$(warning) FivoSense: ${high} High`;
136
+ statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
137
+ } else {
138
+ statusBarItem.text = `$(info) FivoSense: ${medium} Issues`;
139
+ statusBarItem.backgroundColor = undefined;
140
+ }
141
+
142
+ } catch (error: any) {
143
+ statusBarItem.text = '$(shield-x) FivoSense: Error';
144
+ vscode.window.showErrorMessage(`FivoSense scan failed: ${error.message}`);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Convert severity to VS Code diagnostic severity
150
+ */
151
+ function getSeverity(severity: string): vscode.DiagnosticSeverity {
152
+ switch (severity.toLowerCase()) {
153
+ case 'critical':
154
+ case 'high':
155
+ return vscode.DiagnosticSeverity.Error;
156
+ case 'medium':
157
+ return vscode.DiagnosticSeverity.Warning;
158
+ case 'low':
159
+ return vscode.DiagnosticSeverity.Information;
160
+ default:
161
+ return vscode.DiagnosticSeverity.Hint;
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Scan current file command
167
+ */
168
+ async function scanCurrentFile() {
169
+ const editor = vscode.window.activeTextEditor;
170
+ if (!editor) {
171
+ vscode.window.showWarningMessage('No active editor');
172
+ return;
173
+ }
174
+
175
+ if (!shouldScanDocument(editor.document)) {
176
+ vscode.window.showWarningMessage('File type not supported');
177
+ return;
178
+ }
179
+
180
+ await scanDocument(editor.document);
181
+ vscode.window.showInformationMessage('FivoSense scan completed');
182
+ }
183
+
184
+ /**
185
+ * Scan workspace command
186
+ */
187
+ async function scanWorkspace() {
188
+ const files = await vscode.workspace.findFiles('**/*.{js,ts,jsx,tsx}', '**/node_modules/**');
189
+
190
+ let totalFindings = 0;
191
+ let criticalCount = 0;
192
+
193
+ await vscode.window.withProgress({
194
+ location: vscode.ProgressLocation.Notification,
195
+ title: 'FivoSense: Scanning workspace...',
196
+ cancellable: false
197
+ }, async (progress) => {
198
+ for (let i = 0; i < files.length; i++) {
199
+ progress.report({
200
+ increment: (100 / files.length),
201
+ message: `${i + 1}/${files.length} files`
202
+ });
203
+
204
+ const document = await vscode.workspace.openTextDocument(files[i]);
205
+ const result = await auditFile(document.uri.fsPath);
206
+
207
+ totalFindings += result.summary.total;
208
+ criticalCount += result.summary.critical;
209
+
210
+ if (result.summary.total > 0) {
211
+ await scanDocument(document);
212
+ }
213
+ }
214
+ });
215
+
216
+ vscode.window.showInformationMessage(
217
+ `FivoSense: Scanned ${files.length} files. Found ${totalFindings} issues (${criticalCount} critical)`
218
+ );
219
+ }
220
+
221
+ /**
222
+ * Roast mode command
223
+ */
224
+ async function roastMode() {
225
+ const editor = vscode.window.activeTextEditor;
226
+ if (!editor) {
227
+ vscode.window.showWarningMessage('No active editor');
228
+ return;
229
+ }
230
+
231
+ const result = await auditFile(editor.document.uri.fsPath);
232
+
233
+ let roast = '';
234
+ if (result.summary.total === 0) {
235
+ roast = '🎉 Your code is cleaner than your browser history!';
236
+ } else if (result.summary.critical > 0) {
237
+ roast = '🔥 Even script kiddies are embarrassed for you. This code has more holes than Swiss cheese!';
238
+ } else if (result.summary.high > 0) {
239
+ roast = '😬 Living dangerously, I see. Your security posture is... creative.';
240
+ } else {
241
+ roast = '🤔 Not terrible, but I\'ve seen better security at a lemonade stand.';
242
+ }
243
+
244
+ vscode.window.showInformationMessage(roast, { modal: true });
245
+ }
246
+
247
+ /**
248
+ * Show security badge command
249
+ */
250
+ async function showBadge() {
251
+ const editor = vscode.window.activeTextEditor;
252
+ if (!editor) {
253
+ vscode.window.showWarningMessage('No active editor');
254
+ return;
255
+ }
256
+
257
+ const result = await auditFile(editor.document.uri.fsPath);
258
+
259
+ // Calculate grade
260
+ let grade = 'A+';
261
+ let score = 100;
262
+
263
+ if (result.summary.critical > 0) {
264
+ grade = 'F';
265
+ score = 40;
266
+ } else if (result.summary.high > 0) {
267
+ grade = 'D';
268
+ score = 60;
269
+ } else if (result.summary.medium > 0) {
270
+ grade = 'B';
271
+ score = 80;
272
+ }
273
+
274
+ const message = `🛡️ Security Grade: ${grade}\nScore: ${score}/100\n\nFindings:\n` +
275
+ `Critical: ${result.summary.critical}\n` +
276
+ `High: ${result.summary.high}\n` +
277
+ `Medium: ${result.summary.medium}`;
278
+
279
+ vscode.window.showInformationMessage(message, { modal: true });
280
+ }
281
+
282
+ /**
283
+ * Debounce utility
284
+ */
285
+ let debounceTimer: NodeJS.Timeout;
286
+ function debounce(func: Function, delay: number) {
287
+ clearTimeout(debounceTimer);
288
+ debounceTimer = setTimeout(() => func(), delay);
289
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "target": "ES2020",
5
+ "outDir": "dist",
6
+ "lib": ["ES2020"],
7
+ "sourceMap": true,
8
+ "rootDir": "src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true
13
+ },
14
+ "exclude": ["node_modules", ".vscode-test"]
15
+ }