thrivekit 2.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 (164) hide show
  1. package/.claude/commands/explain.md +114 -0
  2. package/.claude/commands/idea.md +370 -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/.claude/settings.json +75 -0
  13. package/.claude/settings.local.json +12 -0
  14. package/.pre-commit-hooks.yaml +102 -0
  15. package/LICENSE +21 -0
  16. package/README.md +214 -0
  17. package/bin/postinstall.sh +29 -0
  18. package/bin/ralph.sh +171 -0
  19. package/bin/thrivekit.sh +24 -0
  20. package/bin/vibe-check.js +19 -0
  21. package/dist/checks/check-any-types.d.ts +6 -0
  22. package/dist/checks/check-any-types.d.ts.map +1 -0
  23. package/dist/checks/check-any-types.js +73 -0
  24. package/dist/checks/check-any-types.js.map +1 -0
  25. package/dist/checks/check-commented-code.d.ts +6 -0
  26. package/dist/checks/check-commented-code.d.ts.map +1 -0
  27. package/dist/checks/check-commented-code.js +81 -0
  28. package/dist/checks/check-commented-code.js.map +1 -0
  29. package/dist/checks/check-console-error.d.ts +6 -0
  30. package/dist/checks/check-console-error.d.ts.map +1 -0
  31. package/dist/checks/check-console-error.js +41 -0
  32. package/dist/checks/check-console-error.js.map +1 -0
  33. package/dist/checks/check-debug-statements.d.ts +6 -0
  34. package/dist/checks/check-debug-statements.d.ts.map +1 -0
  35. package/dist/checks/check-debug-statements.js +120 -0
  36. package/dist/checks/check-debug-statements.js.map +1 -0
  37. package/dist/checks/check-deep-nesting.d.ts +6 -0
  38. package/dist/checks/check-deep-nesting.d.ts.map +1 -0
  39. package/dist/checks/check-deep-nesting.js +116 -0
  40. package/dist/checks/check-deep-nesting.js.map +1 -0
  41. package/dist/checks/check-docker-platform.d.ts +6 -0
  42. package/dist/checks/check-docker-platform.d.ts.map +1 -0
  43. package/dist/checks/check-docker-platform.js +42 -0
  44. package/dist/checks/check-docker-platform.js.map +1 -0
  45. package/dist/checks/check-dry-violations.d.ts +6 -0
  46. package/dist/checks/check-dry-violations.d.ts.map +1 -0
  47. package/dist/checks/check-dry-violations.js +124 -0
  48. package/dist/checks/check-dry-violations.js.map +1 -0
  49. package/dist/checks/check-empty-catch.d.ts +6 -0
  50. package/dist/checks/check-empty-catch.d.ts.map +1 -0
  51. package/dist/checks/check-empty-catch.js +111 -0
  52. package/dist/checks/check-empty-catch.js.map +1 -0
  53. package/dist/checks/check-function-length.d.ts +6 -0
  54. package/dist/checks/check-function-length.d.ts.map +1 -0
  55. package/dist/checks/check-function-length.js +152 -0
  56. package/dist/checks/check-function-length.js.map +1 -0
  57. package/dist/checks/check-hardcoded-ai-models.d.ts +10 -0
  58. package/dist/checks/check-hardcoded-ai-models.d.ts.map +1 -0
  59. package/dist/checks/check-hardcoded-ai-models.js +102 -0
  60. package/dist/checks/check-hardcoded-ai-models.js.map +1 -0
  61. package/dist/checks/check-hardcoded-urls.d.ts +6 -0
  62. package/dist/checks/check-hardcoded-urls.d.ts.map +1 -0
  63. package/dist/checks/check-hardcoded-urls.js +124 -0
  64. package/dist/checks/check-hardcoded-urls.js.map +1 -0
  65. package/dist/checks/check-magic-numbers.d.ts +6 -0
  66. package/dist/checks/check-magic-numbers.d.ts.map +1 -0
  67. package/dist/checks/check-magic-numbers.js +116 -0
  68. package/dist/checks/check-magic-numbers.js.map +1 -0
  69. package/dist/checks/check-secrets.d.ts +6 -0
  70. package/dist/checks/check-secrets.d.ts.map +1 -0
  71. package/dist/checks/check-secrets.js +138 -0
  72. package/dist/checks/check-secrets.js.map +1 -0
  73. package/dist/checks/check-snake-case-ts.d.ts +6 -0
  74. package/dist/checks/check-snake-case-ts.d.ts.map +1 -0
  75. package/dist/checks/check-snake-case-ts.js +78 -0
  76. package/dist/checks/check-snake-case-ts.js.map +1 -0
  77. package/dist/checks/check-todo-fixme.d.ts +6 -0
  78. package/dist/checks/check-todo-fixme.d.ts.map +1 -0
  79. package/dist/checks/check-todo-fixme.js +41 -0
  80. package/dist/checks/check-todo-fixme.js.map +1 -0
  81. package/dist/checks/check-unsafe-html.d.ts +6 -0
  82. package/dist/checks/check-unsafe-html.d.ts.map +1 -0
  83. package/dist/checks/check-unsafe-html.js +101 -0
  84. package/dist/checks/check-unsafe-html.js.map +1 -0
  85. package/dist/checks/index.d.ts +30 -0
  86. package/dist/checks/index.d.ts.map +1 -0
  87. package/dist/checks/index.js +57 -0
  88. package/dist/checks/index.js.map +1 -0
  89. package/dist/cli.d.ts +13 -0
  90. package/dist/cli.d.ts.map +1 -0
  91. package/dist/cli.js +206 -0
  92. package/dist/cli.js.map +1 -0
  93. package/dist/index.d.ts +9 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +10 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/utils/file-reader.d.ts +24 -0
  98. package/dist/utils/file-reader.d.ts.map +1 -0
  99. package/dist/utils/file-reader.js +140 -0
  100. package/dist/utils/file-reader.js.map +1 -0
  101. package/dist/utils/patterns.d.ts +27 -0
  102. package/dist/utils/patterns.d.ts.map +1 -0
  103. package/dist/utils/patterns.js +84 -0
  104. package/dist/utils/patterns.js.map +1 -0
  105. package/dist/utils/reporters.d.ts +21 -0
  106. package/dist/utils/reporters.d.ts.map +1 -0
  107. package/dist/utils/reporters.js +115 -0
  108. package/dist/utils/reporters.js.map +1 -0
  109. package/dist/utils/types.d.ts +71 -0
  110. package/dist/utils/types.d.ts.map +1 -0
  111. package/dist/utils/types.js +5 -0
  112. package/dist/utils/types.js.map +1 -0
  113. package/package.json +82 -0
  114. package/ralph/api.sh +210 -0
  115. package/ralph/backup.sh +838 -0
  116. package/ralph/browser-verify/README.md +135 -0
  117. package/ralph/browser-verify/verify.ts +450 -0
  118. package/ralph/checks/check-fastapi-responses.py +155 -0
  119. package/ralph/hooks/hooks-config.json +72 -0
  120. package/ralph/hooks/inject-context.sh +44 -0
  121. package/ralph/hooks/install.sh +207 -0
  122. package/ralph/hooks/log-tools.sh +45 -0
  123. package/ralph/hooks/protect-prd.sh +27 -0
  124. package/ralph/hooks/save-learnings.sh +36 -0
  125. package/ralph/hooks/warn-debug.sh +54 -0
  126. package/ralph/hooks/warn-empty-catch.sh +63 -0
  127. package/ralph/hooks/warn-secrets.sh +89 -0
  128. package/ralph/hooks/warn-urls.sh +77 -0
  129. package/ralph/init.sh +388 -0
  130. package/ralph/loop.sh +570 -0
  131. package/ralph/playwright.sh +238 -0
  132. package/ralph/prd.sh +295 -0
  133. package/ralph/setup/feature-tour.sh +155 -0
  134. package/ralph/setup/quick-setup.sh +239 -0
  135. package/ralph/setup/tutorial.sh +159 -0
  136. package/ralph/setup/ui.sh +136 -0
  137. package/ralph/setup.sh +353 -0
  138. package/ralph/signs.sh +150 -0
  139. package/ralph/utils.sh +682 -0
  140. package/ralph/verify/browser.sh +324 -0
  141. package/ralph/verify/lint.sh +363 -0
  142. package/ralph/verify/review.sh +164 -0
  143. package/ralph/verify/tests.sh +81 -0
  144. package/ralph/verify.sh +224 -0
  145. package/templates/PROMPT.md +235 -0
  146. package/templates/config/fullstack.json +86 -0
  147. package/templates/config/go.json +81 -0
  148. package/templates/config/minimal.json +76 -0
  149. package/templates/config/node.json +81 -0
  150. package/templates/config/python.json +81 -0
  151. package/templates/config/rust.json +81 -0
  152. package/templates/examples/CLAUDE-django.md +174 -0
  153. package/templates/examples/CLAUDE-fastapi.md +270 -0
  154. package/templates/examples/CLAUDE-fastmcp.md +352 -0
  155. package/templates/examples/CLAUDE-fullstack.md +256 -0
  156. package/templates/examples/CLAUDE-node.md +246 -0
  157. package/templates/examples/CLAUDE-react.md +138 -0
  158. package/templates/optional/cursorrules.template +147 -0
  159. package/templates/optional/eslint.config.js +34 -0
  160. package/templates/optional/lint-staged.config.js +34 -0
  161. package/templates/optional/ruff.toml +125 -0
  162. package/templates/optional/vibe-check.yml +116 -0
  163. package/templates/optional/vscode-settings.json +127 -0
  164. package/templates/signs.json +46 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Check for unsafe HTML/DOM manipulation that could lead to XSS
3
+ */
4
+ export const checkUnsafeHtml = {
5
+ id: 'unsafe-html',
6
+ name: 'Check Unsafe HTML',
7
+ description: 'Detect unsafe innerHTML/DOM manipulation that could lead to XSS',
8
+ severity: 'error',
9
+ fileTypes: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs', 'html'],
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('//') || line.trim().startsWith('*')) {
18
+ continue;
19
+ }
20
+ // Check for innerHTML assignment
21
+ if (/\.innerHTML\s*=/.test(line)) {
22
+ // Check if it's a static string (less dangerous)
23
+ const isStaticString = /\.innerHTML\s*=\s*['"`][^'"`]*['"`]\s*;?\s*$/.test(line);
24
+ if (!isStaticString) {
25
+ results.push({
26
+ line: lineNum,
27
+ column: line.indexOf('innerHTML'),
28
+ message: 'Unsafe innerHTML assignment - use textContent or sanitize input',
29
+ severity: 'error',
30
+ ruleId: 'unsafe-html/innerHTML',
31
+ });
32
+ }
33
+ }
34
+ // Check for outerHTML assignment
35
+ if (/\.outerHTML\s*=/.test(line)) {
36
+ results.push({
37
+ line: lineNum,
38
+ column: line.indexOf('outerHTML'),
39
+ message: 'Unsafe outerHTML assignment - consider safer alternatives',
40
+ severity: 'error',
41
+ ruleId: 'unsafe-html/outerHTML',
42
+ });
43
+ }
44
+ // Check for document.write
45
+ if (/document\.write\s*\(/.test(line)) {
46
+ results.push({
47
+ line: lineNum,
48
+ column: line.indexOf('document.write'),
49
+ message: 'document.write() is unsafe - use DOM manipulation instead',
50
+ severity: 'error',
51
+ ruleId: 'unsafe-html/document-write',
52
+ });
53
+ }
54
+ // Check for insertAdjacentHTML with non-static content
55
+ if (/\.insertAdjacentHTML\s*\([^,]+,/.test(line)) {
56
+ const isStaticString = /\.insertAdjacentHTML\s*\([^,]+,\s*['"`][^'"`]*['"`]\s*\)/.test(line);
57
+ if (!isStaticString) {
58
+ results.push({
59
+ line: lineNum,
60
+ column: line.indexOf('insertAdjacentHTML'),
61
+ message: 'Unsafe insertAdjacentHTML - sanitize input before insertion',
62
+ severity: 'warning',
63
+ ruleId: 'unsafe-html/insertAdjacentHTML',
64
+ });
65
+ }
66
+ }
67
+ // Check for dangerouslySetInnerHTML in React
68
+ if (/dangerouslySetInnerHTML\s*=/.test(line)) {
69
+ results.push({
70
+ line: lineNum,
71
+ column: line.indexOf('dangerouslySetInnerHTML'),
72
+ message: 'dangerouslySetInnerHTML requires careful sanitization',
73
+ severity: 'warning',
74
+ ruleId: 'unsafe-html/react-dangerously',
75
+ });
76
+ }
77
+ // Check for eval
78
+ if (/\beval\s*\(/.test(line)) {
79
+ results.push({
80
+ line: lineNum,
81
+ column: line.indexOf('eval'),
82
+ message: 'eval() is unsafe - avoid using eval with dynamic content',
83
+ severity: 'error',
84
+ ruleId: 'unsafe-html/eval',
85
+ });
86
+ }
87
+ // Check for Function constructor with dynamic content
88
+ if (/new\s+Function\s*\(/.test(line)) {
89
+ results.push({
90
+ line: lineNum,
91
+ column: line.indexOf('Function'),
92
+ message: 'new Function() with dynamic content is similar to eval()',
93
+ severity: 'warning',
94
+ ruleId: 'unsafe-html/function-constructor',
95
+ });
96
+ }
97
+ }
98
+ return results;
99
+ },
100
+ };
101
+ //# sourceMappingURL=check-unsafe-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-unsafe-html.js","sourceRoot":"","sources":["../../src/checks/check-unsafe-html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Hook registry - exports all available hooks
3
+ */
4
+ import type { Hook } from '../utils/types.js';
5
+ import { checkSecrets } from './check-secrets.js';
6
+ import { checkHardcodedUrls } from './check-hardcoded-urls.js';
7
+ import { checkDebugStatements } from './check-debug-statements.js';
8
+ import { checkTodoFixme } from './check-todo-fixme.js';
9
+ import { checkEmptyCatch } from './check-empty-catch.js';
10
+ import { checkDryViolations } from './check-dry-violations.js';
11
+ import { checkMagicNumbers } from './check-magic-numbers.js';
12
+ import { checkFunctionLength } from './check-function-length.js';
13
+ import { checkCommentedCode } from './check-commented-code.js';
14
+ import { checkDeepNesting } from './check-deep-nesting.js';
15
+ import { checkConsoleError } from './check-console-error.js';
16
+ import { checkAnyTypes } from './check-any-types.js';
17
+ import { checkSnakeCaseTs } from './check-snake-case-ts.js';
18
+ import { checkUnsafeHtml } from './check-unsafe-html.js';
19
+ import { checkDockerPlatform } from './check-docker-platform.js';
20
+ import { checkHardcodedAiModels } from './check-hardcoded-ai-models.js';
21
+ /** All available hooks */
22
+ export declare const hooks: Hook[];
23
+ /** Get a hook by its ID */
24
+ export declare function getHook(id: string): Hook | undefined;
25
+ /** Get hooks filtered by file extension */
26
+ export declare function getHooksForFile(extension: string): Hook[];
27
+ /** Get all hook IDs */
28
+ export declare function getHookIds(): string[];
29
+ export { checkSecrets, checkHardcodedUrls, checkDebugStatements, checkTodoFixme, checkEmptyCatch, checkDryViolations, checkMagicNumbers, checkFunctionLength, checkCommentedCode, checkDeepNesting, checkConsoleError, checkAnyTypes, checkSnakeCaseTs, checkUnsafeHtml, checkDockerPlatform, checkHardcodedAiModels, };
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,0BAA0B;AAC1B,eAAO,MAAM,KAAK,EAAE,IAAI,EAwBvB,CAAC;AAEF,2BAA2B;AAC3B,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAEpD;AAED,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,CAEzD;AAED,uBAAuB;AACvB,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAErC;AAED,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,GACvB,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Hook registry - exports all available hooks
3
+ */
4
+ // Import all hooks
5
+ import { checkSecrets } from './check-secrets.js';
6
+ import { checkHardcodedUrls } from './check-hardcoded-urls.js';
7
+ import { checkDebugStatements } from './check-debug-statements.js';
8
+ import { checkTodoFixme } from './check-todo-fixme.js';
9
+ import { checkEmptyCatch } from './check-empty-catch.js';
10
+ import { checkDryViolations } from './check-dry-violations.js';
11
+ import { checkMagicNumbers } from './check-magic-numbers.js';
12
+ import { checkFunctionLength } from './check-function-length.js';
13
+ import { checkCommentedCode } from './check-commented-code.js';
14
+ import { checkDeepNesting } from './check-deep-nesting.js';
15
+ import { checkConsoleError } from './check-console-error.js';
16
+ import { checkAnyTypes } from './check-any-types.js';
17
+ import { checkSnakeCaseTs } from './check-snake-case-ts.js';
18
+ import { checkUnsafeHtml } from './check-unsafe-html.js';
19
+ import { checkDockerPlatform } from './check-docker-platform.js';
20
+ import { checkHardcodedAiModels } from './check-hardcoded-ai-models.js';
21
+ /** All available hooks */
22
+ export const hooks = [
23
+ // Security (blocking)
24
+ checkSecrets,
25
+ checkHardcodedUrls,
26
+ checkUnsafeHtml,
27
+ // Code quality (warnings)
28
+ checkDebugStatements,
29
+ checkTodoFixme,
30
+ checkEmptyCatch,
31
+ checkDryViolations,
32
+ checkMagicNumbers,
33
+ checkFunctionLength,
34
+ checkCommentedCode,
35
+ checkDeepNesting,
36
+ checkConsoleError,
37
+ checkAnyTypes,
38
+ checkSnakeCaseTs,
39
+ // Infrastructure
40
+ checkDockerPlatform,
41
+ // AI/LLM
42
+ checkHardcodedAiModels,
43
+ ];
44
+ /** Get a hook by its ID */
45
+ export function getHook(id) {
46
+ return hooks.find((hook) => hook.id === id);
47
+ }
48
+ /** Get hooks filtered by file extension */
49
+ export function getHooksForFile(extension) {
50
+ return hooks.filter((hook) => hook.fileTypes.includes(extension));
51
+ }
52
+ /** Get all hook IDs */
53
+ export function getHookIds() {
54
+ return hooks.map((hook) => hook.id);
55
+ }
56
+ export { checkSecrets, checkHardcodedUrls, checkDebugStatements, checkTodoFixme, checkEmptyCatch, checkDryViolations, checkMagicNumbers, checkFunctionLength, checkCommentedCode, checkDeepNesting, checkConsoleError, checkAnyTypes, checkSnakeCaseTs, checkUnsafeHtml, checkDockerPlatform, checkHardcodedAiModels, };
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,0BAA0B;AAC1B,MAAM,CAAC,MAAM,KAAK,GAAW;IAC3B,sBAAsB;IACtB,YAAY;IACZ,kBAAkB;IAClB,eAAe;IAEf,0BAA0B;IAC1B,oBAAoB;IACpB,cAAc;IACd,eAAe;IACf,kBAAkB;IAClB,iBAAiB;IACjB,mBAAmB;IACnB,kBAAkB;IAClB,gBAAgB;IAChB,iBAAiB;IACjB,aAAa;IACb,gBAAgB;IAEhB,iBAAiB;IACjB,mBAAmB;IAEnB,SAAS;IACT,sBAAsB;CACvB,CAAC;AAEF,2BAA2B;AAC3B,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,UAAU;IACxB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,GACvB,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * CLI entry point for vibe-check
3
+ */
4
+ import type { CheckOptions, SummaryResult } from './utils/types.js';
5
+ /**
6
+ * Main vibe-check function
7
+ */
8
+ export declare function vibeCheck(files: string[], options?: CheckOptions): SummaryResult;
9
+ /**
10
+ * CLI main function
11
+ */
12
+ export declare function main(args: string[]): Promise<void>;
13
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EACV,YAAY,EAEZ,aAAa,EAId,MAAM,kBAAkB,CAAC;AAsI1B;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,YAAiB,GAAG,aAAa,CA0CpF;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BxD"}
package/dist/cli.js ADDED
@@ -0,0 +1,206 @@
1
+ /**
2
+ * CLI entry point for vibe-check
3
+ */
4
+ import * as path from 'node:path';
5
+ import { resolveFiles, readFile, getExtension } from './utils/file-reader.js';
6
+ import { formatResults } from './utils/reporters.js';
7
+ import { hooks, getHooksForFile } from './checks/index.js';
8
+ /**
9
+ * Parse command line arguments
10
+ */
11
+ function parseArgs(args) {
12
+ const files = [];
13
+ const options = {
14
+ format: 'pretty',
15
+ failOn: 'error',
16
+ };
17
+ let i = 0;
18
+ while (i < args.length) {
19
+ const arg = args[i];
20
+ if (arg === '--only' && args[i + 1]) {
21
+ options.only = args[i + 1].split(',').map((s) => s.trim());
22
+ i += 2;
23
+ }
24
+ else if (arg === '--skip' && args[i + 1]) {
25
+ options.skip = args[i + 1].split(',').map((s) => s.trim());
26
+ i += 2;
27
+ }
28
+ else if (arg === '--format' && args[i + 1]) {
29
+ const format = args[i + 1];
30
+ if (['pretty', 'json', 'compact'].includes(format)) {
31
+ options.format = format;
32
+ }
33
+ i += 2;
34
+ }
35
+ else if (arg === '--fail-on' && args[i + 1]) {
36
+ const failOn = args[i + 1];
37
+ if (['error', 'warning', 'info', 'none'].includes(failOn)) {
38
+ options.failOn = failOn === 'none' ? undefined : failOn;
39
+ }
40
+ i += 2;
41
+ }
42
+ else if (arg === '--fix') {
43
+ options.fix = true;
44
+ i += 1;
45
+ }
46
+ else if (arg === '--help' || arg === '-h') {
47
+ printHelp();
48
+ process.exit(0);
49
+ }
50
+ else if (arg === '--version' || arg === '-v') {
51
+ console.log('vibe-check 1.0.0');
52
+ process.exit(0);
53
+ }
54
+ else if (!arg.startsWith('-')) {
55
+ files.push(arg);
56
+ i += 1;
57
+ }
58
+ else {
59
+ console.error(`Unknown option: ${arg}`);
60
+ process.exit(2);
61
+ }
62
+ }
63
+ return { files, options };
64
+ }
65
+ /**
66
+ * Print help message
67
+ */
68
+ function printHelp() {
69
+ console.log(`
70
+ vibe-check - Catch common AI-generated code issues
71
+
72
+ Usage:
73
+ vibe-check [options] <files...>
74
+
75
+ Options:
76
+ --only <hooks> Only run specified hooks (comma-separated)
77
+ --skip <hooks> Skip specified hooks (comma-separated)
78
+ --format <format> Output format: pretty, json, compact (default: pretty)
79
+ --fail-on <level> Fail on severity level: error, warning, info, none (default: error)
80
+ --fix Auto-fix issues where possible
81
+ -h, --help Show this help message
82
+ -v, --version Show version
83
+
84
+ Examples:
85
+ vibe-check .
86
+ vibe-check src/
87
+ vibe-check --only secrets,urls .
88
+ vibe-check --skip any-types,snake-case .
89
+ vibe-check --format json .
90
+
91
+ Available hooks:
92
+ ${hooks.map((h) => ` ${h.id.padEnd(20)} ${h.description}`).join('\n')}
93
+ `);
94
+ }
95
+ /**
96
+ * Check a single file with applicable hooks
97
+ */
98
+ function checkFile(filePath, options) {
99
+ const extension = getExtension(filePath);
100
+ const content = readFile(filePath);
101
+ const context = {
102
+ filePath,
103
+ content,
104
+ extension,
105
+ };
106
+ // Get hooks for this file type
107
+ let applicableHooks = getHooksForFile(extension);
108
+ // Filter by --only
109
+ if (options.only && options.only.length > 0) {
110
+ applicableHooks = applicableHooks.filter((h) => options.only.includes(h.id));
111
+ }
112
+ // Filter by --skip
113
+ if (options.skip && options.skip.length > 0) {
114
+ applicableHooks = applicableHooks.filter((h) => !options.skip.includes(h.id));
115
+ }
116
+ // Run all applicable hooks
117
+ const issues = [];
118
+ for (const hook of applicableHooks) {
119
+ try {
120
+ const hookIssues = hook.check(context);
121
+ issues.push(...hookIssues);
122
+ }
123
+ catch (error) {
124
+ // Skip hooks that fail - don't crash the whole check
125
+ console.error(`Warning: Hook "${hook.id}" failed on ${filePath}: ${error}`);
126
+ }
127
+ }
128
+ // Sort issues by line number
129
+ issues.sort((a, b) => a.line - b.line);
130
+ return {
131
+ filePath: path.relative(process.cwd(), filePath),
132
+ issues,
133
+ };
134
+ }
135
+ /**
136
+ * Main vibe-check function
137
+ */
138
+ export function vibeCheck(files, options = {}) {
139
+ const resolvedFiles = resolveFiles(files);
140
+ const results = [];
141
+ for (const file of resolvedFiles) {
142
+ const result = checkFile(file, options);
143
+ results.push(result);
144
+ }
145
+ // Calculate summary
146
+ let errorCount = 0;
147
+ let warningCount = 0;
148
+ let infoCount = 0;
149
+ let filesWithIssues = 0;
150
+ for (const result of results) {
151
+ if (result.issues.length > 0) {
152
+ filesWithIssues++;
153
+ }
154
+ for (const issue of result.issues) {
155
+ switch (issue.severity) {
156
+ case 'error':
157
+ errorCount++;
158
+ break;
159
+ case 'warning':
160
+ warningCount++;
161
+ break;
162
+ case 'info':
163
+ infoCount++;
164
+ break;
165
+ }
166
+ }
167
+ }
168
+ return {
169
+ filesChecked: resolvedFiles.length,
170
+ filesWithIssues,
171
+ errorCount,
172
+ warningCount,
173
+ infoCount,
174
+ results,
175
+ };
176
+ }
177
+ /**
178
+ * CLI main function
179
+ */
180
+ export async function main(args) {
181
+ const { files, options } = parseArgs(args);
182
+ if (files.length === 0) {
183
+ console.error('Error: No files specified. Use "vibe-check ." to check current directory.');
184
+ process.exit(2);
185
+ }
186
+ const summary = vibeCheck(files, options);
187
+ const output = formatResults(summary, options.format || 'pretty');
188
+ console.log(output);
189
+ // Determine exit code based on --fail-on
190
+ if (options.failOn) {
191
+ const severityOrder = ['error', 'warning', 'info'];
192
+ const failIndex = severityOrder.indexOf(options.failOn);
193
+ let shouldFail = false;
194
+ if (failIndex <= 0 && summary.errorCount > 0)
195
+ shouldFail = true;
196
+ if (failIndex <= 1 && summary.warningCount > 0)
197
+ shouldFail = true;
198
+ if (failIndex <= 2 && summary.infoCount > 0)
199
+ shouldFail = true;
200
+ if (shouldFail) {
201
+ process.exit(1);
202
+ }
203
+ }
204
+ process.exit(0);
205
+ }
206
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * thrivekit
3
+ *
4
+ * Catch common AI-generated code issues before they hit your codebase.
5
+ */
6
+ export type { Hook, HookResult, FileContext, CheckOptions, CheckResult, SummaryResult, Severity, } from './utils/types.js';
7
+ export { hooks, getHook, getHooksForFile, getHookIds, } from './checks/index.js';
8
+ export { vibeCheck } from './cli.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,IAAI,EACJ,UAAU,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,aAAa,EACb,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,KAAK,EACL,OAAO,EACP,eAAe,EACf,UAAU,GACX,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * thrivekit
3
+ *
4
+ * Catch common AI-generated code issues before they hit your codebase.
5
+ */
6
+ // Export hooks
7
+ export { hooks, getHook, getHooksForFile, getHookIds, } from './checks/index.js';
8
+ // Export main check function
9
+ export { vibeCheck } from './cli.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,eAAe;AACf,OAAO,EACL,KAAK,EACL,OAAO,EACP,eAAe,EACf,UAAU,GACX,MAAM,mBAAmB,CAAC;AAE3B,6BAA6B;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * File discovery and reading utilities
3
+ */
4
+ /**
5
+ * Check if a file should be processed based on extension
6
+ */
7
+ export declare function shouldProcessFile(filePath: string): boolean;
8
+ /**
9
+ * Get file extension (handles special cases like Dockerfile)
10
+ */
11
+ export declare function getExtension(filePath: string): string;
12
+ /**
13
+ * Recursively discover files in a directory
14
+ */
15
+ export declare function discoverFiles(dirPath: string): string[];
16
+ /**
17
+ * Resolve input paths to a list of files
18
+ */
19
+ export declare function resolveFiles(inputs: string[]): string[];
20
+ /**
21
+ * Read file content
22
+ */
23
+ export declare function readFile(filePath: string): string;
24
+ //# sourceMappingURL=file-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-reader.d.ts","sourceRoot":"","sources":["../../src/utils/file-reader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyDH;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAe3D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYrD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAyBvD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAuBvD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjD"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * File discovery and reading utilities
3
+ */
4
+ import * as fs from 'node:fs';
5
+ import * as path from 'node:path';
6
+ /** Directories to always skip */
7
+ const SKIP_DIRS = new Set([
8
+ 'node_modules',
9
+ '.git',
10
+ '__pycache__',
11
+ '.venv',
12
+ 'venv',
13
+ 'env',
14
+ 'dist',
15
+ 'build',
16
+ '.next',
17
+ '.nuxt',
18
+ 'coverage',
19
+ '.pytest_cache',
20
+ '.mypy_cache',
21
+ '.tox',
22
+ 'egg-info',
23
+ '.eggs',
24
+ ]);
25
+ /** File extensions to check */
26
+ const SUPPORTED_EXTENSIONS = new Set([
27
+ // JavaScript/TypeScript
28
+ 'js',
29
+ 'jsx',
30
+ 'ts',
31
+ 'tsx',
32
+ 'mjs',
33
+ 'cjs',
34
+ 'mts',
35
+ 'cts',
36
+ // Python
37
+ 'py',
38
+ 'pyw',
39
+ // Config/Data
40
+ 'json',
41
+ 'jsonc',
42
+ 'yaml',
43
+ 'yml',
44
+ 'toml',
45
+ // Web
46
+ 'html',
47
+ 'htm',
48
+ // Docker
49
+ 'dockerfile',
50
+ // Other
51
+ 'env',
52
+ 'env.local',
53
+ 'env.development',
54
+ 'env.production',
55
+ ]);
56
+ /**
57
+ * Check if a file should be processed based on extension
58
+ */
59
+ export function shouldProcessFile(filePath) {
60
+ const basename = path.basename(filePath).toLowerCase();
61
+ // Handle Dockerfile (no extension)
62
+ if (basename === 'dockerfile' || basename.startsWith('dockerfile.')) {
63
+ return true;
64
+ }
65
+ // Handle .env files
66
+ if (basename.startsWith('.env')) {
67
+ return true;
68
+ }
69
+ const ext = path.extname(filePath).slice(1).toLowerCase();
70
+ return SUPPORTED_EXTENSIONS.has(ext);
71
+ }
72
+ /**
73
+ * Get file extension (handles special cases like Dockerfile)
74
+ */
75
+ export function getExtension(filePath) {
76
+ const basename = path.basename(filePath).toLowerCase();
77
+ if (basename === 'dockerfile' || basename.startsWith('dockerfile.')) {
78
+ return 'dockerfile';
79
+ }
80
+ if (basename.startsWith('.env')) {
81
+ return 'env';
82
+ }
83
+ return path.extname(filePath).slice(1).toLowerCase();
84
+ }
85
+ /**
86
+ * Recursively discover files in a directory
87
+ */
88
+ export function discoverFiles(dirPath) {
89
+ const files = [];
90
+ function walk(currentPath) {
91
+ const entries = fs.readdirSync(currentPath, { withFileTypes: true });
92
+ for (const entry of entries) {
93
+ const fullPath = path.join(currentPath, entry.name);
94
+ if (entry.isDirectory()) {
95
+ // Skip excluded directories
96
+ if (SKIP_DIRS.has(entry.name) || entry.name.startsWith('.')) {
97
+ continue;
98
+ }
99
+ walk(fullPath);
100
+ }
101
+ else if (entry.isFile()) {
102
+ if (shouldProcessFile(fullPath)) {
103
+ files.push(fullPath);
104
+ }
105
+ }
106
+ }
107
+ }
108
+ walk(dirPath);
109
+ return files;
110
+ }
111
+ /**
112
+ * Resolve input paths to a list of files
113
+ */
114
+ export function resolveFiles(inputs) {
115
+ const files = [];
116
+ for (const input of inputs) {
117
+ const resolvedPath = path.resolve(input);
118
+ if (!fs.existsSync(resolvedPath)) {
119
+ console.error(`Warning: Path does not exist: ${input}`);
120
+ continue;
121
+ }
122
+ const stat = fs.statSync(resolvedPath);
123
+ if (stat.isDirectory()) {
124
+ files.push(...discoverFiles(resolvedPath));
125
+ }
126
+ else if (stat.isFile()) {
127
+ if (shouldProcessFile(resolvedPath)) {
128
+ files.push(resolvedPath);
129
+ }
130
+ }
131
+ }
132
+ return [...new Set(files)]; // Deduplicate
133
+ }
134
+ /**
135
+ * Read file content
136
+ */
137
+ export function readFile(filePath) {
138
+ return fs.readFileSync(filePath, 'utf-8');
139
+ }
140
+ //# sourceMappingURL=file-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-reader.js","sourceRoot":"","sources":["../../src/utils/file-reader.ts"],"names":[],"mappings":"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"}