@boshu2/vibe-check 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/.agents/bundles/ml-learning-loop-complete-plan-2025-11-28.md +908 -0
  2. package/.agents/bundles/unified-vibe-system-plan-phase1-2025-11-28.md +962 -0
  3. package/.agents/bundles/unified-vibe-system-research-2025-11-28.md +1003 -0
  4. package/.agents/bundles/vibe-check-ecosystem-plan-2025-11-29.md +635 -0
  5. package/.agents/bundles/vibe-check-gamification-complete-2025-11-29.md +132 -0
  6. package/.agents/bundles/vibe-score-scientific-framework-2025-11-28.md +602 -0
  7. package/.vibe-check/calibration.json +38 -0
  8. package/.vibe-check/latest.json +114 -0
  9. package/CHANGELOG.md +46 -0
  10. package/CLAUDE.md +178 -0
  11. package/README.md +265 -63
  12. package/action.yml +270 -0
  13. package/dashboard/app.js +494 -0
  14. package/dashboard/index.html +235 -0
  15. package/dashboard/styles.css +647 -0
  16. package/dist/calibration/ece.d.ts +26 -0
  17. package/dist/calibration/ece.d.ts.map +1 -0
  18. package/dist/calibration/ece.js +93 -0
  19. package/dist/calibration/ece.js.map +1 -0
  20. package/dist/calibration/index.d.ts +3 -0
  21. package/dist/calibration/index.d.ts.map +1 -0
  22. package/dist/calibration/index.js +15 -0
  23. package/dist/calibration/index.js.map +1 -0
  24. package/dist/calibration/storage.d.ts +34 -0
  25. package/dist/calibration/storage.d.ts.map +1 -0
  26. package/dist/calibration/storage.js +188 -0
  27. package/dist/calibration/storage.js.map +1 -0
  28. package/dist/cli.js +30 -76
  29. package/dist/cli.js.map +1 -1
  30. package/dist/commands/analyze.d.ts +16 -0
  31. package/dist/commands/analyze.d.ts.map +1 -0
  32. package/dist/commands/analyze.js +256 -0
  33. package/dist/commands/analyze.js.map +1 -0
  34. package/dist/commands/index.d.ts +4 -0
  35. package/dist/commands/index.d.ts.map +1 -0
  36. package/dist/commands/index.js +11 -0
  37. package/dist/commands/index.js.map +1 -0
  38. package/dist/commands/level.d.ts +3 -0
  39. package/dist/commands/level.d.ts.map +1 -0
  40. package/dist/commands/level.js +277 -0
  41. package/dist/commands/level.js.map +1 -0
  42. package/dist/commands/profile.d.ts +4 -0
  43. package/dist/commands/profile.d.ts.map +1 -0
  44. package/dist/commands/profile.js +143 -0
  45. package/dist/commands/profile.js.map +1 -0
  46. package/dist/gamification/achievements.d.ts +15 -0
  47. package/dist/gamification/achievements.d.ts.map +1 -0
  48. package/dist/gamification/achievements.js +273 -0
  49. package/dist/gamification/achievements.js.map +1 -0
  50. package/dist/gamification/index.d.ts +8 -0
  51. package/dist/gamification/index.d.ts.map +1 -0
  52. package/dist/gamification/index.js +30 -0
  53. package/dist/gamification/index.js.map +1 -0
  54. package/dist/gamification/profile.d.ts +46 -0
  55. package/dist/gamification/profile.d.ts.map +1 -0
  56. package/dist/gamification/profile.js +272 -0
  57. package/dist/gamification/profile.js.map +1 -0
  58. package/dist/gamification/streaks.d.ts +26 -0
  59. package/dist/gamification/streaks.d.ts.map +1 -0
  60. package/dist/gamification/streaks.js +132 -0
  61. package/dist/gamification/streaks.js.map +1 -0
  62. package/dist/gamification/types.d.ts +111 -0
  63. package/dist/gamification/types.d.ts.map +1 -0
  64. package/dist/gamification/types.js +26 -0
  65. package/dist/gamification/types.js.map +1 -0
  66. package/dist/gamification/xp.d.ts +37 -0
  67. package/dist/gamification/xp.d.ts.map +1 -0
  68. package/dist/gamification/xp.js +115 -0
  69. package/dist/gamification/xp.js.map +1 -0
  70. package/dist/git.d.ts +11 -0
  71. package/dist/git.d.ts.map +1 -1
  72. package/dist/git.js +52 -0
  73. package/dist/git.js.map +1 -1
  74. package/dist/metrics/code-stability.d.ts +13 -0
  75. package/dist/metrics/code-stability.d.ts.map +1 -0
  76. package/dist/metrics/code-stability.js +74 -0
  77. package/dist/metrics/code-stability.js.map +1 -0
  78. package/dist/metrics/file-churn.d.ts +8 -0
  79. package/dist/metrics/file-churn.d.ts.map +1 -0
  80. package/dist/metrics/file-churn.js +75 -0
  81. package/dist/metrics/file-churn.js.map +1 -0
  82. package/dist/metrics/time-spiral.d.ts +8 -0
  83. package/dist/metrics/time-spiral.d.ts.map +1 -0
  84. package/dist/metrics/time-spiral.js +69 -0
  85. package/dist/metrics/time-spiral.js.map +1 -0
  86. package/dist/metrics/velocity-anomaly.d.ts +13 -0
  87. package/dist/metrics/velocity-anomaly.d.ts.map +1 -0
  88. package/dist/metrics/velocity-anomaly.js +67 -0
  89. package/dist/metrics/velocity-anomaly.js.map +1 -0
  90. package/dist/output/index.d.ts +6 -3
  91. package/dist/output/index.d.ts.map +1 -1
  92. package/dist/output/index.js +4 -3
  93. package/dist/output/index.js.map +1 -1
  94. package/dist/output/json.d.ts +2 -2
  95. package/dist/output/json.d.ts.map +1 -1
  96. package/dist/output/json.js +54 -0
  97. package/dist/output/json.js.map +1 -1
  98. package/dist/output/markdown.d.ts +2 -2
  99. package/dist/output/markdown.d.ts.map +1 -1
  100. package/dist/output/markdown.js +34 -1
  101. package/dist/output/markdown.js.map +1 -1
  102. package/dist/output/terminal.d.ts +6 -2
  103. package/dist/output/terminal.d.ts.map +1 -1
  104. package/dist/output/terminal.js +131 -3
  105. package/dist/output/terminal.js.map +1 -1
  106. package/dist/recommend/index.d.ts +3 -0
  107. package/dist/recommend/index.d.ts.map +1 -0
  108. package/dist/recommend/index.js +14 -0
  109. package/dist/recommend/index.js.map +1 -0
  110. package/dist/recommend/ordered-logistic.d.ts +49 -0
  111. package/dist/recommend/ordered-logistic.d.ts.map +1 -0
  112. package/dist/recommend/ordered-logistic.js +153 -0
  113. package/dist/recommend/ordered-logistic.js.map +1 -0
  114. package/dist/recommend/questions.d.ts +19 -0
  115. package/dist/recommend/questions.d.ts.map +1 -0
  116. package/dist/recommend/questions.js +73 -0
  117. package/dist/recommend/questions.js.map +1 -0
  118. package/dist/score/index.d.ts +21 -0
  119. package/dist/score/index.d.ts.map +1 -0
  120. package/dist/score/index.js +48 -0
  121. package/dist/score/index.js.map +1 -0
  122. package/dist/score/weights.d.ts +16 -0
  123. package/dist/score/weights.d.ts.map +1 -0
  124. package/dist/score/weights.js +28 -0
  125. package/dist/score/weights.js.map +1 -0
  126. package/dist/types.d.ts +83 -0
  127. package/dist/types.d.ts.map +1 -1
  128. package/package.json +10 -9
@@ -0,0 +1,143 @@
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.createProfileCommand = createProfileCommand;
7
+ exports.runProfile2 = runProfile2;
8
+ const commander_1 = require("commander");
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const profile_1 = require("../gamification/profile");
11
+ const xp_1 = require("../gamification/xp");
12
+ const types_1 = require("../gamification/types");
13
+ const achievements_1 = require("../gamification/achievements");
14
+ function createProfileCommand() {
15
+ const cmd = new commander_1.Command('profile')
16
+ .description('View your vibe-check profile, stats, and achievements')
17
+ .option('--achievements', 'Show all achievements', false)
18
+ .option('--stats', 'Show detailed stats', false)
19
+ .option('--json', 'Output as JSON', false)
20
+ .action(async (options) => {
21
+ await runProfile(options);
22
+ });
23
+ return cmd;
24
+ }
25
+ async function runProfile(options) {
26
+ const profile = (0, profile_1.loadProfile)();
27
+ if (options.json) {
28
+ console.log(JSON.stringify(profile, null, 2));
29
+ return;
30
+ }
31
+ const { xp, streak, achievements, stats } = profile;
32
+ const levelInfo = types_1.LEVELS.find(l => l.level === xp.level);
33
+ const achievementCounts = (0, profile_1.getAchievementCounts)(profile);
34
+ const recentSessions = (0, profile_1.getRecentSessions)(profile, 30);
35
+ // Header
36
+ console.log();
37
+ console.log(chalk_1.default.cyan('╭─────────────────────────────────────────────╮'));
38
+ console.log(chalk_1.default.cyan('│') + chalk_1.default.bold.white(' Your Vibe Profile ') + chalk_1.default.cyan('│'));
39
+ console.log(chalk_1.default.cyan('├─────────────────────────────────────────────┤'));
40
+ // Level
41
+ const levelBar = createProgressBar((0, xp_1.getLevelProgress)(xp), 20);
42
+ console.log(chalk_1.default.cyan('│') + ` ${levelInfo.icon} ${chalk_1.default.bold(`Level ${xp.level} ${xp.levelName}`)}`.padEnd(52) + chalk_1.default.cyan('│'));
43
+ console.log(chalk_1.default.cyan('│') + ` ${levelBar} ${chalk_1.default.gray(`${xp.currentLevelXP}/${xp.nextLevelXP} XP`)}`.padEnd(60) + chalk_1.default.cyan('│'));
44
+ console.log(chalk_1.default.cyan('│') + ''.padEnd(44) + chalk_1.default.cyan('│'));
45
+ // Streak
46
+ const streakDisplay = streak.current > 0
47
+ ? `🔥 Current Streak: ${chalk_1.default.bold(streak.current.toString())} days${streak.current === streak.longest ? chalk_1.default.yellow(' (Best!)') : ''}`
48
+ : '🔥 No active streak';
49
+ console.log(chalk_1.default.cyan('│') + ` ${streakDisplay}`.padEnd(52) + chalk_1.default.cyan('│'));
50
+ const weeklyBar = createProgressBar((streak.weeklyProgress / streak.weeklyGoal) * 100, 5);
51
+ console.log(chalk_1.default.cyan('│') + ` 📅 Weekly Goal: ${streak.weeklyProgress}/${streak.weeklyGoal} ${weeklyBar}`.padEnd(52) + chalk_1.default.cyan('│'));
52
+ console.log(chalk_1.default.cyan('│') + ` 🏆 Achievements: ${achievementCounts.unlocked}/${achievementCounts.total} unlocked`.padEnd(52) + chalk_1.default.cyan('│'));
53
+ console.log(chalk_1.default.cyan('│') + ''.padEnd(44) + chalk_1.default.cyan('│'));
54
+ // 30-Day Stats
55
+ console.log(chalk_1.default.cyan('│') + chalk_1.default.bold(' 📊 30-Day Stats').padEnd(52) + chalk_1.default.cyan('│'));
56
+ const avgScore = recentSessions.length > 0
57
+ ? Math.round(recentSessions.reduce((sum, s) => sum + s.vibeScore, 0) / recentSessions.length)
58
+ : 0;
59
+ const totalCommits = recentSessions.reduce((sum, s) => sum + s.commits, 0);
60
+ console.log(chalk_1.default.cyan('│') + ` ├─ Avg Vibe Score: ${chalk_1.default.bold(avgScore.toString())}%`.padEnd(52) + chalk_1.default.cyan('│'));
61
+ console.log(chalk_1.default.cyan('│') + ` ├─ Sessions: ${chalk_1.default.bold(recentSessions.length.toString())}`.padEnd(52) + chalk_1.default.cyan('│'));
62
+ console.log(chalk_1.default.cyan('│') + ` ├─ Commits Analyzed: ${chalk_1.default.bold(totalCommits.toString())}`.padEnd(52) + chalk_1.default.cyan('│'));
63
+ const spiralsAvoided = recentSessions.filter(s => s.spirals === 0 && s.commits >= 10).length;
64
+ console.log(chalk_1.default.cyan('│') + ` └─ Zero-Spiral Sessions: ${chalk_1.default.bold(spiralsAvoided.toString())}`.padEnd(52) + chalk_1.default.cyan('│'));
65
+ console.log(chalk_1.default.cyan('│') + ''.padEnd(44) + chalk_1.default.cyan('│'));
66
+ // Recent achievements
67
+ const recentAchievements = achievements.slice(-3).reverse();
68
+ if (recentAchievements.length > 0) {
69
+ console.log(chalk_1.default.cyan('│') + chalk_1.default.bold(' Recent Achievements:').padEnd(52) + chalk_1.default.cyan('│'));
70
+ for (const ach of recentAchievements) {
71
+ const dateStr = ach.unlockedAt
72
+ ? new Date(ach.unlockedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
73
+ : '';
74
+ console.log(chalk_1.default.cyan('│') + ` ${ach.icon} ${ach.name} ${chalk_1.default.gray(`(${dateStr})`)}`.padEnd(52) + chalk_1.default.cyan('│'));
75
+ }
76
+ }
77
+ console.log(chalk_1.default.cyan('╰─────────────────────────────────────────────╯'));
78
+ console.log();
79
+ // Show all achievements if requested
80
+ if (options.achievements) {
81
+ showAllAchievements(achievements);
82
+ }
83
+ // Show detailed stats if requested
84
+ if (options.stats) {
85
+ showDetailedStats(profile);
86
+ }
87
+ }
88
+ function createProgressBar(percent, length) {
89
+ const filled = Math.round((percent / 100) * length);
90
+ const empty = length - filled;
91
+ return chalk_1.default.green('█'.repeat(filled)) + chalk_1.default.gray('░'.repeat(empty));
92
+ }
93
+ function showAllAchievements(unlockedAchievements) {
94
+ const allAchievements = (0, achievements_1.getAllAchievements)(unlockedAchievements);
95
+ const unlockedIds = new Set(unlockedAchievements.map(a => a.id));
96
+ console.log(chalk_1.default.bold('\n🏆 All Achievements\n'));
97
+ const categories = ['streak', 'score', 'sessions', 'special'];
98
+ const categoryNames = {
99
+ streak: '🔥 Streak',
100
+ score: '📈 Score',
101
+ sessions: '📊 Sessions',
102
+ special: '⭐ Special',
103
+ };
104
+ for (const category of categories) {
105
+ const categoryAchievements = allAchievements.filter(a => a.category === category);
106
+ if (categoryAchievements.length === 0)
107
+ continue;
108
+ console.log(chalk_1.default.bold(categoryNames[category]));
109
+ for (const ach of categoryAchievements) {
110
+ const isUnlocked = unlockedIds.has(ach.id);
111
+ const icon = isUnlocked ? ach.icon : (ach.hidden ? '❓' : '🔒');
112
+ const name = isUnlocked || !ach.hidden ? ach.name : '???';
113
+ const desc = isUnlocked || !ach.hidden ? ach.description : 'Keep playing to unlock!';
114
+ const status = isUnlocked
115
+ ? chalk_1.default.green('✓')
116
+ : chalk_1.default.gray('○');
117
+ console.log(` ${status} ${icon} ${isUnlocked ? chalk_1.default.white(name) : chalk_1.default.gray(name)}`);
118
+ console.log(` ${chalk_1.default.gray(desc)}`);
119
+ }
120
+ console.log();
121
+ }
122
+ }
123
+ function showDetailedStats(profile) {
124
+ const { stats, xp, streak } = profile;
125
+ console.log(chalk_1.default.bold('\n📊 Detailed Statistics\n'));
126
+ console.log(chalk_1.default.bold('Lifetime'));
127
+ console.log(` Total Sessions: ${chalk_1.default.bold(stats.totalSessions)}`);
128
+ console.log(` Commits Analyzed: ${chalk_1.default.bold(stats.totalCommitsAnalyzed.toLocaleString())}`);
129
+ console.log(` Average Score: ${chalk_1.default.bold(stats.avgVibeScore)}%`);
130
+ console.log(` Best Score: ${chalk_1.default.bold(stats.bestVibeScore)}%`);
131
+ console.log(` Total Spirals: ${chalk_1.default.bold(stats.totalSpiralsDetected)}`);
132
+ console.log(` Zero-Spiral Sessions: ${chalk_1.default.bold(stats.spiralsAvoided)}`);
133
+ console.log();
134
+ console.log(chalk_1.default.bold('Progress'));
135
+ console.log(` Total XP: ${chalk_1.default.bold(xp.total)}`);
136
+ console.log(` Current Level: ${chalk_1.default.bold(`${xp.level} (${xp.levelName})`)}`);
137
+ console.log(` Longest Streak: ${chalk_1.default.bold(streak.longest)} days`);
138
+ console.log();
139
+ }
140
+ async function runProfile2(options) {
141
+ return runProfile(options);
142
+ }
143
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/commands/profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { Achievement, SessionRecord, StreakState, XPState } from './types';
2
+ export declare const ACHIEVEMENTS: Omit<Achievement, 'unlockedAt' | 'progress'>[];
3
+ /**
4
+ * Check which achievements are newly unlocked based on current state
5
+ */
6
+ export declare function checkAchievements(sessions: SessionRecord[], streak: StreakState, xp: XPState, currentSession: SessionRecord, unlockedIds: string[]): Achievement[];
7
+ /**
8
+ * Get achievement by ID
9
+ */
10
+ export declare function getAchievement(id: string): Achievement | undefined;
11
+ /**
12
+ * Get all achievements with unlock status
13
+ */
14
+ export declare function getAllAchievements(unlockedAchievements: Achievement[]): Achievement[];
15
+ //# sourceMappingURL=achievements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"achievements.d.ts","sourceRoot":"","sources":["../../src/gamification/achievements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAG3E,eAAO,MAAM,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,UAAU,CAAC,EAoKtE,CAAC;AAEF;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,EAAE,WAAW,EACnB,EAAE,EAAE,OAAO,EACX,cAAc,EAAE,aAAa,EAC7B,WAAW,EAAE,MAAM,EAAE,GACpB,WAAW,EAAE,CAyBf;AAyFD;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,oBAAoB,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAOrF"}
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ACHIEVEMENTS = void 0;
4
+ exports.checkAchievements = checkAchievements;
5
+ exports.getAchievement = getAchievement;
6
+ exports.getAllAchievements = getAllAchievements;
7
+ // All available achievements
8
+ exports.ACHIEVEMENTS = [
9
+ // Streak achievements
10
+ {
11
+ id: 'first_check',
12
+ name: 'First Blood',
13
+ description: 'Run your first vibe-check',
14
+ icon: '🩸',
15
+ category: 'sessions',
16
+ condition: 'Complete 1 session',
17
+ },
18
+ {
19
+ id: 'week_warrior',
20
+ name: 'Week Warrior',
21
+ description: 'Maintain a 7-day streak',
22
+ icon: '⚔️',
23
+ category: 'streak',
24
+ condition: '7-day streak',
25
+ },
26
+ {
27
+ id: 'fortnight_force',
28
+ name: 'Fortnight Force',
29
+ description: 'Maintain a 14-day streak',
30
+ icon: '🛡️',
31
+ category: 'streak',
32
+ condition: '14-day streak',
33
+ },
34
+ {
35
+ id: 'monthly_master',
36
+ name: 'Monthly Master',
37
+ description: 'Maintain a 30-day streak',
38
+ icon: '👑',
39
+ category: 'streak',
40
+ condition: '30-day streak',
41
+ },
42
+ // Score achievements
43
+ {
44
+ id: 'elite_vibes',
45
+ name: 'Elite Vibes',
46
+ description: 'Achieve ELITE rating in a session',
47
+ icon: '✨',
48
+ category: 'score',
49
+ condition: 'Get ELITE rating',
50
+ },
51
+ {
52
+ id: 'consistent_high',
53
+ name: 'High Roller',
54
+ description: 'Get HIGH or better for 5 consecutive sessions',
55
+ icon: '🎰',
56
+ category: 'score',
57
+ condition: '5 consecutive HIGH+ sessions',
58
+ },
59
+ {
60
+ id: 'perfect_week',
61
+ name: 'Perfect Week',
62
+ description: 'ELITE rating every day for a week',
63
+ icon: '💎',
64
+ category: 'score',
65
+ condition: '7 consecutive ELITE sessions',
66
+ },
67
+ {
68
+ id: 'score_90',
69
+ name: 'Ninety Club',
70
+ description: 'Achieve a Vibe Score of 90% or higher',
71
+ icon: '🏅',
72
+ category: 'score',
73
+ condition: 'Vibe Score ≥ 90%',
74
+ },
75
+ // Session milestones
76
+ {
77
+ id: 'ten_sessions',
78
+ name: 'Getting Started',
79
+ description: 'Complete 10 vibe-check sessions',
80
+ icon: '📊',
81
+ category: 'sessions',
82
+ condition: '10 sessions',
83
+ },
84
+ {
85
+ id: 'fifty_sessions',
86
+ name: 'Regular',
87
+ description: 'Complete 50 vibe-check sessions',
88
+ icon: '📈',
89
+ category: 'sessions',
90
+ condition: '50 sessions',
91
+ },
92
+ {
93
+ id: 'hundred_sessions',
94
+ name: 'Centurion',
95
+ description: 'Complete 100 vibe-check sessions',
96
+ icon: '💯',
97
+ category: 'sessions',
98
+ condition: '100 sessions',
99
+ },
100
+ // Special achievements
101
+ {
102
+ id: 'zen_master',
103
+ name: 'Zen Master',
104
+ description: '0 debug spirals in a 50+ commit session',
105
+ icon: '🧘',
106
+ category: 'special',
107
+ condition: '50+ commits, 0 spirals',
108
+ },
109
+ {
110
+ id: 'trust_builder',
111
+ name: 'Trust Builder',
112
+ description: 'Maintain 90%+ Trust Pass Rate for 10 sessions',
113
+ icon: '🏗️',
114
+ category: 'special',
115
+ condition: '10 sessions with 90%+ trust',
116
+ },
117
+ {
118
+ id: 'comeback_kid',
119
+ name: 'Comeback Kid',
120
+ description: 'Go from LOW to ELITE in the same week',
121
+ icon: '🔄',
122
+ category: 'special',
123
+ condition: 'LOW → ELITE in 7 days',
124
+ },
125
+ {
126
+ id: 'early_bird',
127
+ name: 'Early Bird',
128
+ description: 'Run vibe-check before 7 AM',
129
+ icon: '🌅',
130
+ category: 'special',
131
+ condition: 'Session before 7 AM',
132
+ },
133
+ {
134
+ id: 'night_owl',
135
+ name: 'Night Owl',
136
+ description: 'Run vibe-check after midnight',
137
+ icon: '🦉',
138
+ category: 'special',
139
+ condition: 'Session after midnight',
140
+ },
141
+ {
142
+ id: 'thousand_commits',
143
+ name: 'Thousand Strong',
144
+ description: 'Analyze 1000 total commits',
145
+ icon: '🎯',
146
+ category: 'special',
147
+ condition: '1000 commits analyzed',
148
+ },
149
+ // Hidden achievements
150
+ {
151
+ id: 'perfect_score',
152
+ name: '???',
153
+ description: 'Achieve a perfect 100% Vibe Score',
154
+ icon: '🌟',
155
+ category: 'special',
156
+ condition: '???',
157
+ hidden: true,
158
+ },
159
+ {
160
+ id: 'spiral_survivor',
161
+ name: '???',
162
+ description: 'Recover from 5+ spirals to ELITE in same session',
163
+ icon: '🌀',
164
+ category: 'special',
165
+ condition: '???',
166
+ hidden: true,
167
+ },
168
+ ];
169
+ /**
170
+ * Check which achievements are newly unlocked based on current state
171
+ */
172
+ function checkAchievements(sessions, streak, xp, currentSession, unlockedIds) {
173
+ const newlyUnlocked = [];
174
+ const now = new Date().toISOString();
175
+ for (const achievement of exports.ACHIEVEMENTS) {
176
+ // Skip already unlocked
177
+ if (unlockedIds.includes(achievement.id))
178
+ continue;
179
+ const unlocked = checkAchievementCondition(achievement.id, sessions, streak, xp, currentSession);
180
+ if (unlocked) {
181
+ newlyUnlocked.push({
182
+ ...achievement,
183
+ unlockedAt: now,
184
+ });
185
+ }
186
+ }
187
+ return newlyUnlocked;
188
+ }
189
+ function checkAchievementCondition(id, sessions, streak, _xp, current) {
190
+ const totalSessions = sessions.length + 1; // Include current
191
+ switch (id) {
192
+ // Session count
193
+ case 'first_check':
194
+ return totalSessions >= 1;
195
+ case 'ten_sessions':
196
+ return totalSessions >= 10;
197
+ case 'fifty_sessions':
198
+ return totalSessions >= 50;
199
+ case 'hundred_sessions':
200
+ return totalSessions >= 100;
201
+ // Streak
202
+ case 'week_warrior':
203
+ return streak.current >= 7;
204
+ case 'fortnight_force':
205
+ return streak.current >= 14;
206
+ case 'monthly_master':
207
+ return streak.current >= 30;
208
+ // Score
209
+ case 'elite_vibes':
210
+ return current.overall === 'ELITE';
211
+ case 'score_90':
212
+ return current.vibeScore >= 90;
213
+ case 'perfect_score':
214
+ return current.vibeScore === 100;
215
+ // Consecutive sessions
216
+ case 'consistent_high': {
217
+ const last5 = [...sessions.slice(-4), current];
218
+ return last5.length >= 5 &&
219
+ last5.every(s => s.overall === 'ELITE' || s.overall === 'HIGH');
220
+ }
221
+ case 'perfect_week': {
222
+ const last7 = [...sessions.slice(-6), current];
223
+ return last7.length >= 7 && last7.every(s => s.overall === 'ELITE');
224
+ }
225
+ // Special
226
+ case 'zen_master':
227
+ return current.commits >= 50 && current.spirals === 0;
228
+ case 'trust_builder': {
229
+ // Would need trust pass rate in session record
230
+ return false; // TODO: Implement when trust is tracked
231
+ }
232
+ case 'comeback_kid': {
233
+ const weekAgo = new Date();
234
+ weekAgo.setDate(weekAgo.getDate() - 7);
235
+ const weekSessions = sessions.filter(s => new Date(s.date) >= weekAgo);
236
+ const hadLow = weekSessions.some(s => s.overall === 'LOW');
237
+ return hadLow && current.overall === 'ELITE';
238
+ }
239
+ case 'early_bird': {
240
+ const hour = new Date(current.timestamp).getHours();
241
+ return hour < 7;
242
+ }
243
+ case 'night_owl': {
244
+ const hour = new Date(current.timestamp).getHours();
245
+ return hour >= 0 && hour < 5;
246
+ }
247
+ case 'thousand_commits': {
248
+ const totalCommits = sessions.reduce((sum, s) => sum + s.commits, 0) + current.commits;
249
+ return totalCommits >= 1000;
250
+ }
251
+ case 'spiral_survivor':
252
+ return current.spirals >= 5 && current.overall === 'ELITE';
253
+ default:
254
+ return false;
255
+ }
256
+ }
257
+ /**
258
+ * Get achievement by ID
259
+ */
260
+ function getAchievement(id) {
261
+ return exports.ACHIEVEMENTS.find(a => a.id === id);
262
+ }
263
+ /**
264
+ * Get all achievements with unlock status
265
+ */
266
+ function getAllAchievements(unlockedAchievements) {
267
+ const unlockedIds = new Set(unlockedAchievements.map(a => a.id));
268
+ return exports.ACHIEVEMENTS.map(a => {
269
+ const unlocked = unlockedAchievements.find(u => u.id === a.id);
270
+ return unlocked || { ...a, unlockedAt: undefined };
271
+ });
272
+ }
273
+ //# sourceMappingURL=achievements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"achievements.js","sourceRoot":"","sources":["../../src/gamification/achievements.ts"],"names":[],"mappings":";;;AA4KA,8CA+BC;AA4FD,wCAEC;AAKD,gDAOC;AAnTD,6BAA6B;AAChB,QAAA,YAAY,GAAmD;IAC1E,sBAAsB;IACtB;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,2BAA2B;QACxC,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,UAAU;QACpB,SAAS,EAAE,oBAAoB;KAChC;IACD;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,yBAAyB;QACtC,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,cAAc;KAC1B;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,0BAA0B;QACvC,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,eAAe;KAC3B;IACD;QACE,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,0BAA0B;QACvC,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,eAAe;KAC3B;IAED,qBAAqB;IACrB;QACE,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,mCAAmC;QAChD,IAAI,EAAE,GAAG;QACT,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,kBAAkB;KAC9B;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,+CAA+C;QAC5D,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,8BAA8B;KAC1C;IACD;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,mCAAmC;QAChD,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,8BAA8B;KAC1C;IACD;QACE,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,uCAAuC;QACpD,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,OAAO;QACjB,SAAS,EAAE,kBAAkB;KAC9B;IAED,qBAAqB;IACrB;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,iCAAiC;QAC9C,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,UAAU;QACpB,SAAS,EAAE,aAAa;KACzB;IACD;QACE,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,iCAAiC;QAC9C,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,UAAU;QACpB,SAAS,EAAE,aAAa;KACzB;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,kCAAkC;QAC/C,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,UAAU;QACpB,SAAS,EAAE,cAAc;KAC1B;IAED,uBAAuB;IACvB;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,yCAAyC;QACtD,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,wBAAwB;KACpC;IACD;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,+CAA+C;QAC5D,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,6BAA6B;KACzC;IACD;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,uCAAuC;QACpD,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,uBAAuB;KACnC;IACD;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,4BAA4B;QACzC,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,qBAAqB;KACjC;IACD;QACE,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,+BAA+B;QAC5C,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,wBAAwB;KACpC;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,4BAA4B;QACzC,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,uBAAuB;KACnC;IAED,sBAAsB;IACtB;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,mCAAmC;QAChD,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,IAAI;KACb;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,kDAAkD;QAC/D,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,SAAS;QACnB,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,IAAI;KACb;CACF,CAAC;AAEF;;GAEG;AACH,SAAgB,iBAAiB,CAC/B,QAAyB,EACzB,MAAmB,EACnB,EAAW,EACX,cAA6B,EAC7B,WAAqB;IAErB,MAAM,aAAa,GAAkB,EAAE,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,KAAK,MAAM,WAAW,IAAI,oBAAY,EAAE,CAAC;QACvC,wBAAwB;QACxB,IAAI,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAAE,SAAS;QAEnD,MAAM,QAAQ,GAAG,yBAAyB,CACxC,WAAW,CAAC,EAAE,EACd,QAAQ,EACR,MAAM,EACN,EAAE,EACF,cAAc,CACf,CAAC;QAEF,IAAI,QAAQ,EAAE,CAAC;YACb,aAAa,CAAC,IAAI,CAAC;gBACjB,GAAG,WAAW;gBACd,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAS,yBAAyB,CAChC,EAAU,EACV,QAAyB,EACzB,MAAmB,EACnB,GAAY,EACZ,OAAsB;IAEtB,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAE,kBAAkB;IAE9D,QAAQ,EAAE,EAAE,CAAC;QACX,gBAAgB;QAChB,KAAK,aAAa;YAChB,OAAO,aAAa,IAAI,CAAC,CAAC;QAC5B,KAAK,cAAc;YACjB,OAAO,aAAa,IAAI,EAAE,CAAC;QAC7B,KAAK,gBAAgB;YACnB,OAAO,aAAa,IAAI,EAAE,CAAC;QAC7B,KAAK,kBAAkB;YACrB,OAAO,aAAa,IAAI,GAAG,CAAC;QAE9B,SAAS;QACT,KAAK,cAAc;YACjB,OAAO,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;QAC7B,KAAK,iBAAiB;YACpB,OAAO,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;QAC9B,KAAK,gBAAgB;YACnB,OAAO,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;QAE9B,QAAQ;QACR,KAAK,aAAa;YAChB,OAAO,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC;QACrC,KAAK,UAAU;YACb,OAAO,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QACjC,KAAK,eAAe;YAClB,OAAO,OAAO,CAAC,SAAS,KAAK,GAAG,CAAC;QAEnC,uBAAuB;QACvB,KAAK,iBAAiB,CAAC,CAAC,CAAC;YACvB,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC/C,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC;gBACjB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;QACzE,CAAC;QACD,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC/C,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;QACtE,CAAC;QAED,UAAU;QACV,KAAK,YAAY;YACf,OAAO,OAAO,CAAC,OAAO,IAAI,EAAE,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC,CAAC;QAExD,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,+CAA+C;YAC/C,OAAO,KAAK,CAAC,CAAC,wCAAwC;QACxD,CAAC;QAED,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACvC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC;YAC3D,OAAO,MAAM,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC;QAC/C,CAAC;QAED,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;YACpD,OAAO,IAAI,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;YACpD,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;QAC/B,CAAC;QAED,KAAK,kBAAkB,CAAC,CAAC,CAAC;YACxB,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;YACvF,OAAO,YAAY,IAAI,IAAI,CAAC;QAC9B,CAAC;QAED,KAAK,iBAAiB;YACpB,OAAO,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC;QAE7D;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,EAAU;IACvC,OAAO,oBAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAA4B,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAAC,oBAAmC;IACpE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEjE,OAAO,oBAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QAC1B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/D,OAAO,QAAQ,IAAI,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ export * from './types';
2
+ export * from './streaks';
3
+ export * from './xp';
4
+ export * from './achievements';
5
+ export * from './profile';
6
+ export { LEVELS, XP_REWARDS } from './types';
7
+ export { ACHIEVEMENTS } from './achievements';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gamification/index.ts"],"names":[],"mappings":"AAEA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,MAAM,CAAC;AACrB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ // Gamification Module - Main Export
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.ACHIEVEMENTS = exports.XP_REWARDS = exports.LEVELS = void 0;
19
+ __exportStar(require("./types"), exports);
20
+ __exportStar(require("./streaks"), exports);
21
+ __exportStar(require("./xp"), exports);
22
+ __exportStar(require("./achievements"), exports);
23
+ __exportStar(require("./profile"), exports);
24
+ // Re-export commonly used items for convenience
25
+ var types_1 = require("./types");
26
+ Object.defineProperty(exports, "LEVELS", { enumerable: true, get: function () { return types_1.LEVELS; } });
27
+ Object.defineProperty(exports, "XP_REWARDS", { enumerable: true, get: function () { return types_1.XP_REWARDS; } });
28
+ var achievements_1 = require("./achievements");
29
+ Object.defineProperty(exports, "ACHIEVEMENTS", { enumerable: true, get: function () { return achievements_1.ACHIEVEMENTS; } });
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gamification/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;;AAEpC,0CAAwB;AACxB,4CAA0B;AAC1B,uCAAqB;AACrB,iDAA+B;AAC/B,4CAA0B;AAE1B,gDAAgD;AAChD,iCAA6C;AAApC,+FAAA,MAAM,OAAA;AAAE,mGAAA,UAAU,OAAA;AAC3B,+CAA8C;AAArC,4GAAA,YAAY,OAAA"}
@@ -0,0 +1,46 @@
1
+ import { UserProfile, SessionRecord, Achievement } from './types';
2
+ /**
3
+ * Get profile directory path (in user's home directory)
4
+ */
5
+ export declare function getProfileDir(): string;
6
+ /**
7
+ * Get profile file path
8
+ */
9
+ export declare function getProfilePath(): string;
10
+ /**
11
+ * Create initial profile
12
+ */
13
+ export declare function createInitialProfile(): UserProfile;
14
+ /**
15
+ * Load profile from disk
16
+ */
17
+ export declare function loadProfile(): UserProfile;
18
+ /**
19
+ * Save profile to disk
20
+ */
21
+ export declare function saveProfile(profile: UserProfile): void;
22
+ /**
23
+ * Record a new session and update all gamification state
24
+ */
25
+ export declare function recordSession(vibeScore: number, overall: 'ELITE' | 'HIGH' | 'MEDIUM' | 'LOW', commits: number, spirals: number, periodFrom?: Date, periodTo?: Date): {
26
+ profile: UserProfile;
27
+ xpEarned: number;
28
+ leveledUp: boolean;
29
+ newLevel?: string;
30
+ achievementsUnlocked: Achievement[];
31
+ streakExtended: boolean;
32
+ isPersonalBest: boolean;
33
+ isDuplicate: boolean;
34
+ };
35
+ /**
36
+ * Get achievement counts
37
+ */
38
+ export declare function getAchievementCounts(profile: UserProfile): {
39
+ unlocked: number;
40
+ total: number;
41
+ };
42
+ /**
43
+ * Get recent sessions (last N days)
44
+ */
45
+ export declare function getRecentSessions(profile: UserProfile, days: number): SessionRecord[];
46
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/gamification/profile.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,WAAW,EACX,aAAa,EAGb,WAAW,EACZ,MAAM,SAAS,CAAC;AAQjB;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,WAAW,CA4BlD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,WAAW,CAczC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAUtD;AAyCD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,EAC5C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,IAAI,EACjB,QAAQ,CAAC,EAAE,IAAI,GACd;IACD,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,WAAW,EAAE,CAAC;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;CACtB,CA+FA;AAkCD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAK9F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAKrF"}