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.
Files changed (162) hide show
  1. package/.claude/commands/explain.md +114 -0
  2. package/.claude/commands/idea.md +398 -0
  3. package/.claude/commands/my-dna.md +122 -0
  4. package/.claude/commands/prd.md +286 -0
  5. package/.claude/commands/review.md +167 -0
  6. package/.claude/commands/sign.md +32 -0
  7. package/.claude/commands/styleguide.md +450 -0
  8. package/.claude/commands/tour.md +301 -0
  9. package/.claude/commands/vibe-check.md +116 -0
  10. package/.claude/commands/vibe-help.md +47 -0
  11. package/.claude/commands/vibe-list.md +203 -0
  12. package/.pre-commit-hooks.yaml +102 -0
  13. package/LICENSE +21 -0
  14. package/README.md +238 -0
  15. package/bin/agentic-loop.sh +24 -0
  16. package/bin/postinstall.sh +29 -0
  17. package/bin/ralph.sh +171 -0
  18. package/bin/vibe-check.js +19 -0
  19. package/dist/checks/check-any-types.d.ts +6 -0
  20. package/dist/checks/check-any-types.d.ts.map +1 -0
  21. package/dist/checks/check-any-types.js +73 -0
  22. package/dist/checks/check-any-types.js.map +1 -0
  23. package/dist/checks/check-commented-code.d.ts +6 -0
  24. package/dist/checks/check-commented-code.d.ts.map +1 -0
  25. package/dist/checks/check-commented-code.js +81 -0
  26. package/dist/checks/check-commented-code.js.map +1 -0
  27. package/dist/checks/check-console-error.d.ts +6 -0
  28. package/dist/checks/check-console-error.d.ts.map +1 -0
  29. package/dist/checks/check-console-error.js +41 -0
  30. package/dist/checks/check-console-error.js.map +1 -0
  31. package/dist/checks/check-debug-statements.d.ts +6 -0
  32. package/dist/checks/check-debug-statements.d.ts.map +1 -0
  33. package/dist/checks/check-debug-statements.js +120 -0
  34. package/dist/checks/check-debug-statements.js.map +1 -0
  35. package/dist/checks/check-deep-nesting.d.ts +6 -0
  36. package/dist/checks/check-deep-nesting.d.ts.map +1 -0
  37. package/dist/checks/check-deep-nesting.js +116 -0
  38. package/dist/checks/check-deep-nesting.js.map +1 -0
  39. package/dist/checks/check-docker-platform.d.ts +6 -0
  40. package/dist/checks/check-docker-platform.d.ts.map +1 -0
  41. package/dist/checks/check-docker-platform.js +42 -0
  42. package/dist/checks/check-docker-platform.js.map +1 -0
  43. package/dist/checks/check-dry-violations.d.ts +6 -0
  44. package/dist/checks/check-dry-violations.d.ts.map +1 -0
  45. package/dist/checks/check-dry-violations.js +124 -0
  46. package/dist/checks/check-dry-violations.js.map +1 -0
  47. package/dist/checks/check-empty-catch.d.ts +6 -0
  48. package/dist/checks/check-empty-catch.d.ts.map +1 -0
  49. package/dist/checks/check-empty-catch.js +111 -0
  50. package/dist/checks/check-empty-catch.js.map +1 -0
  51. package/dist/checks/check-function-length.d.ts +6 -0
  52. package/dist/checks/check-function-length.d.ts.map +1 -0
  53. package/dist/checks/check-function-length.js +152 -0
  54. package/dist/checks/check-function-length.js.map +1 -0
  55. package/dist/checks/check-hardcoded-ai-models.d.ts +10 -0
  56. package/dist/checks/check-hardcoded-ai-models.d.ts.map +1 -0
  57. package/dist/checks/check-hardcoded-ai-models.js +102 -0
  58. package/dist/checks/check-hardcoded-ai-models.js.map +1 -0
  59. package/dist/checks/check-hardcoded-urls.d.ts +6 -0
  60. package/dist/checks/check-hardcoded-urls.d.ts.map +1 -0
  61. package/dist/checks/check-hardcoded-urls.js +124 -0
  62. package/dist/checks/check-hardcoded-urls.js.map +1 -0
  63. package/dist/checks/check-magic-numbers.d.ts +6 -0
  64. package/dist/checks/check-magic-numbers.d.ts.map +1 -0
  65. package/dist/checks/check-magic-numbers.js +116 -0
  66. package/dist/checks/check-magic-numbers.js.map +1 -0
  67. package/dist/checks/check-secrets.d.ts +6 -0
  68. package/dist/checks/check-secrets.d.ts.map +1 -0
  69. package/dist/checks/check-secrets.js +138 -0
  70. package/dist/checks/check-secrets.js.map +1 -0
  71. package/dist/checks/check-snake-case-ts.d.ts +6 -0
  72. package/dist/checks/check-snake-case-ts.d.ts.map +1 -0
  73. package/dist/checks/check-snake-case-ts.js +78 -0
  74. package/dist/checks/check-snake-case-ts.js.map +1 -0
  75. package/dist/checks/check-todo-fixme.d.ts +6 -0
  76. package/dist/checks/check-todo-fixme.d.ts.map +1 -0
  77. package/dist/checks/check-todo-fixme.js +41 -0
  78. package/dist/checks/check-todo-fixme.js.map +1 -0
  79. package/dist/checks/check-unsafe-html.d.ts +6 -0
  80. package/dist/checks/check-unsafe-html.d.ts.map +1 -0
  81. package/dist/checks/check-unsafe-html.js +101 -0
  82. package/dist/checks/check-unsafe-html.js.map +1 -0
  83. package/dist/checks/index.d.ts +30 -0
  84. package/dist/checks/index.d.ts.map +1 -0
  85. package/dist/checks/index.js +57 -0
  86. package/dist/checks/index.js.map +1 -0
  87. package/dist/cli.d.ts +13 -0
  88. package/dist/cli.d.ts.map +1 -0
  89. package/dist/cli.js +208 -0
  90. package/dist/cli.js.map +1 -0
  91. package/dist/index.d.ts +9 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +10 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/utils/file-reader.d.ts +24 -0
  96. package/dist/utils/file-reader.d.ts.map +1 -0
  97. package/dist/utils/file-reader.js +146 -0
  98. package/dist/utils/file-reader.js.map +1 -0
  99. package/dist/utils/patterns.d.ts +27 -0
  100. package/dist/utils/patterns.d.ts.map +1 -0
  101. package/dist/utils/patterns.js +84 -0
  102. package/dist/utils/patterns.js.map +1 -0
  103. package/dist/utils/reporters.d.ts +21 -0
  104. package/dist/utils/reporters.d.ts.map +1 -0
  105. package/dist/utils/reporters.js +115 -0
  106. package/dist/utils/reporters.js.map +1 -0
  107. package/dist/utils/types.d.ts +71 -0
  108. package/dist/utils/types.d.ts.map +1 -0
  109. package/dist/utils/types.js +5 -0
  110. package/dist/utils/types.js.map +1 -0
  111. package/package.json +83 -0
  112. package/ralph/api.sh +216 -0
  113. package/ralph/backup.sh +838 -0
  114. package/ralph/browser-verify/README.md +135 -0
  115. package/ralph/browser-verify/verify.ts +450 -0
  116. package/ralph/checks/check-fastapi-responses.py +155 -0
  117. package/ralph/hooks/hooks-config.json +72 -0
  118. package/ralph/hooks/inject-context.sh +44 -0
  119. package/ralph/hooks/install.sh +207 -0
  120. package/ralph/hooks/log-tools.sh +45 -0
  121. package/ralph/hooks/protect-prd.sh +27 -0
  122. package/ralph/hooks/save-learnings.sh +36 -0
  123. package/ralph/hooks/warn-debug.sh +54 -0
  124. package/ralph/hooks/warn-empty-catch.sh +63 -0
  125. package/ralph/hooks/warn-secrets.sh +89 -0
  126. package/ralph/hooks/warn-urls.sh +77 -0
  127. package/ralph/init.sh +515 -0
  128. package/ralph/loop.sh +730 -0
  129. package/ralph/playwright.sh +238 -0
  130. package/ralph/prd.sh +295 -0
  131. package/ralph/setup/feature-tour.sh +155 -0
  132. package/ralph/setup/quick-setup.sh +239 -0
  133. package/ralph/setup/tutorial.sh +159 -0
  134. package/ralph/setup/ui.sh +136 -0
  135. package/ralph/setup.sh +401 -0
  136. package/ralph/signs.sh +150 -0
  137. package/ralph/utils.sh +682 -0
  138. package/ralph/verify/browser.sh +324 -0
  139. package/ralph/verify/lint.sh +363 -0
  140. package/ralph/verify/review.sh +152 -0
  141. package/ralph/verify/tests.sh +81 -0
  142. package/ralph/verify.sh +268 -0
  143. package/templates/PROMPT.md +235 -0
  144. package/templates/config/fullstack.json +86 -0
  145. package/templates/config/go.json +81 -0
  146. package/templates/config/minimal.json +76 -0
  147. package/templates/config/node.json +81 -0
  148. package/templates/config/python.json +81 -0
  149. package/templates/config/rust.json +81 -0
  150. package/templates/examples/CLAUDE-django.md +174 -0
  151. package/templates/examples/CLAUDE-fastapi.md +270 -0
  152. package/templates/examples/CLAUDE-fastmcp.md +352 -0
  153. package/templates/examples/CLAUDE-fullstack.md +256 -0
  154. package/templates/examples/CLAUDE-node.md +246 -0
  155. package/templates/examples/CLAUDE-react.md +138 -0
  156. package/templates/optional/cursorrules.template +147 -0
  157. package/templates/optional/eslint.config.js +34 -0
  158. package/templates/optional/lint-staged.config.js +34 -0
  159. package/templates/optional/ruff.toml +125 -0
  160. package/templates/optional/vibe-check.yml +116 -0
  161. package/templates/optional/vscode-settings.json +127 -0
  162. package/templates/signs.json +46 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-any-types.js","sourceRoot":"","sources":["../../src/checks/check-any-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,aAAa,GAAS;IACjC,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,0CAA0C;IACvD,QAAQ,EAAE,SAAS;IACnB,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAEtC,KAAK,CAAC,OAAoB;QACxB,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE1C,oCAAoC;QACpC,IAAI,cAAc,GAAG,KAAK,CAAC;QAE3B,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,wBAAwB;YACxB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,cAAc,GAAG,IAAI,CAAC;YACxB,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,cAAc,GAAG,KAAK,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,IAAI,cAAc,EAAE,CAAC;gBACnB,SAAS;YACX,CAAC;YAED,4BAA4B;YAC5B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjC,SAAS;YACX,CAAC;YAED,kDAAkD;YAClD,MAAM,kBAAkB,GAAG,IAAI;iBAC5B,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC;iBACzB,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC;iBACzB,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAE7B,kCAAkC;YAClC,+CAA+C;YAC/C,MAAM,WAAW,GAAG;gBAClB,WAAW,EAAqB,QAAQ;gBACxC,cAAc,EAAkB,UAAU;gBAC1C,cAAc,EAAkB,UAAU;gBAC1C,YAAY,EAAoB,QAAQ;gBACxC,aAAa,EAAmB,QAAQ;gBACxC,aAAa,EAAmB,QAAQ;gBACxC,aAAa,EAAmB,SAAS;gBACzC,YAAY,EAAoB,SAAS;gBACzC,yBAAyB,EAAO,eAAe;gBAC/C,mCAAmC,EAAE,qBAAqB;aAC3D,CAAC;YAEF,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAClC,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAChD,IAAI,KAAK,EAAE,CAAC;oBACV,4CAA4C;oBAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;wBACnE,SAAS;oBACX,CAAC;oBAED,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO;wBACb,MAAM,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;wBACxB,OAAO,EAAE,mEAAmE;wBAC5E,QAAQ,EAAE,SAAS;wBACnB,MAAM,EAAE,kBAAkB;qBAC3B,CAAC,CAAC;oBACH,MAAM,CAAC,4BAA4B;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check for commented-out code blocks
3
+ */
4
+ import type { Hook } from '../utils/types.js';
5
+ export declare const checkCommentedCode: Hook;
6
+ //# sourceMappingURL=check-commented-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-commented-code.d.ts","sourceRoot":"","sources":["../../src/checks/check-commented-code.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAsBvE,eAAO,MAAM,kBAAkB,EAAE,IAwDhC,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Check for commented-out code blocks
3
+ */
4
+ // Patterns that indicate commented-out code vs regular comments
5
+ const JS_CODE_PATTERNS = [
6
+ /^\s*\/\/\s*(?:const|let|var|function|class|import|export|return|if|else|for|while|try|catch|switch)\b/,
7
+ /^\s*\/\/\s*\w+\s*\([^)]*\)\s*[;{]?\s*$/, // function calls
8
+ /^\s*\/\/\s*\w+\s*=\s*.+[;,]?\s*$/, // assignments
9
+ /^\s*\/\/\s*}\s*(?:else|catch|finally)?\s*{?\s*$/, // closing braces
10
+ /^\s*\/\/\s*\w+\.\w+\s*\(/, // method calls
11
+ /^\s*\/\*\s*(?:const|let|var|function|class|import|export)\b/,
12
+ ];
13
+ const PY_CODE_PATTERNS = [
14
+ /^\s*#\s*(?:def|class|import|from|return|if|elif|else|for|while|try|except|with|async)\b/,
15
+ /^\s*#\s*\w+\s*=\s*.+$/, // assignments
16
+ /^\s*#\s*\w+\s*\([^)]*\)\s*$/, // function calls
17
+ /^\s*#\s*\w+\.\w+\s*\(/, // method calls
18
+ ];
19
+ // Minimum consecutive commented lines to report
20
+ const MIN_CONSECUTIVE_LINES = 3;
21
+ export const checkCommentedCode = {
22
+ id: 'commented-code',
23
+ name: 'Check Commented Code',
24
+ description: 'Detect commented-out code blocks that should be removed',
25
+ severity: 'info',
26
+ fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
27
+ check(context) {
28
+ const results = [];
29
+ const lines = context.content.split('\n');
30
+ const language = getLanguage(context.extension);
31
+ const patterns = language === 'python' ? PY_CODE_PATTERNS : JS_CODE_PATTERNS;
32
+ let consecutiveCodeComments = 0;
33
+ let blockStartLine = 0;
34
+ for (let i = 0; i < lines.length; i++) {
35
+ const line = lines[i];
36
+ const lineNum = i + 1;
37
+ // Check if this line looks like commented-out code
38
+ const looksLikeCode = patterns.some((pattern) => pattern.test(line));
39
+ if (looksLikeCode) {
40
+ if (consecutiveCodeComments === 0) {
41
+ blockStartLine = lineNum;
42
+ }
43
+ consecutiveCodeComments++;
44
+ }
45
+ else {
46
+ // End of potential block
47
+ if (consecutiveCodeComments >= MIN_CONSECUTIVE_LINES) {
48
+ results.push({
49
+ line: blockStartLine,
50
+ column: 0,
51
+ message: `${consecutiveCodeComments} lines of commented-out code - consider removing`,
52
+ severity: 'info',
53
+ ruleId: 'commented-code/block',
54
+ });
55
+ }
56
+ consecutiveCodeComments = 0;
57
+ }
58
+ }
59
+ // Check for block at end of file
60
+ if (consecutiveCodeComments >= MIN_CONSECUTIVE_LINES) {
61
+ results.push({
62
+ line: blockStartLine,
63
+ column: 0,
64
+ message: `${consecutiveCodeComments} lines of commented-out code - consider removing`,
65
+ severity: 'info',
66
+ ruleId: 'commented-code/block',
67
+ });
68
+ }
69
+ return results;
70
+ },
71
+ };
72
+ function getLanguage(ext) {
73
+ if (['js', 'jsx', 'mjs', 'cjs'].includes(ext))
74
+ return 'javascript';
75
+ if (['ts', 'tsx', 'mts', 'cts'].includes(ext))
76
+ return 'typescript';
77
+ if (['py', 'pyw'].includes(ext))
78
+ return 'python';
79
+ return 'unknown';
80
+ }
81
+ //# sourceMappingURL=check-commented-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-commented-code.js","sourceRoot":"","sources":["../../src/checks/check-commented-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check for console.error usage that might need proper error handling
3
+ */
4
+ import type { Hook } from '../utils/types.js';
5
+ export declare const checkConsoleError: Hook;
6
+ //# sourceMappingURL=check-console-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-console-error.d.ts","sourceRoot":"","sources":["../../src/checks/check-console-error.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,iBAAiB,EAAE,IA0C/B,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Check for console.error usage that might need proper error handling
3
+ */
4
+ export const checkConsoleError = {
5
+ id: 'console-error',
6
+ name: 'Check Console Error',
7
+ description: 'Detect console.error that might need proper error handling',
8
+ severity: 'info',
9
+ fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'],
10
+ check(context) {
11
+ const results = [];
12
+ const lines = context.content.split('\n');
13
+ for (let i = 0; i < lines.length; i++) {
14
+ const line = lines[i];
15
+ const lineNum = i + 1;
16
+ // Skip comment lines
17
+ if (line.trim().startsWith('//') || line.trim().startsWith('*')) {
18
+ continue;
19
+ }
20
+ // Look for console.error
21
+ const match = line.match(/console\.error\s*\(/);
22
+ if (match) {
23
+ // Check if it's in a catch block (look at nearby lines)
24
+ const nearbyLines = lines.slice(Math.max(0, i - 5), i + 1).join('\n');
25
+ const inCatchBlock = /catch\s*\([^)]*\)\s*\{/.test(nearbyLines);
26
+ if (inCatchBlock) {
27
+ // In a catch block - suggest proper error handling
28
+ results.push({
29
+ line: lineNum,
30
+ column: match.index || 0,
31
+ message: 'console.error in catch block - consider using a logging service or rethrowing',
32
+ severity: 'info',
33
+ ruleId: 'console-error/in-catch',
34
+ });
35
+ }
36
+ }
37
+ }
38
+ return results;
39
+ },
40
+ };
41
+ //# sourceMappingURL=check-console-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-console-error.js","sourceRoot":"","sources":["../../src/checks/check-console-error.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAS;IACrC,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,4DAA4D;IACzE,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAEnD,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,qBAAqB;YACrB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChE,SAAS;YACX,CAAC;YAED,yBAAyB;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAChD,IAAI,KAAK,EAAE,CAAC;gBACV,wDAAwD;gBACxD,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,MAAM,YAAY,GAAG,wBAAwB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAEhE,IAAI,YAAY,EAAE,CAAC;oBACjB,mDAAmD;oBACnD,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO;wBACb,MAAM,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;wBACxB,OAAO,EAAE,+EAA+E;wBACxF,QAAQ,EAAE,MAAM;wBAChB,MAAM,EAAE,wBAAwB;qBACjC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check for debug statements that should be removed before commit
3
+ */
4
+ import type { Hook } from '../utils/types.js';
5
+ export declare const checkDebugStatements: Hook;
6
+ //# sourceMappingURL=check-debug-statements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-debug-statements.d.ts","sourceRoot":"","sources":["../../src/checks/check-debug-statements.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAGvE,eAAO,MAAM,oBAAoB,EAAE,IA0ElC,CAAC"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Check for debug statements that should be removed before commit
3
+ */
4
+ import { DEBUG_PATTERNS } from '../utils/patterns.js';
5
+ export const checkDebugStatements = {
6
+ id: 'debug',
7
+ name: 'Check Debug Statements',
8
+ description: 'Detect console.log, print(), debugger, and other debug statements',
9
+ severity: 'warning',
10
+ fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'py'],
11
+ check(context) {
12
+ const results = [];
13
+ const lines = context.content.split('\n');
14
+ // Get patterns for this language
15
+ const language = getLanguageFromExtension(context.extension);
16
+ const patterns = DEBUG_PATTERNS[language] || [];
17
+ if (patterns.length === 0) {
18
+ return results;
19
+ }
20
+ // Track if we're inside a multi-line comment
21
+ let inBlockComment = false;
22
+ for (let i = 0; i < lines.length; i++) {
23
+ const line = lines[i];
24
+ const lineNum = i + 1;
25
+ // Handle block comments for JS/TS
26
+ if (['javascript', 'typescript'].includes(language)) {
27
+ if (line.includes('/*') && !line.includes('*/')) {
28
+ inBlockComment = true;
29
+ }
30
+ if (line.includes('*/')) {
31
+ inBlockComment = false;
32
+ continue;
33
+ }
34
+ if (inBlockComment) {
35
+ continue;
36
+ }
37
+ }
38
+ // Skip single-line comments
39
+ if (isCommentLine(line, language)) {
40
+ continue;
41
+ }
42
+ // Check each pattern
43
+ for (const pattern of patterns) {
44
+ const match = line.match(pattern);
45
+ if (match) {
46
+ const patternType = getPatternType(pattern.source, language);
47
+ // Skip console.error and console.warn - these are often intentional
48
+ if (patternType === 'console' && /console\.(error|warn)\s*\(/.test(line)) {
49
+ continue;
50
+ }
51
+ // Skip if explicitly marked to keep
52
+ if (line.includes('// eslint-disable') || line.includes('# noqa')) {
53
+ continue;
54
+ }
55
+ results.push({
56
+ line: lineNum,
57
+ column: match.index || 0,
58
+ message: getDebugMessage(patternType, language),
59
+ severity: 'warning',
60
+ ruleId: `debug/${patternType}`,
61
+ });
62
+ }
63
+ }
64
+ }
65
+ return results;
66
+ },
67
+ };
68
+ function getLanguageFromExtension(ext) {
69
+ if (['js', 'jsx', 'mjs', 'cjs'].includes(ext))
70
+ return 'javascript';
71
+ if (['ts', 'tsx', 'mts', 'cts'].includes(ext))
72
+ return 'typescript';
73
+ if (['py', 'pyw'].includes(ext))
74
+ return 'python';
75
+ return 'unknown';
76
+ }
77
+ function isCommentLine(line, language) {
78
+ const trimmed = line.trim();
79
+ if (['javascript', 'typescript'].includes(language)) {
80
+ return trimmed.startsWith('//') || trimmed.startsWith('*');
81
+ }
82
+ if (language === 'python') {
83
+ return trimmed.startsWith('#');
84
+ }
85
+ return false;
86
+ }
87
+ function getPatternType(patternSource, _language) {
88
+ if (patternSource.includes('console'))
89
+ return 'console';
90
+ if (patternSource.includes('debugger'))
91
+ return 'debugger';
92
+ if (patternSource.includes('alert'))
93
+ return 'alert';
94
+ if (patternSource.includes('print'))
95
+ return 'print';
96
+ if (patternSource.includes('breakpoint'))
97
+ return 'breakpoint';
98
+ if (patternSource.includes('pdb') || patternSource.includes('ipdb'))
99
+ return 'pdb';
100
+ return 'debug';
101
+ }
102
+ function getDebugMessage(patternType, _language) {
103
+ switch (patternType) {
104
+ case 'console':
105
+ return 'console.log() statement - remove before commit';
106
+ case 'debugger':
107
+ return 'debugger statement - remove before commit';
108
+ case 'alert':
109
+ return 'alert() statement - remove before commit';
110
+ case 'print':
111
+ return 'print() statement - use proper logging instead';
112
+ case 'breakpoint':
113
+ return 'breakpoint() - remove before commit';
114
+ case 'pdb':
115
+ return 'pdb debugger - remove before commit';
116
+ default:
117
+ return 'Debug statement - remove before commit';
118
+ }
119
+ }
120
+ //# sourceMappingURL=check-debug-statements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-debug-statements.js","sourceRoot":"","sources":["../../src/checks/check-debug-statements.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check for deeply nested code blocks
3
+ */
4
+ import type { Hook } from '../utils/types.js';
5
+ export declare const checkDeepNesting: Hook;
6
+ //# sourceMappingURL=check-deep-nesting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-deep-nesting.d.ts","sourceRoot":"","sources":["../../src/checks/check-deep-nesting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAIvE,eAAO,MAAM,gBAAgB,EAAE,IAmB9B,CAAC"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Check for deeply nested code blocks
3
+ */
4
+ const MAX_NESTING_DEPTH = 4;
5
+ export const checkDeepNesting = {
6
+ id: 'deep-nesting',
7
+ name: 'Check Deep Nesting',
8
+ description: 'Detect deeply nested code blocks that 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(...checkJavaScriptNesting(context.content));
16
+ }
17
+ else if (language === 'python') {
18
+ results.push(...checkPythonNesting(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 checkJavaScriptNesting(content) {
33
+ const results = [];
34
+ const lines = content.split('\n');
35
+ const reportedLines = new Set();
36
+ let nestingDepth = 0;
37
+ let inString = false;
38
+ let stringChar = '';
39
+ for (let i = 0; i < lines.length; i++) {
40
+ const line = lines[i];
41
+ const lineNum = i + 1;
42
+ // Skip comment-only lines
43
+ if (line.trim().startsWith('//') || line.trim().startsWith('*')) {
44
+ continue;
45
+ }
46
+ // Track nesting by counting braces (simplified - doesn't handle all edge cases)
47
+ for (let j = 0; j < line.length; j++) {
48
+ const char = line[j];
49
+ const prevChar = j > 0 ? line[j - 1] : '';
50
+ // Handle strings
51
+ if ((char === '"' || char === "'" || char === '`') && prevChar !== '\\') {
52
+ if (!inString) {
53
+ inString = true;
54
+ stringChar = char;
55
+ }
56
+ else if (char === stringChar) {
57
+ inString = false;
58
+ }
59
+ continue;
60
+ }
61
+ if (inString)
62
+ continue;
63
+ // Track braces
64
+ if (char === '{') {
65
+ nestingDepth++;
66
+ if (nestingDepth > MAX_NESTING_DEPTH && !reportedLines.has(lineNum)) {
67
+ reportedLines.add(lineNum);
68
+ results.push({
69
+ line: lineNum,
70
+ column: j,
71
+ message: `Nesting depth ${nestingDepth} exceeds maximum of ${MAX_NESTING_DEPTH} - consider refactoring`,
72
+ severity: 'warning',
73
+ ruleId: 'deep-nesting/too-deep',
74
+ });
75
+ }
76
+ }
77
+ else if (char === '}') {
78
+ nestingDepth = Math.max(0, nestingDepth - 1);
79
+ }
80
+ }
81
+ }
82
+ return results;
83
+ }
84
+ function checkPythonNesting(content) {
85
+ const results = [];
86
+ const lines = content.split('\n');
87
+ const reportedLines = new Set();
88
+ // In Python, we track indentation-based nesting
89
+ // Each 4 spaces or 1 tab = 1 level of nesting (approximately)
90
+ const INDENT_SIZE = 4;
91
+ for (let i = 0; i < lines.length; i++) {
92
+ const line = lines[i];
93
+ const lineNum = i + 1;
94
+ // Skip empty lines and comments
95
+ if (!line.trim() || line.trim().startsWith('#')) {
96
+ continue;
97
+ }
98
+ // Count leading whitespace
99
+ const leadingSpaces = line.match(/^(\s*)/)?.[1] || '';
100
+ // Convert tabs to spaces for consistent counting
101
+ const normalizedSpaces = leadingSpaces.replace(/\t/g, ' ');
102
+ const indentLevel = Math.floor(normalizedSpaces.length / INDENT_SIZE);
103
+ if (indentLevel > MAX_NESTING_DEPTH && !reportedLines.has(lineNum)) {
104
+ reportedLines.add(lineNum);
105
+ results.push({
106
+ line: lineNum,
107
+ column: 0,
108
+ message: `Indentation level ${indentLevel} exceeds maximum of ${MAX_NESTING_DEPTH} - consider refactoring`,
109
+ severity: 'warning',
110
+ ruleId: 'deep-nesting/too-deep',
111
+ });
112
+ }
113
+ }
114
+ return results;
115
+ }
116
+ //# sourceMappingURL=check-deep-nesting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-deep-nesting.js","sourceRoot":"","sources":["../../src/checks/check-deep-nesting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check for missing platform specification in Dockerfiles
3
+ */
4
+ import type { Hook } from '../utils/types.js';
5
+ export declare const checkDockerPlatform: Hook;
6
+ //# sourceMappingURL=check-docker-platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-docker-platform.d.ts","sourceRoot":"","sources":["../../src/checks/check-docker-platform.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,mBAAmB,EAAE,IA2CjC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Check for missing platform specification in Dockerfiles
3
+ */
4
+ export const checkDockerPlatform = {
5
+ id: 'docker-platform',
6
+ name: 'Check Docker Platform',
7
+ description: 'Detect missing --platform flag in Dockerfile FROM instructions',
8
+ severity: 'info',
9
+ fileTypes: ['dockerfile'],
10
+ check(context) {
11
+ const results = [];
12
+ const lines = context.content.split('\n');
13
+ for (let i = 0; i < lines.length; i++) {
14
+ const line = lines[i];
15
+ const lineNum = i + 1;
16
+ // Skip comments
17
+ if (line.trim().startsWith('#')) {
18
+ continue;
19
+ }
20
+ // Check for FROM instruction
21
+ if (/^\s*FROM\s+/i.test(line)) {
22
+ // Check if --platform is specified
23
+ if (!line.includes('--platform')) {
24
+ // Skip if using ARG for platform (dynamic platform)
25
+ if (/\$\{?TARGETPLATFORM\}?|\$\{?BUILDPLATFORM\}?/i.test(line)) {
26
+ continue;
27
+ }
28
+ results.push({
29
+ line: lineNum,
30
+ column: 0,
31
+ message: 'Consider adding --platform flag for reproducible builds (e.g., --platform=linux/amd64)',
32
+ severity: 'info',
33
+ ruleId: 'docker-platform/missing',
34
+ fix: 'Add --platform=linux/amd64 or --platform=$TARGETPLATFORM',
35
+ });
36
+ }
37
+ }
38
+ }
39
+ return results;
40
+ },
41
+ };
42
+ //# sourceMappingURL=check-docker-platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-docker-platform.js","sourceRoot":"","sources":["../../src/checks/check-docker-platform.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,mBAAmB,GAAS;IACvC,EAAE,EAAE,iBAAiB;IACrB,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EAAE,gEAAgE;IAC7E,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,YAAY,CAAC;IAEzB,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,gBAAgB;YAChB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,SAAS;YACX,CAAC;YAED,6BAA6B;YAC7B,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,mCAAmC;gBACnC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBACjC,oDAAoD;oBACpD,IAAI,+CAA+C,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC/D,SAAS;oBACX,CAAC;oBAED,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO;wBACb,MAAM,EAAE,CAAC;wBACT,OAAO,EAAE,wFAAwF;wBACjG,QAAQ,EAAE,MAAM;wBAChB,MAAM,EAAE,yBAAyB;wBACjC,GAAG,EAAE,0DAA0D;qBAChE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check for DRY (Don't Repeat Yourself) violations - duplicated code blocks
3
+ */
4
+ import type { Hook } from '../utils/types.js';
5
+ export declare const checkDryViolations: Hook;
6
+ //# sourceMappingURL=check-dry-violations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-dry-violations.d.ts","sourceRoot":"","sources":["../../src/checks/check-dry-violations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAA2B,MAAM,mBAAmB,CAAC;AAoBvE,eAAO,MAAM,kBAAkB,EAAE,IAmEhC,CAAC"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Check for DRY (Don't Repeat Yourself) violations - duplicated code blocks
3
+ */
4
+ // Minimum number of similar lines to consider a duplicate
5
+ const MIN_DUPLICATE_LINES = 5;
6
+ // Minimum similarity threshold (0-1)
7
+ const SIMILARITY_THRESHOLD = 0.85;
8
+ // Paths that indicate frontend component files (skip these - too many false positives)
9
+ const FRONTEND_PATH_PATTERNS = [
10
+ /\/components\//i,
11
+ /\/pages\//i,
12
+ /\/views\//i,
13
+ /\/layouts\//i,
14
+ /\/ui\//i,
15
+ /\.styled\./i,
16
+ /\.styles\./i,
17
+ /styleguide/i,
18
+ ];
19
+ export const checkDryViolations = {
20
+ id: 'dry',
21
+ name: 'Check DRY Violations',
22
+ description: 'Detect duplicated code blocks that should be extracted',
23
+ severity: 'warning',
24
+ // Skip JSX/TSX - too many false positives with similar component patterns
25
+ fileTypes: ['js', 'ts', 'mjs', 'cjs', 'py'],
26
+ check(context) {
27
+ const results = [];
28
+ // Skip frontend component files
29
+ if (FRONTEND_PATH_PATTERNS.some((pattern) => pattern.test(context.filePath))) {
30
+ return results;
31
+ }
32
+ const lines = context.content.split('\n');
33
+ // Normalize lines for comparison (remove whitespace, comments)
34
+ const normalizedLines = lines.map((line, index) => ({
35
+ original: line,
36
+ normalized: normalizeLine(line, context.extension),
37
+ lineNum: index + 1,
38
+ }));
39
+ // Filter out empty/trivial lines
40
+ const significantLines = normalizedLines.filter((l) => l.normalized.length > 10 && !isTrivialLine(l.normalized));
41
+ // Find duplicate blocks using a sliding window approach
42
+ const reportedBlocks = new Set();
43
+ for (let i = 0; i < significantLines.length - MIN_DUPLICATE_LINES; i++) {
44
+ // Create a "fingerprint" of the next N lines
45
+ const block1 = significantLines.slice(i, i + MIN_DUPLICATE_LINES);
46
+ const fingerprint1 = block1.map((l) => l.normalized).join('\n');
47
+ // Look for similar blocks later in the file
48
+ for (let j = i + MIN_DUPLICATE_LINES; j < significantLines.length - MIN_DUPLICATE_LINES; j++) {
49
+ const block2 = significantLines.slice(j, j + MIN_DUPLICATE_LINES);
50
+ const fingerprint2 = block2.map((l) => l.normalized).join('\n');
51
+ // Check similarity
52
+ const similarity = calculateSimilarity(fingerprint1, fingerprint2);
53
+ if (similarity >= SIMILARITY_THRESHOLD) {
54
+ // Create a unique key for this duplicate pair
55
+ const blockKey = `${block1[0].lineNum}-${block2[0].lineNum}`;
56
+ if (!reportedBlocks.has(blockKey)) {
57
+ reportedBlocks.add(blockKey);
58
+ results.push({
59
+ line: block1[0].lineNum,
60
+ column: 0,
61
+ message: `Similar code block found at line ${block2[0].lineNum} - consider extracting to a function`,
62
+ severity: 'warning',
63
+ ruleId: 'dry/duplicate-block',
64
+ });
65
+ }
66
+ }
67
+ }
68
+ }
69
+ return results;
70
+ },
71
+ };
72
+ function normalizeLine(line, extension) {
73
+ let normalized = line;
74
+ // Remove comments
75
+ if (['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'].includes(extension)) {
76
+ normalized = normalized.replace(/\/\/.*$/, '').replace(/\/\*.*?\*\//g, '');
77
+ }
78
+ else if (['py', 'pyw'].includes(extension)) {
79
+ normalized = normalized.replace(/#.*$/, '');
80
+ }
81
+ // Normalize whitespace
82
+ normalized = normalized.replace(/\s+/g, ' ').trim();
83
+ // Replace variable names with placeholders (simplified)
84
+ // This helps match similar code with different variable names
85
+ normalized = normalized
86
+ .replace(/\b[a-z][a-zA-Z0-9]*\b/g, 'VAR')
87
+ .replace(/"[^"]*"/g, 'STR')
88
+ .replace(/'[^']*'/g, 'STR')
89
+ .replace(/\d+/g, 'NUM');
90
+ return normalized;
91
+ }
92
+ function isTrivialLine(normalized) {
93
+ // Lines that are too generic to be meaningful duplicates
94
+ const trivialPatterns = [
95
+ /^[{}()\[\];,]+$/, // Just brackets/punctuation
96
+ /^(?:return|break|continue|pass);?$/, // Single keywords
97
+ /^VAR\s*=\s*(?:VAR|STR|NUM);?$/, // Simple assignments
98
+ /^}\s*(?:else|catch|finally)\s*{?$/, // Control flow brackets
99
+ /^import\s/, // Import statements (often similar)
100
+ /^export\s/, // Export statements
101
+ ];
102
+ return trivialPatterns.some((pattern) => pattern.test(normalized));
103
+ }
104
+ function calculateSimilarity(str1, str2) {
105
+ // Simple Jaccard similarity based on character n-grams
106
+ const ngram = (s, n) => {
107
+ const grams = new Set();
108
+ for (let i = 0; i <= s.length - n; i++) {
109
+ grams.add(s.slice(i, i + n));
110
+ }
111
+ return grams;
112
+ };
113
+ const grams1 = ngram(str1, 3);
114
+ const grams2 = ngram(str2, 3);
115
+ let intersection = 0;
116
+ for (const gram of grams1) {
117
+ if (grams2.has(gram)) {
118
+ intersection++;
119
+ }
120
+ }
121
+ const union = grams1.size + grams2.size - intersection;
122
+ return union > 0 ? intersection / union : 0;
123
+ }
124
+ //# sourceMappingURL=check-dry-violations.js.map