@boshu2/vibe-check 1.5.0 → 1.6.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/.agents/bundles/insight-mining-dashboard-research-2025-11-30.md +400 -0
- package/.agents/bundles/storage-enhancement-research-2025-11-30.md +292 -0
- package/.agents/bundles/timeline-feature-research-complete-2025-11-30.md +301 -0
- package/.agents/plans/insight-dashboard-plan-2025-11-30.md +1130 -0
- package/.agents/plans/json-storage-enhancement-plan.md +717 -0
- package/.agents/plans/storage-hardening-and-cache-plan.md +592 -0
- package/.agents/plans/test-coverage-gaps-plan.md +1117 -0
- package/.agents/plans/timeline-feature-plan.md +193 -0
- package/.agents/plans/vibe_timeline_research_findings.md +553 -0
- package/.claude/settings.local.json +1 -0
- package/.vibe-check/.gitignore +6 -0
- package/CHANGELOG.md +46 -0
- package/CLAUDE.md +24 -0
- package/CONTRIBUTING.md +227 -0
- package/README.md +200 -143
- package/claude-progress.json +191 -9
- package/claude-progress.txt +257 -0
- package/dashboard/app.js +75 -2
- package/dashboard/dashboard-data.json +653 -0
- package/dashboard/index.html +13 -0
- package/dashboard/styles.css +61 -0
- package/dist/analysis/cross-session-analysis.d.ts +68 -0
- package/dist/analysis/cross-session-analysis.d.ts.map +1 -0
- package/dist/analysis/cross-session-analysis.js +174 -0
- package/dist/analysis/cross-session-analysis.js.map +1 -0
- package/dist/analysis/index.d.ts +2 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +12 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts +2 -0
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +105 -2
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/cache.d.ts +6 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +168 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/dashboard.d.ts +8 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +109 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +8 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/timeline.d.ts +14 -0
- package/dist/commands/timeline.d.ts.map +1 -0
- package/dist/commands/timeline.js +462 -0
- package/dist/commands/timeline.js.map +1 -0
- package/dist/git.d.ts +24 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +94 -0
- package/dist/git.js.map +1 -1
- package/dist/insights/generators.d.ts +44 -0
- package/dist/insights/generators.d.ts.map +1 -0
- package/dist/insights/generators.js +289 -0
- package/dist/insights/generators.js.map +1 -0
- package/dist/insights/index.d.ts +16 -0
- package/dist/insights/index.d.ts.map +1 -0
- package/dist/insights/index.js +171 -0
- package/dist/insights/index.js.map +1 -0
- package/dist/insights/types.d.ts +93 -0
- package/dist/insights/types.d.ts.map +1 -0
- package/dist/insights/types.js +6 -0
- package/dist/insights/types.js.map +1 -0
- package/dist/output/timeline-html.d.ts +6 -0
- package/dist/output/timeline-html.d.ts.map +1 -0
- package/dist/output/timeline-html.js +389 -0
- package/dist/output/timeline-html.js.map +1 -0
- package/dist/output/timeline-markdown.d.ts +6 -0
- package/dist/output/timeline-markdown.d.ts.map +1 -0
- package/dist/output/timeline-markdown.js +167 -0
- package/dist/output/timeline-markdown.js.map +1 -0
- package/dist/output/timeline.d.ts +9 -0
- package/dist/output/timeline.d.ts.map +1 -0
- package/dist/output/timeline.js +318 -0
- package/dist/output/timeline.js.map +1 -0
- package/dist/patterns/detour.d.ts +32 -0
- package/dist/patterns/detour.d.ts.map +1 -0
- package/dist/patterns/detour.js +137 -0
- package/dist/patterns/detour.js.map +1 -0
- package/dist/patterns/flow-state.d.ts +16 -0
- package/dist/patterns/flow-state.d.ts.map +1 -0
- package/dist/patterns/flow-state.js +40 -0
- package/dist/patterns/flow-state.js.map +1 -0
- package/dist/patterns/index.d.ts +8 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +22 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/patterns/intervention-effectiveness.d.ts +42 -0
- package/dist/patterns/intervention-effectiveness.d.ts.map +1 -0
- package/dist/patterns/intervention-effectiveness.js +196 -0
- package/dist/patterns/intervention-effectiveness.js.map +1 -0
- package/dist/patterns/late-night.d.ts +30 -0
- package/dist/patterns/late-night.d.ts.map +1 -0
- package/dist/patterns/late-night.js +141 -0
- package/dist/patterns/late-night.js.map +1 -0
- package/dist/patterns/post-delete-sprint.d.ts +28 -0
- package/dist/patterns/post-delete-sprint.d.ts.map +1 -0
- package/dist/patterns/post-delete-sprint.js +85 -0
- package/dist/patterns/post-delete-sprint.js.map +1 -0
- package/dist/patterns/spiral-regression.d.ts +49 -0
- package/dist/patterns/spiral-regression.d.ts.map +1 -0
- package/dist/patterns/spiral-regression.js +219 -0
- package/dist/patterns/spiral-regression.js.map +1 -0
- package/dist/patterns/thrashing.d.ts +25 -0
- package/dist/patterns/thrashing.d.ts.map +1 -0
- package/dist/patterns/thrashing.js +111 -0
- package/dist/patterns/thrashing.js.map +1 -0
- package/dist/storage/atomic.d.ts +40 -0
- package/dist/storage/atomic.d.ts.map +1 -0
- package/dist/storage/atomic.js +155 -0
- package/dist/storage/atomic.js.map +1 -0
- package/dist/storage/commit-log.d.ts +35 -0
- package/dist/storage/commit-log.d.ts.map +1 -0
- package/dist/storage/commit-log.js +128 -0
- package/dist/storage/commit-log.js.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +33 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/schema.d.ts +32 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +37 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/timeline-store.d.ts +117 -0
- package/dist/storage/timeline-store.d.ts.map +1 -0
- package/dist/storage/timeline-store.js +438 -0
- package/dist/storage/timeline-store.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/ARCHITECTURE.md +458 -0
- package/docs/DATA-ARCHITECTURE.md +565 -0
- package/docs/GAMIFICATION.md +564 -0
- package/docs/JSON-STORAGE-PATTERNS.md +512 -0
- package/docs/METRICS-EXPLAINED.md +394 -0
- package/docs/UNIFIED-ECOSYSTEM.md +560 -0
- package/docs/VIBE-ECOSYSTEM.md +406 -0
- package/feature-list.json +48 -0
- package/package.json +2 -1
- package/vitest.config.ts +1 -5
- package/.vibe-check/calibration.json +0 -38
- package/.vibe-check/latest.json +0 -114
- package/.vibe-check/sessions.json +0 -44
- package/PLAN-ultimate-game.md +0 -1362
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createTimelineCommand = createTimelineCommand;
|
|
7
|
+
exports.runTimeline = runTimeline;
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const git_1 = require("../git");
|
|
11
|
+
const metrics_1 = require("../metrics");
|
|
12
|
+
const timeline_1 = require("../output/timeline");
|
|
13
|
+
const timeline_markdown_1 = require("../output/timeline-markdown");
|
|
14
|
+
const timeline_html_1 = require("../output/timeline-html");
|
|
15
|
+
const storage_1 = require("../storage");
|
|
16
|
+
const date_fns_1 = require("date-fns");
|
|
17
|
+
const flow_state_1 = require("../patterns/flow-state");
|
|
18
|
+
const post_delete_sprint_1 = require("../patterns/post-delete-sprint");
|
|
19
|
+
const thrashing_1 = require("../patterns/thrashing");
|
|
20
|
+
const detour_1 = require("../patterns/detour");
|
|
21
|
+
const late_night_1 = require("../patterns/late-night");
|
|
22
|
+
const spiral_regression_1 = require("../patterns/spiral-regression");
|
|
23
|
+
// Session gap threshold: 60 minutes
|
|
24
|
+
const SESSION_GAP_MINUTES = 60;
|
|
25
|
+
function createTimelineCommand() {
|
|
26
|
+
const cmd = new commander_1.Command('timeline')
|
|
27
|
+
.description('View your coding journey as a timeline with sessions and patterns')
|
|
28
|
+
.option('--since <date>', 'Start date for analysis (default: "1 week ago")', '1 week ago')
|
|
29
|
+
.option('--until <date>', 'End date for analysis (default: now)')
|
|
30
|
+
.option('-f, --format <type>', 'Output format: terminal, json, markdown, html', 'terminal')
|
|
31
|
+
.option('-r, --repo <path>', 'Repository path', process.cwd())
|
|
32
|
+
.option('-v, --verbose', 'Show verbose output', false)
|
|
33
|
+
.option('--expand [date]', 'Expand day details (all or specific date like "Nov-29")')
|
|
34
|
+
.option('--no-cache', 'Skip cache and fetch fresh data from git')
|
|
35
|
+
.option('--insights', 'Show compounding insights from historical data')
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
await runTimeline(options);
|
|
38
|
+
});
|
|
39
|
+
return cmd;
|
|
40
|
+
}
|
|
41
|
+
async function runTimeline(options) {
|
|
42
|
+
try {
|
|
43
|
+
const { since, until, format: outputFormat, repo, verbose, expand, noCache, insights } = options;
|
|
44
|
+
// Check if repo is valid
|
|
45
|
+
if (!(await (0, git_1.isGitRepo)(repo))) {
|
|
46
|
+
console.error(chalk_1.default.red(`Not a git repository: ${repo}`));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
// Load existing store for caching
|
|
50
|
+
const store = (0, storage_1.loadStore)(repo);
|
|
51
|
+
const latestCommitHash = await (0, git_1.getLatestCommitHash)(repo);
|
|
52
|
+
if (verbose) {
|
|
53
|
+
console.error(chalk_1.default.gray(`Analyzing repository: ${repo}`));
|
|
54
|
+
console.error(chalk_1.default.gray(`Since: ${since}`));
|
|
55
|
+
if (until)
|
|
56
|
+
console.error(chalk_1.default.gray(`Until: ${until}`));
|
|
57
|
+
console.error(chalk_1.default.gray(`Cache: ${(0, storage_1.getStorePath)(repo)}`));
|
|
58
|
+
console.error(chalk_1.default.gray(`Last cached commit: ${store.lastCommitHash || 'none'}`));
|
|
59
|
+
console.error(chalk_1.default.gray(`Latest commit: ${latestCommitHash}`));
|
|
60
|
+
}
|
|
61
|
+
// Get commits
|
|
62
|
+
const commits = await (0, git_1.getCommits)(repo, since, until);
|
|
63
|
+
if (commits.length === 0) {
|
|
64
|
+
console.log(chalk_1.default.yellow('\nNo commits found in the specified range.\n'));
|
|
65
|
+
console.log(chalk_1.default.gray('Try specifying a different date range:'));
|
|
66
|
+
console.log(chalk_1.default.gray(' vibe-check timeline --since "1 month ago"'));
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
if (verbose) {
|
|
70
|
+
console.error(chalk_1.default.gray(`Found ${commits.length} commits`));
|
|
71
|
+
}
|
|
72
|
+
// Get commit stats for pattern detection
|
|
73
|
+
if (verbose) {
|
|
74
|
+
console.error(chalk_1.default.gray('Gathering file stats for pattern detection...'));
|
|
75
|
+
}
|
|
76
|
+
const commitStats = await (0, git_1.getCommitStats)(repo, since, until);
|
|
77
|
+
// Build timeline with pattern detection
|
|
78
|
+
const timeline = buildTimeline(commits, commitStats.filesPerCommit, commitStats.lineStatsPerCommit);
|
|
79
|
+
// Update and save store (unless --no-cache)
|
|
80
|
+
if (!noCache) {
|
|
81
|
+
// Append commits to NDJSON log (source of truth)
|
|
82
|
+
const appendedCount = (0, storage_1.appendCommits)(commits, repo);
|
|
83
|
+
if (verbose && appendedCount > 0) {
|
|
84
|
+
console.error(chalk_1.default.gray(`Appended ${appendedCount} new commits to log`));
|
|
85
|
+
}
|
|
86
|
+
const updatedStore = (0, storage_1.updateStore)(store, timeline, latestCommitHash);
|
|
87
|
+
(0, storage_1.saveStore)(updatedStore, repo);
|
|
88
|
+
if (verbose) {
|
|
89
|
+
console.error(chalk_1.default.gray(`Cache updated: ${updatedStore.sessions.length} sessions, ${updatedStore.insights.length} insights`));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Show insights if requested
|
|
93
|
+
if (insights) {
|
|
94
|
+
console.log('');
|
|
95
|
+
console.log(chalk_1.default.bold.magenta('═'.repeat(64)));
|
|
96
|
+
console.log(chalk_1.default.bold.magenta(' COMPOUNDING INSIGHTS'));
|
|
97
|
+
console.log(chalk_1.default.bold.magenta('═'.repeat(64)));
|
|
98
|
+
console.log('');
|
|
99
|
+
// Check for regressions
|
|
100
|
+
const regressionAnalysis = (0, spiral_regression_1.detectRegressions)(store.trends);
|
|
101
|
+
if (regressionAnalysis.hasRegression) {
|
|
102
|
+
console.log(chalk_1.default.bold.red(' ⚠ REGRESSION ALERTS'));
|
|
103
|
+
for (const alert of regressionAnalysis.alerts) {
|
|
104
|
+
const icon = alert.severity === 'critical' ? chalk_1.default.red('🚨') : chalk_1.default.yellow('⚠');
|
|
105
|
+
console.log(` ${icon} ${alert.message}`);
|
|
106
|
+
console.log(chalk_1.default.gray(` ${alert.recommendation}`));
|
|
107
|
+
}
|
|
108
|
+
console.log('');
|
|
109
|
+
}
|
|
110
|
+
else if (regressionAnalysis.improvementStreak > 0) {
|
|
111
|
+
console.log(chalk_1.default.green(` 🎯 ${regressionAnalysis.improvementStreak}-week improvement streak!`));
|
|
112
|
+
console.log('');
|
|
113
|
+
}
|
|
114
|
+
// Show stored insights
|
|
115
|
+
if (store.insights.length > 0) {
|
|
116
|
+
for (const insight of store.insights.slice(0, 5)) {
|
|
117
|
+
const icon = insight.type === 'pattern' ? '🔄' : insight.type === 'recommendation' ? '💡' : '📈';
|
|
118
|
+
console.log(` ${icon} ${insight.message}`);
|
|
119
|
+
console.log(chalk_1.default.gray(` (${insight.occurrences} occurrences)`));
|
|
120
|
+
}
|
|
121
|
+
console.log('');
|
|
122
|
+
}
|
|
123
|
+
// Show recovery time trends
|
|
124
|
+
const recoveryTrends = (0, spiral_regression_1.getAllRecoveryTrends)(store.sessions);
|
|
125
|
+
const improvingComponents = recoveryTrends.filter(t => t.trend === 'improving');
|
|
126
|
+
const worseningComponents = recoveryTrends.filter(t => t.trend === 'worsening');
|
|
127
|
+
if (improvingComponents.length > 0) {
|
|
128
|
+
console.log(chalk_1.default.bold.green(' 📉 Improving Recovery Times:'));
|
|
129
|
+
for (const comp of improvingComponents.slice(0, 3)) {
|
|
130
|
+
console.log(chalk_1.default.green(` ${comp.component}: ${comp.avgTime}m → ${comp.recentTime}m`));
|
|
131
|
+
}
|
|
132
|
+
console.log('');
|
|
133
|
+
}
|
|
134
|
+
if (worseningComponents.length > 0) {
|
|
135
|
+
console.log(chalk_1.default.bold.yellow(' 📈 Slower Recovery Times:'));
|
|
136
|
+
for (const comp of worseningComponents.slice(0, 3)) {
|
|
137
|
+
console.log(chalk_1.default.yellow(` ${comp.component}: ${comp.avgTime}m → ${comp.recentTime}m`));
|
|
138
|
+
}
|
|
139
|
+
console.log('');
|
|
140
|
+
}
|
|
141
|
+
// Show week-over-week trends
|
|
142
|
+
if (store.trends.improvements.length > 0) {
|
|
143
|
+
console.log(chalk_1.default.bold.white(' Week-over-Week:'));
|
|
144
|
+
for (const imp of store.trends.improvements) {
|
|
145
|
+
const arrow = imp.direction === 'up' ? chalk_1.default.green('↑') : imp.direction === 'down' ? chalk_1.default.red('↓') : chalk_1.default.gray('→');
|
|
146
|
+
console.log(` ${arrow} ${imp.metric}: ${imp.change > 0 ? '+' : ''}${imp.change}%`);
|
|
147
|
+
}
|
|
148
|
+
console.log('');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Output based on format
|
|
152
|
+
if (outputFormat === 'json') {
|
|
153
|
+
// Include store insights in JSON output
|
|
154
|
+
const output = {
|
|
155
|
+
...timeline,
|
|
156
|
+
storedInsights: store.insights,
|
|
157
|
+
trends: store.trends,
|
|
158
|
+
patternStats: store.patterns,
|
|
159
|
+
};
|
|
160
|
+
console.log(JSON.stringify(output, null, 2));
|
|
161
|
+
}
|
|
162
|
+
else if (outputFormat === 'markdown') {
|
|
163
|
+
const output = (0, timeline_markdown_1.formatTimelineMarkdown)(timeline);
|
|
164
|
+
console.log(output);
|
|
165
|
+
}
|
|
166
|
+
else if (outputFormat === 'html') {
|
|
167
|
+
const output = (0, timeline_html_1.formatTimelineHtml)(timeline);
|
|
168
|
+
console.log(output);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// Terminal output
|
|
172
|
+
const output = (0, timeline_1.formatTimelineTerminal)(timeline, { expand });
|
|
173
|
+
console.log(output);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
if (error instanceof Error) {
|
|
178
|
+
console.error(chalk_1.default.red(`Error: ${error.message}`));
|
|
179
|
+
if (options.verbose) {
|
|
180
|
+
console.error(chalk_1.default.gray(error.stack));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.error(chalk_1.default.red('An unexpected error occurred'));
|
|
185
|
+
}
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Build a complete timeline from commits
|
|
191
|
+
*/
|
|
192
|
+
function buildTimeline(commits, filesPerCommit, lineStatsPerCommit) {
|
|
193
|
+
// Sort commits chronologically (oldest first)
|
|
194
|
+
const sortedCommits = [...commits].sort((a, b) => a.date.getTime() - b.date.getTime());
|
|
195
|
+
// Detect sessions
|
|
196
|
+
const sessions = detectSessions(sortedCommits);
|
|
197
|
+
// Group sessions into days
|
|
198
|
+
const days = groupByDay(sessions);
|
|
199
|
+
// Calculate aggregates
|
|
200
|
+
const totalCommits = sortedCommits.length;
|
|
201
|
+
const totalActiveMinutes = sessions.reduce((sum, s) => sum + s.duration, 0);
|
|
202
|
+
const totalFeatures = sortedCommits.filter(c => c.type === 'feat').length;
|
|
203
|
+
const totalFixes = sortedCommits.filter(c => c.type === 'fix').length;
|
|
204
|
+
const totalSpirals = sessions.reduce((sum, s) => sum + s.spirals.length, 0);
|
|
205
|
+
const flowStates = sessions.filter(s => s.flowState).length;
|
|
206
|
+
const totalXp = sessions.reduce((sum, s) => sum + s.xpEarned, 0);
|
|
207
|
+
// Build trend sparkline
|
|
208
|
+
const trend = days.map(d => d.dayScore);
|
|
209
|
+
// Calculate date range
|
|
210
|
+
const from = sortedCommits[0].date;
|
|
211
|
+
const to = sortedCommits[sortedCommits.length - 1].date;
|
|
212
|
+
const totalDays = (0, date_fns_1.differenceInDays)(to, from) + 1;
|
|
213
|
+
// Phase 2: Detect post-delete sprint
|
|
214
|
+
const postDeleteResult = (0, post_delete_sprint_1.detectPostDeleteSprint)(sessions, lineStatsPerCommit);
|
|
215
|
+
const postDeleteSprint = postDeleteResult.detected
|
|
216
|
+
? {
|
|
217
|
+
detected: true,
|
|
218
|
+
linesDeleted: postDeleteResult.deleteSession?.linesDeleted || 0,
|
|
219
|
+
velocityIncrease: postDeleteResult.velocityIncrease,
|
|
220
|
+
message: postDeleteResult.message,
|
|
221
|
+
}
|
|
222
|
+
: null;
|
|
223
|
+
// Phase 2: Detect thrashing across all events
|
|
224
|
+
const allEvents = sessions.flatMap(s => s.commits);
|
|
225
|
+
const thrashingResult = (0, thrashing_1.detectThrashing)(allEvents, filesPerCommit, lineStatsPerCommit);
|
|
226
|
+
const thrashing = thrashingResult.detected
|
|
227
|
+
? {
|
|
228
|
+
detected: true,
|
|
229
|
+
files: thrashingResult.files.map(f => ({
|
|
230
|
+
path: f.path,
|
|
231
|
+
touchCount: f.touchCount,
|
|
232
|
+
efficiency: f.efficiency,
|
|
233
|
+
})),
|
|
234
|
+
message: thrashingResult.message,
|
|
235
|
+
}
|
|
236
|
+
: null;
|
|
237
|
+
// Phase 3: Detect detours (code added then deleted)
|
|
238
|
+
const detourResult = (0, detour_1.detectDetour)(allEvents, filesPerCommit, lineStatsPerCommit);
|
|
239
|
+
const detours = detourResult.detected
|
|
240
|
+
? {
|
|
241
|
+
detected: true,
|
|
242
|
+
detours: detourResult.detours.map(d => ({
|
|
243
|
+
scope: d.scope,
|
|
244
|
+
filesAffected: d.filesAffected,
|
|
245
|
+
linesAdded: d.linesAdded,
|
|
246
|
+
linesDeleted: d.linesDeleted,
|
|
247
|
+
duration: d.duration,
|
|
248
|
+
})),
|
|
249
|
+
totalTimeLost: detourResult.totalTimeLost,
|
|
250
|
+
message: detourResult.message,
|
|
251
|
+
}
|
|
252
|
+
: null;
|
|
253
|
+
// Phase 3: Detect late-night spirals
|
|
254
|
+
const lateNightResult = (0, late_night_1.detectLateNightSpiral)(sessions);
|
|
255
|
+
const lateNightSpirals = lateNightResult.detected
|
|
256
|
+
? {
|
|
257
|
+
detected: true,
|
|
258
|
+
spirals: lateNightResult.spirals.map(s => ({
|
|
259
|
+
component: s.component,
|
|
260
|
+
duration: s.duration,
|
|
261
|
+
fixCount: s.fixCount,
|
|
262
|
+
resolved: s.resolved,
|
|
263
|
+
})),
|
|
264
|
+
totalDuration: lateNightResult.totalDuration,
|
|
265
|
+
message: lateNightResult.message,
|
|
266
|
+
}
|
|
267
|
+
: null;
|
|
268
|
+
return {
|
|
269
|
+
from,
|
|
270
|
+
to,
|
|
271
|
+
activeDays: days.length,
|
|
272
|
+
totalDays,
|
|
273
|
+
days,
|
|
274
|
+
sessions,
|
|
275
|
+
totalCommits,
|
|
276
|
+
totalActiveMinutes,
|
|
277
|
+
totalFeatures,
|
|
278
|
+
totalFixes,
|
|
279
|
+
totalSpirals,
|
|
280
|
+
flowStates,
|
|
281
|
+
postDeleteSprint,
|
|
282
|
+
thrashing,
|
|
283
|
+
detours,
|
|
284
|
+
lateNightSpirals,
|
|
285
|
+
totalXp,
|
|
286
|
+
trend,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Detect sessions from commits using 1-hour gap threshold
|
|
291
|
+
*/
|
|
292
|
+
function detectSessions(commits) {
|
|
293
|
+
if (commits.length === 0)
|
|
294
|
+
return [];
|
|
295
|
+
const sessions = [];
|
|
296
|
+
let currentSession = [];
|
|
297
|
+
let sessionCounter = 0;
|
|
298
|
+
for (let i = 0; i < commits.length; i++) {
|
|
299
|
+
const commit = commits[i];
|
|
300
|
+
const prevCommit = i > 0 ? commits[i - 1] : null;
|
|
301
|
+
// Calculate gap from previous commit
|
|
302
|
+
const gapMinutes = prevCommit
|
|
303
|
+
? (0, date_fns_1.differenceInMinutes)(commit.date, prevCommit.date)
|
|
304
|
+
: 0;
|
|
305
|
+
// Start new session if gap exceeds threshold
|
|
306
|
+
if (gapMinutes > SESSION_GAP_MINUTES && currentSession.length > 0) {
|
|
307
|
+
sessions.push(buildSession(currentSession, sessionCounter));
|
|
308
|
+
sessionCounter++;
|
|
309
|
+
currentSession = [];
|
|
310
|
+
}
|
|
311
|
+
// Add event to current session
|
|
312
|
+
const event = {
|
|
313
|
+
hash: commit.hash,
|
|
314
|
+
timestamp: commit.date,
|
|
315
|
+
author: commit.author,
|
|
316
|
+
subject: commit.message,
|
|
317
|
+
type: commit.type,
|
|
318
|
+
scope: commit.scope,
|
|
319
|
+
sessionId: `session-${sessionCounter}`,
|
|
320
|
+
sessionPosition: currentSession.length,
|
|
321
|
+
gapMinutes,
|
|
322
|
+
isRefactor: commit.type === 'refactor',
|
|
323
|
+
spiralDepth: 0, // Will be calculated in buildSession
|
|
324
|
+
};
|
|
325
|
+
currentSession.push(event);
|
|
326
|
+
}
|
|
327
|
+
// Don't forget the last session
|
|
328
|
+
if (currentSession.length > 0) {
|
|
329
|
+
sessions.push(buildSession(currentSession, sessionCounter));
|
|
330
|
+
}
|
|
331
|
+
return sessions;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Build a session from events
|
|
335
|
+
*/
|
|
336
|
+
function buildSession(events, sessionNum) {
|
|
337
|
+
const start = events[0].timestamp;
|
|
338
|
+
const end = events[events.length - 1].timestamp;
|
|
339
|
+
const duration = (0, date_fns_1.differenceInMinutes)(end, start) || 1; // At least 1 minute
|
|
340
|
+
// Convert events back to Commit format for metrics analysis
|
|
341
|
+
const commits = events.map(e => ({
|
|
342
|
+
hash: e.hash,
|
|
343
|
+
date: e.timestamp,
|
|
344
|
+
message: e.subject,
|
|
345
|
+
type: e.type,
|
|
346
|
+
scope: e.scope,
|
|
347
|
+
author: e.author,
|
|
348
|
+
}));
|
|
349
|
+
// Analyze metrics for this session
|
|
350
|
+
const analysis = (0, metrics_1.analyzeCommits)(commits);
|
|
351
|
+
// Detect fix chains (spirals)
|
|
352
|
+
const spirals = analysis.fixChains.filter(fc => fc.isSpiral);
|
|
353
|
+
// Mark spiral depth on events
|
|
354
|
+
for (const spiral of spirals) {
|
|
355
|
+
let depth = 1;
|
|
356
|
+
for (const event of events) {
|
|
357
|
+
if (event.type === 'fix' && event.scope === spiral.component) {
|
|
358
|
+
event.spiralDepth = depth++;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Detect flow state using enhanced pattern detection
|
|
363
|
+
const flowStateResult = (0, flow_state_1.detectFlowState)(events, duration);
|
|
364
|
+
const flowState = flowStateResult.detected;
|
|
365
|
+
// Calculate XP (simplified - base XP on session quality)
|
|
366
|
+
const xpEarned = calculateSessionXp(analysis.overall, commits.length, spirals.length);
|
|
367
|
+
return {
|
|
368
|
+
id: `session-${sessionNum}`,
|
|
369
|
+
start,
|
|
370
|
+
end,
|
|
371
|
+
duration,
|
|
372
|
+
commits: events,
|
|
373
|
+
vibeScore: null, // Would need semantic-free metrics for full score
|
|
374
|
+
overall: analysis.overall,
|
|
375
|
+
trustPassRate: analysis.metrics.trustPassRate.value,
|
|
376
|
+
reworkRatio: analysis.metrics.reworkRatio.value,
|
|
377
|
+
flowState,
|
|
378
|
+
spirals,
|
|
379
|
+
xpEarned,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Calculate XP for a session
|
|
384
|
+
*/
|
|
385
|
+
function calculateSessionXp(overall, commits, spirals) {
|
|
386
|
+
const baseXp = {
|
|
387
|
+
'ELITE': 50,
|
|
388
|
+
'HIGH': 30,
|
|
389
|
+
'MEDIUM': 20,
|
|
390
|
+
'LOW': 10,
|
|
391
|
+
};
|
|
392
|
+
let xp = baseXp[overall];
|
|
393
|
+
xp += commits * 2; // 2 XP per commit
|
|
394
|
+
xp -= spirals * 10; // -10 XP per spiral
|
|
395
|
+
return Math.max(0, xp);
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Group sessions into days
|
|
399
|
+
*/
|
|
400
|
+
function groupByDay(sessions) {
|
|
401
|
+
const dayMap = new Map();
|
|
402
|
+
for (const session of sessions) {
|
|
403
|
+
const dateKey = (0, date_fns_1.format)(session.start, 'yyyy-MM-dd');
|
|
404
|
+
if (!dayMap.has(dateKey)) {
|
|
405
|
+
dayMap.set(dateKey, []);
|
|
406
|
+
}
|
|
407
|
+
dayMap.get(dateKey).push(session);
|
|
408
|
+
}
|
|
409
|
+
// Convert map to array of TimelineDay
|
|
410
|
+
const days = [];
|
|
411
|
+
for (const [dateKey, daySessions] of dayMap.entries()) {
|
|
412
|
+
const date = (0, date_fns_1.parseISO)(dateKey);
|
|
413
|
+
const totalCommits = daySessions.reduce((sum, s) => sum + s.commits.length, 0);
|
|
414
|
+
const totalDuration = daySessions.reduce((sum, s) => sum + s.duration, 0);
|
|
415
|
+
const totalXp = daySessions.reduce((sum, s) => sum + s.xpEarned, 0);
|
|
416
|
+
const spiralCount = daySessions.reduce((sum, s) => sum + s.spirals.length, 0);
|
|
417
|
+
// Calculate day score (average of session trust pass rates)
|
|
418
|
+
const scores = daySessions.map(s => s.trustPassRate);
|
|
419
|
+
const avgScore = scores.reduce((a, b) => a + b, 0) / scores.length;
|
|
420
|
+
// Calculate day rating
|
|
421
|
+
const dayRating = calculateDayRating(daySessions);
|
|
422
|
+
days.push({
|
|
423
|
+
date: dateKey,
|
|
424
|
+
displayDate: (0, date_fns_1.format)(date, 'EEE MMM d'),
|
|
425
|
+
sessions: daySessions,
|
|
426
|
+
dayScore: Math.round(avgScore),
|
|
427
|
+
dayRating,
|
|
428
|
+
totalCommits,
|
|
429
|
+
totalDuration,
|
|
430
|
+
totalXp,
|
|
431
|
+
spiralCount,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
// Sort by date
|
|
435
|
+
days.sort((a, b) => a.date.localeCompare(b.date));
|
|
436
|
+
return days;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Calculate overall rating for a day
|
|
440
|
+
*/
|
|
441
|
+
function calculateDayRating(sessions) {
|
|
442
|
+
const ratings = sessions.map(s => s.overall);
|
|
443
|
+
// Count each rating type
|
|
444
|
+
const counts = {
|
|
445
|
+
'ELITE': ratings.filter(r => r === 'ELITE').length,
|
|
446
|
+
'HIGH': ratings.filter(r => r === 'HIGH').length,
|
|
447
|
+
'MEDIUM': ratings.filter(r => r === 'MEDIUM').length,
|
|
448
|
+
'LOW': ratings.filter(r => r === 'LOW').length,
|
|
449
|
+
};
|
|
450
|
+
// Majority wins, with tie-breakers favoring higher ratings
|
|
451
|
+
if (counts.ELITE >= counts.HIGH && counts.ELITE >= counts.MEDIUM && counts.ELITE >= counts.LOW) {
|
|
452
|
+
return 'ELITE';
|
|
453
|
+
}
|
|
454
|
+
if (counts.HIGH >= counts.MEDIUM && counts.HIGH >= counts.LOW) {
|
|
455
|
+
return 'HIGH';
|
|
456
|
+
}
|
|
457
|
+
if (counts.MEDIUM >= counts.LOW) {
|
|
458
|
+
return 'MEDIUM';
|
|
459
|
+
}
|
|
460
|
+
return 'LOW';
|
|
461
|
+
}
|
|
462
|
+
//# sourceMappingURL=timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/commands/timeline.ts"],"names":[],"mappings":"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"}
|
package/dist/git.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { Commit } from './types';
|
|
2
2
|
export declare function getCommits(repoPath: string, since?: string, until?: string): Promise<Commit[]>;
|
|
3
3
|
export declare function isGitRepo(repoPath: string): Promise<boolean>;
|
|
4
|
+
/**
|
|
5
|
+
* Get the latest commit hash in the repo
|
|
6
|
+
*/
|
|
7
|
+
export declare function getLatestCommitHash(repoPath: string): Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Get commits since a specific commit hash (for incremental sync)
|
|
10
|
+
*/
|
|
11
|
+
export declare function getCommitsSince(repoPath: string, sinceHash: string): Promise<Commit[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Check if a commit hash exists in the repo
|
|
14
|
+
*/
|
|
15
|
+
export declare function commitExists(repoPath: string, hash: string): Promise<boolean>;
|
|
4
16
|
export interface FileStats {
|
|
5
17
|
filesPerCommit: Map<string, string[]>;
|
|
6
18
|
lineStats: {
|
|
@@ -8,8 +20,20 @@ export interface FileStats {
|
|
|
8
20
|
deletions: number;
|
|
9
21
|
}[];
|
|
10
22
|
}
|
|
23
|
+
export interface CommitStats {
|
|
24
|
+
filesPerCommit: Map<string, string[]>;
|
|
25
|
+
lineStatsPerCommit: Map<string, {
|
|
26
|
+
additions: number;
|
|
27
|
+
deletions: number;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
11
30
|
/**
|
|
12
31
|
* Get file-level statistics for semantic-free metrics.
|
|
13
32
|
*/
|
|
14
33
|
export declare function getFileStats(repoPath: string, since?: string, until?: string): Promise<FileStats>;
|
|
34
|
+
/**
|
|
35
|
+
* Get per-commit statistics for pattern detection.
|
|
36
|
+
* Returns a map of commit hash -> stats
|
|
37
|
+
*/
|
|
38
|
+
export declare function getCommitStats(repoPath: string, since?: string, until?: string): Promise<CommitStats>;
|
|
15
39
|
//# sourceMappingURL=git.d.ts.map
|
package/dist/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAIjC,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBnB;AA+BD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlE;AAED,MAAM,WAAW,SAAS;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,CAAC,CAmDpB"}
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAIjC,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBnB;AA+BD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ3E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAWnB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQnF;AAED,MAAM,WAAW,SAAS;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,CAAC,CAmDpB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,WAAW,CAAC,CAgDtB"}
|
package/dist/git.js
CHANGED
|
@@ -5,7 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getCommits = getCommits;
|
|
7
7
|
exports.isGitRepo = isGitRepo;
|
|
8
|
+
exports.getLatestCommitHash = getLatestCommitHash;
|
|
9
|
+
exports.getCommitsSince = getCommitsSince;
|
|
10
|
+
exports.commitExists = commitExists;
|
|
8
11
|
exports.getFileStats = getFileStats;
|
|
12
|
+
exports.getCommitStats = getCommitStats;
|
|
9
13
|
const simple_git_1 = __importDefault(require("simple-git"));
|
|
10
14
|
const COMMIT_TYPES = ['feat', 'fix', 'docs', 'chore', 'refactor', 'test', 'style'];
|
|
11
15
|
async function getCommits(repoPath, since, until) {
|
|
@@ -62,6 +66,47 @@ async function isGitRepo(repoPath) {
|
|
|
62
66
|
return false;
|
|
63
67
|
}
|
|
64
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the latest commit hash in the repo
|
|
71
|
+
*/
|
|
72
|
+
async function getLatestCommitHash(repoPath) {
|
|
73
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
74
|
+
try {
|
|
75
|
+
const log = await git.log({ n: 1 });
|
|
76
|
+
return log.latest?.hash.substring(0, 7) || '';
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get commits since a specific commit hash (for incremental sync)
|
|
84
|
+
*/
|
|
85
|
+
async function getCommitsSince(repoPath, sinceHash) {
|
|
86
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
87
|
+
try {
|
|
88
|
+
// Get commits after the given hash
|
|
89
|
+
const log = await git.log({ from: sinceHash, to: 'HEAD' });
|
|
90
|
+
return log.all.map((entry) => parseCommit(entry));
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// If hash doesn't exist or error, return empty
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Check if a commit hash exists in the repo
|
|
99
|
+
*/
|
|
100
|
+
async function commitExists(repoPath, hash) {
|
|
101
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
102
|
+
try {
|
|
103
|
+
await git.raw(['cat-file', '-t', hash]);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
65
110
|
/**
|
|
66
111
|
* Get file-level statistics for semantic-free metrics.
|
|
67
112
|
*/
|
|
@@ -113,4 +158,53 @@ async function getFileStats(repoPath, since, until) {
|
|
|
113
158
|
}
|
|
114
159
|
return { filesPerCommit, lineStats };
|
|
115
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Get per-commit statistics for pattern detection.
|
|
163
|
+
* Returns a map of commit hash -> stats
|
|
164
|
+
*/
|
|
165
|
+
async function getCommitStats(repoPath, since, until) {
|
|
166
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
167
|
+
const filesPerCommit = new Map();
|
|
168
|
+
const lineStatsPerCommit = new Map();
|
|
169
|
+
// Build options for git log
|
|
170
|
+
const logOptions = {};
|
|
171
|
+
if (since)
|
|
172
|
+
logOptions['--since'] = since;
|
|
173
|
+
if (until)
|
|
174
|
+
logOptions['--until'] = until;
|
|
175
|
+
try {
|
|
176
|
+
const log = await git.log(logOptions);
|
|
177
|
+
for (const commit of log.all) {
|
|
178
|
+
const hash = commit.hash.substring(0, 7);
|
|
179
|
+
try {
|
|
180
|
+
const diffStat = await git.raw(['diff-tree', '--numstat', '--root', '-r', commit.hash]);
|
|
181
|
+
const lines = diffStat.trim().split('\n').filter(l => l.length > 0);
|
|
182
|
+
const files = [];
|
|
183
|
+
let additions = 0;
|
|
184
|
+
let deletions = 0;
|
|
185
|
+
for (const line of lines) {
|
|
186
|
+
const parts = line.split('\t');
|
|
187
|
+
if (parts.length >= 3) {
|
|
188
|
+
const add = parseInt(parts[0], 10) || 0;
|
|
189
|
+
const del = parseInt(parts[1], 10) || 0;
|
|
190
|
+
const file = parts[2];
|
|
191
|
+
additions += add;
|
|
192
|
+
deletions += del;
|
|
193
|
+
files.push(file);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
filesPerCommit.set(hash, files);
|
|
197
|
+
lineStatsPerCommit.set(hash, { additions, deletions });
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
filesPerCommit.set(hash, []);
|
|
201
|
+
lineStatsPerCommit.set(hash, { additions: 0, deletions: 0 });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// Return empty stats on error
|
|
207
|
+
}
|
|
208
|
+
return { filesPerCommit, lineStatsPerCommit };
|
|
209
|
+
}
|
|
116
210
|
//# sourceMappingURL=git.js.map
|