@boshu2/vibe-check 1.0.2 → 1.2.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/ml-learning-loop-complete-plan-2025-11-28.md +908 -0
- package/.agents/bundles/unified-vibe-system-plan-phase1-2025-11-28.md +962 -0
- package/.agents/bundles/unified-vibe-system-research-2025-11-28.md +1003 -0
- package/.agents/bundles/vibe-check-ecosystem-plan-2025-11-29.md +635 -0
- package/.agents/bundles/vibe-check-gamification-complete-2025-11-29.md +132 -0
- package/.agents/bundles/vibe-score-scientific-framework-2025-11-28.md +602 -0
- package/.vibe-check/calibration.json +38 -0
- package/.vibe-check/latest.json +114 -0
- package/CHANGELOG.md +47 -0
- package/CLAUDE.md +178 -0
- package/README.md +222 -7
- package/action.yml +270 -0
- package/dashboard/app.js +494 -0
- package/dashboard/index.html +235 -0
- package/dashboard/styles.css +647 -0
- package/dist/calibration/ece.d.ts +26 -0
- package/dist/calibration/ece.d.ts.map +1 -0
- package/dist/calibration/ece.js +93 -0
- package/dist/calibration/ece.js.map +1 -0
- package/dist/calibration/index.d.ts +3 -0
- package/dist/calibration/index.d.ts.map +1 -0
- package/dist/calibration/index.js +15 -0
- package/dist/calibration/index.js.map +1 -0
- package/dist/calibration/storage.d.ts +34 -0
- package/dist/calibration/storage.d.ts.map +1 -0
- package/dist/calibration/storage.js +188 -0
- package/dist/calibration/storage.js.map +1 -0
- package/dist/cli.js +31 -76
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts +16 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +256 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/index.d.ts +5 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +13 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init-hook.d.ts +3 -0
- package/dist/commands/init-hook.d.ts.map +1 -0
- package/dist/commands/init-hook.js +161 -0
- package/dist/commands/init-hook.js.map +1 -0
- package/dist/commands/level.d.ts +3 -0
- package/dist/commands/level.d.ts.map +1 -0
- package/dist/commands/level.js +277 -0
- package/dist/commands/level.js.map +1 -0
- package/dist/commands/profile.d.ts +4 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +143 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/gamification/achievements.d.ts +15 -0
- package/dist/gamification/achievements.d.ts.map +1 -0
- package/dist/gamification/achievements.js +273 -0
- package/dist/gamification/achievements.js.map +1 -0
- package/dist/gamification/index.d.ts +8 -0
- package/dist/gamification/index.d.ts.map +1 -0
- package/dist/gamification/index.js +30 -0
- package/dist/gamification/index.js.map +1 -0
- package/dist/gamification/profile.d.ts +46 -0
- package/dist/gamification/profile.d.ts.map +1 -0
- package/dist/gamification/profile.js +272 -0
- package/dist/gamification/profile.js.map +1 -0
- package/dist/gamification/streaks.d.ts +26 -0
- package/dist/gamification/streaks.d.ts.map +1 -0
- package/dist/gamification/streaks.js +132 -0
- package/dist/gamification/streaks.js.map +1 -0
- package/dist/gamification/types.d.ts +111 -0
- package/dist/gamification/types.d.ts.map +1 -0
- package/dist/gamification/types.js +26 -0
- package/dist/gamification/types.js.map +1 -0
- package/dist/gamification/xp.d.ts +37 -0
- package/dist/gamification/xp.d.ts.map +1 -0
- package/dist/gamification/xp.js +115 -0
- package/dist/gamification/xp.js.map +1 -0
- package/dist/git.d.ts +11 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +52 -0
- package/dist/git.js.map +1 -1
- package/dist/metrics/code-stability.d.ts +13 -0
- package/dist/metrics/code-stability.d.ts.map +1 -0
- package/dist/metrics/code-stability.js +74 -0
- package/dist/metrics/code-stability.js.map +1 -0
- package/dist/metrics/file-churn.d.ts +8 -0
- package/dist/metrics/file-churn.d.ts.map +1 -0
- package/dist/metrics/file-churn.js +75 -0
- package/dist/metrics/file-churn.js.map +1 -0
- package/dist/metrics/time-spiral.d.ts +8 -0
- package/dist/metrics/time-spiral.d.ts.map +1 -0
- package/dist/metrics/time-spiral.js +69 -0
- package/dist/metrics/time-spiral.js.map +1 -0
- package/dist/metrics/velocity-anomaly.d.ts +13 -0
- package/dist/metrics/velocity-anomaly.d.ts.map +1 -0
- package/dist/metrics/velocity-anomaly.js +67 -0
- package/dist/metrics/velocity-anomaly.js.map +1 -0
- package/dist/output/index.d.ts +6 -3
- package/dist/output/index.d.ts.map +1 -1
- package/dist/output/index.js +4 -3
- package/dist/output/index.js.map +1 -1
- package/dist/output/json.d.ts +2 -2
- package/dist/output/json.d.ts.map +1 -1
- package/dist/output/json.js +54 -0
- package/dist/output/json.js.map +1 -1
- package/dist/output/markdown.d.ts +2 -2
- package/dist/output/markdown.d.ts.map +1 -1
- package/dist/output/markdown.js +34 -1
- package/dist/output/markdown.js.map +1 -1
- package/dist/output/terminal.d.ts +6 -2
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +131 -3
- package/dist/output/terminal.js.map +1 -1
- package/dist/recommend/index.d.ts +3 -0
- package/dist/recommend/index.d.ts.map +1 -0
- package/dist/recommend/index.js +14 -0
- package/dist/recommend/index.js.map +1 -0
- package/dist/recommend/ordered-logistic.d.ts +49 -0
- package/dist/recommend/ordered-logistic.d.ts.map +1 -0
- package/dist/recommend/ordered-logistic.js +153 -0
- package/dist/recommend/ordered-logistic.js.map +1 -0
- package/dist/recommend/questions.d.ts +19 -0
- package/dist/recommend/questions.d.ts.map +1 -0
- package/dist/recommend/questions.js +73 -0
- package/dist/recommend/questions.js.map +1 -0
- package/dist/score/index.d.ts +21 -0
- package/dist/score/index.d.ts.map +1 -0
- package/dist/score/index.js +48 -0
- package/dist/score/index.js.map +1 -0
- package/dist/score/weights.d.ts +16 -0
- package/dist/score/weights.d.ts.map +1 -0
- package/dist/score/weights.js +28 -0
- package/dist/score/weights.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -1
- package/hooks/pre-push +103 -0
- package/package.json +10 -9
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { StreakState } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Create initial streak state
|
|
4
|
+
*/
|
|
5
|
+
export declare function createInitialStreak(): StreakState;
|
|
6
|
+
/**
|
|
7
|
+
* Update streak based on new session
|
|
8
|
+
*/
|
|
9
|
+
export declare function updateStreak(streak: StreakState, sessionDate: Date): StreakState;
|
|
10
|
+
/**
|
|
11
|
+
* Check if streak is at risk (not checked in today)
|
|
12
|
+
*/
|
|
13
|
+
export declare function isStreakAtRisk(streak: StreakState): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Get days until streak expires
|
|
16
|
+
*/
|
|
17
|
+
export declare function getDaysUntilExpiry(streak: StreakState): number;
|
|
18
|
+
/**
|
|
19
|
+
* Format streak for display
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatStreak(streak: StreakState): string;
|
|
22
|
+
/**
|
|
23
|
+
* Format weekly progress for display
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatWeeklyProgress(streak: StreakState): string;
|
|
26
|
+
//# sourceMappingURL=streaks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaks.d.ts","sourceRoot":"","sources":["../../src/gamification/streaks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,CASjD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,GAAG,WAAW,CAiDhF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAK3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAc9D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAexD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAKhE"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createInitialStreak = createInitialStreak;
|
|
4
|
+
exports.updateStreak = updateStreak;
|
|
5
|
+
exports.isStreakAtRisk = isStreakAtRisk;
|
|
6
|
+
exports.getDaysUntilExpiry = getDaysUntilExpiry;
|
|
7
|
+
exports.formatStreak = formatStreak;
|
|
8
|
+
exports.formatWeeklyProgress = formatWeeklyProgress;
|
|
9
|
+
/**
|
|
10
|
+
* Create initial streak state
|
|
11
|
+
*/
|
|
12
|
+
function createInitialStreak() {
|
|
13
|
+
return {
|
|
14
|
+
current: 0,
|
|
15
|
+
longest: 0,
|
|
16
|
+
lastActiveDate: '',
|
|
17
|
+
weeklyGoal: 5,
|
|
18
|
+
weeklyProgress: 0,
|
|
19
|
+
freezesRemaining: 1,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Update streak based on new session
|
|
24
|
+
*/
|
|
25
|
+
function updateStreak(streak, sessionDate) {
|
|
26
|
+
const today = formatDate(sessionDate);
|
|
27
|
+
const yesterday = formatDate(new Date(sessionDate.getTime() - 24 * 60 * 60 * 1000));
|
|
28
|
+
const twoDaysAgo = formatDate(new Date(sessionDate.getTime() - 2 * 24 * 60 * 60 * 1000));
|
|
29
|
+
// Already checked in today
|
|
30
|
+
if (streak.lastActiveDate === today) {
|
|
31
|
+
return streak;
|
|
32
|
+
}
|
|
33
|
+
let newCurrent = streak.current;
|
|
34
|
+
let freezesRemaining = streak.freezesRemaining;
|
|
35
|
+
let lastFreezeUsed = streak.lastFreezeUsed;
|
|
36
|
+
if (streak.lastActiveDate === yesterday) {
|
|
37
|
+
// Consecutive day - extend streak
|
|
38
|
+
newCurrent = streak.current + 1;
|
|
39
|
+
}
|
|
40
|
+
else if (streak.lastActiveDate === twoDaysAgo && freezesRemaining > 0) {
|
|
41
|
+
// Missed one day but have freeze
|
|
42
|
+
newCurrent = streak.current + 1;
|
|
43
|
+
freezesRemaining -= 1;
|
|
44
|
+
lastFreezeUsed = yesterday;
|
|
45
|
+
}
|
|
46
|
+
else if (streak.lastActiveDate === '') {
|
|
47
|
+
// First ever session
|
|
48
|
+
newCurrent = 1;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Streak broken
|
|
52
|
+
newCurrent = 1;
|
|
53
|
+
}
|
|
54
|
+
// Update weekly progress
|
|
55
|
+
const weekStart = getWeekStart(sessionDate);
|
|
56
|
+
const lastActiveWeekStart = streak.lastActiveDate
|
|
57
|
+
? getWeekStart(new Date(streak.lastActiveDate))
|
|
58
|
+
: '';
|
|
59
|
+
const weeklyProgress = weekStart === lastActiveWeekStart
|
|
60
|
+
? streak.weeklyProgress + (streak.lastActiveDate === today ? 0 : 1)
|
|
61
|
+
: 1;
|
|
62
|
+
return {
|
|
63
|
+
current: newCurrent,
|
|
64
|
+
longest: Math.max(streak.longest, newCurrent),
|
|
65
|
+
lastActiveDate: today,
|
|
66
|
+
weeklyGoal: streak.weeklyGoal,
|
|
67
|
+
weeklyProgress,
|
|
68
|
+
freezesRemaining,
|
|
69
|
+
lastFreezeUsed,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check if streak is at risk (not checked in today)
|
|
74
|
+
*/
|
|
75
|
+
function isStreakAtRisk(streak) {
|
|
76
|
+
if (streak.current === 0)
|
|
77
|
+
return false;
|
|
78
|
+
const today = formatDate(new Date());
|
|
79
|
+
return streak.lastActiveDate !== today;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get days until streak expires
|
|
83
|
+
*/
|
|
84
|
+
function getDaysUntilExpiry(streak) {
|
|
85
|
+
if (streak.current === 0)
|
|
86
|
+
return 0;
|
|
87
|
+
const today = new Date();
|
|
88
|
+
today.setHours(0, 0, 0, 0);
|
|
89
|
+
const lastActive = new Date(streak.lastActiveDate);
|
|
90
|
+
lastActive.setHours(0, 0, 0, 0);
|
|
91
|
+
const diffDays = Math.floor((today.getTime() - lastActive.getTime()) / (24 * 60 * 60 * 1000));
|
|
92
|
+
if (diffDays === 0)
|
|
93
|
+
return 2; // Checked in today, expires day after tomorrow
|
|
94
|
+
if (diffDays === 1)
|
|
95
|
+
return 1; // Checked in yesterday, expires tomorrow
|
|
96
|
+
return 0; // Already expired or will expire today
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Format streak for display
|
|
100
|
+
*/
|
|
101
|
+
function formatStreak(streak) {
|
|
102
|
+
if (streak.current === 0) {
|
|
103
|
+
return 'No active streak';
|
|
104
|
+
}
|
|
105
|
+
const isPersonalBest = streak.current === streak.longest && streak.current > 1;
|
|
106
|
+
const fire = '🔥'.repeat(Math.min(streak.current, 5));
|
|
107
|
+
let text = `${fire} ${streak.current}-day streak`;
|
|
108
|
+
if (isPersonalBest && streak.current > 7) {
|
|
109
|
+
text += ' (Personal best!)';
|
|
110
|
+
}
|
|
111
|
+
return text;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Format weekly progress for display
|
|
115
|
+
*/
|
|
116
|
+
function formatWeeklyProgress(streak) {
|
|
117
|
+
const filled = '█'.repeat(streak.weeklyProgress);
|
|
118
|
+
const empty = '░'.repeat(Math.max(0, streak.weeklyGoal - streak.weeklyProgress));
|
|
119
|
+
return `${streak.weeklyProgress}/${streak.weeklyGoal} days ${filled}${empty}`;
|
|
120
|
+
}
|
|
121
|
+
// Helper functions
|
|
122
|
+
function formatDate(date) {
|
|
123
|
+
return date.toISOString().split('T')[0];
|
|
124
|
+
}
|
|
125
|
+
function getWeekStart(date) {
|
|
126
|
+
const d = new Date(date);
|
|
127
|
+
const day = d.getDay();
|
|
128
|
+
const diff = d.getDate() - day + (day === 0 ? -6 : 1); // Monday start
|
|
129
|
+
d.setDate(diff);
|
|
130
|
+
return formatDate(d);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=streaks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaks.js","sourceRoot":"","sources":["../../src/gamification/streaks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export interface StreakState {
|
|
2
|
+
current: number;
|
|
3
|
+
longest: number;
|
|
4
|
+
lastActiveDate: string;
|
|
5
|
+
weeklyGoal: number;
|
|
6
|
+
weeklyProgress: number;
|
|
7
|
+
freezesRemaining: number;
|
|
8
|
+
lastFreezeUsed?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface XPState {
|
|
11
|
+
total: number;
|
|
12
|
+
level: number;
|
|
13
|
+
levelName: string;
|
|
14
|
+
currentLevelXP: number;
|
|
15
|
+
nextLevelXP: number;
|
|
16
|
+
lastSessionXP: number;
|
|
17
|
+
}
|
|
18
|
+
export interface Achievement {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
icon: string;
|
|
23
|
+
category: 'streak' | 'score' | 'sessions' | 'special';
|
|
24
|
+
condition: string;
|
|
25
|
+
unlockedAt?: string;
|
|
26
|
+
progress?: number;
|
|
27
|
+
hidden?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface SessionRecord {
|
|
30
|
+
date: string;
|
|
31
|
+
timestamp: string;
|
|
32
|
+
vibeScore: number;
|
|
33
|
+
overall: 'ELITE' | 'HIGH' | 'MEDIUM' | 'LOW';
|
|
34
|
+
commits: number;
|
|
35
|
+
spirals: number;
|
|
36
|
+
xpEarned: number;
|
|
37
|
+
achievementsUnlocked: string[];
|
|
38
|
+
periodFrom?: string;
|
|
39
|
+
periodTo?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface UserProfile {
|
|
42
|
+
version: string;
|
|
43
|
+
createdAt: string;
|
|
44
|
+
updatedAt: string;
|
|
45
|
+
streak: StreakState;
|
|
46
|
+
xp: XPState;
|
|
47
|
+
achievements: Achievement[];
|
|
48
|
+
sessions: SessionRecord[];
|
|
49
|
+
preferences: {
|
|
50
|
+
weeklyGoal: number;
|
|
51
|
+
showNotifications: boolean;
|
|
52
|
+
publicProfile: boolean;
|
|
53
|
+
};
|
|
54
|
+
stats: {
|
|
55
|
+
totalSessions: number;
|
|
56
|
+
totalCommitsAnalyzed: number;
|
|
57
|
+
avgVibeScore: number;
|
|
58
|
+
bestVibeScore: number;
|
|
59
|
+
totalSpiralsDetected: number;
|
|
60
|
+
spiralsAvoided: number;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export declare const LEVELS: readonly [{
|
|
64
|
+
readonly level: 1;
|
|
65
|
+
readonly name: "Novice";
|
|
66
|
+
readonly icon: "🌱";
|
|
67
|
+
readonly minXP: 0;
|
|
68
|
+
readonly maxXP: 100;
|
|
69
|
+
}, {
|
|
70
|
+
readonly level: 2;
|
|
71
|
+
readonly name: "Apprentice";
|
|
72
|
+
readonly icon: "🌿";
|
|
73
|
+
readonly minXP: 100;
|
|
74
|
+
readonly maxXP: 300;
|
|
75
|
+
}, {
|
|
76
|
+
readonly level: 3;
|
|
77
|
+
readonly name: "Practitioner";
|
|
78
|
+
readonly icon: "🌳";
|
|
79
|
+
readonly minXP: 300;
|
|
80
|
+
readonly maxXP: 600;
|
|
81
|
+
}, {
|
|
82
|
+
readonly level: 4;
|
|
83
|
+
readonly name: "Expert";
|
|
84
|
+
readonly icon: "🌲";
|
|
85
|
+
readonly minXP: 600;
|
|
86
|
+
readonly maxXP: 1000;
|
|
87
|
+
}, {
|
|
88
|
+
readonly level: 5;
|
|
89
|
+
readonly name: "Master";
|
|
90
|
+
readonly icon: "🎋";
|
|
91
|
+
readonly minXP: 1000;
|
|
92
|
+
readonly maxXP: 2000;
|
|
93
|
+
}, {
|
|
94
|
+
readonly level: 6;
|
|
95
|
+
readonly name: "Grandmaster";
|
|
96
|
+
readonly icon: "🏔️";
|
|
97
|
+
readonly minXP: 2000;
|
|
98
|
+
readonly maxXP: number;
|
|
99
|
+
}];
|
|
100
|
+
export declare const XP_REWARDS: {
|
|
101
|
+
readonly dailyCheckIn: 10;
|
|
102
|
+
readonly eliteSession: 50;
|
|
103
|
+
readonly highSession: 25;
|
|
104
|
+
readonly mediumSession: 10;
|
|
105
|
+
readonly lowSession: 5;
|
|
106
|
+
readonly streakBonus: 5;
|
|
107
|
+
readonly achievementBase: 25;
|
|
108
|
+
readonly noSpirals: 15;
|
|
109
|
+
readonly perfectTrust: 20;
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/gamification/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAElB,MAAM,EAAE,WAAW,CAAC;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAG1B,WAAW,EAAE;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IAGF,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAGD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOT,CAAC;AAGX,eAAO,MAAM,UAAU;;;;;;;;;;CAUb,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Gamification Types for Vibe-Check
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.XP_REWARDS = exports.LEVELS = void 0;
|
|
5
|
+
// Level progression
|
|
6
|
+
exports.LEVELS = [
|
|
7
|
+
{ level: 1, name: 'Novice', icon: '🌱', minXP: 0, maxXP: 100 },
|
|
8
|
+
{ level: 2, name: 'Apprentice', icon: '🌿', minXP: 100, maxXP: 300 },
|
|
9
|
+
{ level: 3, name: 'Practitioner', icon: '🌳', minXP: 300, maxXP: 600 },
|
|
10
|
+
{ level: 4, name: 'Expert', icon: '🌲', minXP: 600, maxXP: 1000 },
|
|
11
|
+
{ level: 5, name: 'Master', icon: '🎋', minXP: 1000, maxXP: 2000 },
|
|
12
|
+
{ level: 6, name: 'Grandmaster', icon: '🏔️', minXP: 2000, maxXP: Infinity },
|
|
13
|
+
];
|
|
14
|
+
// XP rewards
|
|
15
|
+
exports.XP_REWARDS = {
|
|
16
|
+
dailyCheckIn: 10,
|
|
17
|
+
eliteSession: 50,
|
|
18
|
+
highSession: 25,
|
|
19
|
+
mediumSession: 10,
|
|
20
|
+
lowSession: 5,
|
|
21
|
+
streakBonus: 5, // Per day of streak
|
|
22
|
+
achievementBase: 25, // Base for achievements
|
|
23
|
+
noSpirals: 15, // Bonus for 0 spirals
|
|
24
|
+
perfectTrust: 20, // 100% trust pass rate
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/gamification/types.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;AA0EpC,oBAAoB;AACP,QAAA,MAAM,GAAG;IACpB,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE;IAC9D,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;IACpE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;IACtE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE;IACjE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IAClE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;CACpE,CAAC;AAEX,aAAa;AACA,QAAA,UAAU,GAAG;IACxB,YAAY,EAAE,EAAE;IAChB,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,EAAE;IACf,aAAa,EAAE,EAAE;IACjB,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC,EAAY,oBAAoB;IAC9C,eAAe,EAAE,EAAE,EAAO,wBAAwB;IAClD,SAAS,EAAE,EAAE,EAAa,sBAAsB;IAChD,YAAY,EAAE,EAAE,EAAU,uBAAuB;CACzC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { XPState, LEVELS, SessionRecord, StreakState } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Create initial XP state
|
|
4
|
+
*/
|
|
5
|
+
export declare function createInitialXP(): XPState;
|
|
6
|
+
/**
|
|
7
|
+
* Calculate XP earned from a session
|
|
8
|
+
*/
|
|
9
|
+
export declare function calculateSessionXP(session: SessionRecord, streak: StreakState, achievementsUnlocked: number): number;
|
|
10
|
+
/**
|
|
11
|
+
* Add XP and handle level ups
|
|
12
|
+
*/
|
|
13
|
+
export declare function addXP(currentXP: XPState, earnedXP: number): {
|
|
14
|
+
xp: XPState;
|
|
15
|
+
leveledUp: boolean;
|
|
16
|
+
newLevel?: typeof LEVELS[number];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Get level for given XP amount
|
|
20
|
+
*/
|
|
21
|
+
export declare function getLevelForXP(xp: number): {
|
|
22
|
+
level: number;
|
|
23
|
+
levelInfo: typeof LEVELS[number];
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Format XP progress for display
|
|
27
|
+
*/
|
|
28
|
+
export declare function formatXPProgress(xp: XPState): string;
|
|
29
|
+
/**
|
|
30
|
+
* Format level for compact display
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatLevel(xp: XPState): string;
|
|
33
|
+
/**
|
|
34
|
+
* Get progress percentage to next level
|
|
35
|
+
*/
|
|
36
|
+
export declare function getLevelProgress(xp: XPState): number;
|
|
37
|
+
//# sourceMappingURL=xp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xp.d.ts","sourceRoot":"","sources":["../../src/gamification/xp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAc,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAElF;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CASzC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,WAAW,EACnB,oBAAoB,EAAE,MAAM,GAC3B,MAAM,CAkCR;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAA;CAAE,CAoBjI;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAA;CAAE,CAO7F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CAUpD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CAG/C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CAGpD"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createInitialXP = createInitialXP;
|
|
4
|
+
exports.calculateSessionXP = calculateSessionXP;
|
|
5
|
+
exports.addXP = addXP;
|
|
6
|
+
exports.getLevelForXP = getLevelForXP;
|
|
7
|
+
exports.formatXPProgress = formatXPProgress;
|
|
8
|
+
exports.formatLevel = formatLevel;
|
|
9
|
+
exports.getLevelProgress = getLevelProgress;
|
|
10
|
+
const types_1 = require("./types");
|
|
11
|
+
/**
|
|
12
|
+
* Create initial XP state
|
|
13
|
+
*/
|
|
14
|
+
function createInitialXP() {
|
|
15
|
+
return {
|
|
16
|
+
total: 0,
|
|
17
|
+
level: 1,
|
|
18
|
+
levelName: types_1.LEVELS[0].name,
|
|
19
|
+
currentLevelXP: 0,
|
|
20
|
+
nextLevelXP: types_1.LEVELS[0].maxXP,
|
|
21
|
+
lastSessionXP: 0,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Calculate XP earned from a session
|
|
26
|
+
*/
|
|
27
|
+
function calculateSessionXP(session, streak, achievementsUnlocked) {
|
|
28
|
+
let xp = 0;
|
|
29
|
+
// Base XP from rating
|
|
30
|
+
switch (session.overall) {
|
|
31
|
+
case 'ELITE':
|
|
32
|
+
xp += types_1.XP_REWARDS.eliteSession;
|
|
33
|
+
break;
|
|
34
|
+
case 'HIGH':
|
|
35
|
+
xp += types_1.XP_REWARDS.highSession;
|
|
36
|
+
break;
|
|
37
|
+
case 'MEDIUM':
|
|
38
|
+
xp += types_1.XP_REWARDS.mediumSession;
|
|
39
|
+
break;
|
|
40
|
+
case 'LOW':
|
|
41
|
+
xp += types_1.XP_REWARDS.lowSession;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
// Daily check-in bonus
|
|
45
|
+
xp += types_1.XP_REWARDS.dailyCheckIn;
|
|
46
|
+
// Streak bonus
|
|
47
|
+
xp += types_1.XP_REWARDS.streakBonus * Math.min(streak.current, 30); // Cap at 30 days
|
|
48
|
+
// Bonus for no spirals
|
|
49
|
+
if (session.spirals === 0 && session.commits >= 10) {
|
|
50
|
+
xp += types_1.XP_REWARDS.noSpirals;
|
|
51
|
+
}
|
|
52
|
+
// Achievement bonuses
|
|
53
|
+
xp += achievementsUnlocked * types_1.XP_REWARDS.achievementBase;
|
|
54
|
+
return xp;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Add XP and handle level ups
|
|
58
|
+
*/
|
|
59
|
+
function addXP(currentXP, earnedXP) {
|
|
60
|
+
const newTotal = currentXP.total + earnedXP;
|
|
61
|
+
const { level, levelInfo } = getLevelForXP(newTotal);
|
|
62
|
+
const leveledUp = level > currentXP.level;
|
|
63
|
+
const newXP = {
|
|
64
|
+
total: newTotal,
|
|
65
|
+
level,
|
|
66
|
+
levelName: levelInfo.name,
|
|
67
|
+
currentLevelXP: newTotal - levelInfo.minXP,
|
|
68
|
+
nextLevelXP: levelInfo.maxXP - levelInfo.minXP,
|
|
69
|
+
lastSessionXP: earnedXP,
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
xp: newXP,
|
|
73
|
+
leveledUp,
|
|
74
|
+
newLevel: leveledUp ? levelInfo : undefined,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get level for given XP amount
|
|
79
|
+
*/
|
|
80
|
+
function getLevelForXP(xp) {
|
|
81
|
+
for (let i = types_1.LEVELS.length - 1; i >= 0; i--) {
|
|
82
|
+
if (xp >= types_1.LEVELS[i].minXP) {
|
|
83
|
+
return { level: types_1.LEVELS[i].level, levelInfo: types_1.LEVELS[i] };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { level: 1, levelInfo: types_1.LEVELS[0] };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Format XP progress for display
|
|
90
|
+
*/
|
|
91
|
+
function formatXPProgress(xp) {
|
|
92
|
+
const levelInfo = types_1.LEVELS.find(l => l.level === xp.level);
|
|
93
|
+
const progress = xp.currentLevelXP / xp.nextLevelXP;
|
|
94
|
+
const barLength = 20;
|
|
95
|
+
const filled = Math.round(progress * barLength);
|
|
96
|
+
const empty = barLength - filled;
|
|
97
|
+
const bar = '█'.repeat(filled) + '░'.repeat(empty);
|
|
98
|
+
return `Level ${xp.level} ${levelInfo.name} ${levelInfo.icon}\n${bar} ${xp.currentLevelXP}/${xp.nextLevelXP} XP`;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Format level for compact display
|
|
102
|
+
*/
|
|
103
|
+
function formatLevel(xp) {
|
|
104
|
+
const levelInfo = types_1.LEVELS.find(l => l.level === xp.level);
|
|
105
|
+
return `Level ${xp.level} ${levelInfo.name} ${levelInfo.icon}`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get progress percentage to next level
|
|
109
|
+
*/
|
|
110
|
+
function getLevelProgress(xp) {
|
|
111
|
+
if (xp.nextLevelXP === Infinity)
|
|
112
|
+
return 100;
|
|
113
|
+
return Math.round((xp.currentLevelXP / xp.nextLevelXP) * 100);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=xp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xp.js","sourceRoot":"","sources":["../../src/gamification/xp.ts"],"names":[],"mappings":"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"}
|
package/dist/git.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
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
|
+
export interface FileStats {
|
|
5
|
+
filesPerCommit: Map<string, string[]>;
|
|
6
|
+
lineStats: {
|
|
7
|
+
additions: number;
|
|
8
|
+
deletions: number;
|
|
9
|
+
}[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get file-level statistics for semantic-free metrics.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getFileStats(repoPath: string, since?: string, until?: string): Promise<FileStats>;
|
|
4
15
|
//# 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"}
|
|
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"}
|
package/dist/git.js
CHANGED
|
@@ -5,6 +5,7 @@ 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.getFileStats = getFileStats;
|
|
8
9
|
const simple_git_1 = __importDefault(require("simple-git"));
|
|
9
10
|
const COMMIT_TYPES = ['feat', 'fix', 'docs', 'chore', 'refactor', 'test', 'style'];
|
|
10
11
|
async function getCommits(repoPath, since, until) {
|
|
@@ -61,4 +62,55 @@ async function isGitRepo(repoPath) {
|
|
|
61
62
|
return false;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Get file-level statistics for semantic-free metrics.
|
|
67
|
+
*/
|
|
68
|
+
async function getFileStats(repoPath, since, until) {
|
|
69
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
70
|
+
const filesPerCommit = new Map();
|
|
71
|
+
const lineStats = [];
|
|
72
|
+
// Build options for git log
|
|
73
|
+
const logOptions = {};
|
|
74
|
+
if (since)
|
|
75
|
+
logOptions['--since'] = since;
|
|
76
|
+
if (until)
|
|
77
|
+
logOptions['--until'] = until;
|
|
78
|
+
try {
|
|
79
|
+
// Get log with file names
|
|
80
|
+
const log = await git.log(logOptions);
|
|
81
|
+
for (const commit of log.all) {
|
|
82
|
+
const hash = commit.hash.substring(0, 7);
|
|
83
|
+
// Get diff stats for this commit
|
|
84
|
+
try {
|
|
85
|
+
const diffStat = await git.raw(['diff-tree', '--numstat', '--root', '-r', commit.hash]);
|
|
86
|
+
const lines = diffStat.trim().split('\n').filter(l => l.length > 0);
|
|
87
|
+
const files = [];
|
|
88
|
+
let additions = 0;
|
|
89
|
+
let deletions = 0;
|
|
90
|
+
for (const line of lines) {
|
|
91
|
+
const parts = line.split('\t');
|
|
92
|
+
if (parts.length >= 3) {
|
|
93
|
+
const add = parseInt(parts[0], 10) || 0;
|
|
94
|
+
const del = parseInt(parts[1], 10) || 0;
|
|
95
|
+
const file = parts[2];
|
|
96
|
+
additions += add;
|
|
97
|
+
deletions += del;
|
|
98
|
+
files.push(file);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
filesPerCommit.set(hash, files);
|
|
102
|
+
lineStats.push({ additions, deletions });
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// If diff-tree fails, just record empty
|
|
106
|
+
filesPerCommit.set(hash, []);
|
|
107
|
+
lineStats.push({ additions: 0, deletions: 0 });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Return empty stats on error - silent fail
|
|
113
|
+
}
|
|
114
|
+
return { filesPerCommit, lineStats };
|
|
115
|
+
}
|
|
64
116
|
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":";;;;;AAKA,gCA2BC;AA+BD,8BAQC;
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Commit, CodeStabilityResult } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Calculate code stability score.
|
|
4
|
+
* Measures what percentage of added lines survive.
|
|
5
|
+
*
|
|
6
|
+
* NOTE: Full implementation requires git blame analysis.
|
|
7
|
+
* This is a simplified version using addition/deletion ratios.
|
|
8
|
+
*/
|
|
9
|
+
export declare function calculateCodeStability(commits: Commit[], stats?: {
|
|
10
|
+
additions: number;
|
|
11
|
+
deletions: number;
|
|
12
|
+
}[]): CodeStabilityResult;
|
|
13
|
+
//# sourceMappingURL=code-stability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-stability.d.ts","sourceRoot":"","sources":["../../src/metrics/code-stability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAU,MAAM,UAAU,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,CAAC,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,GACjD,mBAAmB,CAiCrB"}
|