@boshu2/vibe-check 1.0.0 → 1.0.2
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/CHANGELOG.md +35 -0
- package/LICENSE +21 -0
- package/README.md +89 -65
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/package.json +7 -4
- package/vitest.config.ts +14 -0
- package/src/cli.ts +0 -96
- package/src/git.ts +0 -72
- package/src/metrics/flow.ts +0 -53
- package/src/metrics/index.ts +0 -169
- package/src/metrics/rework.ts +0 -45
- package/src/metrics/spirals.ts +0 -173
- package/src/metrics/trust.ts +0 -80
- package/src/metrics/velocity.ts +0 -86
- package/src/output/index.ts +0 -20
- package/src/output/json.ts +0 -51
- package/src/output/markdown.ts +0 -111
- package/src/output/terminal.ts +0 -109
- package/src/types.ts +0 -68
- package/tsconfig.json +0 -19
package/src/output/markdown.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { VibeCheckResult } from '../types';
|
|
2
|
-
import { format } from 'date-fns';
|
|
3
|
-
|
|
4
|
-
export function formatMarkdown(result: VibeCheckResult): string {
|
|
5
|
-
const lines: string[] = [];
|
|
6
|
-
|
|
7
|
-
// Header
|
|
8
|
-
lines.push('# Vibe-Check Report');
|
|
9
|
-
lines.push('');
|
|
10
|
-
|
|
11
|
-
// Period
|
|
12
|
-
const fromStr = format(result.period.from, 'MMM d, yyyy');
|
|
13
|
-
const toStr = format(result.period.to, 'MMM d, yyyy');
|
|
14
|
-
lines.push(`**Period:** ${fromStr} - ${toStr} (${result.period.activeHours}h active)`);
|
|
15
|
-
lines.push(
|
|
16
|
-
`**Commits:** ${result.commits.total} total (${result.commits.feat} feat, ${result.commits.fix} fix, ${result.commits.docs} docs, ${result.commits.other} other)`
|
|
17
|
-
);
|
|
18
|
-
lines.push('');
|
|
19
|
-
|
|
20
|
-
// Overall
|
|
21
|
-
lines.push(`**Overall Rating:** ${result.overall}`);
|
|
22
|
-
lines.push('');
|
|
23
|
-
|
|
24
|
-
// Metrics table
|
|
25
|
-
lines.push('## Metrics');
|
|
26
|
-
lines.push('');
|
|
27
|
-
lines.push('| Metric | Value | Rating | Description |');
|
|
28
|
-
lines.push('|--------|-------|--------|-------------|');
|
|
29
|
-
|
|
30
|
-
const metrics = [
|
|
31
|
-
{ name: 'Iteration Velocity', metric: result.metrics.iterationVelocity },
|
|
32
|
-
{ name: 'Rework Ratio', metric: result.metrics.reworkRatio },
|
|
33
|
-
{ name: 'Trust Pass Rate', metric: result.metrics.trustPassRate },
|
|
34
|
-
{ name: 'Debug Spiral Duration', metric: result.metrics.debugSpiralDuration },
|
|
35
|
-
{ name: 'Flow Efficiency', metric: result.metrics.flowEfficiency },
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
for (const { name, metric } of metrics) {
|
|
39
|
-
const rating = metric.rating.toUpperCase();
|
|
40
|
-
lines.push(
|
|
41
|
-
`| ${name} | ${metric.value}${metric.unit} | ${rating} | ${metric.description} |`
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
lines.push('');
|
|
45
|
-
|
|
46
|
-
// Debug spirals
|
|
47
|
-
if (result.fixChains.length > 0) {
|
|
48
|
-
lines.push('## Debug Spirals');
|
|
49
|
-
lines.push('');
|
|
50
|
-
lines.push('| Component | Commits | Duration | Pattern |');
|
|
51
|
-
lines.push('|-----------|---------|----------|---------|');
|
|
52
|
-
|
|
53
|
-
for (const chain of result.fixChains) {
|
|
54
|
-
const pattern = chain.pattern || '-';
|
|
55
|
-
lines.push(
|
|
56
|
-
`| ${chain.component} | ${chain.commits} | ${chain.duration}m | ${pattern} |`
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
lines.push('');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Patterns
|
|
63
|
-
if (result.patterns.total > 0) {
|
|
64
|
-
lines.push('## Pattern Analysis');
|
|
65
|
-
lines.push('');
|
|
66
|
-
lines.push('| Pattern | Fix Count | Tracer Available |');
|
|
67
|
-
lines.push('|---------|-----------|------------------|');
|
|
68
|
-
|
|
69
|
-
for (const [pattern, count] of Object.entries(result.patterns.categories)) {
|
|
70
|
-
const tracer = pattern !== 'OTHER' ? 'Yes' : 'No';
|
|
71
|
-
lines.push(`| ${pattern} | ${count} | ${tracer} |`);
|
|
72
|
-
}
|
|
73
|
-
lines.push('');
|
|
74
|
-
lines.push(
|
|
75
|
-
`**${result.patterns.tracerAvailable}%** of fix patterns have tracer tests available.`
|
|
76
|
-
);
|
|
77
|
-
lines.push('');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Recommendations
|
|
81
|
-
lines.push('## Recommendations');
|
|
82
|
-
lines.push('');
|
|
83
|
-
|
|
84
|
-
if (result.metrics.reworkRatio.rating === 'low') {
|
|
85
|
-
lines.push('- High rework ratio detected. Consider running tracer tests before implementation.');
|
|
86
|
-
}
|
|
87
|
-
if (result.metrics.trustPassRate.rating === 'low' || result.metrics.trustPassRate.rating === 'medium') {
|
|
88
|
-
lines.push('- Trust pass rate below target. Validate assumptions before coding.');
|
|
89
|
-
}
|
|
90
|
-
if (result.metrics.debugSpiralDuration.rating === 'low') {
|
|
91
|
-
lines.push('- Long debug spirals detected. Break work into smaller, verifiable steps.');
|
|
92
|
-
}
|
|
93
|
-
if (result.fixChains.length > 0) {
|
|
94
|
-
const patterns = result.fixChains
|
|
95
|
-
.filter((c) => c.pattern)
|
|
96
|
-
.map((c) => c.pattern);
|
|
97
|
-
if (patterns.length > 0) {
|
|
98
|
-
lines.push(`- Consider adding tracer tests for: ${[...new Set(patterns)].join(', ')}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (lines[lines.length - 1] === '') {
|
|
103
|
-
lines.push('- All metrics healthy. Maintain current practices.');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
lines.push('');
|
|
107
|
-
lines.push('---');
|
|
108
|
-
lines.push(`*Generated by vibe-check on ${format(new Date(), 'yyyy-MM-dd HH:mm')}*`);
|
|
109
|
-
|
|
110
|
-
return lines.join('\n');
|
|
111
|
-
}
|
package/src/output/terminal.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { VibeCheckResult, Rating, OverallRating } from '../types';
|
|
3
|
-
import { format } from 'date-fns';
|
|
4
|
-
|
|
5
|
-
export function formatTerminal(result: VibeCheckResult): string {
|
|
6
|
-
const lines: string[] = [];
|
|
7
|
-
|
|
8
|
-
// Header
|
|
9
|
-
lines.push('');
|
|
10
|
-
lines.push(chalk.bold.cyan('=' .repeat(64)));
|
|
11
|
-
lines.push(chalk.bold.cyan(' VIBE-CHECK RESULTS'));
|
|
12
|
-
lines.push(chalk.bold.cyan('=' .repeat(64)));
|
|
13
|
-
|
|
14
|
-
// Period info
|
|
15
|
-
const fromStr = format(result.period.from, 'MMM d, yyyy');
|
|
16
|
-
const toStr = format(result.period.to, 'MMM d, yyyy');
|
|
17
|
-
lines.push('');
|
|
18
|
-
lines.push(
|
|
19
|
-
chalk.gray(` Period: ${fromStr} - ${toStr} (${result.period.activeHours}h active)`)
|
|
20
|
-
);
|
|
21
|
-
lines.push(
|
|
22
|
-
chalk.gray(
|
|
23
|
-
` Commits: ${result.commits.total} total (${result.commits.feat} feat, ${result.commits.fix} fix, ${result.commits.docs} docs, ${result.commits.other} other)`
|
|
24
|
-
)
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
// Metrics table
|
|
28
|
-
lines.push('');
|
|
29
|
-
lines.push(chalk.bold.white(' METRIC VALUE RATING'));
|
|
30
|
-
lines.push(chalk.gray(' ' + '-'.repeat(50)));
|
|
31
|
-
|
|
32
|
-
const metrics = [
|
|
33
|
-
{ name: 'Iteration Velocity', metric: result.metrics.iterationVelocity },
|
|
34
|
-
{ name: 'Rework Ratio', metric: result.metrics.reworkRatio },
|
|
35
|
-
{ name: 'Trust Pass Rate', metric: result.metrics.trustPassRate },
|
|
36
|
-
{ name: 'Debug Spiral Duration', metric: result.metrics.debugSpiralDuration },
|
|
37
|
-
{ name: 'Flow Efficiency', metric: result.metrics.flowEfficiency },
|
|
38
|
-
];
|
|
39
|
-
|
|
40
|
-
for (const { name, metric } of metrics) {
|
|
41
|
-
const valueStr = `${metric.value}${metric.unit}`.padEnd(10);
|
|
42
|
-
const ratingStr = formatRating(metric.rating);
|
|
43
|
-
lines.push(` ${name.padEnd(26)} ${valueStr} ${ratingStr}`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Overall rating
|
|
47
|
-
lines.push('');
|
|
48
|
-
lines.push(chalk.bold.cyan('-'.repeat(64)));
|
|
49
|
-
lines.push(` ${chalk.bold('OVERALL:')} ${formatOverallRating(result.overall)}`);
|
|
50
|
-
lines.push(chalk.bold.cyan('-'.repeat(64)));
|
|
51
|
-
|
|
52
|
-
// Debug spirals
|
|
53
|
-
if (result.fixChains.length > 0) {
|
|
54
|
-
lines.push('');
|
|
55
|
-
lines.push(
|
|
56
|
-
chalk.bold.yellow(` DEBUG SPIRALS (${result.fixChains.length} detected):`)
|
|
57
|
-
);
|
|
58
|
-
for (const chain of result.fixChains) {
|
|
59
|
-
const patternStr = chain.pattern ? ` (${chain.pattern})` : '';
|
|
60
|
-
lines.push(
|
|
61
|
-
chalk.yellow(
|
|
62
|
-
` - ${chain.component}: ${chain.commits} commits, ${chain.duration}m${patternStr}`
|
|
63
|
-
)
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Patterns
|
|
69
|
-
if (result.patterns.total > 0) {
|
|
70
|
-
lines.push('');
|
|
71
|
-
lines.push(chalk.bold.magenta(' PATTERNS:'));
|
|
72
|
-
for (const [pattern, count] of Object.entries(result.patterns.categories)) {
|
|
73
|
-
const tracerNote = pattern !== 'OTHER' ? ' (tracer available)' : '';
|
|
74
|
-
lines.push(chalk.magenta(` - ${pattern}: ${count} fixes${tracerNote}`));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
lines.push('');
|
|
79
|
-
lines.push(chalk.bold.cyan('=' .repeat(64)));
|
|
80
|
-
lines.push('');
|
|
81
|
-
|
|
82
|
-
return lines.join('\n');
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function formatRating(rating: Rating): string {
|
|
86
|
-
switch (rating) {
|
|
87
|
-
case 'elite':
|
|
88
|
-
return chalk.green.bold('ELITE');
|
|
89
|
-
case 'high':
|
|
90
|
-
return chalk.blue.bold('HIGH');
|
|
91
|
-
case 'medium':
|
|
92
|
-
return chalk.yellow.bold('MEDIUM');
|
|
93
|
-
case 'low':
|
|
94
|
-
return chalk.red.bold('LOW');
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function formatOverallRating(rating: OverallRating): string {
|
|
99
|
-
switch (rating) {
|
|
100
|
-
case 'ELITE':
|
|
101
|
-
return chalk.green.bold('ELITE');
|
|
102
|
-
case 'HIGH':
|
|
103
|
-
return chalk.blue.bold('HIGH');
|
|
104
|
-
case 'MEDIUM':
|
|
105
|
-
return chalk.yellow.bold('MEDIUM');
|
|
106
|
-
case 'LOW':
|
|
107
|
-
return chalk.red.bold('LOW');
|
|
108
|
-
}
|
|
109
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
export type Rating = 'elite' | 'high' | 'medium' | 'low';
|
|
2
|
-
export type OutputFormat = 'terminal' | 'json' | 'markdown';
|
|
3
|
-
export type OverallRating = 'ELITE' | 'HIGH' | 'MEDIUM' | 'LOW';
|
|
4
|
-
|
|
5
|
-
export interface Commit {
|
|
6
|
-
hash: string;
|
|
7
|
-
date: Date;
|
|
8
|
-
message: string;
|
|
9
|
-
type: 'feat' | 'fix' | 'docs' | 'chore' | 'refactor' | 'test' | 'style' | 'other';
|
|
10
|
-
scope: string | null;
|
|
11
|
-
author: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface MetricResult {
|
|
15
|
-
value: number;
|
|
16
|
-
unit: string;
|
|
17
|
-
rating: Rating;
|
|
18
|
-
description: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface FixChain {
|
|
22
|
-
component: string;
|
|
23
|
-
commits: number;
|
|
24
|
-
duration: number; // minutes
|
|
25
|
-
isSpiral: boolean;
|
|
26
|
-
pattern: string | null;
|
|
27
|
-
firstCommit: Date;
|
|
28
|
-
lastCommit: Date;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface PatternSummary {
|
|
32
|
-
categories: Record<string, number>;
|
|
33
|
-
total: number;
|
|
34
|
-
tracerAvailable: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface VibeCheckResult {
|
|
38
|
-
period: {
|
|
39
|
-
from: Date;
|
|
40
|
-
to: Date;
|
|
41
|
-
activeHours: number;
|
|
42
|
-
};
|
|
43
|
-
commits: {
|
|
44
|
-
total: number;
|
|
45
|
-
feat: number;
|
|
46
|
-
fix: number;
|
|
47
|
-
docs: number;
|
|
48
|
-
other: number;
|
|
49
|
-
};
|
|
50
|
-
metrics: {
|
|
51
|
-
iterationVelocity: MetricResult;
|
|
52
|
-
reworkRatio: MetricResult;
|
|
53
|
-
trustPassRate: MetricResult;
|
|
54
|
-
debugSpiralDuration: MetricResult;
|
|
55
|
-
flowEfficiency: MetricResult;
|
|
56
|
-
};
|
|
57
|
-
fixChains: FixChain[];
|
|
58
|
-
patterns: PatternSummary;
|
|
59
|
-
overall: OverallRating;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface CliOptions {
|
|
63
|
-
since?: string;
|
|
64
|
-
until?: string;
|
|
65
|
-
format: OutputFormat;
|
|
66
|
-
repo: string;
|
|
67
|
-
verbose: boolean;
|
|
68
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"lib": ["ES2020"],
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"rootDir": "./src",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"declaration": true,
|
|
14
|
-
"declarationMap": true,
|
|
15
|
-
"sourceMap": true
|
|
16
|
-
},
|
|
17
|
-
"include": ["src/**/*"],
|
|
18
|
-
"exclude": ["node_modules", "dist"]
|
|
19
|
-
}
|