code-sentinel-mcp 0.2.3 → 0.2.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.
package/README.md CHANGED
@@ -12,6 +12,75 @@ AI coding assistants can inadvertently introduce subtle issues: hardcoded secret
12
12
  - **Balanced analysis**: Detects both issues AND strengths for fair code assessment
13
13
  - **Multi-language support**: Works with TypeScript, JavaScript, Python, Go, Rust, Java, and more
14
14
 
15
+ ## Why Not Tree-sitter or AST-Based Tools?
16
+
17
+ CodeSentinel intentionally uses a **pattern-based approach** rather than AST parsing. Here's why:
18
+
19
+ ### The Problem We Solve Is Different
20
+
21
+ Traditional linters (ESLint, tree-sitter) detect **syntax errors** and **style violations**. CodeSentinel detects **semantically deceptive patterns** - code that is:
22
+
23
+ - Syntactically valid (passes all linters)
24
+ - Structurally correct (valid AST)
25
+ - **But hides serious issues** that AI agents commonly produce
26
+
27
+ ### Examples AST Tools Miss
28
+
29
+ ```javascript
30
+ // AST sees: valid try-catch block
31
+ // CodeSentinel sees: error swallowing that masks failures
32
+ try { riskyOperation(); } catch(e) { }
33
+
34
+ // AST sees: valid function returning boolean
35
+ // CodeSentinel sees: fake implementation that always succeeds
36
+ function validateUser() { return true; } // TODO: implement
37
+
38
+ // AST sees: valid fallback expression
39
+ // CodeSentinel sees: failure masking - "no data" vs "fetch failed" indistinguishable
40
+ const users = response.data || [];
41
+
42
+ // AST sees: valid return statement
43
+ // CodeSentinel sees: silent failure hiding
44
+ if (error) { return null; } // error case
45
+ ```
46
+
47
+ ### What Each Approach Detects
48
+
49
+ | Issue Type | AST/Tree-sitter | CodeSentinel |
50
+ |:-----------|:----------------|:-------------|
51
+ | Syntax errors | Yes | No (not our goal) |
52
+ | Missing semicolons | Yes | No |
53
+ | Unused variables | Yes | No |
54
+ | **Empty catch blocks** | Partially | Yes |
55
+ | **Silent error returns** | No | Yes |
56
+ | **Fake success responses** | No | Yes |
57
+ | **TODO/placeholder code** | No | Yes |
58
+ | **Error-masking fallbacks** | No | Yes |
59
+ | **Hardcoded secrets** | Limited | Yes |
60
+ | **Deceptive comments** | No | Yes |
61
+
62
+ ### The Real Issue: Agent Behavior
63
+
64
+ AI coding agents produce code that **looks correct** but contains subtle deceptions:
65
+
66
+ 1. **"Making the error go away"** - Empty catches, silent returns, swallowed exceptions
67
+ 2. **Placeholder implementations** - `return true`, `return []`, TODO comments
68
+ 3. **False confidence patterns** - `|| []` fallbacks that mask fetch failures
69
+ 4. **Suppression abuse** - `@ts-ignore`, `eslint-disable` to hide type errors
70
+
71
+ These patterns pass every linter and compile successfully. AST tools see valid structure. Only pattern-based detection catches the **semantic intent** behind the code.
72
+
73
+ ### When to Use What
74
+
75
+ | Tool | Use For |
76
+ |:-----|:--------|
77
+ | ESLint/TSLint | Style consistency, syntax rules, unused code |
78
+ | Tree-sitter | Syntax highlighting, code navigation, refactoring |
79
+ | TypeScript | Type safety, compile-time errors |
80
+ | **CodeSentinel** | Agent-generated deceptions, error hiding, incomplete implementations |
81
+
82
+ CodeSentinel complements these tools - it catches what they structurally cannot.
83
+
15
84
  ## Features
16
85
 
17
86
  - **Security Analysis** (16 patterns): Hardcoded secrets, SQL injection, XSS, command injection, insecure crypto, disabled SSL, and more
@@ -32,7 +101,7 @@ npm install -g code-sentinel-mcp
32
101
  ### From source
33
102
 
34
103
  ```bash
35
- git clone https://github.com/your-username/code-sentinel.git
104
+ git clone https://github.com/salrad22/code-sentinel.git
36
105
  cd code-sentinel
37
106
  npm install
38
107
  npm run build
@@ -67,6 +136,47 @@ Add to your Claude Code MCP configuration file (`~/.claude/claude_desktop_config
67
136
  }
68
137
  ```
69
138
 
139
+ ## Remote Server (Cloudflare Workers)
140
+
141
+ CodeSentinel is also available as a remote MCP server on Cloudflare Workers. **No local installation required!**
142
+
143
+ ### Quick connect (Claude Code)
144
+
145
+ ```bash
146
+ claude mcp add-remote code-sentinel https://code-sentinel-mcp.sharara.dev/sse
147
+ ```
148
+
149
+ Or use the Streamable HTTP endpoint (recommended for newer clients):
150
+ ```bash
151
+ claude mcp add --transport http code-sentinel https://code-sentinel-mcp.sharara.dev/mcp
152
+ ```
153
+
154
+ ### Endpoints
155
+
156
+ | Endpoint | Protocol | Description |
157
+ |:---------|:---------|:------------|
158
+ | `https://code-sentinel-mcp.sharara.dev/mcp` | Streamable HTTP | Recommended |
159
+ | `https://code-sentinel-mcp.sharara.dev/sse` | Server-Sent Events | Legacy support |
160
+ | `https://code-sentinel-mcp.sharara.dev/` | HTTP GET | Health check / server info |
161
+
162
+ ### Self-hosting on Cloudflare
163
+
164
+ Deploy your own instance:
165
+
166
+ ```bash
167
+ cd cloudflare
168
+ npm install
169
+ npm run dev # Local development at localhost:8787
170
+ npm run deploy # Deploy to your Cloudflare account
171
+ ```
172
+
173
+ **Requirements:**
174
+ - Cloudflare account (free tier works)
175
+ - Wrangler CLI (`npm install -g wrangler`)
176
+ - `wrangler login` to authenticate
177
+
178
+ The server uses Durable Objects for persistent MCP connections. No database required.
179
+
70
180
  ## Available Tools
71
181
 
72
182
  ### `analyze_code`
@@ -245,32 +355,105 @@ CodeSentinel detects language from file extensions:
245
355
 
246
356
  ## Extending CodeSentinel
247
357
 
248
- Add custom patterns by editing files in `src/analyzers/`:
358
+ CodeSentinel uses a **data-driven pattern system** that separates pattern definitions from regex generation. This makes adding new patterns easier and more maintainable.
359
+
360
+ ### Project Structure
249
361
 
250
362
  ```
251
- src/analyzers/
252
- ├── security.ts # Security vulnerability patterns
253
- ├── deceptive.ts # Error-hiding patterns
254
- ├── placeholders.ts # Incomplete code patterns
255
- ├── errors.ts # Code smell patterns
256
- └── strengths.ts # Good practice patterns
363
+ src/
364
+ ├── patterns/
365
+ ├── types.ts # Type definitions for pattern configs
366
+ ├── builders.ts # Functions that generate regex from configs
367
+ ├── compiler.ts # Compiles definitions to executable patterns
368
+ └── definitions/
369
+ │ ├── security.ts # Security vulnerability patterns
370
+ │ ├── deceptive.ts # Error-hiding patterns
371
+ │ ├── placeholders.ts # Incomplete code patterns
372
+ │ ├── errors.ts # Code smell patterns
373
+ │ └── index.ts # Exports all definitions
374
+ ├── analyzers/
375
+ │ ├── core.ts # Unified analyzer using compiled patterns
376
+ │ ├── security.ts # Security analyzer (delegates to core)
377
+ │ ├── deceptive.ts # Deceptive analyzer (delegates to core)
378
+ │ ├── placeholders.ts # Placeholder analyzer (delegates to core)
379
+ │ ├── errors.ts # Error analyzer (delegates to core)
380
+ │ └── strengths.ts # Strength analyzer
381
+ └── index.ts # MCP server entry point
257
382
  ```
258
383
 
259
- Each pattern follows this structure:
384
+ ### Adding a New Pattern
385
+
386
+ Instead of writing regex manually, you define **what** to detect and the system generates the regex:
260
387
 
261
388
  ```typescript
389
+ // Old approach (manual regex)
390
+ {
391
+ id: 'CS-DEC001',
392
+ pattern: /catch\s*\([^)]*\)\s*\{\s*\}/g, // Error-prone
393
+ title: 'Empty Catch Block',
394
+ // ...
395
+ }
396
+
397
+ // New approach (data-driven)
262
398
  {
263
- id: 'CS-SEC001', // Unique ID with category prefix
264
- pattern: /regex/g, // RegExp to match
265
- title: 'Short description',
266
- description: 'Detailed explanation',
267
- severity: 'critical', // critical | high | medium | low | info
268
- category: 'security',
269
- suggestion: 'How to fix',
270
- verification: { // Optional: reduce false positives
271
- assumption: 'What we assume is true',
272
- confirmIf: 'When to confirm as real issue',
273
- falsePositiveIf: 'When to dismiss'
399
+ id: 'CS-DEC001',
400
+ title: 'Empty Catch Block',
401
+ description: 'Silently swallowing errors makes debugging impossible.',
402
+ severity: 'high',
403
+ category: 'deceptive',
404
+ suggestion: 'At minimum, log the error. Better: handle it appropriately.',
405
+ match: {
406
+ type: 'catch_handler',
407
+ behavior: 'empty'
408
+ }
409
+ }
410
+ ```
411
+
412
+ ### Available Match Types
413
+
414
+ | Match Type | Description | Example Config |
415
+ |:-----------|:------------|:---------------|
416
+ | `empty_block` | Empty catch/finally/promise blocks | `{ type: 'empty_block', constructs: ['catch', '.catch'] }` |
417
+ | `function_call` | Function/method calls | `{ type: 'function_call', names: ['eval', 'exec'] }` |
418
+ | `returns_only` | Return statements with specific values | `{ type: 'returns_only', values: ['null', '[]', '{}'] }` |
419
+ | `contains_text` | Text in comments/strings | `{ type: 'contains_text', terms: ['TODO', 'FIXME'], context: 'comment' }` |
420
+ | `fallback_value` | Fallback patterns | `{ type: 'fallback_value', operators: ['\|\|'], values: ['[]'] }` |
421
+ | `catch_handler` | Catch block behaviors | `{ type: 'catch_handler', behavior: 'empty' }` |
422
+ | `promise_catch` | Promise .catch() behaviors | `{ type: 'promise_catch', behavior: 'returns_silent' }` |
423
+ | `comment_marker` | TODO/FIXME/HACK markers | `{ type: 'comment_marker', markers: ['TODO', 'FIXME'] }` |
424
+ | `string_literal` | Patterns inside strings | `{ type: 'string_literal', patterns: ['password', 'secret'] }` |
425
+ | `secret_pattern` | API keys and tokens | `{ type: 'secret_pattern', kind: 'github' }` |
426
+ | `url_pattern` | URL patterns | `{ type: 'url_pattern', protocol: 'http', excludeLocalhost: true }` |
427
+ | `suppression_comment` | Linter suppressions | `{ type: 'suppression_comment', tools: ['ts-ignore', 'eslint-disable'] }` |
428
+ | `type_cast` | Type casts | `{ type: 'type_cast', targets: ['any'] }` |
429
+ | `comparison` | Comparison operators | `{ type: 'comparison', operators: ['==', '!='] }` |
430
+ | `loop_pattern` | Loop patterns | `{ type: 'loop_pattern', kind: 'while_true' }` |
431
+ | `raw_regex` | Escape hatch for complex patterns | `{ type: 'raw_regex', pattern: 'your-regex', flags: 'gi' }` |
432
+
433
+ ### Step-by-Step: Adding a Pattern
434
+
435
+ 1. **Choose the category** - security, deceptive, placeholder, or error
436
+ 2. **Open the definition file** - `src/patterns/definitions/<category>.ts`
437
+ 3. **Add a new pattern definition** using the appropriate match type
438
+ 4. **Build** - `npm run build`
439
+ 5. **Test** - Use the MCP inspector to verify detection
440
+
441
+ ### Pattern Definition Structure
442
+
443
+ ```typescript
444
+ {
445
+ id: string; // Unique ID: CS-<CAT><NUM> (e.g., CS-SEC001)
446
+ title: string; // Short description (displayed in results)
447
+ description: string; // Detailed explanation of the issue
448
+ severity: Severity; // 'critical' | 'high' | 'medium' | 'low' | 'info'
449
+ category: Category; // 'security' | 'deceptive' | 'placeholder' | 'error'
450
+ suggestion?: string; // How to fix the issue
451
+ match: MatchConfig; // What to detect (see match types above)
452
+ verification?: { // Optional: reduce false positives
453
+ status: 'needs_verification' | 'confirmed';
454
+ assumption?: string;
455
+ confirmIf?: string;
456
+ falsePositiveIf?: string;
274
457
  }
275
458
  }
276
459
  ```
@@ -306,6 +489,8 @@ MIT
306
489
 
307
490
  ## Links
308
491
 
492
+ - [GitHub Repository](https://github.com/salrad22/code-sentinel)
493
+ - [npm package](https://www.npmjs.com/package/code-sentinel-mcp)
494
+ - [Remote Server](https://code-sentinel-mcp.sharara.dev/)
309
495
  - [Model Context Protocol](https://modelcontextprotocol.io/)
310
496
  - [Claude Code](https://claude.ai/code)
311
- - [npm package](https://www.npmjs.com/package/code-sentinel-mcp)
@@ -0,0 +1,7 @@
1
+ import { Issue, Category } from '../types.js';
2
+ export declare function analyzeWithPatterns(code: string, filename: string, category: Category): Issue[];
3
+ export declare function analyzeSecurityWithPatterns(code: string, filename: string): Issue[];
4
+ export declare function analyzeDeceptiveWithPatterns(code: string, filename: string): Issue[];
5
+ export declare function analyzePlaceholdersWithPatterns(code: string, filename: string): Issue[];
6
+ export declare function analyzeErrorsWithPatterns(code: string, filename: string): Issue[];
7
+ export declare function analyzeAllWithPatterns(code: string, filename: string): Issue[];
@@ -0,0 +1,69 @@
1
+ // Core analyzer - uses compiled patterns from the data-driven system
2
+ import { getCompiledPatterns } from '../patterns/index.js';
3
+ // Analyze code using compiled patterns
4
+ export function analyzeWithPatterns(code, filename, category) {
5
+ const issues = [];
6
+ const lines = code.split('\n');
7
+ const compiledPatterns = getCompiledPatterns(category);
8
+ for (const pattern of compiledPatterns) {
9
+ for (const regex of pattern.patterns) {
10
+ // Reset regex state for global patterns
11
+ regex.lastIndex = 0;
12
+ let match;
13
+ while ((match = regex.exec(code)) !== null) {
14
+ // Calculate line number
15
+ const beforeMatch = code.substring(0, match.index);
16
+ const lineNumber = beforeMatch.split('\n').length;
17
+ const lineContent = lines[lineNumber - 1] || '';
18
+ const matchedValue = match[0];
19
+ // Build verification with actual values substituted
20
+ let verification = pattern.verification;
21
+ if (verification) {
22
+ verification = {
23
+ ...verification,
24
+ commands: verification.commands?.map(cmd => cmd
25
+ .replace(/<matched_value>/g, matchedValue.substring(0, 20) + '...')
26
+ .replace(/<filename>/g, filename))
27
+ };
28
+ }
29
+ issues.push({
30
+ id: pattern.id,
31
+ category: pattern.category,
32
+ severity: pattern.severity,
33
+ title: pattern.title,
34
+ description: pattern.description,
35
+ line: lineNumber,
36
+ code: lineContent.trim(),
37
+ suggestion: pattern.suggestion,
38
+ verification
39
+ });
40
+ // Prevent infinite loops for patterns without global flag
41
+ if (!regex.global)
42
+ break;
43
+ }
44
+ }
45
+ }
46
+ return issues;
47
+ }
48
+ // Convenience functions for each category
49
+ export function analyzeSecurityWithPatterns(code, filename) {
50
+ return analyzeWithPatterns(code, filename, 'security');
51
+ }
52
+ export function analyzeDeceptiveWithPatterns(code, filename) {
53
+ return analyzeWithPatterns(code, filename, 'deceptive');
54
+ }
55
+ export function analyzePlaceholdersWithPatterns(code, filename) {
56
+ return analyzeWithPatterns(code, filename, 'placeholder');
57
+ }
58
+ export function analyzeErrorsWithPatterns(code, filename) {
59
+ return analyzeWithPatterns(code, filename, 'error');
60
+ }
61
+ // Analyze all categories at once
62
+ export function analyzeAllWithPatterns(code, filename) {
63
+ return [
64
+ ...analyzeSecurityWithPatterns(code, filename),
65
+ ...analyzeDeceptiveWithPatterns(code, filename),
66
+ ...analyzePlaceholdersWithPatterns(code, filename),
67
+ ...analyzeErrorsWithPatterns(code, filename),
68
+ ];
69
+ }
@@ -1,200 +1,7 @@
1
- // These patterns detect code that hides errors or creates false confidence
2
- const deceptivePatterns = [
3
- // Empty catch blocks
4
- {
5
- id: 'CS-DEC001',
6
- pattern: /catch\s*\([^)]*\)\s*\{\s*\}/g,
7
- title: 'Empty Catch Block',
8
- description: 'Silently swallowing errors makes debugging impossible.',
9
- severity: 'high',
10
- category: 'deceptive',
11
- suggestion: 'At minimum, log the error. Better: handle it appropriately or rethrow.'
12
- },
13
- {
14
- id: 'CS-DEC002',
15
- pattern: /catch\s*\([^)]*\)\s*\{\s*\/\/.*?\s*\}/gs,
16
- title: 'Catch Block with Only Comments',
17
- description: 'A catch block with only comments still swallows errors.',
18
- severity: 'high',
19
- category: 'deceptive',
20
- suggestion: 'Add actual error handling, not just comments.'
21
- },
22
- {
23
- id: 'CS-DEC003',
24
- pattern: /catch\s*\([^)]*\)\s*\{\s*(?:console\.log|print)\s*\([^)]*\)\s*;?\s*\}/g,
25
- title: 'Catch with Only Console.log',
26
- description: 'Logging alone does not handle the error - execution continues as if nothing happened.',
27
- severity: 'medium',
28
- category: 'deceptive',
29
- suggestion: 'Decide: should execution continue? Add recovery logic or rethrow.'
30
- },
31
- // Silent promise rejections
32
- {
33
- id: 'CS-DEC010',
34
- pattern: /\.catch\s*\(\s*\(\s*\)\s*=>\s*\{\s*\}\s*\)/g,
35
- title: 'Empty Promise Catch',
36
- description: 'Silently ignoring promise rejections hides async errors.',
37
- severity: 'high',
38
- category: 'deceptive',
39
- suggestion: 'Handle the rejection or let it propagate for proper error handling.'
40
- },
41
- {
42
- id: 'CS-DEC011',
43
- pattern: /\.catch\s*\(\s*\(\s*\)\s*=>\s*(?:null|undefined|false|true|''|"")\s*\)/g,
44
- title: 'Promise Catch Returns Silent Value',
45
- description: 'Returning a value from catch masks the error - callers won\'t know something failed.',
46
- severity: 'high',
47
- category: 'deceptive',
48
- suggestion: 'Return a distinguishable error state or rethrow.'
49
- },
50
- {
51
- id: 'CS-DEC012',
52
- pattern: /\.catch\s*\(\s*_\s*=>\s*\{?\s*\}?\s*\)/g,
53
- title: 'Catch with Ignored Error Parameter',
54
- description: 'Using _ for error parameter signals intentional ignore - but is it really safe to ignore?',
55
- severity: 'medium',
56
- category: 'deceptive',
57
- suggestion: 'Document why ignoring this error is safe, or handle it.'
58
- },
59
- // Fallback values that mask failures
60
- {
61
- id: 'CS-DEC020',
62
- pattern: /\|\|\s*\[\s*\]/g,
63
- title: 'Empty Array Fallback',
64
- description: 'Falling back to [] can mask failed data fetching - code continues as if data was empty.',
65
- severity: 'medium',
66
- category: 'deceptive',
67
- suggestion: 'Distinguish between "no data" and "failed to fetch". Consider throwing or returning null.'
68
- },
69
- {
70
- id: 'CS-DEC021',
71
- pattern: /\|\|\s*\{\s*\}/g,
72
- title: 'Empty Object Fallback',
73
- description: 'Falling back to {} can hide parsing or fetching failures.',
74
- severity: 'medium',
75
- category: 'deceptive',
76
- suggestion: 'Handle the undefined/null case explicitly rather than masking it.'
77
- },
78
- {
79
- id: 'CS-DEC022',
80
- pattern: /\?\?\s*(?:\[\s*\]|\{\s*\}|''|"")/g,
81
- title: 'Nullish Coalescing to Empty Value',
82
- description: 'Defaulting to empty values with ?? can mask null responses that indicate errors.',
83
- severity: 'low',
84
- category: 'deceptive',
85
- suggestion: 'Verify that null/undefined truly means "use default" vs "something went wrong".'
86
- },
87
- // Optional chaining abuse
88
- {
89
- id: 'CS-DEC030',
90
- pattern: /\?\.\w+\?\.\w+\?\.\w+\?\.\w+/g,
91
- title: 'Excessive Optional Chaining',
92
- description: 'Deep optional chaining (4+ levels) often masks structural problems or missing validation.',
93
- severity: 'medium',
94
- category: 'deceptive',
95
- suggestion: 'Validate data shape upfront rather than optional-chaining through uncertain structures.'
96
- },
97
- // Error-hiding returns
98
- {
99
- id: 'CS-DEC040',
100
- pattern: /return\s+(?:null|undefined|false)\s*;?\s*\/\/\s*(?:error|fail|todo|fixme)/gi,
101
- title: 'Silent Error Return',
102
- description: 'Returning null/false on error with a comment - callers may not check for this.',
103
- severity: 'high',
104
- category: 'deceptive',
105
- suggestion: 'Throw an error or return a Result/Either type that forces handling.'
106
- },
107
- {
108
- id: 'CS-DEC041',
109
- pattern: /if\s*\([^)]*error[^)]*\)\s*\{\s*return\s*;?\s*\}/gi,
110
- title: 'Silent Return on Error',
111
- description: 'Returning silently when an error is detected - no logging, no propagation.',
112
- severity: 'high',
113
- category: 'deceptive',
114
- suggestion: 'Log the error or throw it. Silent returns make debugging a nightmare.'
115
- },
116
- // Timeout-based "fixes"
117
- {
118
- id: 'CS-DEC050',
119
- pattern: /setTimeout\s*\([^,]+,\s*\d+\s*\)\s*;?\s*\/\/.*?(?:fix|hack|workaround|retry)/gi,
120
- title: 'Timeout as Error Workaround',
121
- description: 'Using setTimeout to "fix" timing issues often masks race conditions.',
122
- severity: 'medium',
123
- category: 'deceptive',
124
- suggestion: 'Fix the underlying race condition. Use proper async coordination.'
125
- },
126
- // Suppressed warnings/errors
127
- {
128
- id: 'CS-DEC060',
129
- pattern: /\/\/\s*(?:@ts-ignore|@ts-expect-error|eslint-disable|noqa)/g,
130
- title: 'Linter/Type Check Suppression',
131
- description: 'Suppressing type errors or linter warnings may hide real issues.',
132
- severity: 'low',
133
- category: 'deceptive',
134
- suggestion: 'Fix the underlying issue. If suppression is needed, document why.'
135
- },
136
- {
137
- id: 'CS-DEC061',
138
- pattern: /as\s+any(?!\w)/g,
139
- title: 'TypeScript "as any" Cast',
140
- description: 'Casting to any defeats TypeScript\'s type safety.',
141
- severity: 'medium',
142
- category: 'deceptive',
143
- suggestion: 'Use proper type definitions or unknown with type guards.'
144
- },
145
- // Fake success responses
146
- {
147
- id: 'CS-DEC070',
148
- pattern: /return\s*\{\s*(?:success|ok|status)\s*:\s*true[^}]*\}\s*;?\s*\/\/.*?(?:todo|fixme|hack)/gi,
149
- title: 'Fake Success Response',
150
- description: 'Returning success without actually doing the work.',
151
- severity: 'critical',
152
- category: 'deceptive',
153
- suggestion: 'Implement the actual functionality or return an honest error.'
154
- },
155
- // Console.error without throwing
156
- {
157
- id: 'CS-DEC080',
158
- pattern: /console\.error\s*\([^)]+\)\s*;?\s*(?!\s*throw)/g,
159
- title: 'console.error Without Throw',
160
- description: 'Logging an error but continuing execution - the error may not be handled.',
161
- severity: 'low',
162
- category: 'deceptive',
163
- suggestion: 'Consider if execution should continue. If not, throw after logging.'
164
- }
165
- ];
1
+ // Deceptive pattern analyzer - uses data-driven pattern system
2
+ // This file now delegates to the core analyzer with compiled patterns
3
+ import { analyzeDeceptiveWithPatterns } from './core.js';
4
+ // Main export - uses the data-driven pattern system
166
5
  export function analyzeDeceptivePatterns(code, filename) {
167
- const issues = [];
168
- const lines = code.split('\n');
169
- for (const patternDef of deceptivePatterns) {
170
- patternDef.pattern.lastIndex = 0;
171
- let match;
172
- while ((match = patternDef.pattern.exec(code)) !== null) {
173
- const beforeMatch = code.substring(0, match.index);
174
- const lineNumber = beforeMatch.split('\n').length;
175
- const lineContent = lines[lineNumber - 1] || '';
176
- // Build verification with actual values substituted
177
- let verification = patternDef.verification;
178
- if (verification) {
179
- verification = {
180
- ...verification,
181
- commands: verification.commands?.map(cmd => cmd.replace(/<filename>/g, filename))
182
- };
183
- }
184
- issues.push({
185
- id: patternDef.id,
186
- category: patternDef.category,
187
- severity: patternDef.severity,
188
- title: patternDef.title,
189
- description: patternDef.description,
190
- line: lineNumber,
191
- code: lineContent.trim(),
192
- suggestion: patternDef.suggestion,
193
- verification
194
- });
195
- if (!patternDef.pattern.global)
196
- break;
197
- }
198
- }
199
- return issues;
6
+ return analyzeDeceptiveWithPatterns(code, filename);
200
7
  }