vibe-and-thrive 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/add-tests.md +240 -0
- package/.claude/commands/e2e-scaffold.md +212 -0
- package/.claude/commands/explain.md +110 -0
- package/.claude/commands/fix-types.md +238 -0
- package/.claude/commands/refactor.md +184 -0
- package/.claude/commands/review.md +136 -0
- package/.claude/commands/security-check.md +223 -0
- package/.claude/commands/styleguide.md +446 -0
- package/.claude/commands/tdd-feature.md +227 -0
- package/.claude/commands/vibe-check.md +112 -0
- package/.pre-commit-hooks.yaml +77 -0
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/bin/vibe-check.js +19 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +206 -0
- package/dist/cli.js.map +1 -0
- package/dist/eslint-plugin/index.d.ts +66 -0
- package/dist/eslint-plugin/index.d.ts.map +1 -0
- package/dist/eslint-plugin/index.js +67 -0
- package/dist/eslint-plugin/index.js.map +1 -0
- package/dist/eslint-plugin/rules/max-function-length.d.ts +8 -0
- package/dist/eslint-plugin/rules/max-function-length.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/max-function-length.js +69 -0
- package/dist/eslint-plugin/rules/max-function-length.js.map +1 -0
- package/dist/eslint-plugin/rules/no-any-type.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-any-type.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-any-type.js +29 -0
- package/dist/eslint-plugin/rules/no-any-type.js.map +1 -0
- package/dist/eslint-plugin/rules/no-debug-statements.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-debug-statements.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-debug-statements.js +59 -0
- package/dist/eslint-plugin/rules/no-debug-statements.js.map +1 -0
- package/dist/eslint-plugin/rules/no-deep-nesting.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-deep-nesting.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-deep-nesting.js +56 -0
- package/dist/eslint-plugin/rules/no-deep-nesting.js.map +1 -0
- package/dist/eslint-plugin/rules/no-empty-catch.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-empty-catch.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-empty-catch.js +31 -0
- package/dist/eslint-plugin/rules/no-empty-catch.js.map +1 -0
- package/dist/eslint-plugin/rules/no-magic-numbers.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-magic-numbers.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-magic-numbers.js +58 -0
- package/dist/eslint-plugin/rules/no-magic-numbers.js.map +1 -0
- package/dist/eslint-plugin/rules/no-snake-case-props.d.ts +8 -0
- package/dist/eslint-plugin/rules/no-snake-case-props.d.ts.map +1 -0
- package/dist/eslint-plugin/rules/no-snake-case-props.js +48 -0
- package/dist/eslint-plugin/rules/no-snake-case-props.js.map +1 -0
- package/dist/hooks/check-any-types.d.ts +6 -0
- package/dist/hooks/check-any-types.d.ts.map +1 -0
- package/dist/hooks/check-any-types.js +73 -0
- package/dist/hooks/check-any-types.js.map +1 -0
- package/dist/hooks/check-commented-code.d.ts +6 -0
- package/dist/hooks/check-commented-code.d.ts.map +1 -0
- package/dist/hooks/check-commented-code.js +81 -0
- package/dist/hooks/check-commented-code.js.map +1 -0
- package/dist/hooks/check-console-error.d.ts +6 -0
- package/dist/hooks/check-console-error.d.ts.map +1 -0
- package/dist/hooks/check-console-error.js +41 -0
- package/dist/hooks/check-console-error.js.map +1 -0
- package/dist/hooks/check-debug-statements.d.ts +6 -0
- package/dist/hooks/check-debug-statements.d.ts.map +1 -0
- package/dist/hooks/check-debug-statements.js +120 -0
- package/dist/hooks/check-debug-statements.js.map +1 -0
- package/dist/hooks/check-deep-nesting.d.ts +6 -0
- package/dist/hooks/check-deep-nesting.d.ts.map +1 -0
- package/dist/hooks/check-deep-nesting.js +116 -0
- package/dist/hooks/check-deep-nesting.js.map +1 -0
- package/dist/hooks/check-docker-platform.d.ts +6 -0
- package/dist/hooks/check-docker-platform.d.ts.map +1 -0
- package/dist/hooks/check-docker-platform.js +42 -0
- package/dist/hooks/check-docker-platform.js.map +1 -0
- package/dist/hooks/check-dry-violations.d.ts +6 -0
- package/dist/hooks/check-dry-violations.d.ts.map +1 -0
- package/dist/hooks/check-dry-violations.js +124 -0
- package/dist/hooks/check-dry-violations.js.map +1 -0
- package/dist/hooks/check-empty-catch.d.ts +6 -0
- package/dist/hooks/check-empty-catch.d.ts.map +1 -0
- package/dist/hooks/check-empty-catch.js +111 -0
- package/dist/hooks/check-empty-catch.js.map +1 -0
- package/dist/hooks/check-function-length.d.ts +6 -0
- package/dist/hooks/check-function-length.d.ts.map +1 -0
- package/dist/hooks/check-function-length.js +152 -0
- package/dist/hooks/check-function-length.js.map +1 -0
- package/dist/hooks/check-hardcoded-urls.d.ts +6 -0
- package/dist/hooks/check-hardcoded-urls.d.ts.map +1 -0
- package/dist/hooks/check-hardcoded-urls.js +124 -0
- package/dist/hooks/check-hardcoded-urls.js.map +1 -0
- package/dist/hooks/check-magic-numbers.d.ts +6 -0
- package/dist/hooks/check-magic-numbers.d.ts.map +1 -0
- package/dist/hooks/check-magic-numbers.js +116 -0
- package/dist/hooks/check-magic-numbers.js.map +1 -0
- package/dist/hooks/check-secrets.d.ts +6 -0
- package/dist/hooks/check-secrets.d.ts.map +1 -0
- package/dist/hooks/check-secrets.js +138 -0
- package/dist/hooks/check-secrets.js.map +1 -0
- package/dist/hooks/check-snake-case-ts.d.ts +6 -0
- package/dist/hooks/check-snake-case-ts.d.ts.map +1 -0
- package/dist/hooks/check-snake-case-ts.js +78 -0
- package/dist/hooks/check-snake-case-ts.js.map +1 -0
- package/dist/hooks/check-todo-fixme.d.ts +6 -0
- package/dist/hooks/check-todo-fixme.d.ts.map +1 -0
- package/dist/hooks/check-todo-fixme.js +41 -0
- package/dist/hooks/check-todo-fixme.js.map +1 -0
- package/dist/hooks/check-unsafe-html.d.ts +6 -0
- package/dist/hooks/check-unsafe-html.d.ts.map +1 -0
- package/dist/hooks/check-unsafe-html.js +101 -0
- package/dist/hooks/check-unsafe-html.js.map +1 -0
- package/dist/hooks/index.d.ts +29 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +54 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/lint-staged/config.d.ts +20 -0
- package/dist/lint-staged/config.d.ts.map +1 -0
- package/dist/lint-staged/config.js +27 -0
- package/dist/lint-staged/config.js.map +1 -0
- package/dist/utils/file-reader.d.ts +24 -0
- package/dist/utils/file-reader.d.ts.map +1 -0
- package/dist/utils/file-reader.js +140 -0
- package/dist/utils/file-reader.js.map +1 -0
- package/dist/utils/patterns.d.ts +27 -0
- package/dist/utils/patterns.d.ts.map +1 -0
- package/dist/utils/patterns.js +84 -0
- package/dist/utils/patterns.js.map +1 -0
- package/dist/utils/reporters.d.ts +21 -0
- package/dist/utils/reporters.d.ts.map +1 -0
- package/dist/utils/reporters.js +115 -0
- package/dist/utils/reporters.js.map +1 -0
- package/dist/utils/types.d.ts +71 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +5 -0
- package/dist/utils/types.js.map +1 -0
- package/integrations/cursorrules.template +147 -0
- package/integrations/eslint.config.js +34 -0
- package/integrations/lint-staged.config.js +34 -0
- package/integrations/ruff.toml +125 -0
- package/integrations/vibe-check.yml +116 -0
- package/integrations/vscode-settings.json +127 -0
- package/package.json +81 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatters for CLI results
|
|
3
|
+
*/
|
|
4
|
+
// ANSI color codes
|
|
5
|
+
const colors = {
|
|
6
|
+
reset: '\x1b[0m',
|
|
7
|
+
bold: '\x1b[1m',
|
|
8
|
+
dim: '\x1b[2m',
|
|
9
|
+
red: '\x1b[31m',
|
|
10
|
+
yellow: '\x1b[33m',
|
|
11
|
+
blue: '\x1b[34m',
|
|
12
|
+
cyan: '\x1b[36m',
|
|
13
|
+
gray: '\x1b[90m',
|
|
14
|
+
};
|
|
15
|
+
function severityColor(severity) {
|
|
16
|
+
switch (severity) {
|
|
17
|
+
case 'error':
|
|
18
|
+
return colors.red;
|
|
19
|
+
case 'warning':
|
|
20
|
+
return colors.yellow;
|
|
21
|
+
case 'info':
|
|
22
|
+
return colors.blue;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function severityIcon(severity) {
|
|
26
|
+
switch (severity) {
|
|
27
|
+
case 'error':
|
|
28
|
+
return '✖';
|
|
29
|
+
case 'warning':
|
|
30
|
+
return '⚠';
|
|
31
|
+
case 'info':
|
|
32
|
+
return 'ℹ';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Pretty format - colored terminal output
|
|
37
|
+
*/
|
|
38
|
+
export function formatPretty(summary) {
|
|
39
|
+
const lines = [];
|
|
40
|
+
// Header
|
|
41
|
+
lines.push('');
|
|
42
|
+
lines.push(`${colors.bold}vibe-check${colors.reset}`);
|
|
43
|
+
lines.push('');
|
|
44
|
+
// Results by file
|
|
45
|
+
for (const result of summary.results) {
|
|
46
|
+
if (result.issues.length === 0)
|
|
47
|
+
continue;
|
|
48
|
+
lines.push(`${colors.cyan}${result.filePath}${colors.reset}`);
|
|
49
|
+
for (const issue of result.issues) {
|
|
50
|
+
const color = severityColor(issue.severity);
|
|
51
|
+
const icon = severityIcon(issue.severity);
|
|
52
|
+
const location = issue.column
|
|
53
|
+
? `${issue.line}:${issue.column}`
|
|
54
|
+
: `${issue.line}`;
|
|
55
|
+
lines.push(` ${colors.gray}${location.padEnd(8)}${colors.reset}` +
|
|
56
|
+
`${color}${icon}${colors.reset} ` +
|
|
57
|
+
`${issue.message} ${colors.dim}${issue.ruleId}${colors.reset}`);
|
|
58
|
+
}
|
|
59
|
+
lines.push('');
|
|
60
|
+
}
|
|
61
|
+
// Summary
|
|
62
|
+
const problems = [];
|
|
63
|
+
if (summary.errorCount > 0) {
|
|
64
|
+
problems.push(`${colors.red}${summary.errorCount} error${summary.errorCount === 1 ? '' : 's'}${colors.reset}`);
|
|
65
|
+
}
|
|
66
|
+
if (summary.warningCount > 0) {
|
|
67
|
+
problems.push(`${colors.yellow}${summary.warningCount} warning${summary.warningCount === 1 ? '' : 's'}${colors.reset}`);
|
|
68
|
+
}
|
|
69
|
+
if (summary.infoCount > 0) {
|
|
70
|
+
problems.push(`${colors.blue}${summary.infoCount} info${colors.reset}`);
|
|
71
|
+
}
|
|
72
|
+
if (problems.length > 0) {
|
|
73
|
+
lines.push(`${problems.join(', ')} in ${summary.filesWithIssues} file${summary.filesWithIssues === 1 ? '' : 's'}`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
lines.push(`${colors.bold}✓${colors.reset} ${summary.filesChecked} file${summary.filesChecked === 1 ? '' : 's'} checked - no issues found`);
|
|
77
|
+
}
|
|
78
|
+
lines.push('');
|
|
79
|
+
return lines.join('\n');
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* JSON format - machine-readable output
|
|
83
|
+
*/
|
|
84
|
+
export function formatJson(summary) {
|
|
85
|
+
return JSON.stringify(summary, null, 2);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Compact format - one line per issue
|
|
89
|
+
*/
|
|
90
|
+
export function formatCompact(summary) {
|
|
91
|
+
const lines = [];
|
|
92
|
+
for (const result of summary.results) {
|
|
93
|
+
for (const issue of result.issues) {
|
|
94
|
+
const location = issue.column
|
|
95
|
+
? `${issue.line}:${issue.column}`
|
|
96
|
+
: `${issue.line}`;
|
|
97
|
+
lines.push(`${result.filePath}:${location}: ${issue.severity}: ${issue.message} [${issue.ruleId}]`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return lines.join('\n');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Format results based on output format option
|
|
104
|
+
*/
|
|
105
|
+
export function formatResults(summary, format) {
|
|
106
|
+
switch (format) {
|
|
107
|
+
case 'pretty':
|
|
108
|
+
return formatPretty(summary);
|
|
109
|
+
case 'json':
|
|
110
|
+
return formatJson(summary);
|
|
111
|
+
case 'compact':
|
|
112
|
+
return formatCompact(summary);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=reporters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporters.js","sourceRoot":"","sources":["../../src/utils/reporters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for vibe-and-thrive
|
|
3
|
+
*/
|
|
4
|
+
export type Severity = 'error' | 'warning' | 'info';
|
|
5
|
+
export interface FileContext {
|
|
6
|
+
/** Absolute path to the file */
|
|
7
|
+
filePath: string;
|
|
8
|
+
/** File content as string */
|
|
9
|
+
content: string;
|
|
10
|
+
/** File extension without dot (e.g., 'ts', 'py') */
|
|
11
|
+
extension: string;
|
|
12
|
+
}
|
|
13
|
+
export interface HookResult {
|
|
14
|
+
/** 1-based line number */
|
|
15
|
+
line: number;
|
|
16
|
+
/** 0-based column number */
|
|
17
|
+
column?: number;
|
|
18
|
+
/** Human-readable message */
|
|
19
|
+
message: string;
|
|
20
|
+
/** Severity level */
|
|
21
|
+
severity: Severity;
|
|
22
|
+
/** Rule identifier (e.g., 'secrets/aws-key') */
|
|
23
|
+
ruleId: string;
|
|
24
|
+
/** Optional fix suggestion */
|
|
25
|
+
fix?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface Hook {
|
|
28
|
+
/** Unique identifier (e.g., 'secrets', 'debug-statements') */
|
|
29
|
+
id: string;
|
|
30
|
+
/** Human-readable name */
|
|
31
|
+
name: string;
|
|
32
|
+
/** Description of what this hook checks */
|
|
33
|
+
description: string;
|
|
34
|
+
/** Default severity level */
|
|
35
|
+
severity: Severity;
|
|
36
|
+
/** File extensions this hook applies to (without dots) */
|
|
37
|
+
fileTypes: string[];
|
|
38
|
+
/** Check function that returns issues found */
|
|
39
|
+
check: (context: FileContext) => HookResult[];
|
|
40
|
+
}
|
|
41
|
+
export interface CheckOptions {
|
|
42
|
+
/** Only run these hooks (by id) */
|
|
43
|
+
only?: string[];
|
|
44
|
+
/** Skip these hooks (by id) */
|
|
45
|
+
skip?: string[];
|
|
46
|
+
/** Minimum severity to fail on */
|
|
47
|
+
failOn?: Severity;
|
|
48
|
+
/** Output format */
|
|
49
|
+
format?: 'pretty' | 'json' | 'compact';
|
|
50
|
+
/** Auto-fix issues where possible */
|
|
51
|
+
fix?: boolean;
|
|
52
|
+
}
|
|
53
|
+
export interface CheckResult {
|
|
54
|
+
/** File path */
|
|
55
|
+
filePath: string;
|
|
56
|
+
/** All issues found in this file */
|
|
57
|
+
issues: HookResult[];
|
|
58
|
+
}
|
|
59
|
+
export interface SummaryResult {
|
|
60
|
+
/** Total files checked */
|
|
61
|
+
filesChecked: number;
|
|
62
|
+
/** Files with issues */
|
|
63
|
+
filesWithIssues: number;
|
|
64
|
+
/** Total issues by severity */
|
|
65
|
+
errorCount: number;
|
|
66
|
+
warningCount: number;
|
|
67
|
+
infoCount: number;
|
|
68
|
+
/** All results */
|
|
69
|
+
results: CheckResult[];
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,IAAI;IACnB,8DAA8D;IAC9D,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,+CAA+C;IAC/C,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,UAAU,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,kCAAkC;IAClC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,oBAAoB;IACpB,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACvC,qCAAqC;IACrC,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Cursor Rules for Vibe Coding
|
|
2
|
+
# Copy this file to your project root as `.cursorrules`
|
|
3
|
+
|
|
4
|
+
You are an expert developer helping with this project. Follow these rules:
|
|
5
|
+
|
|
6
|
+
## Code Quality
|
|
7
|
+
|
|
8
|
+
### Never Use These Patterns
|
|
9
|
+
- `any` type in TypeScript - create proper interfaces
|
|
10
|
+
- Empty catch blocks - handle errors properly
|
|
11
|
+
- `console.log` for error handling - use proper logging
|
|
12
|
+
- Hardcoded URLs - use environment variables
|
|
13
|
+
- Functions over 50 lines - break them up
|
|
14
|
+
- Deep nesting (4+ levels) - refactor with early returns
|
|
15
|
+
|
|
16
|
+
### Always Do This
|
|
17
|
+
- Handle loading, error, and empty states
|
|
18
|
+
- Use proper TypeScript types
|
|
19
|
+
- Write descriptive variable names
|
|
20
|
+
- Add error handling for async operations
|
|
21
|
+
- Use environment variables for configuration
|
|
22
|
+
|
|
23
|
+
## Response Format
|
|
24
|
+
|
|
25
|
+
When writing code:
|
|
26
|
+
1. Explain what you're doing briefly
|
|
27
|
+
2. Write clean, typed code
|
|
28
|
+
3. Include error handling
|
|
29
|
+
4. Mention any edge cases to consider
|
|
30
|
+
|
|
31
|
+
When I ask you to fix something:
|
|
32
|
+
1. Explain what was wrong
|
|
33
|
+
2. Show the fix
|
|
34
|
+
3. Explain why it's better
|
|
35
|
+
|
|
36
|
+
## TypeScript Rules
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// DON'T
|
|
40
|
+
const data: any = await fetch('/api');
|
|
41
|
+
function process(input: any): any { }
|
|
42
|
+
|
|
43
|
+
// DO
|
|
44
|
+
interface User { id: string; name: string; }
|
|
45
|
+
const data: User = await fetchUser();
|
|
46
|
+
function process(input: UserInput): ProcessedUser { }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Error Handling
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// DON'T
|
|
53
|
+
try { doThing(); } catch (e) { }
|
|
54
|
+
|
|
55
|
+
// DO
|
|
56
|
+
try {
|
|
57
|
+
await doThing();
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (error instanceof NetworkError) {
|
|
60
|
+
logger.warn('Network error, retrying', { error });
|
|
61
|
+
return retry(doThing);
|
|
62
|
+
}
|
|
63
|
+
logger.error('Failed to do thing', { error });
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## React Components
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// DON'T
|
|
72
|
+
function UserProfile({ userId }) {
|
|
73
|
+
const [user, setUser] = useState();
|
|
74
|
+
// No loading/error handling
|
|
75
|
+
return <div>{user.name}</div>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// DO
|
|
79
|
+
function UserProfile({ userId }: { userId: string }) {
|
|
80
|
+
const { data: user, isLoading, error } = useUser(userId);
|
|
81
|
+
|
|
82
|
+
if (isLoading) return <Skeleton />;
|
|
83
|
+
if (error) return <ErrorMessage error={error} />;
|
|
84
|
+
if (!user) return <NotFound />;
|
|
85
|
+
|
|
86
|
+
return <div>{user.name}</div>;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Testing
|
|
91
|
+
|
|
92
|
+
When I ask you to write tests:
|
|
93
|
+
1. Use the SCENARIO/EXPECTED/FAILURE pattern
|
|
94
|
+
2. Test behavior, not implementation
|
|
95
|
+
3. Include happy path and error cases
|
|
96
|
+
4. Keep tests independent
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
test('user can submit form', async () => {
|
|
100
|
+
/**
|
|
101
|
+
* SCENARIO: User fills out valid form and submits
|
|
102
|
+
* EXPECTED: Success message shown, form cleared
|
|
103
|
+
* FAILURE: Error shown or form stuck
|
|
104
|
+
*/
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Security
|
|
109
|
+
|
|
110
|
+
Never:
|
|
111
|
+
- Put secrets in code
|
|
112
|
+
- Use innerHTML with user content
|
|
113
|
+
- Build SQL queries with string concatenation
|
|
114
|
+
- Trust user input without validation
|
|
115
|
+
|
|
116
|
+
Always:
|
|
117
|
+
- Use parameterized queries
|
|
118
|
+
- Sanitize HTML if you must render it
|
|
119
|
+
- Validate input on both client and server
|
|
120
|
+
- Use HTTPS for external requests
|
|
121
|
+
|
|
122
|
+
## When Asked to Review Code
|
|
123
|
+
|
|
124
|
+
Check for:
|
|
125
|
+
1. Security vulnerabilities
|
|
126
|
+
2. Missing error handling
|
|
127
|
+
3. `any` types
|
|
128
|
+
4. Code duplication
|
|
129
|
+
5. Long functions
|
|
130
|
+
6. Missing tests for critical paths
|
|
131
|
+
|
|
132
|
+
## Project-Specific Notes
|
|
133
|
+
|
|
134
|
+
<!-- Add your project-specific patterns here -->
|
|
135
|
+
|
|
136
|
+
### Tech Stack
|
|
137
|
+
- Frontend: [Your stack]
|
|
138
|
+
- Backend: [Your stack]
|
|
139
|
+
- Database: [Your database]
|
|
140
|
+
|
|
141
|
+
### Patterns to Follow
|
|
142
|
+
- [Pattern 1]
|
|
143
|
+
- [Pattern 2]
|
|
144
|
+
|
|
145
|
+
### Things to Avoid
|
|
146
|
+
- [Anti-pattern 1]
|
|
147
|
+
- [Anti-pattern 2]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example ESLint configuration using vibe-and-thrive plugin
|
|
3
|
+
*
|
|
4
|
+
* Copy this file to your project root and customize as needed.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import vibe from "vibe-and-thrive/eslint-plugin";
|
|
8
|
+
|
|
9
|
+
export default [
|
|
10
|
+
// Use the recommended config (balanced defaults)
|
|
11
|
+
vibe.configs.recommended,
|
|
12
|
+
|
|
13
|
+
// Or use strict config for stricter rules
|
|
14
|
+
// vibe.configs.strict,
|
|
15
|
+
|
|
16
|
+
// Custom configuration
|
|
17
|
+
{
|
|
18
|
+
files: ["**/*.ts", "**/*.tsx"],
|
|
19
|
+
rules: {
|
|
20
|
+
// Override specific rules if needed
|
|
21
|
+
// "vibe/no-any-type": "error",
|
|
22
|
+
// "vibe/max-function-length": ["warn", { max: 40 }],
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// Disable rules for test files
|
|
27
|
+
{
|
|
28
|
+
files: ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx"],
|
|
29
|
+
rules: {
|
|
30
|
+
"vibe/no-magic-numbers": "off",
|
|
31
|
+
"vibe/max-function-length": "off",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ready-to-use lint-staged configuration for vibe-and-thrive
|
|
3
|
+
*
|
|
4
|
+
* Copy this file to your project root, or reference the config:
|
|
5
|
+
*
|
|
6
|
+
* // package.json
|
|
7
|
+
* {
|
|
8
|
+
* "lint-staged": {
|
|
9
|
+
* "*.{js,ts,jsx,tsx}": "vibe-check --fail-on error"
|
|
10
|
+
* }
|
|
11
|
+
* }
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
// JavaScript/TypeScript files - full security and quality checks
|
|
16
|
+
'*.{js,jsx,ts,tsx,mjs,cjs}': [
|
|
17
|
+
'vibe-check --only secrets,urls,debug,unsafe-html,any-types,snake-case,empty-catch --fail-on error',
|
|
18
|
+
],
|
|
19
|
+
|
|
20
|
+
// Python files
|
|
21
|
+
'*.py': [
|
|
22
|
+
'vibe-check --only secrets,urls,debug,empty-catch,magic-numbers --fail-on error',
|
|
23
|
+
],
|
|
24
|
+
|
|
25
|
+
// Config files - secrets check only
|
|
26
|
+
'*.{json,yaml,yml,toml}': [
|
|
27
|
+
'vibe-check --only secrets --fail-on error',
|
|
28
|
+
],
|
|
29
|
+
|
|
30
|
+
// Dockerfiles
|
|
31
|
+
'Dockerfile*': [
|
|
32
|
+
'vibe-check --only docker-platform --fail-on warning',
|
|
33
|
+
],
|
|
34
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Ruff Configuration for Vibe Coding
|
|
2
|
+
#
|
|
3
|
+
# Catches common AI-generated code issues in Python.
|
|
4
|
+
# Copy to your project root as ruff.toml or pyproject.toml [tool.ruff] section.
|
|
5
|
+
#
|
|
6
|
+
# Install: pip install ruff
|
|
7
|
+
|
|
8
|
+
# Target Python version
|
|
9
|
+
target-version = "py311"
|
|
10
|
+
|
|
11
|
+
# Line length (match Black)
|
|
12
|
+
line-length = 100
|
|
13
|
+
|
|
14
|
+
# Exclude common directories
|
|
15
|
+
exclude = [
|
|
16
|
+
".git",
|
|
17
|
+
".venv",
|
|
18
|
+
"venv",
|
|
19
|
+
"__pycache__",
|
|
20
|
+
"migrations",
|
|
21
|
+
"node_modules",
|
|
22
|
+
"dist",
|
|
23
|
+
"build",
|
|
24
|
+
".eggs",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[lint]
|
|
28
|
+
# Enable these rule sets
|
|
29
|
+
select = [
|
|
30
|
+
# ===========================================
|
|
31
|
+
# Core rules - catch common AI mistakes
|
|
32
|
+
# ===========================================
|
|
33
|
+
"E", # pycodestyle errors
|
|
34
|
+
"W", # pycodestyle warnings
|
|
35
|
+
"F", # Pyflakes (unused imports, variables)
|
|
36
|
+
"I", # isort (import sorting)
|
|
37
|
+
"B", # flake8-bugbear (common bugs)
|
|
38
|
+
"C4", # flake8-comprehensions
|
|
39
|
+
"UP", # pyupgrade (modern Python syntax)
|
|
40
|
+
"SIM", # flake8-simplify (simplify code)
|
|
41
|
+
|
|
42
|
+
# ===========================================
|
|
43
|
+
# Security - AI can introduce vulnerabilities
|
|
44
|
+
# ===========================================
|
|
45
|
+
"S", # flake8-bandit (security issues)
|
|
46
|
+
|
|
47
|
+
# ===========================================
|
|
48
|
+
# Code quality
|
|
49
|
+
# ===========================================
|
|
50
|
+
"N", # pep8-naming
|
|
51
|
+
"RUF", # Ruff-specific rules
|
|
52
|
+
"PTH", # flake8-use-pathlib
|
|
53
|
+
"ERA", # eradicate (commented-out code)
|
|
54
|
+
"PL", # Pylint
|
|
55
|
+
"PERF", # Perflint (performance)
|
|
56
|
+
|
|
57
|
+
# ===========================================
|
|
58
|
+
# Type checking helpers
|
|
59
|
+
# ===========================================
|
|
60
|
+
"TCH", # flake8-type-checking
|
|
61
|
+
"ANN", # flake8-annotations
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
# Rules to ignore
|
|
65
|
+
ignore = [
|
|
66
|
+
# Allow missing type annotations in some cases
|
|
67
|
+
"ANN101", # Missing type annotation for self
|
|
68
|
+
"ANN102", # Missing type annotation for cls
|
|
69
|
+
"ANN401", # Dynamically typed expressions (Any)
|
|
70
|
+
|
|
71
|
+
# Allow assert in tests
|
|
72
|
+
"S101", # Use of assert
|
|
73
|
+
|
|
74
|
+
# These can be too strict
|
|
75
|
+
"PLR0913", # Too many arguments
|
|
76
|
+
"PLR2004", # Magic value comparison
|
|
77
|
+
"PLR0911", # Too many return statements
|
|
78
|
+
|
|
79
|
+
# Let formatter handle these
|
|
80
|
+
"E501", # Line too long (handled by formatter)
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
# Per-file ignores
|
|
84
|
+
[lint.per-file-ignores]
|
|
85
|
+
# Tests can have more relaxed rules
|
|
86
|
+
"tests/**/*.py" = [
|
|
87
|
+
"S101", # assert is fine in tests
|
|
88
|
+
"ANN", # Don't require annotations in tests
|
|
89
|
+
"PLR2004", # Magic values OK in tests
|
|
90
|
+
]
|
|
91
|
+
# Migrations are auto-generated
|
|
92
|
+
"**/migrations/*.py" = ["ALL"]
|
|
93
|
+
# Config files
|
|
94
|
+
"conftest.py" = ["ANN"]
|
|
95
|
+
|
|
96
|
+
[lint.isort]
|
|
97
|
+
# isort configuration
|
|
98
|
+
known-first-party = ["app", "core", "services"]
|
|
99
|
+
force-single-line = false
|
|
100
|
+
combine-as-imports = true
|
|
101
|
+
|
|
102
|
+
[lint.flake8-bugbear]
|
|
103
|
+
# Extend immutable calls (AI often mutates defaults)
|
|
104
|
+
extend-immutable-calls = ["fastapi.Depends", "fastapi.Query"]
|
|
105
|
+
|
|
106
|
+
[lint.pylint]
|
|
107
|
+
# Limit function complexity
|
|
108
|
+
max-args = 7
|
|
109
|
+
max-branches = 12
|
|
110
|
+
max-returns = 6
|
|
111
|
+
max-statements = 50
|
|
112
|
+
|
|
113
|
+
[lint.mccabe]
|
|
114
|
+
# Cyclomatic complexity threshold
|
|
115
|
+
max-complexity = 10
|
|
116
|
+
|
|
117
|
+
[format]
|
|
118
|
+
# Use double quotes (match Black)
|
|
119
|
+
quote-style = "double"
|
|
120
|
+
|
|
121
|
+
# Indent with spaces
|
|
122
|
+
indent-style = "space"
|
|
123
|
+
|
|
124
|
+
# Unix line endings
|
|
125
|
+
line-ending = "lf"
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# GitHub Action: Vibe Check
|
|
2
|
+
# Runs vibe-and-thrive pre-commit hooks on PRs
|
|
3
|
+
#
|
|
4
|
+
# Add this to your repo: .github/workflows/vibe-check.yml
|
|
5
|
+
|
|
6
|
+
name: Vibe Check
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [main, master]
|
|
11
|
+
push:
|
|
12
|
+
branches: [main, master]
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
vibe-check:
|
|
16
|
+
name: Code Quality Check
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout code
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: '3.11'
|
|
27
|
+
|
|
28
|
+
- name: Set up Node.js
|
|
29
|
+
uses: actions/setup-node@v4
|
|
30
|
+
with:
|
|
31
|
+
node-version: '20'
|
|
32
|
+
|
|
33
|
+
- name: Install pre-commit
|
|
34
|
+
run: pip install pre-commit
|
|
35
|
+
|
|
36
|
+
- name: Run pre-commit hooks
|
|
37
|
+
run: pre-commit run --all-files --show-diff-on-failure
|
|
38
|
+
continue-on-error: true
|
|
39
|
+
id: precommit
|
|
40
|
+
|
|
41
|
+
- name: Comment on PR (if issues found)
|
|
42
|
+
if: steps.precommit.outcome == 'failure' && github.event_name == 'pull_request'
|
|
43
|
+
uses: actions/github-script@v7
|
|
44
|
+
with:
|
|
45
|
+
script: |
|
|
46
|
+
github.rest.issues.createComment({
|
|
47
|
+
issue_number: context.issue.number,
|
|
48
|
+
owner: context.repo.owner,
|
|
49
|
+
repo: context.repo.repo,
|
|
50
|
+
body: `## ⚠️ Vibe Check Found Issues
|
|
51
|
+
|
|
52
|
+
The pre-commit hooks found some issues in this PR. Please review the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
|
|
53
|
+
|
|
54
|
+
Common fixes:
|
|
55
|
+
- \`any\` types → Create proper TypeScript interfaces
|
|
56
|
+
- Empty catch blocks → Add proper error handling
|
|
57
|
+
- Hardcoded URLs → Use environment variables
|
|
58
|
+
- console.log → Remove or use proper logging
|
|
59
|
+
|
|
60
|
+
Run \`pre-commit run --all-files\` locally to see all issues.`
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
- name: Check for blocking issues
|
|
64
|
+
run: |
|
|
65
|
+
# Only fail on blocking hooks (secrets, hardcoded URLs)
|
|
66
|
+
pre-commit run check-secrets --all-files
|
|
67
|
+
pre-commit run check-hardcoded-urls --all-files
|
|
68
|
+
|
|
69
|
+
# Optional: TypeScript type checking
|
|
70
|
+
typecheck:
|
|
71
|
+
name: TypeScript Check
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
if: hashFiles('**/tsconfig.json') != ''
|
|
74
|
+
|
|
75
|
+
steps:
|
|
76
|
+
- name: Checkout code
|
|
77
|
+
uses: actions/checkout@v4
|
|
78
|
+
|
|
79
|
+
- name: Set up Node.js
|
|
80
|
+
uses: actions/setup-node@v4
|
|
81
|
+
with:
|
|
82
|
+
node-version: '20'
|
|
83
|
+
cache: 'npm'
|
|
84
|
+
|
|
85
|
+
- name: Install dependencies
|
|
86
|
+
run: npm ci
|
|
87
|
+
working-directory: ${{ hashFiles('frontend/package.json') != '' && 'frontend' || '.' }}
|
|
88
|
+
|
|
89
|
+
- name: Run type check
|
|
90
|
+
run: npm run typecheck || npm run tsc -- --noEmit
|
|
91
|
+
working-directory: ${{ hashFiles('frontend/package.json') != '' && 'frontend' || '.' }}
|
|
92
|
+
continue-on-error: true
|
|
93
|
+
|
|
94
|
+
# Optional: Python type checking
|
|
95
|
+
mypy:
|
|
96
|
+
name: Python Type Check
|
|
97
|
+
runs-on: ubuntu-latest
|
|
98
|
+
if: hashFiles('**/pyproject.toml') != '' || hashFiles('**/setup.py') != ''
|
|
99
|
+
|
|
100
|
+
steps:
|
|
101
|
+
- name: Checkout code
|
|
102
|
+
uses: actions/checkout@v4
|
|
103
|
+
|
|
104
|
+
- name: Set up Python
|
|
105
|
+
uses: actions/setup-python@v5
|
|
106
|
+
with:
|
|
107
|
+
python-version: '3.11'
|
|
108
|
+
|
|
109
|
+
- name: Install dependencies
|
|
110
|
+
run: |
|
|
111
|
+
pip install mypy
|
|
112
|
+
pip install -e . || pip install -r requirements.txt || true
|
|
113
|
+
|
|
114
|
+
- name: Run mypy
|
|
115
|
+
run: mypy . --ignore-missing-imports
|
|
116
|
+
continue-on-error: true
|