@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/CHANGELOG.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.2] - 2025-11-28
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Complete README rewrite with problem-first structure
|
|
12
|
+
- Added "The Problem" and "The Insight" sections
|
|
13
|
+
- Added practical "When to Run" guidance
|
|
14
|
+
- Added prevention tips for debug spiral patterns
|
|
15
|
+
|
|
16
|
+
## [1.0.1] - 2025-11-28
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- LICENSE file (MIT)
|
|
20
|
+
- CHANGELOG.md
|
|
21
|
+
- .npmignore for cleaner package
|
|
22
|
+
- Jest test suite
|
|
23
|
+
- GitHub Actions CI
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- Version now imported from package.json (was hardcoded)
|
|
27
|
+
|
|
28
|
+
## [1.0.0] - 2025-11-28
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- Initial release
|
|
32
|
+
- 5 FAAFO metrics: Iteration Velocity, Rework Ratio, Trust Pass Rate, Debug Spiral Duration, Flow Efficiency
|
|
33
|
+
- Terminal, JSON, and Markdown output formats
|
|
34
|
+
- Debug spiral detection with pattern categorization
|
|
35
|
+
- Conventional commit parsing
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 bodefuller
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,107 +1,130 @@
|
|
|
1
1
|
# vibe-check
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Stop guessing if AI coding is working. Start measuring.**
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## The Problem
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
You're using AI to write code, but how do you know if it's actually helping?
|
|
8
|
+
|
|
9
|
+
Are you shipping features faster, or just generating more commits? Building new features, or debugging AI mistakes? Moving forward, or stuck in fix-fix-fix loops?
|
|
10
|
+
|
|
11
|
+
Without data, you're guessing.
|
|
12
|
+
|
|
13
|
+
## The Insight
|
|
14
|
+
|
|
15
|
+
vibe-check analyzes your git history and tells you:
|
|
16
|
+
|
|
17
|
+
| What You'll Learn | Why It Matters |
|
|
18
|
+
|-------------------|----------------|
|
|
19
|
+
| **Trust Pass Rate** | Are you accepting AI code that works, or code that breaks immediately? |
|
|
20
|
+
| **Debug Spirals** | Are you stuck in fix loops on the same component? |
|
|
21
|
+
| **Rework Ratio** | What percentage of your work is building vs. cleaning up? |
|
|
22
|
+
| **Pattern Detection** | What types of problems keep recurring? (auth, config, APIs...) |
|
|
23
|
+
|
|
24
|
+
## Quick Demo
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
$ npx @boshu2/vibe-check --since "1 week ago"
|
|
28
|
+
|
|
29
|
+
================================================================
|
|
30
|
+
VIBE-CHECK RESULTS
|
|
31
|
+
================================================================
|
|
32
|
+
Period: Nov 21 - Nov 28, 2025 (12.5h active)
|
|
33
|
+
Commits: 47 total (28 feat, 15 fix, 4 docs)
|
|
34
|
+
|
|
35
|
+
METRIC VALUE RATING
|
|
36
|
+
--------------------------------------------------
|
|
37
|
+
Iteration Velocity 4.2/hr HIGH
|
|
38
|
+
Rework Ratio 35% MEDIUM
|
|
39
|
+
Trust Pass Rate 92% HIGH
|
|
40
|
+
Debug Spiral Duration 18min HIGH
|
|
41
|
+
Flow Efficiency 85% HIGH
|
|
42
|
+
|
|
43
|
+
DEBUG SPIRALS (2 detected):
|
|
44
|
+
- auth: 4 commits, 25m (SECRETS_AUTH)
|
|
45
|
+
- api: 3 commits, 12m (API_MISMATCH)
|
|
46
|
+
|
|
47
|
+
OVERALL: HIGH
|
|
48
|
+
================================================================
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**What this tells you:** You're productive (4.2 commits/hour, 92% trust pass rate), but 35% of your work is fixing things—room to improve. OAuth caused a 25-minute spiral. Next time: validate auth flows with a tracer test before full implementation.
|
|
8
52
|
|
|
9
53
|
## Installation
|
|
10
54
|
|
|
11
55
|
```bash
|
|
12
|
-
npm install -g vibe-check
|
|
56
|
+
npm install -g @boshu2/vibe-check
|
|
13
57
|
```
|
|
14
58
|
|
|
15
|
-
Or run directly
|
|
59
|
+
Or run directly:
|
|
16
60
|
|
|
17
61
|
```bash
|
|
18
|
-
npx vibe-check
|
|
62
|
+
npx @boshu2/vibe-check
|
|
19
63
|
```
|
|
20
64
|
|
|
21
65
|
## Usage
|
|
22
66
|
|
|
23
67
|
```bash
|
|
24
|
-
# Analyze current repository
|
|
68
|
+
# Analyze current repository (all history)
|
|
25
69
|
vibe-check
|
|
26
70
|
|
|
27
|
-
# Analyze
|
|
71
|
+
# Analyze specific time period
|
|
28
72
|
vibe-check --since "1 week ago"
|
|
73
|
+
vibe-check --since "2025-11-01"
|
|
29
74
|
|
|
30
|
-
#
|
|
31
|
-
vibe-check --format json
|
|
75
|
+
# Different output formats
|
|
76
|
+
vibe-check --format json # For CI/automation
|
|
77
|
+
vibe-check --format markdown # For reports
|
|
32
78
|
|
|
33
|
-
#
|
|
34
|
-
vibe-check --format markdown
|
|
35
|
-
|
|
36
|
-
# Analyze specific repo
|
|
79
|
+
# Analyze a different repo
|
|
37
80
|
vibe-check --repo /path/to/repo
|
|
38
81
|
```
|
|
39
82
|
|
|
40
|
-
## The 5
|
|
41
|
-
|
|
42
|
-
| Metric | What It Measures | Target |
|
|
43
|
-
|--------|------------------|--------|
|
|
44
|
-
| **Iteration Velocity** | Commits per hour | >5/hr = Elite |
|
|
45
|
-
| **Rework Ratio** | % commits that are fixes | <30% = Elite |
|
|
46
|
-
| **Trust Pass Rate** | % commits that stick (no immediate fix) | >95% = Elite |
|
|
47
|
-
| **Debug Spiral Duration** | Time spent in fix chains | <15m = Elite |
|
|
48
|
-
| **Flow Efficiency** | % time in productive work vs debugging | >90% = Elite |
|
|
83
|
+
## The 5 Metrics
|
|
49
84
|
|
|
50
|
-
|
|
85
|
+
| Metric | What It Measures | Elite | Good | Needs Work |
|
|
86
|
+
|--------|------------------|-------|------|------------|
|
|
87
|
+
| **Iteration Velocity** | Commits per hour | >5/hr | 3-5/hr | <3/hr |
|
|
88
|
+
| **Rework Ratio** | % of commits that are fixes | <30% | 30-50% | >50% |
|
|
89
|
+
| **Trust Pass Rate** | % of commits without immediate fix | >95% | 80-95% | <80% |
|
|
90
|
+
| **Debug Spiral Duration** | Avg time stuck in fix chains | <15m | 15-30m | >30m |
|
|
91
|
+
| **Flow Efficiency** | % time building vs debugging | >90% | 75-90% | <75% |
|
|
51
92
|
|
|
52
|
-
|
|
53
|
-
|--------|---------|
|
|
54
|
-
| **ELITE** | Vibe coding working excellently |
|
|
55
|
-
| **HIGH** | Good effectiveness, minor improvements possible |
|
|
56
|
-
| **MEDIUM** | Room for improvement |
|
|
57
|
-
| **LOW** | Process issues, reassess approach |
|
|
93
|
+
### What the ratings mean
|
|
58
94
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
║ VIBE CHECK RESULTS ║
|
|
64
|
-
╠════════════════════════════════════════════════════════════╣
|
|
65
|
-
║ Period: Nov 21 - Nov 28, 2025 ║
|
|
66
|
-
║ Commits Analyzed: 47 ║
|
|
67
|
-
╠════════════════════════════════════════════════════════════╣
|
|
68
|
-
║ ║
|
|
69
|
-
║ Iteration Velocity ████████████░░░░ 4.2/hr HIGH ║
|
|
70
|
-
║ Rework Ratio ██████░░░░░░░░░░ 35% MEDIUM ║
|
|
71
|
-
║ Trust Pass Rate ████████████████ 92% HIGH ║
|
|
72
|
-
║ Debug Spiral Duration ██████████████░░ 18min HIGH ║
|
|
73
|
-
║ Flow Efficiency ██████████████░░ 85% HIGH ║
|
|
74
|
-
║ ║
|
|
75
|
-
╠════════════════════════════════════════════════════════════╣
|
|
76
|
-
║ Overall Rating: HIGH ║
|
|
77
|
-
╚════════════════════════════════════════════════════════════╝
|
|
78
|
-
```
|
|
95
|
+
- **ELITE**: Your AI collaboration is working excellently
|
|
96
|
+
- **HIGH**: Good effectiveness, minor improvements possible
|
|
97
|
+
- **MEDIUM**: Room for improvement—check which metrics are lagging
|
|
98
|
+
- **LOW**: Process issues—you're debugging more than building
|
|
79
99
|
|
|
80
100
|
## Debug Spiral Detection
|
|
81
101
|
|
|
82
|
-
When
|
|
83
|
-
- Which component had issues
|
|
84
|
-
- Pattern category (e.g., `API_MISMATCH`, `SSL_TLS`, `VOLUME_CONFIG`)
|
|
85
|
-
- Duration of the spiral
|
|
86
|
-
- Suggested tracer test to prevent recurrence
|
|
102
|
+
When vibe-check detects 3+ consecutive fix commits on the same component, it flags a "debug spiral" and categorizes the pattern:
|
|
87
103
|
|
|
88
|
-
|
|
104
|
+
| Pattern | What It Means | Prevention |
|
|
105
|
+
|---------|---------------|------------|
|
|
106
|
+
| `SECRETS_AUTH` | Auth/OAuth/credentials issues | Validate auth flow before implementation |
|
|
107
|
+
| `API_MISMATCH` | API version or schema problems | Check API docs, deploy minimal test first |
|
|
108
|
+
| `VOLUME_CONFIG` | Mount/path/permission issues | Test volume config in isolation |
|
|
109
|
+
| `SSL_TLS` | Certificate/HTTPS problems | Verify certs before deploying |
|
|
110
|
+
| `IMAGE_REGISTRY` | Container pull/tag issues | Test image pull separately |
|
|
89
111
|
|
|
90
|
-
|
|
112
|
+
## When to Run
|
|
91
113
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
114
|
+
- **Before starting work**: Establish your baseline
|
|
115
|
+
- **After a session**: Measure what just happened
|
|
116
|
+
- **Weekly**: Track trends over time
|
|
117
|
+
- **After frustrating sessions**: Identify what went wrong
|
|
95
118
|
|
|
96
|
-
## Options
|
|
119
|
+
## CLI Options
|
|
97
120
|
|
|
98
121
|
```
|
|
99
122
|
-V, --version Output version number
|
|
100
|
-
--since <date> Start date
|
|
101
|
-
--until <date> End date
|
|
102
|
-
-f, --format <type> Output
|
|
123
|
+
--since <date> Start date (e.g., "1 week ago", "2025-11-01")
|
|
124
|
+
--until <date> End date (default: now)
|
|
125
|
+
-f, --format <type> Output: terminal, json, markdown
|
|
103
126
|
-r, --repo <path> Repository path (default: current directory)
|
|
104
|
-
-v, --verbose Show
|
|
127
|
+
-v, --verbose Show detailed output
|
|
105
128
|
-h, --help Display help
|
|
106
129
|
```
|
|
107
130
|
|
|
@@ -109,6 +132,7 @@ This tool is designed to work with the RPI (Research-Plan-Implement) workflow:
|
|
|
109
132
|
|
|
110
133
|
- Node.js >= 18.0.0
|
|
111
134
|
- Git repository with commit history
|
|
135
|
+
- Conventional commits recommended (but not required)
|
|
112
136
|
|
|
113
137
|
## License
|
|
114
138
|
|
package/dist/cli.js
CHANGED
|
@@ -9,11 +9,13 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
9
9
|
const git_1 = require("./git");
|
|
10
10
|
const metrics_1 = require("./metrics");
|
|
11
11
|
const output_1 = require("./output");
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
13
|
+
const { version } = require('../package.json');
|
|
12
14
|
const program = new commander_1.Command();
|
|
13
15
|
program
|
|
14
16
|
.name('vibe-check')
|
|
15
17
|
.description('Measure vibe coding effectiveness with git commit analysis')
|
|
16
|
-
.version(
|
|
18
|
+
.version(version)
|
|
17
19
|
.option('--since <date>', 'Start date for analysis (e.g., "1 week ago", "2025-11-01")')
|
|
18
20
|
.option('--until <date>', 'End date for analysis (default: now)')
|
|
19
21
|
.option('-f, --format <type>', 'Output format: terminal, json, markdown', 'terminal')
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boshu2/vibe-check",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Measure vibe coding effectiveness with git commit analysis",
|
|
5
5
|
"main": "dist/cli.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"vibe-check": "
|
|
7
|
+
"vibe-check": "bin/vibe-check.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc",
|
|
11
11
|
"dev": "ts-node src/cli.ts",
|
|
12
12
|
"start": "node dist/cli.js",
|
|
13
|
-
"
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:coverage": "vitest run --coverage",
|
|
15
|
+
"prepublishOnly": "npm run build && npm test"
|
|
14
16
|
},
|
|
15
17
|
"keywords": [
|
|
16
18
|
"vibe-coding",
|
|
@@ -33,8 +35,9 @@
|
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"@types/node": "^20.17.6",
|
|
38
|
+
"ts-node": "^10.9.2",
|
|
36
39
|
"typescript": "^5.6.3",
|
|
37
|
-
"
|
|
40
|
+
"vitest": "^4.0.14"
|
|
38
41
|
},
|
|
39
42
|
"engines": {
|
|
40
43
|
"node": ">=18.0.0"
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
include: ['tests/**/*.test.ts'],
|
|
8
|
+
coverage: {
|
|
9
|
+
provider: 'v8',
|
|
10
|
+
include: ['src/**/*.ts'],
|
|
11
|
+
exclude: ['src/cli.ts'],
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
package/src/cli.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import { getCommits, isGitRepo } from './git';
|
|
6
|
-
import { analyzeCommits } from './metrics';
|
|
7
|
-
import { formatOutput } from './output';
|
|
8
|
-
import { OutputFormat } from './types';
|
|
9
|
-
|
|
10
|
-
const program = new Command();
|
|
11
|
-
|
|
12
|
-
program
|
|
13
|
-
.name('vibe-check')
|
|
14
|
-
.description('Measure vibe coding effectiveness with git commit analysis')
|
|
15
|
-
.version('1.0.0')
|
|
16
|
-
.option('--since <date>', 'Start date for analysis (e.g., "1 week ago", "2025-11-01")')
|
|
17
|
-
.option('--until <date>', 'End date for analysis (default: now)')
|
|
18
|
-
.option(
|
|
19
|
-
'-f, --format <type>',
|
|
20
|
-
'Output format: terminal, json, markdown',
|
|
21
|
-
'terminal'
|
|
22
|
-
)
|
|
23
|
-
.option('-r, --repo <path>', 'Repository path (default: current directory)', process.cwd())
|
|
24
|
-
.option('-v, --verbose', 'Show verbose output', false)
|
|
25
|
-
.action(async (options) => {
|
|
26
|
-
try {
|
|
27
|
-
const { since, until, format, repo, verbose } = options;
|
|
28
|
-
|
|
29
|
-
// Validate format
|
|
30
|
-
const validFormats: OutputFormat[] = ['terminal', 'json', 'markdown'];
|
|
31
|
-
if (!validFormats.includes(format)) {
|
|
32
|
-
console.error(chalk.red(`Invalid format: ${format}`));
|
|
33
|
-
console.error(chalk.gray(`Valid formats: ${validFormats.join(', ')}`));
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Check if repo is valid
|
|
38
|
-
if (!(await isGitRepo(repo))) {
|
|
39
|
-
console.error(chalk.red(`Not a git repository: ${repo}`));
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (verbose) {
|
|
44
|
-
console.error(chalk.gray(`Analyzing repository: ${repo}`));
|
|
45
|
-
if (since) console.error(chalk.gray(`Since: ${since}`));
|
|
46
|
-
if (until) console.error(chalk.gray(`Until: ${until}`));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Get commits
|
|
50
|
-
const commits = await getCommits(repo, since, until);
|
|
51
|
-
|
|
52
|
-
if (commits.length === 0) {
|
|
53
|
-
if (format === 'terminal') {
|
|
54
|
-
console.log(chalk.yellow('\nNo commits found in the specified range.\n'));
|
|
55
|
-
if (!since) {
|
|
56
|
-
console.log(chalk.gray('Try specifying a date range:'));
|
|
57
|
-
console.log(chalk.gray(' vibe-check --since "1 week ago"'));
|
|
58
|
-
console.log(chalk.gray(' vibe-check --since "2025-11-01"'));
|
|
59
|
-
}
|
|
60
|
-
} else if (format === 'json') {
|
|
61
|
-
console.log(JSON.stringify({ error: 'No commits found', commits: 0 }));
|
|
62
|
-
} else {
|
|
63
|
-
console.log('# Vibe-Check Report\n\nNo commits found in the specified range.');
|
|
64
|
-
}
|
|
65
|
-
process.exit(0);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (verbose) {
|
|
69
|
-
console.error(chalk.gray(`Found ${commits.length} commits`));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Analyze commits
|
|
73
|
-
const result = analyzeCommits(commits);
|
|
74
|
-
|
|
75
|
-
// Output result
|
|
76
|
-
const output = formatOutput(result, format as OutputFormat);
|
|
77
|
-
console.log(output);
|
|
78
|
-
|
|
79
|
-
// Exit with appropriate code based on overall rating
|
|
80
|
-
if (result.overall === 'LOW') {
|
|
81
|
-
process.exit(1);
|
|
82
|
-
}
|
|
83
|
-
} catch (error) {
|
|
84
|
-
if (error instanceof Error) {
|
|
85
|
-
console.error(chalk.red(`Error: ${error.message}`));
|
|
86
|
-
if (options.verbose) {
|
|
87
|
-
console.error(chalk.gray(error.stack));
|
|
88
|
-
}
|
|
89
|
-
} else {
|
|
90
|
-
console.error(chalk.red('An unexpected error occurred'));
|
|
91
|
-
}
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
program.parse();
|
package/src/git.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import simpleGit, { SimpleGit, LogResult, DefaultLogFields } from 'simple-git';
|
|
2
|
-
import { Commit } from './types';
|
|
3
|
-
|
|
4
|
-
const COMMIT_TYPES = ['feat', 'fix', 'docs', 'chore', 'refactor', 'test', 'style'] as const;
|
|
5
|
-
|
|
6
|
-
export async function getCommits(
|
|
7
|
-
repoPath: string,
|
|
8
|
-
since?: string,
|
|
9
|
-
until?: string
|
|
10
|
-
): Promise<Commit[]> {
|
|
11
|
-
const git: SimpleGit = simpleGit(repoPath);
|
|
12
|
-
|
|
13
|
-
// Build options for git log
|
|
14
|
-
const options: Record<string, string | number | boolean> = {};
|
|
15
|
-
|
|
16
|
-
if (since) {
|
|
17
|
-
options['--since'] = since;
|
|
18
|
-
}
|
|
19
|
-
if (until) {
|
|
20
|
-
options['--until'] = until;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
const log: LogResult<DefaultLogFields> = await git.log(options);
|
|
25
|
-
|
|
26
|
-
return log.all.map((entry) => parseCommit(entry));
|
|
27
|
-
} catch (error) {
|
|
28
|
-
if (error instanceof Error) {
|
|
29
|
-
throw new Error(`Failed to read git log: ${error.message}`);
|
|
30
|
-
}
|
|
31
|
-
throw error;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function parseCommit(entry: DefaultLogFields): Commit {
|
|
36
|
-
const { hash, date, message, author_name } = entry;
|
|
37
|
-
|
|
38
|
-
// Parse conventional commit format: type(scope): description
|
|
39
|
-
const conventionalMatch = message.match(/^(\w+)(?:\(([^)]+)\))?:\s*(.+)/);
|
|
40
|
-
|
|
41
|
-
let type: Commit['type'] = 'other';
|
|
42
|
-
let scope: string | null = null;
|
|
43
|
-
|
|
44
|
-
if (conventionalMatch) {
|
|
45
|
-
const [, rawType, rawScope] = conventionalMatch;
|
|
46
|
-
const normalizedType = rawType.toLowerCase();
|
|
47
|
-
|
|
48
|
-
if (COMMIT_TYPES.includes(normalizedType as typeof COMMIT_TYPES[number])) {
|
|
49
|
-
type = normalizedType as Commit['type'];
|
|
50
|
-
}
|
|
51
|
-
scope = rawScope || null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
hash: hash.substring(0, 7),
|
|
56
|
-
date: new Date(date),
|
|
57
|
-
message: message.split('\n')[0], // First line only
|
|
58
|
-
type,
|
|
59
|
-
scope,
|
|
60
|
-
author: author_name,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export async function isGitRepo(repoPath: string): Promise<boolean> {
|
|
65
|
-
const git: SimpleGit = simpleGit(repoPath);
|
|
66
|
-
try {
|
|
67
|
-
await git.status();
|
|
68
|
-
return true;
|
|
69
|
-
} catch {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
}
|
package/src/metrics/flow.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { FixChain, MetricResult, Rating } from '../types';
|
|
2
|
-
|
|
3
|
-
export function calculateFlowEfficiency(
|
|
4
|
-
activeMinutes: number,
|
|
5
|
-
spirals: FixChain[]
|
|
6
|
-
): MetricResult {
|
|
7
|
-
if (activeMinutes === 0) {
|
|
8
|
-
return {
|
|
9
|
-
value: 100,
|
|
10
|
-
unit: '%',
|
|
11
|
-
rating: 'elite',
|
|
12
|
-
description: 'No active time recorded',
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const spiralMinutes = spirals
|
|
17
|
-
.filter((s) => s.isSpiral)
|
|
18
|
-
.reduce((sum, s) => sum + s.duration, 0);
|
|
19
|
-
|
|
20
|
-
const efficiency = ((activeMinutes - spiralMinutes) / activeMinutes) * 100;
|
|
21
|
-
const clampedEfficiency = Math.max(0, Math.min(100, efficiency));
|
|
22
|
-
const rating = getRating(clampedEfficiency);
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
value: Math.round(clampedEfficiency),
|
|
26
|
-
unit: '%',
|
|
27
|
-
rating,
|
|
28
|
-
description: getDescription(rating, spiralMinutes),
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function getRating(efficiency: number): Rating {
|
|
33
|
-
if (efficiency > 90) return 'elite';
|
|
34
|
-
if (efficiency >= 75) return 'high';
|
|
35
|
-
if (efficiency >= 50) return 'medium';
|
|
36
|
-
return 'low';
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function getDescription(rating: Rating, spiralMinutes: number): string {
|
|
40
|
-
const spiralText =
|
|
41
|
-
spiralMinutes > 0 ? `${spiralMinutes}m spent in debug spirals` : 'No debug spirals';
|
|
42
|
-
|
|
43
|
-
switch (rating) {
|
|
44
|
-
case 'elite':
|
|
45
|
-
return `${spiralText}. Excellent productive flow`;
|
|
46
|
-
case 'high':
|
|
47
|
-
return `${spiralText}. Good balance`;
|
|
48
|
-
case 'medium':
|
|
49
|
-
return `${spiralText}. Significant debugging overhead`;
|
|
50
|
-
case 'low':
|
|
51
|
-
return `${spiralText}. More debugging than building`;
|
|
52
|
-
}
|
|
53
|
-
}
|