agentic-loop 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/explain.md +114 -0
- package/.claude/commands/idea.md +398 -0
- package/.claude/commands/my-dna.md +122 -0
- package/.claude/commands/prd.md +286 -0
- package/.claude/commands/review.md +167 -0
- package/.claude/commands/sign.md +32 -0
- package/.claude/commands/styleguide.md +450 -0
- package/.claude/commands/tour.md +301 -0
- package/.claude/commands/vibe-check.md +116 -0
- package/.claude/commands/vibe-help.md +47 -0
- package/.claude/commands/vibe-list.md +203 -0
- package/.pre-commit-hooks.yaml +102 -0
- package/LICENSE +21 -0
- package/README.md +238 -0
- package/bin/agentic-loop.sh +24 -0
- package/bin/postinstall.sh +29 -0
- package/bin/ralph.sh +171 -0
- package/bin/vibe-check.js +19 -0
- package/dist/checks/check-any-types.d.ts +6 -0
- package/dist/checks/check-any-types.d.ts.map +1 -0
- package/dist/checks/check-any-types.js +73 -0
- package/dist/checks/check-any-types.js.map +1 -0
- package/dist/checks/check-commented-code.d.ts +6 -0
- package/dist/checks/check-commented-code.d.ts.map +1 -0
- package/dist/checks/check-commented-code.js +81 -0
- package/dist/checks/check-commented-code.js.map +1 -0
- package/dist/checks/check-console-error.d.ts +6 -0
- package/dist/checks/check-console-error.d.ts.map +1 -0
- package/dist/checks/check-console-error.js +41 -0
- package/dist/checks/check-console-error.js.map +1 -0
- package/dist/checks/check-debug-statements.d.ts +6 -0
- package/dist/checks/check-debug-statements.d.ts.map +1 -0
- package/dist/checks/check-debug-statements.js +120 -0
- package/dist/checks/check-debug-statements.js.map +1 -0
- package/dist/checks/check-deep-nesting.d.ts +6 -0
- package/dist/checks/check-deep-nesting.d.ts.map +1 -0
- package/dist/checks/check-deep-nesting.js +116 -0
- package/dist/checks/check-deep-nesting.js.map +1 -0
- package/dist/checks/check-docker-platform.d.ts +6 -0
- package/dist/checks/check-docker-platform.d.ts.map +1 -0
- package/dist/checks/check-docker-platform.js +42 -0
- package/dist/checks/check-docker-platform.js.map +1 -0
- package/dist/checks/check-dry-violations.d.ts +6 -0
- package/dist/checks/check-dry-violations.d.ts.map +1 -0
- package/dist/checks/check-dry-violations.js +124 -0
- package/dist/checks/check-dry-violations.js.map +1 -0
- package/dist/checks/check-empty-catch.d.ts +6 -0
- package/dist/checks/check-empty-catch.d.ts.map +1 -0
- package/dist/checks/check-empty-catch.js +111 -0
- package/dist/checks/check-empty-catch.js.map +1 -0
- package/dist/checks/check-function-length.d.ts +6 -0
- package/dist/checks/check-function-length.d.ts.map +1 -0
- package/dist/checks/check-function-length.js +152 -0
- package/dist/checks/check-function-length.js.map +1 -0
- package/dist/checks/check-hardcoded-ai-models.d.ts +10 -0
- package/dist/checks/check-hardcoded-ai-models.d.ts.map +1 -0
- package/dist/checks/check-hardcoded-ai-models.js +102 -0
- package/dist/checks/check-hardcoded-ai-models.js.map +1 -0
- package/dist/checks/check-hardcoded-urls.d.ts +6 -0
- package/dist/checks/check-hardcoded-urls.d.ts.map +1 -0
- package/dist/checks/check-hardcoded-urls.js +124 -0
- package/dist/checks/check-hardcoded-urls.js.map +1 -0
- package/dist/checks/check-magic-numbers.d.ts +6 -0
- package/dist/checks/check-magic-numbers.d.ts.map +1 -0
- package/dist/checks/check-magic-numbers.js +116 -0
- package/dist/checks/check-magic-numbers.js.map +1 -0
- package/dist/checks/check-secrets.d.ts +6 -0
- package/dist/checks/check-secrets.d.ts.map +1 -0
- package/dist/checks/check-secrets.js +138 -0
- package/dist/checks/check-secrets.js.map +1 -0
- package/dist/checks/check-snake-case-ts.d.ts +6 -0
- package/dist/checks/check-snake-case-ts.d.ts.map +1 -0
- package/dist/checks/check-snake-case-ts.js +78 -0
- package/dist/checks/check-snake-case-ts.js.map +1 -0
- package/dist/checks/check-todo-fixme.d.ts +6 -0
- package/dist/checks/check-todo-fixme.d.ts.map +1 -0
- package/dist/checks/check-todo-fixme.js +41 -0
- package/dist/checks/check-todo-fixme.js.map +1 -0
- package/dist/checks/check-unsafe-html.d.ts +6 -0
- package/dist/checks/check-unsafe-html.d.ts.map +1 -0
- package/dist/checks/check-unsafe-html.js +101 -0
- package/dist/checks/check-unsafe-html.js.map +1 -0
- package/dist/checks/index.d.ts +30 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +57 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +208 -0
- package/dist/cli.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/utils/file-reader.d.ts +24 -0
- package/dist/utils/file-reader.d.ts.map +1 -0
- package/dist/utils/file-reader.js +146 -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/package.json +83 -0
- package/ralph/api.sh +216 -0
- package/ralph/backup.sh +838 -0
- package/ralph/browser-verify/README.md +135 -0
- package/ralph/browser-verify/verify.ts +450 -0
- package/ralph/checks/check-fastapi-responses.py +155 -0
- package/ralph/hooks/hooks-config.json +72 -0
- package/ralph/hooks/inject-context.sh +44 -0
- package/ralph/hooks/install.sh +207 -0
- package/ralph/hooks/log-tools.sh +45 -0
- package/ralph/hooks/protect-prd.sh +27 -0
- package/ralph/hooks/save-learnings.sh +36 -0
- package/ralph/hooks/warn-debug.sh +54 -0
- package/ralph/hooks/warn-empty-catch.sh +63 -0
- package/ralph/hooks/warn-secrets.sh +89 -0
- package/ralph/hooks/warn-urls.sh +77 -0
- package/ralph/init.sh +515 -0
- package/ralph/loop.sh +730 -0
- package/ralph/playwright.sh +238 -0
- package/ralph/prd.sh +295 -0
- package/ralph/setup/feature-tour.sh +155 -0
- package/ralph/setup/quick-setup.sh +239 -0
- package/ralph/setup/tutorial.sh +159 -0
- package/ralph/setup/ui.sh +136 -0
- package/ralph/setup.sh +401 -0
- package/ralph/signs.sh +150 -0
- package/ralph/utils.sh +682 -0
- package/ralph/verify/browser.sh +324 -0
- package/ralph/verify/lint.sh +363 -0
- package/ralph/verify/review.sh +152 -0
- package/ralph/verify/tests.sh +81 -0
- package/ralph/verify.sh +268 -0
- package/templates/PROMPT.md +235 -0
- package/templates/config/fullstack.json +86 -0
- package/templates/config/go.json +81 -0
- package/templates/config/minimal.json +76 -0
- package/templates/config/node.json +81 -0
- package/templates/config/python.json +81 -0
- package/templates/config/rust.json +81 -0
- package/templates/examples/CLAUDE-django.md +174 -0
- package/templates/examples/CLAUDE-fastapi.md +270 -0
- package/templates/examples/CLAUDE-fastmcp.md +352 -0
- package/templates/examples/CLAUDE-fullstack.md +256 -0
- package/templates/examples/CLAUDE-node.md +246 -0
- package/templates/examples/CLAUDE-react.md +138 -0
- package/templates/optional/cursorrules.template +147 -0
- package/templates/optional/eslint.config.js +34 -0
- package/templates/optional/lint-staged.config.js +34 -0
- package/templates/optional/ruff.toml +125 -0
- package/templates/optional/vibe-check.yml +116 -0
- package/templates/optional/vscode-settings.json +127 -0
- package/templates/signs.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-dry-violations.js","sourceRoot":"","sources":["../../src/checks/check-dry-violations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-empty-catch.d.ts","sourceRoot":"","sources":["../../src/checks/check-empty-catch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,eAAe,EAAE,IAoB7B,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for empty catch blocks that silently swallow errors
|
|
3
|
+
*/
|
|
4
|
+
export const checkEmptyCatch = {
|
|
5
|
+
id: 'empty-catch',
|
|
6
|
+
name: 'Check Empty Catch',
|
|
7
|
+
description: 'Detect empty catch blocks that silently swallow errors',
|
|
8
|
+
severity: 'warning',
|
|
9
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
|
|
10
|
+
check(context) {
|
|
11
|
+
const results = [];
|
|
12
|
+
const lines = context.content.split('\n');
|
|
13
|
+
const language = getLanguage(context.extension);
|
|
14
|
+
if (language === 'javascript' || language === 'typescript') {
|
|
15
|
+
results.push(...checkJavaScriptCatch(lines));
|
|
16
|
+
}
|
|
17
|
+
else if (language === 'python') {
|
|
18
|
+
results.push(...checkPythonCatch(lines));
|
|
19
|
+
}
|
|
20
|
+
return results;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
function getLanguage(ext) {
|
|
24
|
+
if (['js', 'jsx', 'mjs', 'cjs'].includes(ext))
|
|
25
|
+
return 'javascript';
|
|
26
|
+
if (['ts', 'tsx', 'mts', 'cts'].includes(ext))
|
|
27
|
+
return 'typescript';
|
|
28
|
+
if (['py', 'pyw'].includes(ext))
|
|
29
|
+
return 'python';
|
|
30
|
+
return 'unknown';
|
|
31
|
+
}
|
|
32
|
+
function checkJavaScriptCatch(lines) {
|
|
33
|
+
const results = [];
|
|
34
|
+
const content = lines.join('\n');
|
|
35
|
+
// Pattern: catch block with empty body or just whitespace/comments
|
|
36
|
+
// Matches: catch (e) { } or catch { } or catch(error) { /* comment */ }
|
|
37
|
+
const catchPattern = /catch\s*\([^)]*\)\s*\{\s*(?:\/\/[^\n]*\n?\s*|\/\*[\s\S]*?\*\/\s*)?\}/g;
|
|
38
|
+
let match;
|
|
39
|
+
while ((match = catchPattern.exec(content)) !== null) {
|
|
40
|
+
// Find line number
|
|
41
|
+
const beforeMatch = content.substring(0, match.index);
|
|
42
|
+
const lineNum = beforeMatch.split('\n').length;
|
|
43
|
+
results.push({
|
|
44
|
+
line: lineNum,
|
|
45
|
+
column: 0,
|
|
46
|
+
message: 'Empty catch block - handle or rethrow the error',
|
|
47
|
+
severity: 'warning',
|
|
48
|
+
ruleId: 'empty-catch/js',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// Also check for catch without body content (single line)
|
|
52
|
+
for (let i = 0; i < lines.length; i++) {
|
|
53
|
+
const line = lines[i];
|
|
54
|
+
// Pattern: catch (e) {} on single line
|
|
55
|
+
if (/catch\s*\([^)]*\)\s*\{\s*\}/.test(line)) {
|
|
56
|
+
// Avoid duplicates from the multi-line check
|
|
57
|
+
if (!results.some((r) => r.line === i + 1)) {
|
|
58
|
+
results.push({
|
|
59
|
+
line: i + 1,
|
|
60
|
+
column: line.indexOf('catch'),
|
|
61
|
+
message: 'Empty catch block - handle or rethrow the error',
|
|
62
|
+
severity: 'warning',
|
|
63
|
+
ruleId: 'empty-catch/js',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return results;
|
|
69
|
+
}
|
|
70
|
+
function checkPythonCatch(lines) {
|
|
71
|
+
const results = [];
|
|
72
|
+
for (let i = 0; i < lines.length; i++) {
|
|
73
|
+
const line = lines[i];
|
|
74
|
+
const lineNum = i + 1;
|
|
75
|
+
// Look for except: or except Exception: etc.
|
|
76
|
+
if (/^\s*except\s*(?:\w+(?:\s+as\s+\w+)?)?:\s*$/.test(line)) {
|
|
77
|
+
// Check next non-empty line
|
|
78
|
+
let nextLineIndex = i + 1;
|
|
79
|
+
while (nextLineIndex < lines.length) {
|
|
80
|
+
const nextLine = lines[nextLineIndex].trim();
|
|
81
|
+
if (nextLine === '') {
|
|
82
|
+
nextLineIndex++;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
// Check if it's just 'pass' or a comment
|
|
86
|
+
if (nextLine === 'pass' || nextLine.startsWith('#')) {
|
|
87
|
+
results.push({
|
|
88
|
+
line: lineNum,
|
|
89
|
+
column: 0,
|
|
90
|
+
message: 'Empty except block - handle or reraise the exception',
|
|
91
|
+
severity: 'warning',
|
|
92
|
+
ruleId: 'empty-catch/py',
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Also catch bare except: pass on same or adjacent line
|
|
99
|
+
if (/except.*:\s*pass\s*$/.test(line)) {
|
|
100
|
+
results.push({
|
|
101
|
+
line: lineNum,
|
|
102
|
+
column: line.indexOf('except'),
|
|
103
|
+
message: 'Empty except block - handle or reraise the exception',
|
|
104
|
+
severity: 'warning',
|
|
105
|
+
ruleId: 'empty-catch/py',
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return results;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=check-empty-catch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-empty-catch.js","sourceRoot":"","sources":["../../src/checks/check-empty-catch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-function-length.d.ts","sourceRoot":"","sources":["../../src/checks/check-function-length.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAIvE,eAAO,MAAM,mBAAmB,EAAE,IAmBjC,CAAC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for functions that are too long
|
|
3
|
+
*/
|
|
4
|
+
const MAX_FUNCTION_LENGTH = 150; // lines
|
|
5
|
+
export const checkFunctionLength = {
|
|
6
|
+
id: 'function-length',
|
|
7
|
+
name: 'Check Function Length',
|
|
8
|
+
description: 'Detect functions that are too long and should be refactored',
|
|
9
|
+
severity: 'warning',
|
|
10
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
|
|
11
|
+
check(context) {
|
|
12
|
+
const results = [];
|
|
13
|
+
const language = getLanguage(context.extension);
|
|
14
|
+
if (language === 'javascript' || language === 'typescript') {
|
|
15
|
+
results.push(...checkJavaScriptFunctions(context.content));
|
|
16
|
+
}
|
|
17
|
+
else if (language === 'python') {
|
|
18
|
+
results.push(...checkPythonFunctions(context.content));
|
|
19
|
+
}
|
|
20
|
+
return results;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
function getLanguage(ext) {
|
|
24
|
+
if (['js', 'jsx', 'mjs', 'cjs'].includes(ext))
|
|
25
|
+
return 'javascript';
|
|
26
|
+
if (['ts', 'tsx', 'mts', 'cts'].includes(ext))
|
|
27
|
+
return 'typescript';
|
|
28
|
+
if (['py', 'pyw'].includes(ext))
|
|
29
|
+
return 'python';
|
|
30
|
+
return 'unknown';
|
|
31
|
+
}
|
|
32
|
+
function checkJavaScriptFunctions(content) {
|
|
33
|
+
const results = [];
|
|
34
|
+
const lines = content.split('\n');
|
|
35
|
+
// Track function declarations
|
|
36
|
+
const functionStarts = [];
|
|
37
|
+
for (let i = 0; i < lines.length; i++) {
|
|
38
|
+
const line = lines[i];
|
|
39
|
+
const lineNum = i + 1;
|
|
40
|
+
// Detect function starts
|
|
41
|
+
// - function name()
|
|
42
|
+
// - const name = function
|
|
43
|
+
// - const name = () =>
|
|
44
|
+
// - async function name()
|
|
45
|
+
// - method() { or method = () =>
|
|
46
|
+
const funcMatch = line.match(/(?:(?:async\s+)?function\s+(\w+)|(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s*)?\(?|(\w+)\s*(?:=\s*(?:async\s*)?\(|[:(]\s*\)\s*(?:=>|{)))/);
|
|
47
|
+
if (funcMatch) {
|
|
48
|
+
const name = funcMatch[1] || funcMatch[2] || funcMatch[3] || 'anonymous';
|
|
49
|
+
// Count opening braces on this line
|
|
50
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
51
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
52
|
+
if (openBraces > 0) {
|
|
53
|
+
functionStarts.push({
|
|
54
|
+
line: lineNum,
|
|
55
|
+
name,
|
|
56
|
+
braceCount: openBraces - closeBraces,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Update brace counts for tracked functions
|
|
62
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
63
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
64
|
+
for (let j = functionStarts.length - 1; j >= 0; j--) {
|
|
65
|
+
functionStarts[j].braceCount += openBraces - closeBraces;
|
|
66
|
+
// Function ended
|
|
67
|
+
if (functionStarts[j].braceCount <= 0) {
|
|
68
|
+
const func = functionStarts[j];
|
|
69
|
+
const length = lineNum - func.line + 1;
|
|
70
|
+
if (length > MAX_FUNCTION_LENGTH) {
|
|
71
|
+
results.push({
|
|
72
|
+
line: func.line,
|
|
73
|
+
column: 0,
|
|
74
|
+
message: `Function "${func.name}" is ${length} lines (max: ${MAX_FUNCTION_LENGTH}) - consider refactoring`,
|
|
75
|
+
severity: 'warning',
|
|
76
|
+
ruleId: 'function-length/too-long',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
functionStarts.splice(j, 1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return results;
|
|
85
|
+
}
|
|
86
|
+
function checkPythonFunctions(content) {
|
|
87
|
+
const results = [];
|
|
88
|
+
const lines = content.split('\n');
|
|
89
|
+
// Track function definitions by indentation
|
|
90
|
+
const functionStarts = [];
|
|
91
|
+
for (let i = 0; i < lines.length; i++) {
|
|
92
|
+
const line = lines[i];
|
|
93
|
+
const lineNum = i + 1;
|
|
94
|
+
// Detect function definition
|
|
95
|
+
const funcMatch = line.match(/^(\s*)(?:async\s+)?def\s+(\w+)\s*\(/);
|
|
96
|
+
if (funcMatch) {
|
|
97
|
+
const indent = funcMatch[1].length;
|
|
98
|
+
const name = funcMatch[2];
|
|
99
|
+
// Close any functions with same or greater indentation
|
|
100
|
+
while (functionStarts.length > 0 &&
|
|
101
|
+
functionStarts[functionStarts.length - 1].indent >= indent) {
|
|
102
|
+
const func = functionStarts.pop();
|
|
103
|
+
const length = lineNum - func.line;
|
|
104
|
+
if (length > MAX_FUNCTION_LENGTH) {
|
|
105
|
+
results.push({
|
|
106
|
+
line: func.line,
|
|
107
|
+
column: 0,
|
|
108
|
+
message: `Function "${func.name}" is ${length} lines (max: ${MAX_FUNCTION_LENGTH}) - consider refactoring`,
|
|
109
|
+
severity: 'warning',
|
|
110
|
+
ruleId: 'function-length/too-long',
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
functionStarts.push({ line: lineNum, name, indent });
|
|
115
|
+
}
|
|
116
|
+
else if (line.trim() && !line.trim().startsWith('#')) {
|
|
117
|
+
// Non-empty, non-comment line - check indentation to close functions
|
|
118
|
+
const indent = line.match(/^(\s*)/)?.[1].length || 0;
|
|
119
|
+
while (functionStarts.length > 0 &&
|
|
120
|
+
indent <= functionStarts[functionStarts.length - 1].indent &&
|
|
121
|
+
!line.trim().startsWith('@') // decorators don't close functions
|
|
122
|
+
) {
|
|
123
|
+
const func = functionStarts.pop();
|
|
124
|
+
const length = i - func.line; // Previous line was the end
|
|
125
|
+
if (length > MAX_FUNCTION_LENGTH) {
|
|
126
|
+
results.push({
|
|
127
|
+
line: func.line,
|
|
128
|
+
column: 0,
|
|
129
|
+
message: `Function "${func.name}" is ${length} lines (max: ${MAX_FUNCTION_LENGTH}) - consider refactoring`,
|
|
130
|
+
severity: 'warning',
|
|
131
|
+
ruleId: 'function-length/too-long',
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Close remaining functions at EOF
|
|
138
|
+
for (const func of functionStarts) {
|
|
139
|
+
const length = lines.length - func.line + 1;
|
|
140
|
+
if (length > MAX_FUNCTION_LENGTH) {
|
|
141
|
+
results.push({
|
|
142
|
+
line: func.line,
|
|
143
|
+
column: 0,
|
|
144
|
+
message: `Function "${func.name}" is ${length} lines (max: ${MAX_FUNCTION_LENGTH}) - consider refactoring`,
|
|
145
|
+
severity: 'warning',
|
|
146
|
+
ruleId: 'function-length/too-long',
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return results;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=check-function-length.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-function-length.js","sourceRoot":"","sources":["../../src/checks/check-function-length.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for hardcoded AI model names and configurations
|
|
3
|
+
*
|
|
4
|
+
* AI models should be configured via environment variables or settings,
|
|
5
|
+
* not hardcoded in the source code. This allows for easy model switching
|
|
6
|
+
* and proper configuration management.
|
|
7
|
+
*/
|
|
8
|
+
import type { Hook } from '../utils/types.js';
|
|
9
|
+
export declare const checkHardcodedAiModels: Hook;
|
|
10
|
+
//# sourceMappingURL=check-hardcoded-ai-models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-hardcoded-ai-models.d.ts","sourceRoot":"","sources":["../../src/checks/check-hardcoded-ai-models.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAiDvE,eAAO,MAAM,sBAAsB,EAAE,IAgDpC,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check for hardcoded AI model names and configurations
|
|
3
|
+
*
|
|
4
|
+
* AI models should be configured via environment variables or settings,
|
|
5
|
+
* not hardcoded in the source code. This allows for easy model switching
|
|
6
|
+
* and proper configuration management.
|
|
7
|
+
*/
|
|
8
|
+
// Common AI model name patterns
|
|
9
|
+
const AI_MODEL_PATTERNS = [
|
|
10
|
+
// OpenAI models
|
|
11
|
+
/["']gpt-4(?:-turbo|-vision|-\d+)?["']/gi,
|
|
12
|
+
/["']gpt-3\.5-turbo(?:-\d+)?["']/gi,
|
|
13
|
+
/["']text-davinci-\d+["']/gi,
|
|
14
|
+
/["']text-embedding-(?:ada-\d+|3-\w+)["']/gi,
|
|
15
|
+
/["']dall-e-\d+["']/gi,
|
|
16
|
+
/["']whisper-\d+["']/gi,
|
|
17
|
+
/["']tts-\d+(?:-hd)?["']/gi,
|
|
18
|
+
/["']o1(?:-preview|-mini)?["']/gi,
|
|
19
|
+
// Anthropic models
|
|
20
|
+
/["']claude-(?:3|2|instant)(?:-\d+)?(?:-sonnet|-opus|-haiku)?(?:-\d+)?["']/gi,
|
|
21
|
+
// Google models
|
|
22
|
+
/["']gemini-(?:pro|ultra|nano)(?:-vision)?(?:-\d+)?["']/gi,
|
|
23
|
+
/["']palm-\d+["']/gi,
|
|
24
|
+
// Cohere models
|
|
25
|
+
/["']command(?:-light|-nightly|-r)?(?:-\d+)?["']/gi,
|
|
26
|
+
// Mistral models
|
|
27
|
+
/["']mistral-(?:tiny|small|medium|large)(?:-\d+)?["']/gi,
|
|
28
|
+
/["']mixtral-\d+x\d+b(?:-\d+)?["']/gi,
|
|
29
|
+
// Llama models
|
|
30
|
+
/["']llama-?\d+(?:-\d+b)?(?:-chat)?["']/gi,
|
|
31
|
+
/["']codellama-\d+b["']/gi,
|
|
32
|
+
];
|
|
33
|
+
// Patterns that indicate it's in a config/env context (OK)
|
|
34
|
+
const ALLOWED_CONTEXTS = [
|
|
35
|
+
/process\.env\./,
|
|
36
|
+
/os\.environ/,
|
|
37
|
+
/settings\./,
|
|
38
|
+
/config\./,
|
|
39
|
+
/getenv/,
|
|
40
|
+
/ENV\[/,
|
|
41
|
+
/default[=:]/i, // Default value in env lookup
|
|
42
|
+
/fallback/i,
|
|
43
|
+
/\.env/,
|
|
44
|
+
/# noqa/,
|
|
45
|
+
/\/\/ noqa/,
|
|
46
|
+
/eslint-disable/,
|
|
47
|
+
];
|
|
48
|
+
export const checkHardcodedAiModels = {
|
|
49
|
+
id: 'ai-models',
|
|
50
|
+
name: 'Check Hardcoded AI Models',
|
|
51
|
+
description: 'Detect hardcoded AI model names - use environment variables or settings instead',
|
|
52
|
+
severity: 'warning',
|
|
53
|
+
fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
|
|
54
|
+
check(context) {
|
|
55
|
+
const results = [];
|
|
56
|
+
const lines = context.content.split('\n');
|
|
57
|
+
for (let i = 0; i < lines.length; i++) {
|
|
58
|
+
const line = lines[i];
|
|
59
|
+
const lineNum = i + 1;
|
|
60
|
+
// Skip comments
|
|
61
|
+
if (isCommentLine(line, context.extension)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Skip if line has noqa directive
|
|
65
|
+
if (line.includes('noqa') || line.includes('eslint-disable')) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
// Check if line is in an allowed context (env lookup, config, etc.)
|
|
69
|
+
if (ALLOWED_CONTEXTS.some(pattern => pattern.test(line))) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Check for hardcoded model names
|
|
73
|
+
for (const pattern of AI_MODEL_PATTERNS) {
|
|
74
|
+
const match = line.match(pattern);
|
|
75
|
+
if (match) {
|
|
76
|
+
results.push({
|
|
77
|
+
line: lineNum,
|
|
78
|
+
column: line.indexOf(match[0]),
|
|
79
|
+
message: `Hardcoded AI model "${match[0].replace(/["']/g, '')}" - use environment variable or settings`,
|
|
80
|
+
severity: 'warning',
|
|
81
|
+
ruleId: 'ai-models/hardcoded-model',
|
|
82
|
+
fix: 'Use os.environ.get("AI_MODEL") or settings.AI_MODEL instead',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return results;
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
function isCommentLine(line, extension) {
|
|
91
|
+
const trimmed = line.trim();
|
|
92
|
+
// JavaScript/TypeScript style comments
|
|
93
|
+
if (['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'].includes(extension)) {
|
|
94
|
+
return trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*');
|
|
95
|
+
}
|
|
96
|
+
// Python style comments
|
|
97
|
+
if (['py', 'pyw'].includes(extension)) {
|
|
98
|
+
return trimmed.startsWith('#');
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=check-hardcoded-ai-models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-hardcoded-ai-models.js","sourceRoot":"","sources":["../../src/checks/check-hardcoded-ai-models.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-hardcoded-urls.d.ts","sourceRoot":"","sources":["../../src/checks/check-hardcoded-urls.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AA8BvE,eAAO,MAAM,kBAAkB,EAAE,IA4FhC,CAAC"}
|
|
@@ -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/checks/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/checks/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"}
|