@boshu2/vibe-check 0.1.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 (143) hide show
  1. package/.dockerignore +46 -0
  2. package/.gitattributes +3 -0
  3. package/.pre-commit-hooks.yaml +11 -0
  4. package/AGENTS.md +40 -0
  5. package/CHANGELOG.md +322 -0
  6. package/CLAUDE.md +342 -0
  7. package/CONTRIBUTING.md +227 -0
  8. package/Dockerfile +26 -0
  9. package/LICENSE +201 -0
  10. package/Makefile +213 -0
  11. package/README.md +165 -0
  12. package/SECURITY.md +182 -0
  13. package/action.yml +270 -0
  14. package/assets/logo-dark.svg +47 -0
  15. package/assets/logo.svg +47 -0
  16. package/bin/vc.js +2 -0
  17. package/bin/vibe-check.js +2 -0
  18. package/claude-progress.json +312 -0
  19. package/claude-progress.txt +572 -0
  20. package/dist/cli.d.ts +3 -0
  21. package/dist/cli.d.ts.map +1 -0
  22. package/dist/cli.js +70 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/commands/analyze-helpers.d.ts +43 -0
  25. package/dist/commands/analyze-helpers.d.ts.map +1 -0
  26. package/dist/commands/analyze-helpers.js +124 -0
  27. package/dist/commands/analyze-helpers.js.map +1 -0
  28. package/dist/commands/analyze.d.ts +21 -0
  29. package/dist/commands/analyze.d.ts.map +1 -0
  30. package/dist/commands/analyze.js +114 -0
  31. package/dist/commands/analyze.js.map +1 -0
  32. package/dist/commands/index.d.ts +2 -0
  33. package/dist/commands/index.d.ts.map +1 -0
  34. package/dist/commands/index.js +2 -0
  35. package/dist/commands/index.js.map +1 -0
  36. package/dist/errors.d.ts +100 -0
  37. package/dist/errors.d.ts.map +1 -0
  38. package/dist/errors.js +208 -0
  39. package/dist/errors.js.map +1 -0
  40. package/dist/git.d.ts +39 -0
  41. package/dist/git.d.ts.map +1 -0
  42. package/dist/git.js +206 -0
  43. package/dist/git.js.map +1 -0
  44. package/dist/inner-loop/context-amnesia.d.ts +20 -0
  45. package/dist/inner-loop/context-amnesia.d.ts.map +1 -0
  46. package/dist/inner-loop/context-amnesia.js +246 -0
  47. package/dist/inner-loop/context-amnesia.js.map +1 -0
  48. package/dist/inner-loop/index.d.ts +39 -0
  49. package/dist/inner-loop/index.d.ts.map +1 -0
  50. package/dist/inner-loop/index.js +181 -0
  51. package/dist/inner-loop/index.js.map +1 -0
  52. package/dist/inner-loop/instruction-drift.d.ts +36 -0
  53. package/dist/inner-loop/instruction-drift.d.ts.map +1 -0
  54. package/dist/inner-loop/instruction-drift.js +270 -0
  55. package/dist/inner-loop/instruction-drift.js.map +1 -0
  56. package/dist/inner-loop/logging-only.d.ts +64 -0
  57. package/dist/inner-loop/logging-only.d.ts.map +1 -0
  58. package/dist/inner-loop/logging-only.js +292 -0
  59. package/dist/inner-loop/logging-only.js.map +1 -0
  60. package/dist/inner-loop/tests-passing-lie.d.ts +34 -0
  61. package/dist/inner-loop/tests-passing-lie.d.ts.map +1 -0
  62. package/dist/inner-loop/tests-passing-lie.js +213 -0
  63. package/dist/inner-loop/tests-passing-lie.js.map +1 -0
  64. package/dist/inner-loop/types.d.ts +125 -0
  65. package/dist/inner-loop/types.d.ts.map +1 -0
  66. package/dist/inner-loop/types.js +27 -0
  67. package/dist/inner-loop/types.js.map +1 -0
  68. package/dist/internal/context/index.d.ts +74 -0
  69. package/dist/internal/context/index.d.ts.map +1 -0
  70. package/dist/internal/context/index.js +151 -0
  71. package/dist/internal/context/index.js.map +1 -0
  72. package/dist/internal/context/types.d.ts +75 -0
  73. package/dist/internal/context/types.d.ts.map +1 -0
  74. package/dist/internal/context/types.js +8 -0
  75. package/dist/internal/context/types.js.map +1 -0
  76. package/dist/internal/output/contract.d.ts +81 -0
  77. package/dist/internal/output/contract.d.ts.map +1 -0
  78. package/dist/internal/output/contract.js +112 -0
  79. package/dist/internal/output/contract.js.map +1 -0
  80. package/dist/internal/output/index.d.ts +7 -0
  81. package/dist/internal/output/index.d.ts.map +1 -0
  82. package/dist/internal/output/index.js +7 -0
  83. package/dist/internal/output/index.js.map +1 -0
  84. package/dist/metrics/flow.d.ts +20 -0
  85. package/dist/metrics/flow.d.ts.map +1 -0
  86. package/dist/metrics/flow.js +85 -0
  87. package/dist/metrics/flow.js.map +1 -0
  88. package/dist/metrics/index.d.ts +4 -0
  89. package/dist/metrics/index.d.ts.map +1 -0
  90. package/dist/metrics/index.js +161 -0
  91. package/dist/metrics/index.js.map +1 -0
  92. package/dist/metrics/rework.d.ts +12 -0
  93. package/dist/metrics/rework.d.ts.map +1 -0
  94. package/dist/metrics/rework.js +51 -0
  95. package/dist/metrics/rework.js.map +1 -0
  96. package/dist/metrics/spirals.d.ts +17 -0
  97. package/dist/metrics/spirals.d.ts.map +1 -0
  98. package/dist/metrics/spirals.js +157 -0
  99. package/dist/metrics/spirals.js.map +1 -0
  100. package/dist/metrics/trust.d.ts +12 -0
  101. package/dist/metrics/trust.d.ts.map +1 -0
  102. package/dist/metrics/trust.js +175 -0
  103. package/dist/metrics/trust.js.map +1 -0
  104. package/dist/metrics/velocity.d.ts +25 -0
  105. package/dist/metrics/velocity.d.ts.map +1 -0
  106. package/dist/metrics/velocity.js +120 -0
  107. package/dist/metrics/velocity.js.map +1 -0
  108. package/dist/output/index.d.ts +10 -0
  109. package/dist/output/index.d.ts.map +1 -0
  110. package/dist/output/index.js +20 -0
  111. package/dist/output/index.js.map +1 -0
  112. package/dist/output/json.d.ts +3 -0
  113. package/dist/output/json.d.ts.map +1 -0
  114. package/dist/output/json.js +48 -0
  115. package/dist/output/json.js.map +1 -0
  116. package/dist/output/markdown.d.ts +3 -0
  117. package/dist/output/markdown.d.ts.map +1 -0
  118. package/dist/output/markdown.js +84 -0
  119. package/dist/output/markdown.js.map +1 -0
  120. package/dist/output/terminal.d.ts +10 -0
  121. package/dist/output/terminal.d.ts.map +1 -0
  122. package/dist/output/terminal.js +153 -0
  123. package/dist/output/terminal.js.map +1 -0
  124. package/dist/types.d.ts +75 -0
  125. package/dist/types.d.ts.map +1 -0
  126. package/dist/types.js +5 -0
  127. package/dist/types.js.map +1 -0
  128. package/docs/ARCHITECTURE.md +450 -0
  129. package/docs/DEPLOYMENT.md +394 -0
  130. package/docs/METRICS-EXPLAINED.md +394 -0
  131. package/docs/REFERENCE.md +230 -0
  132. package/docs/images/dashboard.png +0 -0
  133. package/drivers/README.md +327 -0
  134. package/drivers/go.sh +131 -0
  135. package/drivers/java.sh +137 -0
  136. package/drivers/javascript.sh +134 -0
  137. package/drivers/php.sh +132 -0
  138. package/drivers/python.sh +90 -0
  139. package/drivers/rust.sh +132 -0
  140. package/feature-list.json +273 -0
  141. package/hooks/pre-push +107 -0
  142. package/package.json +47 -0
  143. package/vitest.config.ts +25 -0
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Analyze command helper functions - encapsulates data loading, metrics computation, and output formatting
3
+ * Reduces coupling in analyze.ts by providing focused single-responsibility functions
4
+ */
5
+ import { analyzeCommits } from '../metrics/index.js';
6
+ import { OutputFormat, VibeCheckResultV2, Commit } from '../types.js';
7
+ export interface AnalyzeData {
8
+ commits: Commit[];
9
+ filtered: boolean;
10
+ filterScope?: string;
11
+ }
12
+ export interface ComputedMetrics {
13
+ result: ReturnType<typeof analyzeCommits>;
14
+ resultV2: VibeCheckResultV2;
15
+ }
16
+ /**
17
+ * Load commits from git repository with optional scope filtering
18
+ */
19
+ export declare function loadAnalyzeData(repo: string, since?: string, until?: string, scope?: string, verbose?: boolean): Promise<AnalyzeData>;
20
+ /**
21
+ * Compute all metrics from commits
22
+ */
23
+ export declare function computeAnalyzeMetrics(commits: Commit[], _repo: string, options?: {
24
+ includeEnhanced?: boolean;
25
+ since?: string;
26
+ until?: string;
27
+ verbose?: boolean;
28
+ }): Promise<ComputedMetrics>;
29
+ export interface OutputOptions {
30
+ format: OutputFormat;
31
+ simple?: boolean;
32
+ outputFile?: string;
33
+ verbose?: boolean;
34
+ }
35
+ /**
36
+ * Format and output analysis results
37
+ */
38
+ export declare function formatAnalyzeOutput(resultV2: VibeCheckResultV2, options: OutputOptions): string;
39
+ /**
40
+ * Handle the "no commits found" case with appropriate output
41
+ */
42
+ export declare function handleNoCommits(format: OutputFormat, since?: string): string;
43
+ //# sourceMappingURL=analyze-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/analyze-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,MAAM,EACP,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC1C,QAAQ,EAAE,iBAAiB,CAAC;CAC7B;AAMD;;GAEG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,WAAW,CAAC,CA6CtB;AAMD;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACd,GACL,OAAO,CAAC,eAAe,CAAC,CAW1B;AAMD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,aAAa,GACrB,MAAM,CAiBR;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CAcR"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Analyze command helper functions - encapsulates data loading, metrics computation, and output formatting
3
+ * Reduces coupling in analyze.ts by providing focused single-responsibility functions
4
+ */
5
+ import chalk from 'chalk';
6
+ import { writeFileSync } from 'fs';
7
+ import { getCommits } from '../git.js';
8
+ import { analyzeCommits } from '../metrics/index.js';
9
+ import { formatOutput } from '../output/index.js';
10
+ import { formatJson } from '../output/json.js';
11
+ import { getContext, hasContext, debugLog } from '../internal/context/index.js';
12
+ // ============================================================================
13
+ // Data Loading
14
+ // ============================================================================
15
+ /**
16
+ * Load commits from git repository with optional scope filtering
17
+ */
18
+ export async function loadAnalyzeData(repo, since, until, scope, verbose) {
19
+ // Use debug logging if context is available
20
+ const ctx = hasContext() ? getContext() : null;
21
+ if (ctx) {
22
+ debugLog(ctx, `Analyzing repository: ${repo}`);
23
+ if (since)
24
+ debugLog(ctx, `Since: ${since}`);
25
+ if (until)
26
+ debugLog(ctx, `Until: ${until}`);
27
+ if (scope)
28
+ debugLog(ctx, `Scope filter: ${scope}`);
29
+ }
30
+ else if (verbose) {
31
+ // Fallback for when context isn't available
32
+ console.error(chalk.gray(`Analyzing repository: ${repo}`));
33
+ if (since)
34
+ console.error(chalk.gray(`Since: ${since}`));
35
+ if (until)
36
+ console.error(chalk.gray(`Until: ${until}`));
37
+ if (scope)
38
+ console.error(chalk.gray(`Scope filter: ${scope}`));
39
+ }
40
+ // Get commits from git
41
+ const timeout = ctx?.timeout;
42
+ const maxCommits = ctx?.maxCommits;
43
+ let commits = await getCommits(repo, since, until, timeout, maxCommits);
44
+ let filtered = false;
45
+ // Apply scope filter if specified
46
+ if (scope) {
47
+ commits = commits.filter(c => c.scope === scope);
48
+ filtered = true;
49
+ if (ctx) {
50
+ debugLog(ctx, `Filtered to ${commits.length} commits in scope "${scope}"`);
51
+ }
52
+ else if (verbose) {
53
+ console.error(chalk.gray(`Filtered to ${commits.length} commits in scope "${scope}"`));
54
+ }
55
+ }
56
+ if (ctx) {
57
+ debugLog(ctx, `Found ${commits.length} commits`);
58
+ }
59
+ else if (verbose) {
60
+ console.error(chalk.gray(`Found ${commits.length} commits`));
61
+ }
62
+ return {
63
+ commits,
64
+ filtered,
65
+ filterScope: scope,
66
+ };
67
+ }
68
+ // ============================================================================
69
+ // Metrics Computation
70
+ // ============================================================================
71
+ /**
72
+ * Compute all metrics from commits
73
+ */
74
+ export async function computeAnalyzeMetrics(commits, _repo, options = {}) {
75
+ // Analyze commits (semantic metrics)
76
+ const result = analyzeCommits(commits);
77
+ // Build result
78
+ const resultV2 = {
79
+ ...result,
80
+ semanticMetrics: result.metrics,
81
+ };
82
+ return { result, resultV2 };
83
+ }
84
+ /**
85
+ * Format and output analysis results
86
+ */
87
+ export function formatAnalyzeOutput(resultV2, options) {
88
+ const { format, simple = false, outputFile, verbose } = options;
89
+ // Write to file if requested
90
+ if (outputFile) {
91
+ const jsonOutput = formatJson(resultV2);
92
+ writeFileSync(outputFile, jsonOutput);
93
+ const ctx = hasContext() ? getContext() : null;
94
+ if (ctx) {
95
+ debugLog(ctx, `Results written to: ${outputFile}`);
96
+ }
97
+ else if (verbose) {
98
+ console.error(chalk.gray(`Results written to: ${outputFile}`));
99
+ }
100
+ }
101
+ // Format output for console
102
+ return formatOutput(resultV2, format, { simple, verbose });
103
+ }
104
+ /**
105
+ * Handle the "no commits found" case with appropriate output
106
+ */
107
+ export function handleNoCommits(format, since) {
108
+ if (format === 'terminal') {
109
+ let output = chalk.yellow('\nNo commits found in the specified range.\n');
110
+ if (!since) {
111
+ output += chalk.gray('Try specifying a date range:\n');
112
+ output += chalk.gray(' vc --since "1 week ago"\n');
113
+ output += chalk.gray(' vc --since "2025-11-01"\n');
114
+ }
115
+ return output;
116
+ }
117
+ else if (format === 'json') {
118
+ return JSON.stringify({ error: 'No commits found', commits: 0 });
119
+ }
120
+ else {
121
+ return '# Vibe-Check Report\n\nNo commits found in the specified range.';
122
+ }
123
+ }
124
+ //# sourceMappingURL=analyze-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-helpers.js","sourceRoot":"","sources":["../../src/commands/analyze-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { Command } from 'commander';
2
+ import { ExitCode } from '../errors.js';
3
+ export interface AnalyzeOptions {
4
+ since?: string;
5
+ until?: string;
6
+ format: string;
7
+ repo: string;
8
+ verbose: boolean;
9
+ score: boolean;
10
+ output?: string;
11
+ simple: boolean;
12
+ scope?: string;
13
+ }
14
+ export declare function createAnalyzeCommand(): Command;
15
+ /**
16
+ * Main analyze function - orchestrator pattern
17
+ * Coordinates: validation -> data loading -> metrics -> output
18
+ * Returns exit code instead of calling process.exit
19
+ */
20
+ export declare function runAnalyze(options: AnalyzeOptions): Promise<ExitCode>;
21
+ //# sourceMappingURL=analyze.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,OAAO,EAGL,QAAQ,EAGT,MAAM,cAAc,CAAC;AAYtB,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwBD,wBAAgB,oBAAoB,IAAI,OAAO,CAoB9C;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwC3E"}
@@ -0,0 +1,114 @@
1
+ // ============================================================================
2
+ // IMPORTS
3
+ // ============================================================================
4
+ import { Command } from 'commander';
5
+ import chalk from 'chalk';
6
+ import { isGitRepo } from '../git.js';
7
+ import { GitError, ValidationError, ExitCode, isVibeCheckError, formatError, } from '../errors.js';
8
+ import { loadAnalyzeData, computeAnalyzeMetrics, formatAnalyzeOutput, handleNoCommits, } from './analyze-helpers.js';
9
+ // ============================================================================
10
+ // Validation Helpers
11
+ // ============================================================================
12
+ const VALID_FORMATS = ['terminal', 'json', 'markdown'];
13
+ function validateOptions(options) {
14
+ if (!VALID_FORMATS.includes(options.format)) {
15
+ throw ValidationError.invalidFormat(options.format, VALID_FORMATS);
16
+ }
17
+ }
18
+ async function validateRepo(repo) {
19
+ if (!(await isGitRepo(repo))) {
20
+ throw GitError.notARepo(repo);
21
+ }
22
+ }
23
+ // ============================================================================
24
+ // Command Implementation
25
+ // ============================================================================
26
+ export function createAnalyzeCommand() {
27
+ const cmd = new Command('analyze')
28
+ .description('Analyze git history for vibe coding metrics')
29
+ .option('--since <date>', 'Start date for analysis (e.g., "1 week ago")')
30
+ .option('--until <date>', 'End date for analysis (default: now)')
31
+ .option('-f, --format <type>', 'Output format: terminal, json, markdown', 'terminal')
32
+ .option('-r, --repo <path>', 'Repository path', process.cwd())
33
+ .option('-v, --verbose', 'Show verbose output', false)
34
+ .option('--score', 'Include VibeScore metrics', false)
35
+ .option('-o, --output <file>', 'Write JSON results to file')
36
+ .option('-s, --simple', 'Simplified output (fewer details)', false)
37
+ .option('--scope <scope>', 'Filter analysis to specific scope (e.g., "auth", "api")')
38
+ .action(async (options) => {
39
+ const exitCode = await runAnalyze(options);
40
+ if (exitCode !== ExitCode.SUCCESS) {
41
+ process.exit(exitCode);
42
+ }
43
+ });
44
+ return cmd;
45
+ }
46
+ /**
47
+ * Main analyze function - orchestrator pattern
48
+ * Coordinates: validation -> data loading -> metrics -> output
49
+ * Returns exit code instead of calling process.exit
50
+ */
51
+ export async function runAnalyze(options) {
52
+ try {
53
+ const { since, until, format, repo, verbose, score, output, simple, scope } = options;
54
+ // Step 1: Validate options and repo
55
+ validateOptions(options);
56
+ await validateRepo(repo);
57
+ // Step 2: Load data from git
58
+ const { commits } = await loadAnalyzeData(repo, since, until, scope, verbose);
59
+ // Handle no commits case
60
+ if (commits.length === 0) {
61
+ console.log(handleNoCommits(format, since));
62
+ return ExitCode.SUCCESS;
63
+ }
64
+ // Step 3: Compute metrics
65
+ const { result, resultV2 } = await computeAnalyzeMetrics(commits, repo, {
66
+ includeEnhanced: score,
67
+ since,
68
+ until,
69
+ verbose,
70
+ });
71
+ // Step 4: Format and output results
72
+ const formattedOutput = formatAnalyzeOutput(resultV2, {
73
+ format: format,
74
+ simple,
75
+ outputFile: output,
76
+ verbose,
77
+ });
78
+ console.log(formattedOutput);
79
+ // Return appropriate exit code based on overall rating
80
+ return result.overall === 'LOW' ? ExitCode.GENERAL_ERROR : ExitCode.SUCCESS;
81
+ }
82
+ catch (error) {
83
+ return handleAnalyzeError(error, options);
84
+ }
85
+ }
86
+ /**
87
+ * Handle errors from analyze command with appropriate formatting
88
+ */
89
+ function handleAnalyzeError(error, options) {
90
+ if (isVibeCheckError(error)) {
91
+ if (options.format === 'json') {
92
+ console.log(JSON.stringify(error.toJSON()));
93
+ }
94
+ else {
95
+ console.error(chalk.red(`Error: ${error.message}`));
96
+ if (options.verbose && error.stack) {
97
+ console.error(chalk.gray(error.stack));
98
+ }
99
+ }
100
+ return error.code;
101
+ }
102
+ // Handle unknown errors
103
+ if (options.format === 'json') {
104
+ console.log(JSON.stringify({ error: formatError(error) }));
105
+ }
106
+ else {
107
+ console.error(chalk.red(`Error: ${formatError(error)}`));
108
+ if (options.verbose && error instanceof Error && error.stack) {
109
+ console.error(chalk.gray(error.stack));
110
+ }
111
+ }
112
+ return ExitCode.GENERAL_ERROR;
113
+ }
114
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { runAnalyze, AnalyzeOptions } from './analyze.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { runAnalyze } from './analyze.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Custom error classes for vibe-check CLI
3
+ *
4
+ * Error hierarchy:
5
+ * VibeCheckError (base)
6
+ * ├── GitError (git operations)
7
+ * ├── ValidationError (input/option validation)
8
+ * ├── ConfigError (configuration issues)
9
+ * └── AnalysisError (metrics calculation)
10
+ *
11
+ * Exit codes:
12
+ * 0: Success
13
+ * 1: General error (analysis shows LOW rating)
14
+ * 2: Git error (not a repo, git command failed)
15
+ * 3: Validation error (invalid options, bad input)
16
+ * 5: Config error (invalid configuration)
17
+ * 6: Analysis error (metrics calculation failed)
18
+ */
19
+ export declare enum ExitCode {
20
+ SUCCESS = 0,
21
+ GENERAL_ERROR = 1,
22
+ GIT_ERROR = 2,
23
+ VALIDATION_ERROR = 3,
24
+ CONFIG_ERROR = 5,
25
+ ANALYSIS_ERROR = 6
26
+ }
27
+ /**
28
+ * Granular error codes for programmatic error handling.
29
+ */
30
+ export declare enum ErrorCode {
31
+ GIT_NOT_A_REPO = "GIT_NOT_A_REPO",
32
+ GIT_LOG_FAILED = "GIT_LOG_FAILED",
33
+ GIT_COMMIT_NOT_FOUND = "GIT_COMMIT_NOT_FOUND",
34
+ GIT_DIFF_FAILED = "GIT_DIFF_FAILED",
35
+ VALIDATION_INVALID_FORMAT = "VALIDATION_INVALID_FORMAT",
36
+ VALIDATION_INVALID_DATE_RANGE = "VALIDATION_INVALID_DATE_RANGE",
37
+ VALIDATION_MISSING_REQUIRED = "VALIDATION_MISSING_REQUIRED",
38
+ VALIDATION_INVALID_OPTION = "VALIDATION_INVALID_OPTION",
39
+ CONFIG_INVALID = "CONFIG_INVALID",
40
+ ANALYSIS_NO_COMMITS = "ANALYSIS_NO_COMMITS",
41
+ ANALYSIS_INSUFFICIENT_DATA = "ANALYSIS_INSUFFICIENT_DATA",
42
+ ANALYSIS_CALCULATION_FAILED = "ANALYSIS_CALCULATION_FAILED",
43
+ GENERAL_UNKNOWN = "GENERAL_UNKNOWN"
44
+ }
45
+ /**
46
+ * Base error class for all vibe-check errors.
47
+ */
48
+ export declare class VibeCheckError extends Error {
49
+ readonly exitCode: ExitCode;
50
+ readonly errorCode: ErrorCode;
51
+ readonly context: Record<string, unknown>;
52
+ /** @deprecated Use exitCode instead */
53
+ get code(): ExitCode;
54
+ constructor(message: string, exitCode?: ExitCode, errorCode?: ErrorCode, context?: Record<string, unknown>);
55
+ toJSON(): Record<string, unknown>;
56
+ }
57
+ /**
58
+ * Error thrown when git operations fail.
59
+ */
60
+ export declare class GitError extends VibeCheckError {
61
+ constructor(message: string, errorCode?: ErrorCode, context?: Record<string, unknown>);
62
+ static notARepo(path: string): GitError;
63
+ static logFailed(reason: string): GitError;
64
+ }
65
+ /**
66
+ * Error thrown when input validation fails.
67
+ */
68
+ export declare class ValidationError extends VibeCheckError {
69
+ constructor(message: string, errorCode?: ErrorCode, context?: Record<string, unknown>);
70
+ static invalidFormat(format: string, validFormats: string[]): ValidationError;
71
+ static invalidDateRange(since?: string, until?: string): ValidationError;
72
+ static missingRequired(option: string): ValidationError;
73
+ static invalidOption(option: string, value: unknown, reason: string): ValidationError;
74
+ }
75
+ /**
76
+ * Error thrown when configuration is invalid.
77
+ */
78
+ export declare class ConfigError extends VibeCheckError {
79
+ constructor(message: string, errorCode?: ErrorCode, context?: Record<string, unknown>);
80
+ static invalidConfig(path: string, reason: string): ConfigError;
81
+ }
82
+ /**
83
+ * Error thrown when analysis/metrics calculation fails.
84
+ */
85
+ export declare class AnalysisError extends VibeCheckError {
86
+ constructor(message: string, errorCode?: ErrorCode, context?: Record<string, unknown>);
87
+ static noCommits(since?: string, until?: string): AnalysisError;
88
+ static insufficientData(required: number, actual: number): AnalysisError;
89
+ static calculationFailed(metric: string, reason: string): AnalysisError;
90
+ }
91
+ export declare function isVibeCheckError(error: unknown): error is VibeCheckError;
92
+ export declare function isGitError(error: unknown): error is GitError;
93
+ export declare function isValidationError(error: unknown): error is ValidationError;
94
+ export declare function isConfigError(error: unknown): error is ConfigError;
95
+ export declare function isAnalysisError(error: unknown): error is AnalysisError;
96
+ export declare function getExitCode(error: unknown): ExitCode;
97
+ export declare function getErrorCode(error: unknown): ErrorCode;
98
+ export declare function formatError(error: unknown, verbose?: boolean): string;
99
+ export declare function wrapError(error: unknown, exitCode?: ExitCode, errorCode?: ErrorCode): VibeCheckError;
100
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/errors.js ADDED
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Custom error classes for vibe-check CLI
3
+ *
4
+ * Error hierarchy:
5
+ * VibeCheckError (base)
6
+ * ├── GitError (git operations)
7
+ * ├── ValidationError (input/option validation)
8
+ * ├── ConfigError (configuration issues)
9
+ * └── AnalysisError (metrics calculation)
10
+ *
11
+ * Exit codes:
12
+ * 0: Success
13
+ * 1: General error (analysis shows LOW rating)
14
+ * 2: Git error (not a repo, git command failed)
15
+ * 3: Validation error (invalid options, bad input)
16
+ * 5: Config error (invalid configuration)
17
+ * 6: Analysis error (metrics calculation failed)
18
+ */
19
+ export var ExitCode;
20
+ (function (ExitCode) {
21
+ ExitCode[ExitCode["SUCCESS"] = 0] = "SUCCESS";
22
+ ExitCode[ExitCode["GENERAL_ERROR"] = 1] = "GENERAL_ERROR";
23
+ ExitCode[ExitCode["GIT_ERROR"] = 2] = "GIT_ERROR";
24
+ ExitCode[ExitCode["VALIDATION_ERROR"] = 3] = "VALIDATION_ERROR";
25
+ ExitCode[ExitCode["CONFIG_ERROR"] = 5] = "CONFIG_ERROR";
26
+ ExitCode[ExitCode["ANALYSIS_ERROR"] = 6] = "ANALYSIS_ERROR";
27
+ })(ExitCode || (ExitCode = {}));
28
+ /**
29
+ * Granular error codes for programmatic error handling.
30
+ */
31
+ export var ErrorCode;
32
+ (function (ErrorCode) {
33
+ // Git errors
34
+ ErrorCode["GIT_NOT_A_REPO"] = "GIT_NOT_A_REPO";
35
+ ErrorCode["GIT_LOG_FAILED"] = "GIT_LOG_FAILED";
36
+ ErrorCode["GIT_COMMIT_NOT_FOUND"] = "GIT_COMMIT_NOT_FOUND";
37
+ ErrorCode["GIT_DIFF_FAILED"] = "GIT_DIFF_FAILED";
38
+ // Validation errors
39
+ ErrorCode["VALIDATION_INVALID_FORMAT"] = "VALIDATION_INVALID_FORMAT";
40
+ ErrorCode["VALIDATION_INVALID_DATE_RANGE"] = "VALIDATION_INVALID_DATE_RANGE";
41
+ ErrorCode["VALIDATION_MISSING_REQUIRED"] = "VALIDATION_MISSING_REQUIRED";
42
+ ErrorCode["VALIDATION_INVALID_OPTION"] = "VALIDATION_INVALID_OPTION";
43
+ // Config errors
44
+ ErrorCode["CONFIG_INVALID"] = "CONFIG_INVALID";
45
+ // Analysis errors
46
+ ErrorCode["ANALYSIS_NO_COMMITS"] = "ANALYSIS_NO_COMMITS";
47
+ ErrorCode["ANALYSIS_INSUFFICIENT_DATA"] = "ANALYSIS_INSUFFICIENT_DATA";
48
+ ErrorCode["ANALYSIS_CALCULATION_FAILED"] = "ANALYSIS_CALCULATION_FAILED";
49
+ // General errors
50
+ ErrorCode["GENERAL_UNKNOWN"] = "GENERAL_UNKNOWN";
51
+ })(ErrorCode || (ErrorCode = {}));
52
+ /**
53
+ * Base error class for all vibe-check errors.
54
+ */
55
+ export class VibeCheckError extends Error {
56
+ exitCode;
57
+ errorCode;
58
+ context;
59
+ /** @deprecated Use exitCode instead */
60
+ get code() {
61
+ return this.exitCode;
62
+ }
63
+ constructor(message, exitCode = ExitCode.GENERAL_ERROR, errorCode = ErrorCode.GENERAL_UNKNOWN, context = {}) {
64
+ super(message);
65
+ this.name = 'VibeCheckError';
66
+ this.exitCode = exitCode;
67
+ this.errorCode = errorCode;
68
+ this.context = context;
69
+ if (Error.captureStackTrace) {
70
+ Error.captureStackTrace(this, this.constructor);
71
+ }
72
+ }
73
+ toJSON() {
74
+ return {
75
+ error: this.name,
76
+ message: this.message,
77
+ exitCode: this.exitCode,
78
+ errorCode: this.errorCode,
79
+ ...this.context,
80
+ };
81
+ }
82
+ }
83
+ /**
84
+ * Error thrown when git operations fail.
85
+ */
86
+ export class GitError extends VibeCheckError {
87
+ constructor(message, errorCode = ErrorCode.GIT_LOG_FAILED, context = {}) {
88
+ super(message, ExitCode.GIT_ERROR, errorCode, context);
89
+ this.name = 'GitError';
90
+ }
91
+ static notARepo(path) {
92
+ return new GitError(`Not a git repository: ${path}`, ErrorCode.GIT_NOT_A_REPO, { path });
93
+ }
94
+ static logFailed(reason) {
95
+ return new GitError(`Failed to read git log: ${reason}`, ErrorCode.GIT_LOG_FAILED, { reason });
96
+ }
97
+ }
98
+ /**
99
+ * Error thrown when input validation fails.
100
+ */
101
+ export class ValidationError extends VibeCheckError {
102
+ constructor(message, errorCode = ErrorCode.VALIDATION_INVALID_OPTION, context = {}) {
103
+ super(message, ExitCode.VALIDATION_ERROR, errorCode, context);
104
+ this.name = 'ValidationError';
105
+ }
106
+ static invalidFormat(format, validFormats) {
107
+ return new ValidationError(`Invalid format: ${format}. Valid formats: ${validFormats.join(', ')}`, ErrorCode.VALIDATION_INVALID_FORMAT, { format, validFormats });
108
+ }
109
+ static invalidDateRange(since, until) {
110
+ return new ValidationError(`Invalid date range: since="${since}" until="${until}"`, ErrorCode.VALIDATION_INVALID_DATE_RANGE, { since, until });
111
+ }
112
+ static missingRequired(option) {
113
+ return new ValidationError(`Missing required option: ${option}`, ErrorCode.VALIDATION_MISSING_REQUIRED, { option });
114
+ }
115
+ static invalidOption(option, value, reason) {
116
+ return new ValidationError(`Invalid value for ${option}: ${reason}`, ErrorCode.VALIDATION_INVALID_OPTION, { option, value, reason });
117
+ }
118
+ }
119
+ /**
120
+ * Error thrown when configuration is invalid.
121
+ */
122
+ export class ConfigError extends VibeCheckError {
123
+ constructor(message, errorCode = ErrorCode.CONFIG_INVALID, context = {}) {
124
+ super(message, ExitCode.CONFIG_ERROR, errorCode, context);
125
+ this.name = 'ConfigError';
126
+ }
127
+ static invalidConfig(path, reason) {
128
+ return new ConfigError(`Invalid configuration in ${path}: ${reason}`, ErrorCode.CONFIG_INVALID, { path, reason });
129
+ }
130
+ }
131
+ /**
132
+ * Error thrown when analysis/metrics calculation fails.
133
+ */
134
+ export class AnalysisError extends VibeCheckError {
135
+ constructor(message, errorCode = ErrorCode.ANALYSIS_CALCULATION_FAILED, context = {}) {
136
+ super(message, ExitCode.ANALYSIS_ERROR, errorCode, context);
137
+ this.name = 'AnalysisError';
138
+ }
139
+ static noCommits(since, until) {
140
+ return new AnalysisError('No commits found in the specified range', ErrorCode.ANALYSIS_NO_COMMITS, { since, until });
141
+ }
142
+ static insufficientData(required, actual) {
143
+ return new AnalysisError(`Insufficient data: need ${required} commits, found ${actual}`, ErrorCode.ANALYSIS_INSUFFICIENT_DATA, { required, actual });
144
+ }
145
+ static calculationFailed(metric, reason) {
146
+ return new AnalysisError(`Failed to calculate ${metric}: ${reason}`, ErrorCode.ANALYSIS_CALCULATION_FAILED, { metric, reason });
147
+ }
148
+ }
149
+ // Type guards
150
+ export function isVibeCheckError(error) {
151
+ return error instanceof VibeCheckError;
152
+ }
153
+ export function isGitError(error) {
154
+ return error instanceof GitError;
155
+ }
156
+ export function isValidationError(error) {
157
+ return error instanceof ValidationError;
158
+ }
159
+ export function isConfigError(error) {
160
+ return error instanceof ConfigError;
161
+ }
162
+ export function isAnalysisError(error) {
163
+ return error instanceof AnalysisError;
164
+ }
165
+ // Utility functions
166
+ export function getExitCode(error) {
167
+ if (isVibeCheckError(error)) {
168
+ return error.exitCode;
169
+ }
170
+ return ExitCode.GENERAL_ERROR;
171
+ }
172
+ export function getErrorCode(error) {
173
+ if (isVibeCheckError(error)) {
174
+ return error.errorCode;
175
+ }
176
+ return ErrorCode.GENERAL_UNKNOWN;
177
+ }
178
+ export function formatError(error, verbose = false) {
179
+ if (isVibeCheckError(error)) {
180
+ const base = verbose
181
+ ? `[${error.errorCode}] ${error.message}`
182
+ : error.message;
183
+ if (verbose && error.stack) {
184
+ return `${base}\n${error.stack}`;
185
+ }
186
+ return base;
187
+ }
188
+ if (error instanceof Error) {
189
+ if (verbose && error.stack) {
190
+ return `${error.message}\n${error.stack}`;
191
+ }
192
+ return error.message;
193
+ }
194
+ return String(error);
195
+ }
196
+ export function wrapError(error, exitCode = ExitCode.GENERAL_ERROR, errorCode = ErrorCode.GENERAL_UNKNOWN) {
197
+ if (isVibeCheckError(error)) {
198
+ return error;
199
+ }
200
+ if (error instanceof Error) {
201
+ return new VibeCheckError(error.message, exitCode, errorCode, {
202
+ originalError: error.name,
203
+ stack: error.stack,
204
+ });
205
+ }
206
+ return new VibeCheckError(String(error), exitCode, errorCode);
207
+ }
208
+ //# sourceMappingURL=errors.js.map