repo-wrapped 0.0.7 → 0.0.9
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/.github/agents/complete.agent.md +257 -0
- package/.github/agents/feature-scaffold.agent.md +248 -0
- package/.github/agents/jsdoc.agent.md +243 -0
- package/.github/agents/plan.agent.md +202 -0
- package/.github/agents/spec-writer.agent.md +169 -0
- package/.github/agents/test-writer.agent.md +169 -0
- package/.stylelintrc.json +27 -0
- package/README.md +94 -94
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +446 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +446 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +7039 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/commands/generate.js +56 -56
- package/dist/config/defaults.js +158 -0
- package/dist/config/index.js +10 -0
- package/dist/features/achievements/data/achievements.json +284 -0
- package/dist/features/achievements/engine.js +140 -0
- package/dist/features/achievements/evaluators.js +246 -0
- package/dist/features/achievements/helpers.js +58 -0
- package/dist/features/achievements/index.js +57 -0
- package/dist/features/achievements/loader.js +88 -0
- package/dist/features/achievements/template.js +155 -0
- package/dist/features/achievements/types.js +7 -0
- package/dist/features/commit-quality/analyzer.js +378 -0
- package/dist/features/commit-quality/analyzer.test.js +484 -0
- package/dist/features/commit-quality/index.js +28 -0
- package/dist/features/commit-quality/template.js +114 -0
- package/dist/features/commit-quality/types.js +2 -0
- package/dist/features/comparison/analyzer.js +222 -0
- package/dist/features/comparison/index.js +28 -0
- package/dist/features/comparison/template.js +119 -0
- package/dist/features/comparison/types.js +2 -0
- package/dist/features/contribution-graph/index.js +9 -0
- package/dist/features/contribution-graph/template.js +89 -0
- package/dist/features/events/index.js +31 -0
- package/dist/features/events/parser.js +253 -0
- package/dist/features/events/template.js +113 -0
- package/dist/features/events/types.js +2 -0
- package/dist/features/executive-summary/generator.js +275 -0
- package/dist/features/executive-summary/index.js +27 -0
- package/dist/features/executive-summary/template.js +80 -0
- package/dist/features/executive-summary/types.js +2 -0
- package/dist/features/gaps/analyzer.js +298 -0
- package/dist/features/gaps/analyzer.test.js +517 -0
- package/dist/features/gaps/index.js +27 -0
- package/dist/features/gaps/template.js +190 -0
- package/dist/features/gaps/types.js +2 -0
- package/dist/features/impact/analyzer.js +248 -0
- package/dist/features/impact/index.js +26 -0
- package/dist/features/impact/template.js +118 -0
- package/dist/features/impact/types.js +2 -0
- package/dist/features/index.js +40 -0
- package/dist/features/knowledge/analyzer.js +385 -0
- package/dist/features/knowledge/index.js +26 -0
- package/dist/features/knowledge/template.js +239 -0
- package/dist/features/knowledge/types.js +2 -0
- package/dist/features/streaks/calculator.js +184 -0
- package/dist/features/streaks/calculator.test.js +366 -0
- package/dist/features/streaks/index.js +36 -0
- package/dist/features/streaks/template.js +41 -0
- package/dist/features/streaks/types.js +9 -0
- package/dist/features/team/analyzer.js +316 -0
- package/dist/features/team/index.js +30 -0
- package/dist/features/team/template.js +146 -0
- package/dist/features/team/types.js +2 -0
- package/dist/features/time-patterns/analyzer.js +319 -0
- package/dist/features/time-patterns/analyzer.test.js +278 -0
- package/dist/features/time-patterns/index.js +37 -0
- package/dist/features/time-patterns/template.js +109 -0
- package/dist/features/time-patterns/types.js +9 -0
- package/dist/features/velocity/analyzer.js +257 -0
- package/dist/features/velocity/analyzer.test.js +383 -0
- package/dist/features/velocity/index.js +27 -0
- package/dist/features/velocity/template.js +189 -0
- package/dist/features/velocity/types.js +2 -0
- package/dist/generators/html/scripts/knowledge.js +17 -0
- package/dist/generators/html/styles/base.css +8 -3
- package/dist/generators/html/styles/components.css +121 -1
- package/dist/generators/html/styles/knowledge.css +21 -0
- package/dist/generators/html/styles/leaddev.css +108 -48
- package/dist/generators/html/styles/strategic-insights.css +1337 -0
- package/dist/generators/html/templates/commitQualitySection.js +28 -2
- package/dist/generators/html/templates/executiveSummarySection.js +0 -4
- package/dist/generators/html/templates/impactSection.js +8 -6
- package/dist/generators/html/templates/knowledgeSection.js +16 -2
- package/dist/generators/html/templates/velocitySection.js +2 -2
- package/dist/generators/html/types.js +7 -0
- package/dist/generators/html/utils/analysisRunner.js +93 -0
- package/dist/generators/html/utils/cardBuilder.js +47 -0
- package/dist/generators/html/utils/contextBuilder.js +54 -0
- package/dist/generators/html/utils/htmlDocumentBuilder.js +396 -0
- package/dist/generators/html/utils/kpiBuilder.js +76 -0
- package/dist/generators/html/utils/sectionWrapper.js +71 -0
- package/dist/generators/html/utils/styleLoader.js +2 -2
- package/dist/html/analysisRunner.js +93 -0
- package/dist/html/htmlDocumentBuilder.js +396 -0
- package/dist/html/index.js +29 -0
- package/dist/html/shared/colorUtils.js +61 -0
- package/dist/html/shared/commitMapBuilder.js +23 -0
- package/dist/html/shared/components/cardBuilder.js +47 -0
- package/dist/html/shared/components/index.js +18 -0
- package/dist/html/shared/components/kpiBuilder.js +76 -0
- package/dist/html/shared/components/sectionWrapper.js +71 -0
- package/dist/html/shared/contextBuilder.js +54 -0
- package/dist/html/shared/dateRangeCalculator.js +56 -0
- package/dist/html/shared/developerStatsCalculator.js +28 -0
- package/dist/html/shared/index.js +39 -0
- package/dist/html/shared/scriptLoader.js +15 -0
- package/dist/html/shared/scripts/export.js +125 -0
- package/dist/html/shared/scripts/knowledge.js +137 -0
- package/dist/html/shared/scripts/modal.js +68 -0
- package/dist/html/shared/scripts/navigation.js +156 -0
- package/dist/html/shared/scripts/tabs.js +18 -0
- package/dist/html/shared/scripts/tooltip.js +21 -0
- package/dist/html/shared/styleLoader.js +18 -0
- package/dist/html/shared/styles/achievements.css +387 -0
- package/dist/html/shared/styles/base.css +822 -0
- package/dist/html/shared/styles/components.css +1511 -0
- package/dist/html/shared/styles/knowledge.css +242 -0
- package/dist/html/shared/styles/strategic-insights.css +1337 -0
- package/dist/html/shared/weekGrouper.js +27 -0
- package/dist/html/types.js +7 -0
- package/dist/index.js +39 -39
- package/dist/test/helpers/commitFactory.js +166 -0
- package/dist/test/helpers/dateUtils.js +101 -0
- package/dist/test/helpers/index.js +29 -0
- package/dist/test/setup.js +17 -0
- package/dist/test/smoke.test.js +94 -0
- package/dist/types/achievements.js +7 -0
- package/dist/types/analysis.js +7 -0
- package/dist/types/core.js +7 -0
- package/dist/types/index.js +38 -0
- package/dist/types/options.js +7 -0
- package/dist/types/shared.js +7 -0
- package/dist/types/strategic.js +7 -0
- package/dist/types/summary.js +7 -0
- package/dist/utils/achievementDefinitions.js +22 -22
- package/dist/utils/analyzerContextBuilder.js +124 -0
- package/dist/utils/commitQualityAnalyzer.js +13 -2
- package/dist/utils/emptyResults.js +95 -0
- package/dist/utils/fileHotspotAnalyzer.js +4 -12
- package/dist/utils/gapAnalyzer.js +26 -28
- package/dist/utils/gitParser.test.js +363 -0
- package/dist/utils/htmlGenerator.js +62 -466
- package/dist/utils/impactAnalyzer.js +20 -19
- package/dist/utils/knowledgeDistributionAnalyzer.js +32 -27
- package/dist/utils/matrixGenerator.js +13 -13
- package/dist/utils/rangeComparisonAnalyzer.js +2 -2
- package/dist/utils/streakCalculator.js +77 -27
- package/dist/utils/teamAnalyzer.js +20 -1
- package/dist/utils/timePatternAnalyzer.js +18 -3
- package/dist/utils/velocityAnalyzer.js +23 -18
- package/dist/utils/wrappedGenerator.js +8 -8
- package/package.json +74 -64
- package/vitest.config.ts +46 -0
- package/SPECS.md +0 -490
- package/dist/cli.js +0 -24
- package/dist/commands/index.js +0 -24
- package/test-team.txt +0 -2
|
@@ -1,83 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HTML Generator - Orchestrates the HTML dashboard generation pipeline.
|
|
4
|
+
*
|
|
5
|
+
* This module coordinates the generation of the complete HTML dashboard by:
|
|
6
|
+
* 1. Building context from options
|
|
7
|
+
* 2. Running all analyzers
|
|
8
|
+
* 3. Assembling the final HTML document
|
|
9
|
+
*
|
|
10
|
+
* For implementation details, see:
|
|
11
|
+
* - html/shared/contextBuilder.ts - Context building
|
|
12
|
+
* - html/analysisRunner.ts - Analyzer execution
|
|
13
|
+
* - html/htmlDocumentBuilder.ts - Document assembly
|
|
14
|
+
*
|
|
15
|
+
* @module utils/htmlGenerator
|
|
16
|
+
*/
|
|
2
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
18
|
exports.generateSummaryOnlyHTML = generateSummaryOnlyHTML;
|
|
4
19
|
exports.generateHTML = generateHTML;
|
|
5
20
|
const date_fns_1 = require("date-fns");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const fileHotspotAnalyzer_1 = require("./fileHotspotAnalyzer");
|
|
9
|
-
const impactAnalyzer_1 = require("./impactAnalyzer");
|
|
10
|
-
const knowledgeDistributionAnalyzer_1 = require("./knowledgeDistributionAnalyzer");
|
|
11
|
-
const streakCalculator_1 = require("./streakCalculator");
|
|
12
|
-
const timePatternAnalyzer_1 = require("./timePatternAnalyzer");
|
|
13
|
-
const styleLoader_1 = require("../generators/html/utils/styleLoader");
|
|
14
|
-
const scriptLoader_1 = require("../generators/html/utils/scriptLoader");
|
|
15
|
-
const contributionGraph_1 = require("../generators/html/templates/contributionGraph");
|
|
16
|
-
const streakSection_1 = require("../generators/html/templates/streakSection");
|
|
17
|
-
const timePatternsSection_1 = require("../generators/html/templates/timePatternsSection");
|
|
18
|
-
const commitQualitySection_1 = require("../generators/html/templates/commitQualitySection");
|
|
19
|
-
const achievementsSection_1 = require("../generators/html/templates/achievementsSection");
|
|
20
|
-
const impactSection_1 = require("../generators/html/templates/impactSection");
|
|
21
|
-
const knowledgeSection_1 = require("../generators/html/templates/knowledgeSection");
|
|
22
|
-
const velocitySection_1 = require("../generators/html/templates/velocitySection");
|
|
23
|
-
const gapSection_1 = require("../generators/html/templates/gapSection");
|
|
24
|
-
const comparisonSection_1 = require("../generators/html/templates/comparisonSection");
|
|
25
|
-
const executiveSummarySection_1 = require("../generators/html/templates/executiveSummarySection");
|
|
26
|
-
const teamSection_1 = require("../generators/html/templates/teamSection");
|
|
27
|
-
const eventsSection_1 = require("../generators/html/templates/eventsSection");
|
|
28
|
-
const commitMapBuilder_1 = require("../generators/html/utils/commitMapBuilder");
|
|
29
|
-
const developerStatsCalculator_1 = require("../generators/html/utils/developerStatsCalculator");
|
|
30
|
-
const dateRangeCalculator_1 = require("../generators/html/utils/dateRangeCalculator");
|
|
31
|
-
const weekGrouper_1 = require("../generators/html/utils/weekGrouper");
|
|
32
|
-
const colorUtils_1 = require("../generators/html/utils/colorUtils");
|
|
33
|
-
// Helper to format date range for display
|
|
34
|
-
function formatDateRange(start, end) {
|
|
35
|
-
return `${(0, date_fns_1.format)(start, 'MMM d, yyyy')} – ${(0, date_fns_1.format)(end, 'MMM d, yyyy')}`;
|
|
36
|
-
}
|
|
37
|
-
// Helper to build KPI header
|
|
38
|
-
function buildKPIHeader(totalCommits, qualityScore, currentStreak, activeDayPercentage) {
|
|
39
|
-
const healthScore = ((qualityScore / 10) * 0.4 + (activeDayPercentage / 100) * 0.3 + Math.min(currentStreak / 30, 1) * 0.3) * 10;
|
|
40
|
-
return `
|
|
41
|
-
<header class="kpi-header">
|
|
42
|
-
<div class="kpi-card">
|
|
43
|
-
<span class="kpi-label">Total Commits</span>
|
|
44
|
-
<span class="kpi-value">${totalCommits.toLocaleString()}</span>
|
|
45
|
-
</div>
|
|
46
|
-
<div class="kpi-card">
|
|
47
|
-
<span class="kpi-label">Health Score</span>
|
|
48
|
-
<span class="kpi-value">${healthScore.toFixed(1)}</span>
|
|
49
|
-
</div>
|
|
50
|
-
<div class="kpi-card">
|
|
51
|
-
<span class="kpi-label">Current Streak</span>
|
|
52
|
-
<span class="kpi-value">${currentStreak}d</span>
|
|
53
|
-
</div>
|
|
54
|
-
<div class="kpi-card">
|
|
55
|
-
<span class="kpi-label">Quality</span>
|
|
56
|
-
<span class="kpi-value">${qualityScore.toFixed(1)}</span>
|
|
57
|
-
</div>
|
|
58
|
-
<div class="kpi-card">
|
|
59
|
-
<span class="kpi-label">Active Days</span>
|
|
60
|
-
<span class="kpi-value">${activeDayPercentage.toFixed(0)}%</span>
|
|
61
|
-
</div>
|
|
62
|
-
</header>
|
|
63
|
-
`;
|
|
64
|
-
}
|
|
65
|
-
// Helper to wrap content in collapsible section
|
|
66
|
-
function wrapInSection(id, title, content, icon = '') {
|
|
67
|
-
return `
|
|
68
|
-
<section class="dashboard-section" id="${id}">
|
|
69
|
-
<header class="section-header" role="button" aria-expanded="true">
|
|
70
|
-
<h2>${icon ? icon + ' ' : ''}${title}</h2>
|
|
71
|
-
<span class="collapse-icon">▼</span>
|
|
72
|
-
</header>
|
|
73
|
-
<div class="section-content">
|
|
74
|
-
${content}
|
|
75
|
-
</div>
|
|
76
|
-
</section>
|
|
77
|
-
`;
|
|
78
|
-
}
|
|
21
|
+
const html_1 = require("../html");
|
|
22
|
+
const executive_summary_1 = require("../features/executive-summary");
|
|
79
23
|
/**
|
|
80
|
-
* Generate a minimal HTML page with only the executive summary
|
|
24
|
+
* Generate a minimal HTML page with only the executive summary.
|
|
25
|
+
*
|
|
26
|
+
* @param summary - Executive summary data
|
|
27
|
+
* @param repoName - Repository name for title
|
|
28
|
+
* @returns Complete HTML document string
|
|
81
29
|
*/
|
|
82
30
|
function generateSummaryOnlyHTML(summary, repoName) {
|
|
83
31
|
return `<!DOCTYPE html>
|
|
@@ -87,7 +35,7 @@ function generateSummaryOnlyHTML(summary, repoName) {
|
|
|
87
35
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
88
36
|
<title>Executive Summary - ${repoName}</title>
|
|
89
37
|
<style>
|
|
90
|
-
${(0,
|
|
38
|
+
${(0, html_1.loadStyles)()}
|
|
91
39
|
|
|
92
40
|
/* Summary-only specific styles */
|
|
93
41
|
body.summary-only {
|
|
@@ -146,401 +94,49 @@ function generateSummaryOnlyHTML(summary, repoName) {
|
|
|
146
94
|
<p class="generated">Generated ${(0, date_fns_1.format)(summary.generatedAt, 'MMM d, yyyy \'at\' h:mm a')}</p>
|
|
147
95
|
</header>
|
|
148
96
|
|
|
149
|
-
${(0,
|
|
97
|
+
${(0, executive_summary_1.buildExecutiveSummarySection)(summary)}
|
|
150
98
|
</div>
|
|
151
99
|
</body>
|
|
152
100
|
</html>`;
|
|
153
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Generate complete HTML dashboard.
|
|
104
|
+
*
|
|
105
|
+
* This is the main entry point for HTML generation. It orchestrates:
|
|
106
|
+
* 1. Context building (date ranges, user detection, commit filtering)
|
|
107
|
+
* 2. Running all analyzers (streaks, patterns, quality, achievements, etc.)
|
|
108
|
+
* 3. Assembling the final HTML document with all tabs
|
|
109
|
+
*
|
|
110
|
+
* @param commits - All commits in the repository
|
|
111
|
+
* @param year - Year to analyze
|
|
112
|
+
* @param monthsToShow - Number of months to include
|
|
113
|
+
* @param repoPath - Absolute path to the repository
|
|
114
|
+
* @param repoName - Display name for the repository
|
|
115
|
+
* @param repoUrl - URL to the repository (for links)
|
|
116
|
+
* @param skipBodyCheck - Skip commit body validation
|
|
117
|
+
* @param allTime - Show all-time data instead of year
|
|
118
|
+
* @param deepAnalysis - Enable deep analysis (more expensive)
|
|
119
|
+
* @param leadDevOptions - Pre-computed strategic insights
|
|
120
|
+
* @returns Complete HTML document string
|
|
121
|
+
*/
|
|
154
122
|
function generateHTML(commits, year, monthsToShow, repoPath, repoName, repoUrl, skipBodyCheck = false, allTime = false, deepAnalysis = false, leadDevOptions) {
|
|
155
|
-
//
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
// Create commit maps for overall and personal commits
|
|
168
|
-
const { commitMap, commitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(filteredCommits, startDate, endDate);
|
|
169
|
-
const personalCommits = filteredCommits.filter(c => c.author === currentUser);
|
|
170
|
-
const { commitMap: personalCommitMap, commitDetailsMap: personalCommitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(personalCommits, startDate, endDate);
|
|
171
|
-
// Calculate per-developer statistics
|
|
172
|
-
const developerStats = (0, developerStatsCalculator_1.calculateDeveloperStats)(filteredCommits, startDate, endDate);
|
|
173
|
-
// Calculate streak data (overall and personal)
|
|
174
|
-
const streakData = (0, streakCalculator_1.calculateStreaks)(filteredCommits, startDate, endDate);
|
|
175
|
-
const personalStreakData = (0, streakCalculator_1.calculateStreaks)(personalCommits, startDate, endDate);
|
|
176
|
-
// Analyze time patterns (overall and personal)
|
|
177
|
-
const timePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(filteredCommits, startDate, endDate);
|
|
178
|
-
const personalTimePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(personalCommits, startDate, endDate);
|
|
179
|
-
// Analyze commit quality (overall and personal)
|
|
180
|
-
const commitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(filteredCommits, { skipBodyCheck });
|
|
181
|
-
const personalCommitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(personalCommits, { skipBodyCheck });
|
|
182
|
-
// Analyze file hotspots
|
|
183
|
-
const fileHotspots = (0, fileHotspotAnalyzer_1.analyzeFileHotspots)(repoPath, startDate, endDate);
|
|
184
|
-
// Analyze impact and knowledge distribution (enterprise insights)
|
|
185
|
-
const impactAnalysis = (0, impactAnalyzer_1.analyzeImpact)(filteredCommits);
|
|
186
|
-
const knowledgeDistribution = (0, knowledgeDistributionAnalyzer_1.analyzeKnowledgeDistribution)(filteredCommits, repoPath, deepAnalysis);
|
|
187
|
-
const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
188
|
-
const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
189
|
-
// Prepare analysis data for achievements (overall and personal)
|
|
190
|
-
const analysisData = {
|
|
191
|
-
commits: filteredCommits,
|
|
192
|
-
totalCommits,
|
|
193
|
-
streakData,
|
|
194
|
-
timePattern,
|
|
195
|
-
commitQuality,
|
|
196
|
-
fileHotspots,
|
|
197
|
-
dateRange: { start: startDate, end: endDate }
|
|
198
|
-
};
|
|
199
|
-
const personalAnalysisData = {
|
|
200
|
-
commits: personalCommits,
|
|
201
|
-
totalCommits: totalPersonalCommits,
|
|
202
|
-
streakData: personalStreakData,
|
|
203
|
-
timePattern: personalTimePattern,
|
|
204
|
-
commitQuality: personalCommitQuality,
|
|
205
|
-
fileHotspots,
|
|
206
|
-
dateRange: { start: startDate, end: endDate }
|
|
123
|
+
// Build options object
|
|
124
|
+
const options = {
|
|
125
|
+
commits,
|
|
126
|
+
repoPath,
|
|
127
|
+
repoName,
|
|
128
|
+
repoUrl,
|
|
129
|
+
year,
|
|
130
|
+
monthsToShow,
|
|
131
|
+
allTime,
|
|
132
|
+
skipBodyCheck,
|
|
133
|
+
deepAnalysis,
|
|
134
|
+
features: leadDevOptions,
|
|
207
135
|
};
|
|
208
|
-
//
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
|
|
215
|
-
const dayLabels = (0, weekGrouper_1.getDayLabels)();
|
|
216
|
-
// Build KPI header for personal stats
|
|
217
|
-
const kpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
|
|
218
|
-
// Generate sections using template builders
|
|
219
|
-
const contributionGraphHtml = (0, contributionGraph_1.buildContributionGraph)({
|
|
220
|
-
commitMap: personalCommitMap,
|
|
221
|
-
commitDetailsMap: personalCommitDetailsMap,
|
|
222
|
-
weeks,
|
|
223
|
-
dayLabels,
|
|
224
|
-
dataStartDate,
|
|
225
|
-
dataEndDate,
|
|
226
|
-
totalCommits,
|
|
227
|
-
title: 'Your contributions',
|
|
228
|
-
getColorFn: (0, colorUtils_1.createDynamicColorFn)(personalCommitMap)
|
|
229
|
-
});
|
|
230
|
-
const streakSectionHtml = (0, streakSection_1.buildStreakSection)(streakData);
|
|
231
|
-
const timePatternsHtml = (0, timePatternsSection_1.buildTimePatternsSection)(timePattern);
|
|
232
|
-
const commitQualityHtml = (0, commitQualitySection_1.buildCommitQualitySection)(commitQuality, totalCommits, skipBodyCheck);
|
|
233
|
-
const achievementsHtml = (0, achievementsSection_1.buildAchievementsSection)(achievementProgress);
|
|
234
|
-
// Combine all sections with collapsible wrappers
|
|
235
|
-
return `
|
|
236
|
-
${kpiHeader}
|
|
237
|
-
|
|
238
|
-
${wrapInSection('personal-overview', 'Contribution Overview', contributionGraphHtml)}
|
|
239
|
-
${wrapInSection('personal-streaks', 'Streak Analysis', streakSectionHtml)}
|
|
240
|
-
${wrapInSection('personal-patterns', 'Time Patterns', timePatternsHtml)}
|
|
241
|
-
${wrapInSection('personal-quality', 'Commit Quality', commitQualityHtml)}
|
|
242
|
-
${wrapInSection('personal-achievements', 'Achievements', achievementsHtml)}
|
|
243
|
-
`;
|
|
244
|
-
}
|
|
245
|
-
function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, repoName, repoUrl, currentUser, skipBodyCheck = false, impactAnalysis, knowledgeDistribution, leadDevOptions) {
|
|
246
|
-
const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
247
|
-
const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
|
|
248
|
-
// Create dynamic color function based on commit distribution
|
|
249
|
-
const getColor = (0, colorUtils_1.createDynamicColorFn)(commitMap);
|
|
250
|
-
// Build month labels and track month boundaries
|
|
251
|
-
let monthLabels = '';
|
|
252
|
-
let currentMonth = '';
|
|
253
|
-
const monthBoundaries = new Set();
|
|
254
|
-
weeks.forEach((week, weekIndex) => {
|
|
255
|
-
const firstDayOfWeek = week[0];
|
|
256
|
-
const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
|
|
257
|
-
if (monthName !== currentMonth) {
|
|
258
|
-
currentMonth = monthName;
|
|
259
|
-
if (weekIndex > 0) {
|
|
260
|
-
monthBoundaries.add(weekIndex);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
// Build week columns
|
|
265
|
-
let weekColumns = '';
|
|
266
|
-
const dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
267
|
-
weeks.forEach((week, weekIndex) => {
|
|
268
|
-
let weekColumn = `<div class="graph-column">`;
|
|
269
|
-
week.forEach((day, dayOfWeek) => {
|
|
270
|
-
const dateKey = (0, date_fns_1.format)(day, 'yyyy-MM-dd');
|
|
271
|
-
const count = commitMap.get(dateKey) || 0;
|
|
272
|
-
const isInRange = day >= dataStartDate && day <= dataEndDate;
|
|
273
|
-
const color = isInRange ? getColor(count) : 'transparent';
|
|
274
|
-
const dateStr = (0, date_fns_1.format)(day, 'MMM d, yyyy');
|
|
275
|
-
const emptyClass = count === 0 ? ' empty' : '';
|
|
276
|
-
const clickable = count > 0 ? ' clickable' : '';
|
|
277
|
-
const rawCommits = commitDetailsMap.get(dateKey) || [];
|
|
278
|
-
const sanitizedCommits = rawCommits.map(c => ({
|
|
279
|
-
...c,
|
|
280
|
-
message: c.message
|
|
281
|
-
.replace(/[\r\n]+/g, ' ')
|
|
282
|
-
.replace(/'/g, ''')
|
|
283
|
-
.replace(/"/g, '"')
|
|
284
|
-
.replace(/</g, '<')
|
|
285
|
-
.replace(/>/g, '>')
|
|
286
|
-
.substring(0, 200)
|
|
287
|
-
}));
|
|
288
|
-
const detailsData = count > 0 ? `data-details='${JSON.stringify(sanitizedCommits)}'` : '';
|
|
289
|
-
weekColumn += `<div class="day${emptyClass}${clickable}" style="background-color: ${color};" data-count="${count}" data-date="${dateStr}" ${detailsData}></div>`;
|
|
290
|
-
});
|
|
291
|
-
weekColumn += '</div>';
|
|
292
|
-
weekColumns += weekColumn;
|
|
293
|
-
});
|
|
294
|
-
// Build day labels column
|
|
295
|
-
let dayLabelsHtml = '<div class="day-labels">';
|
|
296
|
-
dayLabels.forEach((label, index) => {
|
|
297
|
-
const displayLabel = [1, 3, 5].includes(index) ? label : '';
|
|
298
|
-
dayLabelsHtml += `<div class="day-label">${displayLabel}</div>`;
|
|
299
|
-
});
|
|
300
|
-
dayLabelsHtml += '</div>';
|
|
301
|
-
// Build month labels header
|
|
302
|
-
let monthLabelsHtml = '';
|
|
303
|
-
currentMonth = '';
|
|
304
|
-
weeks.forEach((week, weekIndex) => {
|
|
305
|
-
const firstDayOfWeek = week[0];
|
|
306
|
-
const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
|
|
307
|
-
if (monthName !== currentMonth) {
|
|
308
|
-
monthLabelsHtml += `<div class="month-label">${monthName}</div>`;
|
|
309
|
-
currentMonth = monthName;
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
monthLabelsHtml += `<div class="month-label"></div>`;
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
|
|
316
|
-
// Sort developers by commit count
|
|
317
|
-
const sortedDevelopers = Array.from(developerStats.entries())
|
|
318
|
-
.sort((a, b) => b[1].commits - a[1].commits);
|
|
319
|
-
// Generate developer analysis HTML
|
|
320
|
-
const developerAnalysisHtml = sortedDevelopers.map(([author, stats]) => {
|
|
321
|
-
const percentage = ((stats.commits / totalCommits) * 100).toFixed(1);
|
|
322
|
-
const dateRange = stats.firstCommit.toDateString() === stats.lastCommit.toDateString()
|
|
323
|
-
? (0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')
|
|
324
|
-
: `${(0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')} - ${(0, date_fns_1.format)(stats.lastCommit, 'MMM d, yyyy')}`;
|
|
325
|
-
return `
|
|
326
|
-
<div class="developer-row">
|
|
327
|
-
<div class="developer-info">
|
|
328
|
-
<div class="developer-name">${author}</div>
|
|
329
|
-
<div class="developer-date-range">${dateRange}</div>
|
|
330
|
-
</div>
|
|
331
|
-
<div class="developer-stats">
|
|
332
|
-
<div class="developer-bar-container">
|
|
333
|
-
<div class="developer-bar" style="width: ${percentage}%"></div>
|
|
334
|
-
</div>
|
|
335
|
-
<div class="developer-count">${stats.commits} commits (${percentage}%)</div>
|
|
336
|
-
</div>
|
|
337
|
-
</div>
|
|
338
|
-
`;
|
|
339
|
-
}).join('');
|
|
340
|
-
// Build contribution graph HTML for Overall tab
|
|
341
|
-
const contributionGraphHtml = `
|
|
342
|
-
<div class="graph-container">
|
|
343
|
-
<div class="months">
|
|
344
|
-
${monthLabelsHtml}
|
|
345
|
-
</div>
|
|
346
|
-
|
|
347
|
-
<div class="graph">
|
|
348
|
-
${dayLabelsHtml}
|
|
349
|
-
${weekColumns}
|
|
350
|
-
</div>
|
|
351
|
-
|
|
352
|
-
<div class="legend">
|
|
353
|
-
<span>Less</span>
|
|
354
|
-
<span class="legend-box" style="background-color: rgba(235, 237, 240, 0.1); border: 1px solid #21262d;"></span>
|
|
355
|
-
<span class="legend-box" style="background-color: #9be9a8;"></span>
|
|
356
|
-
<span class="legend-box" style="background-color: #40c463;"></span>
|
|
357
|
-
<span class="legend-box" style="background-color: #30a14e;"></span>
|
|
358
|
-
<span class="legend-box" style="background-color: #216e39;"></span>
|
|
359
|
-
<span>More</span>
|
|
360
|
-
</div>
|
|
361
|
-
</div>
|
|
362
|
-
`;
|
|
363
|
-
const developerSectionHtml = `
|
|
364
|
-
<div class="developer-analysis">
|
|
365
|
-
${developerAnalysisHtml}
|
|
366
|
-
</div>
|
|
367
|
-
`;
|
|
368
|
-
// Build KPI header for Overall tab
|
|
369
|
-
const overallKpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
|
|
370
|
-
return `<!DOCTYPE html>
|
|
371
|
-
<html lang="en">
|
|
372
|
-
<head>
|
|
373
|
-
<meta charset="UTF-8">
|
|
374
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
375
|
-
<title>Git Wrapped - ${repoName}</title>
|
|
376
|
-
<style>
|
|
377
|
-
${(0, styleLoader_1.loadStyles)()}
|
|
378
|
-
</style>
|
|
379
|
-
</head>
|
|
380
|
-
<body>
|
|
381
|
-
<!-- Mobile Navigation Toggle -->
|
|
382
|
-
<button class="mobile-nav-toggle" aria-label="Toggle navigation">
|
|
383
|
-
<span class="hamburger-icon"></span>
|
|
384
|
-
</button>
|
|
385
|
-
|
|
386
|
-
<div class="dashboard-layout">
|
|
387
|
-
<!-- Sidebar Navigation -->
|
|
388
|
-
<nav class="sidebar" role="navigation" aria-label="Main navigation">
|
|
389
|
-
<div class="sidebar-header">
|
|
390
|
-
<h2>Git Wrapped</h2>
|
|
391
|
-
<span class="version">v1.0</span>
|
|
392
|
-
</div>
|
|
393
|
-
|
|
394
|
-
<div class="nav-section">
|
|
395
|
-
<div class="nav-section-title">Views</div>
|
|
396
|
-
<a href="#" class="nav-item active" data-tab="overall">
|
|
397
|
-
<span class="nav-label">Team Overview</span>
|
|
398
|
-
</a>
|
|
399
|
-
<a href="#" class="nav-item" data-tab="personal">
|
|
400
|
-
<span class="nav-label">Personal Stats</span>
|
|
401
|
-
</a>
|
|
402
|
-
${leadDevOptions?.velocityAnalysis || leadDevOptions?.gapAnalysis || leadDevOptions?.rangeComparison || leadDevOptions?.executiveSummary || leadDevOptions?.teamAnalysis || leadDevOptions?.events?.length ? `
|
|
403
|
-
<a href="#" class="nav-item" data-tab="leaddev">
|
|
404
|
-
<span class="nav-label">Strategic Insights</span>
|
|
405
|
-
</a>
|
|
406
|
-
` : ''}
|
|
407
|
-
</div>
|
|
408
|
-
|
|
409
|
-
<div class="sidebar-footer">
|
|
410
|
-
<div class="repo-info">
|
|
411
|
-
<span class="repo-name">${repoName}</span>
|
|
412
|
-
${repoUrl ? `<a href="${repoUrl}" target="_blank" class="repo-link">View Repository →</a>` : ''}
|
|
413
|
-
</div>
|
|
414
|
-
</div>
|
|
415
|
-
</nav>
|
|
416
|
-
|
|
417
|
-
<!-- Main Content Area -->
|
|
418
|
-
<main class="main-content">
|
|
419
|
-
<div class="container">
|
|
420
|
-
<header class="dashboard-header">
|
|
421
|
-
<div class="header-left">
|
|
422
|
-
<h1 class="repo-name">${repoName}</h1>
|
|
423
|
-
</div>
|
|
424
|
-
<div class="header-right">
|
|
425
|
-
<div class="export-controls">
|
|
426
|
-
<button class="btn btn-secondary btn-sm" data-export="json">Export JSON</button>
|
|
427
|
-
<button class="btn btn-secondary btn-sm" data-export="csv">Export CSV</button>
|
|
428
|
-
</div>
|
|
429
|
-
</div>
|
|
430
|
-
</header>
|
|
431
|
-
|
|
432
|
-
<div class="filter-bar">
|
|
433
|
-
<div class="filter-group">
|
|
434
|
-
<label class="filter-label">Period</label>
|
|
435
|
-
<span class="filter-value">${formatDateRange(dataStartDate, dataEndDate)}</span>
|
|
436
|
-
</div>
|
|
437
|
-
<div class="filter-group">
|
|
438
|
-
<label class="filter-label">Author</label>
|
|
439
|
-
<span class="filter-value">${currentUser !== 'Unknown' ? currentUser : 'All Contributors'}</span>
|
|
440
|
-
</div>
|
|
441
|
-
</div>
|
|
442
|
-
|
|
443
|
-
<!-- Tab Navigation (kept for backwards compatibility) -->
|
|
444
|
-
<div class="tab-nav">
|
|
445
|
-
<button class="tab-button active" data-tab="overall">📊 Team Overview</button>
|
|
446
|
-
<button class="tab-button" data-tab="personal">👤 Personal</button>
|
|
447
|
-
${leadDevOptions?.velocityAnalysis || leadDevOptions?.gapAnalysis || leadDevOptions?.rangeComparison || leadDevOptions?.executiveSummary || leadDevOptions?.teamAnalysis ? '<button class="tab-button" data-tab="leaddev">📊 Strategic Insights</button>' : ''}
|
|
448
|
-
</div>
|
|
449
|
-
|
|
450
|
-
<!-- Overall Tab Content -->
|
|
451
|
-
<div class="tab-content active" id="overall-content">
|
|
452
|
-
${overallKpiHeader}
|
|
453
|
-
|
|
454
|
-
${wrapInSection('contributions', 'Contribution Activity', contributionGraphHtml)}
|
|
455
|
-
${wrapInSection('team-developers', 'Developer Contributions', developerSectionHtml)}
|
|
456
|
-
${impactAnalysis ? wrapInSection('impact', 'Developer Impact', (0, impactSection_1.buildImpactSection)(impactAnalysis)) : ''}
|
|
457
|
-
${knowledgeDistribution ? wrapInSection('knowledge', 'Knowledge Distribution', (0, knowledgeSection_1.buildKnowledgeSection)(knowledgeDistribution)) : ''}
|
|
458
|
-
</div>
|
|
459
|
-
<!-- End Overall Tab Content -->
|
|
460
|
-
|
|
461
|
-
<!-- Lead Developer Tab Content -->
|
|
462
|
-
${(leadDevOptions?.velocityAnalysis || leadDevOptions?.gapAnalysis || leadDevOptions?.rangeComparison || leadDevOptions?.executiveSummary || leadDevOptions?.teamAnalysis || leadDevOptions?.events?.length) ? `
|
|
463
|
-
<div class="tab-content" id="leaddev-content">
|
|
464
|
-
${leadDevOptions?.executiveSummary ? wrapInSection('executive-summary', 'Executive Summary', (0, executiveSummarySection_1.buildExecutiveSummarySection)(leadDevOptions.executiveSummary), '📋') : ''}
|
|
465
|
-
${leadDevOptions?.velocityAnalysis ? wrapInSection('velocity', 'Velocity Timeline', (0, velocitySection_1.buildVelocitySection)(leadDevOptions.velocityAnalysis), '📈') : ''}
|
|
466
|
-
${leadDevOptions?.gapAnalysis ? wrapInSection('gaps', 'Gap Analysis', (0, gapSection_1.buildGapSection)(leadDevOptions.gapAnalysis), '🚧') : ''}
|
|
467
|
-
${leadDevOptions?.rangeComparison ? wrapInSection('comparison', 'Period Comparison', (0, comparisonSection_1.buildComparisonSection)(leadDevOptions.rangeComparison), '⚖️') : ''}
|
|
468
|
-
${leadDevOptions?.teamAnalysis ? wrapInSection('team-analysis', 'Team Analysis', (0, teamSection_1.buildTeamSection)(leadDevOptions.teamAnalysis), '👥') : ''}
|
|
469
|
-
${leadDevOptions?.events?.length ? wrapInSection('events', 'Event Timeline', (0, eventsSection_1.buildEventsSection)(leadDevOptions.events), '📅') : ''}
|
|
470
|
-
</div>
|
|
471
|
-
` : ''}
|
|
472
|
-
<!-- End Lead Developer Tab Content -->
|
|
473
|
-
|
|
474
|
-
<!-- Personal Tab Content -->
|
|
475
|
-
<div class="tab-content" id="personal-content">
|
|
476
|
-
${generatePersonalContent(personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, currentUser, totalPersonalCommits, skipBodyCheck)}
|
|
477
|
-
</div>
|
|
478
|
-
<!-- End Personal Tab Content -->
|
|
479
|
-
|
|
480
|
-
</div>
|
|
481
|
-
</main>
|
|
482
|
-
</div>
|
|
483
|
-
|
|
484
|
-
<div class="tooltip" id="tooltip"></div>
|
|
485
|
-
|
|
486
|
-
<div class="modal" id="modal">
|
|
487
|
-
<div class="modal-content">
|
|
488
|
-
<div class="modal-header">
|
|
489
|
-
<div class="modal-title" id="modal-title"></div>
|
|
490
|
-
<button class="modal-close" id="modal-close">×</button>
|
|
491
|
-
</div>
|
|
492
|
-
<div class="commit-list" id="commit-list"></div>
|
|
493
|
-
</div>
|
|
494
|
-
</div>
|
|
495
|
-
|
|
496
|
-
<script>
|
|
497
|
-
// Embed data for export functionality
|
|
498
|
-
window.__GITWRAPPED_DATA__ = ${JSON.stringify({
|
|
499
|
-
repository: repoName,
|
|
500
|
-
period: {
|
|
501
|
-
start: dataStartDate.toISOString(),
|
|
502
|
-
end: dataEndDate.toISOString()
|
|
503
|
-
},
|
|
504
|
-
author: currentUser,
|
|
505
|
-
summary: {
|
|
506
|
-
totalCommits: totalCommits,
|
|
507
|
-
totalContributors: developerStats.size,
|
|
508
|
-
activeDays: commitMap.size
|
|
509
|
-
},
|
|
510
|
-
streaks: {
|
|
511
|
-
currentStreak: streakData.currentStreak.days,
|
|
512
|
-
longestStreak: streakData.longestStreak.days,
|
|
513
|
-
totalActiveDays: streakData.totalActiveDays,
|
|
514
|
-
activeDayPercentage: streakData.activeDayPercentage
|
|
515
|
-
},
|
|
516
|
-
quality: {
|
|
517
|
-
overallScore: commitQuality.overallScore,
|
|
518
|
-
conventionalAdherence: commitQuality.conventionalCommits.adherence,
|
|
519
|
-
avgSubjectLength: commitQuality.subjectQuality.avgLength
|
|
520
|
-
},
|
|
521
|
-
timePattern: {
|
|
522
|
-
chronotype: timePattern.chronotype,
|
|
523
|
-
peakHour: timePattern.peakHour.hour,
|
|
524
|
-
consistency: timePattern.consistency?.score || 0
|
|
525
|
-
},
|
|
526
|
-
commits: Array.from(commitDetailsMap.values()).flat().map((c) => ({
|
|
527
|
-
date: c.date,
|
|
528
|
-
author: c.author,
|
|
529
|
-
message: c.message.split('\\n')[0],
|
|
530
|
-
hash: c.hash
|
|
531
|
-
})),
|
|
532
|
-
developerStats: Array.from(developerStats.entries()).map(([name, stats]) => ({
|
|
533
|
-
name,
|
|
534
|
-
commits: stats.commits,
|
|
535
|
-
firstCommit: stats.firstCommit.toISOString(),
|
|
536
|
-
lastCommit: stats.lastCommit.toISOString()
|
|
537
|
-
}))
|
|
538
|
-
})};
|
|
539
|
-
</script>
|
|
540
|
-
|
|
541
|
-
<script>
|
|
542
|
-
${(0, scriptLoader_1.loadScripts)()}
|
|
543
|
-
</script>
|
|
544
|
-
</body>
|
|
545
|
-
</html>`;
|
|
136
|
+
// Build context
|
|
137
|
+
const context = (0, html_1.buildHtmlContext)(options);
|
|
138
|
+
// Run all analyzers
|
|
139
|
+
const results = (0, html_1.runAllAnalyzers)(context, skipBodyCheck, deepAnalysis, leadDevOptions);
|
|
140
|
+
// Build and return HTML document
|
|
141
|
+
return (0, html_1.buildHtmlDocument)(context, results, skipBodyCheck);
|
|
546
142
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.analyzeImpact = analyzeImpact;
|
|
4
|
+
const emptyResults_1 = require("./emptyResults");
|
|
4
5
|
// File weight patterns based on criticality
|
|
5
6
|
const FILE_WEIGHTS = [
|
|
6
7
|
{ pattern: /^src\/(core|lib)\//, weight: 1.5, category: 'core' },
|
|
@@ -69,11 +70,28 @@ function extractFilesFromCommit(commit) {
|
|
|
69
70
|
return [];
|
|
70
71
|
}
|
|
71
72
|
/**
|
|
72
|
-
*
|
|
73
|
+
* Analyzes the impact of commits based on file criticality and change patterns.
|
|
74
|
+
*
|
|
75
|
+
* Calculates an overall impact score (0-100) by weighting commits based on:
|
|
76
|
+
* - File criticality (core files > features > tests > config > docs)
|
|
77
|
+
* - Commit type (feat/perf > fix/refactor > test > docs/chore)
|
|
78
|
+
* - Recency (recent changes weighted higher)
|
|
79
|
+
*
|
|
80
|
+
* @param commits - Array of commit data to analyze
|
|
81
|
+
* @param changedFiles - Optional pre-computed file change data from fileHotspotAnalyzer
|
|
82
|
+
* @returns Impact analysis with score breakdown, top files, trend, and insights
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const impact = analyzeImpact(commits);
|
|
87
|
+
* console.log(`Impact score: ${impact.overallScore}/100`);
|
|
88
|
+
* console.log(`Trend: ${impact.impactTrend}`);
|
|
89
|
+
* console.log(`Core contributions: ${impact.scoreBreakdown.coreContributions} points`);
|
|
90
|
+
* ```
|
|
73
91
|
*/
|
|
74
92
|
function analyzeImpact(commits, changedFiles) {
|
|
75
93
|
if (commits.length === 0) {
|
|
76
|
-
return getEmptyImpactAnalysis();
|
|
94
|
+
return (0, emptyResults_1.getEmptyImpactAnalysis)();
|
|
77
95
|
}
|
|
78
96
|
const now = new Date();
|
|
79
97
|
const fileImpacts = new Map();
|
|
@@ -228,20 +246,3 @@ function generateInsights(data) {
|
|
|
228
246
|
}
|
|
229
247
|
return insights.slice(0, 5); // Limit to 5 insights
|
|
230
248
|
}
|
|
231
|
-
/**
|
|
232
|
-
* Return empty analysis for no commits
|
|
233
|
-
*/
|
|
234
|
-
function getEmptyImpactAnalysis() {
|
|
235
|
-
return {
|
|
236
|
-
overallScore: 0,
|
|
237
|
-
scoreBreakdown: {
|
|
238
|
-
coreContributions: 0,
|
|
239
|
-
featureWork: 0,
|
|
240
|
-
maintenanceWork: 0,
|
|
241
|
-
documentationWork: 0,
|
|
242
|
-
},
|
|
243
|
-
topImpactFiles: [],
|
|
244
|
-
impactTrend: 'stable',
|
|
245
|
-
insights: ['No commit data available for analysis']
|
|
246
|
-
};
|
|
247
|
-
}
|