vibe-and-thrive 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.
- package/.claude/commands/add-tests.md +240 -0
- package/.claude/commands/e2e-scaffold.md +212 -0
- package/.claude/commands/explain.md +110 -0
- package/.claude/commands/fix-types.md +238 -0
- package/.claude/commands/refactor.md +184 -0
- package/.claude/commands/review.md +136 -0
- package/.claude/commands/security-check.md +223 -0
- package/.claude/commands/styleguide.md +446 -0
- package/.claude/commands/tdd-feature.md +227 -0
- package/.claude/commands/vibe-check.md +112 -0
- package/.pre-commit-hooks.yaml +77 -0
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/bin/vibe-check.js +19 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +206 -0
- package/dist/cli.js.map +1 -0
- package/dist/eslint-plugin/index.d.ts +66 -0
- package/dist/eslint-plugin/index.d.ts.map +1 -0
- package/dist/eslint-plugin/index.js +67 -0
- package/dist/eslint-plugin/index.js.map +1 -0
- package/dist/eslint-plugin/rules/max-function-length.d.ts +8 -0
- package/dist/eslint-plugin/rules/max-function-length.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/max-function-length.js +69 -0
- package/dist/eslint-plugin/rules/max-function-length.js.map +1 -0
- package/dist/eslint-plugin/rules/no-any-type.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-any-type.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-any-type.js +29 -0
- package/dist/eslint-plugin/rules/no-any-type.js.map +1 -0
- package/dist/eslint-plugin/rules/no-debug-statements.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-debug-statements.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-debug-statements.js +59 -0
- package/dist/eslint-plugin/rules/no-debug-statements.js.map +1 -0
- package/dist/eslint-plugin/rules/no-deep-nesting.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-deep-nesting.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-deep-nesting.js +56 -0
- package/dist/eslint-plugin/rules/no-deep-nesting.js.map +1 -0
- package/dist/eslint-plugin/rules/no-empty-catch.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-empty-catch.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-empty-catch.js +31 -0
- package/dist/eslint-plugin/rules/no-empty-catch.js.map +1 -0
- package/dist/eslint-plugin/rules/no-magic-numbers.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-magic-numbers.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-magic-numbers.js +58 -0
- package/dist/eslint-plugin/rules/no-magic-numbers.js.map +1 -0
- package/dist/eslint-plugin/rules/no-snake-case-props.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-snake-case-props.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-snake-case-props.js +48 -0
- package/dist/eslint-plugin/rules/no-snake-case-props.js.map +1 -0
- package/dist/hooks/check-any-types.d.ts +6 -0
- package/dist/hooks/check-any-types.d.ts.map +1 -0
- package/dist/hooks/check-any-types.js +73 -0
- package/dist/hooks/check-any-types.js.map +1 -0
- package/dist/hooks/check-commented-code.d.ts +6 -0
- package/dist/hooks/check-commented-code.d.ts.map +1 -0
- package/dist/hooks/check-commented-code.js +81 -0
- package/dist/hooks/check-commented-code.js.map +1 -0
- package/dist/hooks/check-console-error.d.ts +6 -0
- package/dist/hooks/check-console-error.d.ts.map +1 -0
- package/dist/hooks/check-console-error.js +41 -0
- package/dist/hooks/check-console-error.js.map +1 -0
- package/dist/hooks/check-debug-statements.d.ts +6 -0
- package/dist/hooks/check-debug-statements.d.ts.map +1 -0
- package/dist/hooks/check-debug-statements.js +120 -0
- package/dist/hooks/check-debug-statements.js.map +1 -0
- package/dist/hooks/check-deep-nesting.d.ts +6 -0
- package/dist/hooks/check-deep-nesting.d.ts.map +1 -0
- package/dist/hooks/check-deep-nesting.js +116 -0
- package/dist/hooks/check-deep-nesting.js.map +1 -0
- package/dist/hooks/check-docker-platform.d.ts +6 -0
- package/dist/hooks/check-docker-platform.d.ts.map +1 -0
- package/dist/hooks/check-docker-platform.js +42 -0
- package/dist/hooks/check-docker-platform.js.map +1 -0
- package/dist/hooks/check-dry-violations.d.ts +6 -0
- package/dist/hooks/check-dry-violations.d.ts.map +1 -0
- package/dist/hooks/check-dry-violations.js +124 -0
- package/dist/hooks/check-dry-violations.js.map +1 -0
- package/dist/hooks/check-empty-catch.d.ts +6 -0
- package/dist/hooks/check-empty-catch.d.ts.map +1 -0
- package/dist/hooks/check-empty-catch.js +111 -0
- package/dist/hooks/check-empty-catch.js.map +1 -0
- package/dist/hooks/check-function-length.d.ts +6 -0
- package/dist/hooks/check-function-length.d.ts.map +1 -0
- package/dist/hooks/check-function-length.js +152 -0
- package/dist/hooks/check-function-length.js.map +1 -0
- package/dist/hooks/check-hardcoded-urls.d.ts +6 -0
- package/dist/hooks/check-hardcoded-urls.d.ts.map +1 -0
- package/dist/hooks/check-hardcoded-urls.js +124 -0
- package/dist/hooks/check-hardcoded-urls.js.map +1 -0
- package/dist/hooks/check-magic-numbers.d.ts +6 -0
- package/dist/hooks/check-magic-numbers.d.ts.map +1 -0
- package/dist/hooks/check-magic-numbers.js +116 -0
- package/dist/hooks/check-magic-numbers.js.map +1 -0
- package/dist/hooks/check-secrets.d.ts +6 -0
- package/dist/hooks/check-secrets.d.ts.map +1 -0
- package/dist/hooks/check-secrets.js +138 -0
- package/dist/hooks/check-secrets.js.map +1 -0
- package/dist/hooks/check-snake-case-ts.d.ts +6 -0
- package/dist/hooks/check-snake-case-ts.d.ts.map +1 -0
- package/dist/hooks/check-snake-case-ts.js +78 -0
- package/dist/hooks/check-snake-case-ts.js.map +1 -0
- package/dist/hooks/check-todo-fixme.d.ts +6 -0
- package/dist/hooks/check-todo-fixme.d.ts.map +1 -0
- package/dist/hooks/check-todo-fixme.js +41 -0
- package/dist/hooks/check-todo-fixme.js.map +1 -0
- package/dist/hooks/check-unsafe-html.d.ts +6 -0
- package/dist/hooks/check-unsafe-html.d.ts.map +1 -0
- package/dist/hooks/check-unsafe-html.js +101 -0
- package/dist/hooks/check-unsafe-html.js.map +1 -0
- package/dist/hooks/index.d.ts +29 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +54 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/lint-staged/config.d.ts +20 -0
- package/dist/lint-staged/config.d.ts.map +1 -0
- package/dist/lint-staged/config.js +27 -0
- package/dist/lint-staged/config.js.map +1 -0
- package/dist/utils/file-reader.d.ts +24 -0
- package/dist/utils/file-reader.d.ts.map +1 -0
- package/dist/utils/file-reader.js +140 -0
- package/dist/utils/file-reader.js.map +1 -0
- package/dist/utils/patterns.d.ts +27 -0
- package/dist/utils/patterns.d.ts.map +1 -0
- package/dist/utils/patterns.js +84 -0
- package/dist/utils/patterns.js.map +1 -0
- package/dist/utils/reporters.d.ts +21 -0
- package/dist/utils/reporters.d.ts.map +1 -0
- package/dist/utils/reporters.js +115 -0
- package/dist/utils/reporters.js.map +1 -0
- package/dist/utils/types.d.ts +71 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +5 -0
- package/dist/utils/types.js.map +1 -0
- package/integrations/cursorrules.template +147 -0
- package/integrations/eslint.config.js +34 -0
- package/integrations/lint-staged.config.js +34 -0
- package/integrations/ruff.toml +125 -0
- package/integrations/vibe-check.yml +116 -0
- package/integrations/vscode-settings.json +127 -0
- package/package.json +81 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for hardcoded URLs that should use environment variables
|
|
3
|
+
*/
|
|
4
|
+
// Common CDN and safe domains to ignore
|
|
5
|
+
const SAFE_DOMAINS = new Set([
|
|
6
|
+
'cdn.jsdelivr.net',
|
|
7
|
+
'cdnjs.cloudflare.com',
|
|
8
|
+
'unpkg.com',
|
|
9
|
+
'fonts.googleapis.com',
|
|
10
|
+
'fonts.gstatic.com',
|
|
11
|
+
'fonts.bunny.net',
|
|
12
|
+
'api.github.com',
|
|
13
|
+
'raw.githubusercontent.com',
|
|
14
|
+
'registry.npmjs.org',
|
|
15
|
+
'pypi.org',
|
|
16
|
+
'schema.org',
|
|
17
|
+
'www.w3.org',
|
|
18
|
+
'example.com',
|
|
19
|
+
'example.org',
|
|
20
|
+
]);
|
|
21
|
+
// Patterns that indicate this is likely test/example code
|
|
22
|
+
const TEST_PATTERNS = [
|
|
23
|
+
/\.test\./,
|
|
24
|
+
/\.spec\./,
|
|
25
|
+
/\/__tests__\//,
|
|
26
|
+
/\/test\//,
|
|
27
|
+
/\/fixtures?\//,
|
|
28
|
+
/\.mock\./,
|
|
29
|
+
];
|
|
30
|
+
export const checkHardcodedUrls = {
|
|
31
|
+
id: 'urls',
|
|
32
|
+
name: 'Check Hardcoded URLs',
|
|
33
|
+
description: 'Detect hardcoded URLs that should use environment variables',
|
|
34
|
+
severity: 'error',
|
|
35
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
|
|
36
|
+
check(context) {
|
|
37
|
+
const results = [];
|
|
38
|
+
const lines = context.content.split('\n');
|
|
39
|
+
// Skip test files
|
|
40
|
+
if (TEST_PATTERNS.some((p) => p.test(context.filePath))) {
|
|
41
|
+
return results;
|
|
42
|
+
}
|
|
43
|
+
for (let i = 0; i < lines.length; i++) {
|
|
44
|
+
const line = lines[i];
|
|
45
|
+
const lineNum = i + 1;
|
|
46
|
+
// Skip comments
|
|
47
|
+
if (isCommentLine(line, context.extension)) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Check for localhost URLs
|
|
51
|
+
const localhostMatches = line.matchAll(/https?:\/\/localhost(?::\d+)?(?:\/[^\s'")\]]*)?/g);
|
|
52
|
+
for (const match of localhostMatches) {
|
|
53
|
+
// Skip if in a fallback/default pattern
|
|
54
|
+
if (isFallbackPattern(line, match.index || 0)) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
results.push({
|
|
58
|
+
line: lineNum,
|
|
59
|
+
column: match.index || 0,
|
|
60
|
+
message: 'Hardcoded localhost URL - use environment variable',
|
|
61
|
+
severity: 'warning',
|
|
62
|
+
ruleId: 'urls/localhost',
|
|
63
|
+
fix: 'Use process.env.API_URL or similar',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// Check for 127.0.0.1 URLs
|
|
67
|
+
const ipMatches = line.matchAll(/https?:\/\/127\.0\.0\.1(?::\d+)?(?:\/[^\s'")\]]*)?/g);
|
|
68
|
+
for (const match of ipMatches) {
|
|
69
|
+
if (isFallbackPattern(line, match.index || 0)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
results.push({
|
|
73
|
+
line: lineNum,
|
|
74
|
+
column: match.index || 0,
|
|
75
|
+
message: 'Hardcoded localhost IP - use environment variable',
|
|
76
|
+
severity: 'warning',
|
|
77
|
+
ruleId: 'urls/localhost-ip',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// Check for production URLs
|
|
81
|
+
const urlMatches = line.matchAll(/https?:\/\/([a-zA-Z0-9][a-zA-Z0-9-]*\.[a-zA-Z]{2,}(?:\.[a-zA-Z]{2,})?)(?::\d+)?(?:\/[^\s'")\]]*)?/g);
|
|
82
|
+
for (const match of urlMatches) {
|
|
83
|
+
const domain = match[1].toLowerCase();
|
|
84
|
+
// Skip safe domains
|
|
85
|
+
if (SAFE_DOMAINS.has(domain)) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
// Skip if in a fallback pattern
|
|
89
|
+
if (isFallbackPattern(line, match.index || 0)) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
// Skip common documentation/example patterns
|
|
93
|
+
if (domain.includes('example') || domain.includes('placeholder')) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
// Flag as potential hardcoded production URL
|
|
97
|
+
results.push({
|
|
98
|
+
line: lineNum,
|
|
99
|
+
column: match.index || 0,
|
|
100
|
+
message: `Hardcoded URL (${domain}) - consider using environment variable`,
|
|
101
|
+
severity: 'warning',
|
|
102
|
+
ruleId: 'urls/hardcoded',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return results;
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
function isCommentLine(line, extension) {
|
|
110
|
+
const trimmed = line.trim();
|
|
111
|
+
if (['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'].includes(extension)) {
|
|
112
|
+
return trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*');
|
|
113
|
+
}
|
|
114
|
+
if (['py', 'pyw'].includes(extension)) {
|
|
115
|
+
return trimmed.startsWith('#');
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
function isFallbackPattern(line, urlIndex) {
|
|
120
|
+
// Check if URL appears after || or ?? or as a default value
|
|
121
|
+
const before = line.substring(0, urlIndex);
|
|
122
|
+
return /(\|\||\?\?|:\s*$|,\s*$|=\s*$|default[:\s]*$)/i.test(before.trim());
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=check-hardcoded-urls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-hardcoded-urls.js","sourceRoot":"","sources":["../../src/hooks/check-hardcoded-urls.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-magic-numbers.d.ts","sourceRoot":"","sources":["../../src/hooks/check-magic-numbers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AA0CvE,eAAO,MAAM,iBAAiB,EAAE,IAkE/B,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for magic numbers that should be named constants
|
|
3
|
+
*/
|
|
4
|
+
// Numbers that are commonly acceptable and don't need constants
|
|
5
|
+
const ACCEPTABLE_NUMBERS = new Set([
|
|
6
|
+
-1, 0, 1, 2, 10, 100, 1000,
|
|
7
|
+
// Common time values
|
|
8
|
+
60, 1000, 3600, 86400,
|
|
9
|
+
// Array/string indices
|
|
10
|
+
0, 1, 2,
|
|
11
|
+
]);
|
|
12
|
+
// Contexts where magic numbers are acceptable
|
|
13
|
+
const ACCEPTABLE_CONTEXTS = [
|
|
14
|
+
/\.length\s*[<>=!]/, // array length comparisons
|
|
15
|
+
/\[\s*\d+\s*\]/, // array indexing
|
|
16
|
+
/slice\s*\(\s*\d+/, // slice operations
|
|
17
|
+
/substring\s*\(\s*\d+/, // substring operations
|
|
18
|
+
/repeat\s*\(\s*\d+/, // repeat operations
|
|
19
|
+
/^\s*(?:return|throw)\s+\d+/, // return/throw numeric values
|
|
20
|
+
/port\s*[:=]/i, // port numbers
|
|
21
|
+
/\.toFixed\s*\(\s*\d+/, // decimal places
|
|
22
|
+
/Math\./, // Math operations
|
|
23
|
+
/parseInt|parseFloat/, // parsing functions
|
|
24
|
+
/0x[0-9a-fA-F]+/, // hex numbers (color codes, etc.)
|
|
25
|
+
/rgba?\s*\(/, // CSS colors
|
|
26
|
+
/version/i, // version numbers
|
|
27
|
+
/new Date\(/, // date constructors
|
|
28
|
+
/setTimeout|setInterval/, // timer functions (often have inline ms)
|
|
29
|
+
/padding|margin|width|height/i, // CSS-related
|
|
30
|
+
];
|
|
31
|
+
// Paths that indicate frontend component files (skip these)
|
|
32
|
+
const FRONTEND_PATH_PATTERNS = [
|
|
33
|
+
/\/components\//i,
|
|
34
|
+
/\/pages\//i,
|
|
35
|
+
/\/views\//i,
|
|
36
|
+
/\/layouts\//i,
|
|
37
|
+
/\/ui\//i,
|
|
38
|
+
/\.styled\./i,
|
|
39
|
+
/\.styles\./i,
|
|
40
|
+
];
|
|
41
|
+
export const checkMagicNumbers = {
|
|
42
|
+
id: 'magic-numbers',
|
|
43
|
+
name: 'Check Magic Numbers',
|
|
44
|
+
description: 'Detect magic numbers that should be named constants',
|
|
45
|
+
severity: 'warning',
|
|
46
|
+
// Skip JSX/TSX - too many false positives with CSS values
|
|
47
|
+
fileTypes: ['js', 'ts', 'mjs', 'cjs', 'py'],
|
|
48
|
+
check(context) {
|
|
49
|
+
const results = [];
|
|
50
|
+
// Skip frontend component files even if they're .js/.ts
|
|
51
|
+
if (FRONTEND_PATH_PATTERNS.some((pattern) => pattern.test(context.filePath))) {
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
54
|
+
const lines = context.content.split('\n');
|
|
55
|
+
for (let i = 0; i < lines.length; i++) {
|
|
56
|
+
const line = lines[i];
|
|
57
|
+
const lineNum = i + 1;
|
|
58
|
+
// Skip comments
|
|
59
|
+
if (isCommentLine(line, context.extension)) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// Skip constant/variable declarations with descriptive names
|
|
63
|
+
if (isConstantDeclaration(line)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
// Find all numbers in the line
|
|
67
|
+
const numberMatches = line.matchAll(/(?<![a-zA-Z_])(-?\d+(?:\.\d+)?)\b/g);
|
|
68
|
+
for (const match of numberMatches) {
|
|
69
|
+
const numStr = match[1];
|
|
70
|
+
const num = parseFloat(numStr);
|
|
71
|
+
// Skip acceptable numbers
|
|
72
|
+
if (ACCEPTABLE_NUMBERS.has(num)) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
// Skip if in acceptable context
|
|
76
|
+
if (ACCEPTABLE_CONTEXTS.some((pattern) => pattern.test(line))) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
// Skip very small numbers (likely not magic)
|
|
80
|
+
if (num >= -10 && num <= 10 && Number.isInteger(num)) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
results.push({
|
|
84
|
+
line: lineNum,
|
|
85
|
+
column: match.index || 0,
|
|
86
|
+
message: `Magic number ${numStr} - consider using a named constant`,
|
|
87
|
+
severity: 'warning',
|
|
88
|
+
ruleId: 'magic-numbers/unnamed',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return results;
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
function isCommentLine(line, extension) {
|
|
96
|
+
const trimmed = line.trim();
|
|
97
|
+
if (['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'].includes(extension)) {
|
|
98
|
+
return trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*');
|
|
99
|
+
}
|
|
100
|
+
if (['py', 'pyw'].includes(extension)) {
|
|
101
|
+
return trimmed.startsWith('#');
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
function isConstantDeclaration(line) {
|
|
106
|
+
// JavaScript/TypeScript const with UPPER_CASE name
|
|
107
|
+
if (/const\s+[A-Z][A-Z0-9_]+\s*=/.test(line)) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
// Python uppercase variable (convention for constants)
|
|
111
|
+
if (/^[A-Z][A-Z0-9_]+\s*=/.test(line.trim())) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=check-magic-numbers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-magic-numbers.js","sourceRoot":"","sources":["../../src/hooks/check-magic-numbers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-secrets.d.ts","sourceRoot":"","sources":["../../src/hooks/check-secrets.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAGvE,eAAO,MAAM,YAAY,EAAE,IAkI1B,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for hardcoded secrets, API keys, and tokens
|
|
3
|
+
*/
|
|
4
|
+
import { SECRET_PATTERNS, isPlaceholder } from '../utils/patterns.js';
|
|
5
|
+
export const checkSecrets = {
|
|
6
|
+
id: 'secrets',
|
|
7
|
+
name: 'Check Secrets',
|
|
8
|
+
description: 'Detect hardcoded API keys, passwords, and tokens',
|
|
9
|
+
severity: 'error',
|
|
10
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py', 'json', 'yaml', 'yml', 'toml', 'env'],
|
|
11
|
+
check(context) {
|
|
12
|
+
const results = [];
|
|
13
|
+
const lines = context.content.split('\n');
|
|
14
|
+
for (let i = 0; i < lines.length; i++) {
|
|
15
|
+
const line = lines[i];
|
|
16
|
+
const lineNum = i + 1;
|
|
17
|
+
// Skip comments
|
|
18
|
+
if (isCommentLine(line, context.extension)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
// AWS Access Key
|
|
22
|
+
const awsMatch = line.match(SECRET_PATTERNS.awsAccessKey);
|
|
23
|
+
if (awsMatch && !isPlaceholder(awsMatch[0])) {
|
|
24
|
+
results.push({
|
|
25
|
+
line: lineNum,
|
|
26
|
+
column: line.indexOf(awsMatch[0]),
|
|
27
|
+
message: 'Possible AWS Access Key detected',
|
|
28
|
+
severity: 'error',
|
|
29
|
+
ruleId: 'secrets/aws-key',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// Stripe Key
|
|
33
|
+
const stripeMatch = line.match(SECRET_PATTERNS.stripeKey);
|
|
34
|
+
if (stripeMatch && !isPlaceholder(stripeMatch[0])) {
|
|
35
|
+
results.push({
|
|
36
|
+
line: lineNum,
|
|
37
|
+
column: line.indexOf(stripeMatch[0]),
|
|
38
|
+
message: 'Stripe API key detected',
|
|
39
|
+
severity: 'error',
|
|
40
|
+
ruleId: 'secrets/stripe-key',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// GitHub Token
|
|
44
|
+
const githubMatch = line.match(SECRET_PATTERNS.githubToken);
|
|
45
|
+
if (githubMatch && !isPlaceholder(githubMatch[0])) {
|
|
46
|
+
results.push({
|
|
47
|
+
line: lineNum,
|
|
48
|
+
column: line.indexOf(githubMatch[0]),
|
|
49
|
+
message: 'GitHub token detected',
|
|
50
|
+
severity: 'error',
|
|
51
|
+
ruleId: 'secrets/github-token',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Slack Token
|
|
55
|
+
const slackMatch = line.match(SECRET_PATTERNS.slackToken);
|
|
56
|
+
if (slackMatch && !isPlaceholder(slackMatch[0])) {
|
|
57
|
+
results.push({
|
|
58
|
+
line: lineNum,
|
|
59
|
+
column: line.indexOf(slackMatch[0]),
|
|
60
|
+
message: 'Slack token detected',
|
|
61
|
+
severity: 'error',
|
|
62
|
+
ruleId: 'secrets/slack-token',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// SendGrid Key
|
|
66
|
+
const sendgridMatch = line.match(SECRET_PATTERNS.sendgridKey);
|
|
67
|
+
if (sendgridMatch && !isPlaceholder(sendgridMatch[0])) {
|
|
68
|
+
results.push({
|
|
69
|
+
line: lineNum,
|
|
70
|
+
column: line.indexOf(sendgridMatch[0]),
|
|
71
|
+
message: 'SendGrid API key detected',
|
|
72
|
+
severity: 'error',
|
|
73
|
+
ruleId: 'secrets/sendgrid-key',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Private Key
|
|
77
|
+
if (SECRET_PATTERNS.privateKey.test(line)) {
|
|
78
|
+
results.push({
|
|
79
|
+
line: lineNum,
|
|
80
|
+
column: 0,
|
|
81
|
+
message: 'Private key detected - never commit private keys',
|
|
82
|
+
severity: 'error',
|
|
83
|
+
ruleId: 'secrets/private-key',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// Generic API key patterns
|
|
87
|
+
const genericApiMatch = line.match(SECRET_PATTERNS.genericApiKey);
|
|
88
|
+
if (genericApiMatch && !isPlaceholder(genericApiMatch[0])) {
|
|
89
|
+
// Only flag if it looks like a real key (long enough, not a placeholder)
|
|
90
|
+
const value = genericApiMatch[0];
|
|
91
|
+
if (value.length > 30) {
|
|
92
|
+
results.push({
|
|
93
|
+
line: lineNum,
|
|
94
|
+
column: line.indexOf(value),
|
|
95
|
+
message: 'Possible hardcoded API key - use environment variables',
|
|
96
|
+
severity: 'error',
|
|
97
|
+
ruleId: 'secrets/generic-api-key',
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Generic secrets (password, token, etc.)
|
|
102
|
+
const secretMatch = line.match(SECRET_PATTERNS.genericSecret);
|
|
103
|
+
if (secretMatch && !isPlaceholder(secretMatch[0])) {
|
|
104
|
+
// Skip obvious non-secrets
|
|
105
|
+
const value = secretMatch[0].toLowerCase();
|
|
106
|
+
if (!value.includes('password:') && // Not a type annotation
|
|
107
|
+
!value.includes('password =') && // Assignment with placeholder
|
|
108
|
+
value.length > 20) {
|
|
109
|
+
results.push({
|
|
110
|
+
line: lineNum,
|
|
111
|
+
column: line.indexOf(secretMatch[0]),
|
|
112
|
+
message: 'Possible hardcoded secret - use environment variables',
|
|
113
|
+
severity: 'warning',
|
|
114
|
+
ruleId: 'secrets/generic-secret',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return results;
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
function isCommentLine(line, extension) {
|
|
123
|
+
const trimmed = line.trim();
|
|
124
|
+
// JavaScript/TypeScript style comments
|
|
125
|
+
if (['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'].includes(extension)) {
|
|
126
|
+
return trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*');
|
|
127
|
+
}
|
|
128
|
+
// Python style comments
|
|
129
|
+
if (['py', 'pyw'].includes(extension)) {
|
|
130
|
+
return trimmed.startsWith('#');
|
|
131
|
+
}
|
|
132
|
+
// YAML style comments
|
|
133
|
+
if (['yaml', 'yml'].includes(extension)) {
|
|
134
|
+
return trimmed.startsWith('#');
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=check-secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-secrets.js","sourceRoot":"","sources":["../../src/hooks/check-secrets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-snake-case-ts.d.ts","sourceRoot":"","sources":["../../src/hooks/check-snake-case-ts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,gBAAgB,EAAE,IAmF9B,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for snake_case property names in TypeScript interfaces/types
|
|
3
|
+
*/
|
|
4
|
+
export const checkSnakeCaseTs = {
|
|
5
|
+
id: 'snake-case',
|
|
6
|
+
name: 'Check Snake Case',
|
|
7
|
+
description: 'Detect snake_case properties in TypeScript that should be camelCase',
|
|
8
|
+
severity: 'warning',
|
|
9
|
+
fileTypes: ['ts', 'tsx', 'mts', 'cts'],
|
|
10
|
+
check(context) {
|
|
11
|
+
const results = [];
|
|
12
|
+
const lines = context.content.split('\n');
|
|
13
|
+
// Track if we're inside an interface or type definition
|
|
14
|
+
let inInterfaceOrType = false;
|
|
15
|
+
let braceDepth = 0;
|
|
16
|
+
for (let i = 0; i < lines.length; i++) {
|
|
17
|
+
const line = lines[i];
|
|
18
|
+
const lineNum = i + 1;
|
|
19
|
+
// Skip comments
|
|
20
|
+
if (line.trim().startsWith('//') || line.trim().startsWith('*')) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
// Detect interface or type start
|
|
24
|
+
if (/^\s*(?:export\s+)?(?:interface|type)\s+\w+/.test(line)) {
|
|
25
|
+
inInterfaceOrType = true;
|
|
26
|
+
braceDepth = 0;
|
|
27
|
+
}
|
|
28
|
+
// Track brace depth
|
|
29
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
30
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
31
|
+
if (inInterfaceOrType) {
|
|
32
|
+
braceDepth += openBraces - closeBraces;
|
|
33
|
+
// Check for snake_case properties
|
|
34
|
+
// Match property names in interface/type definitions
|
|
35
|
+
const propertyMatch = line.match(/^\s*['"]?([a-z][a-z0-9]*(?:_[a-z0-9]+)+)['"]?\s*[?]?\s*:/);
|
|
36
|
+
if (propertyMatch) {
|
|
37
|
+
const propertyName = propertyMatch[1];
|
|
38
|
+
const suggestedName = toCamelCase(propertyName);
|
|
39
|
+
results.push({
|
|
40
|
+
line: lineNum,
|
|
41
|
+
column: line.indexOf(propertyName),
|
|
42
|
+
message: `Property "${propertyName}" uses snake_case - consider using camelCase "${suggestedName}"`,
|
|
43
|
+
severity: 'warning',
|
|
44
|
+
ruleId: 'snake-case/property',
|
|
45
|
+
fix: suggestedName,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// End of interface/type
|
|
49
|
+
if (braceDepth <= 0 && closeBraces > 0) {
|
|
50
|
+
inInterfaceOrType = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Also check for snake_case in object destructuring from API responses
|
|
54
|
+
// This is a common issue when copying from API response types
|
|
55
|
+
const destructMatch = line.match(/const\s*\{\s*([^}]+)\s*\}\s*=/);
|
|
56
|
+
if (destructMatch) {
|
|
57
|
+
const props = destructMatch[1].split(',');
|
|
58
|
+
for (const prop of props) {
|
|
59
|
+
const propName = prop.trim().split(':')[0].trim();
|
|
60
|
+
if (/^[a-z][a-z0-9]*(?:_[a-z0-9]+)+$/.test(propName)) {
|
|
61
|
+
results.push({
|
|
62
|
+
line: lineNum,
|
|
63
|
+
column: line.indexOf(propName),
|
|
64
|
+
message: `Destructured property "${propName}" uses snake_case - API response may need transformation`,
|
|
65
|
+
severity: 'info',
|
|
66
|
+
ruleId: 'snake-case/destructure',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return results;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
function toCamelCase(snakeCase) {
|
|
76
|
+
return snakeCase.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=check-snake-case-ts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-snake-case-ts.js","sourceRoot":"","sources":["../../src/hooks/check-snake-case-ts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-todo-fixme.d.ts","sourceRoot":"","sources":["../../src/hooks/check-todo-fixme.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAKvE,eAAO,MAAM,cAAc,EAAE,IAwC5B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for TODO/FIXME comments that indicate incomplete work
|
|
3
|
+
*/
|
|
4
|
+
// Patterns to match TODO/FIXME comments
|
|
5
|
+
const TODO_PATTERN = /\b(TODO|FIXME|XXX|HACK|BUG|OPTIMIZE)\b[:\s]*(.*)/i;
|
|
6
|
+
export const checkTodoFixme = {
|
|
7
|
+
id: 'todo',
|
|
8
|
+
name: 'Check TODO/FIXME',
|
|
9
|
+
description: 'Detect TODO, FIXME, and other incomplete work markers',
|
|
10
|
+
severity: 'info',
|
|
11
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py', 'html', 'css'],
|
|
12
|
+
check(context) {
|
|
13
|
+
const results = [];
|
|
14
|
+
const lines = context.content.split('\n');
|
|
15
|
+
for (let i = 0; i < lines.length; i++) {
|
|
16
|
+
const line = lines[i];
|
|
17
|
+
const lineNum = i + 1;
|
|
18
|
+
const match = line.match(TODO_PATTERN);
|
|
19
|
+
if (match) {
|
|
20
|
+
const type = match[1].toUpperCase();
|
|
21
|
+
const description = match[2]?.trim() || '';
|
|
22
|
+
// Determine severity based on type
|
|
23
|
+
let severity = 'info';
|
|
24
|
+
if (type === 'FIXME' || type === 'BUG') {
|
|
25
|
+
severity = 'warning';
|
|
26
|
+
}
|
|
27
|
+
results.push({
|
|
28
|
+
line: lineNum,
|
|
29
|
+
column: line.indexOf(match[0]),
|
|
30
|
+
message: description
|
|
31
|
+
? `${type}: ${description}`
|
|
32
|
+
: `${type} marker without description`,
|
|
33
|
+
severity,
|
|
34
|
+
ruleId: `todo/${type.toLowerCase()}`,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return results;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=check-todo-fixme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-todo-fixme.js","sourceRoot":"","sources":["../../src/hooks/check-todo-fixme.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wCAAwC;AACxC,MAAM,YAAY,GAAG,mDAAmD,CAAC;AAEzE,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,uDAAuD;IACpE,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC;IAExE,KAAK,CAAC,OAAoB;QACxB,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YAEtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACvC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;gBACpC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBAE3C,mCAAmC;gBACnC,IAAI,QAAQ,GAAuB,MAAM,CAAC;gBAC1C,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;oBACvC,QAAQ,GAAG,SAAS,CAAC;gBACvB,CAAC;gBAED,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC9B,OAAO,EAAE,WAAW;wBAClB,CAAC,CAAC,GAAG,IAAI,KAAK,WAAW,EAAE;wBAC3B,CAAC,CAAC,GAAG,IAAI,6BAA6B;oBACxC,QAAQ;oBACR,MAAM,EAAE,QAAQ,IAAI,CAAC,WAAW,EAAE,EAAE;iBACrC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-unsafe-html.d.ts","sourceRoot":"","sources":["../../src/hooks/check-unsafe-html.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,eAAe,EAAE,IA6G7B,CAAC"}
|