openspec-stat 1.1.0 → 1.3.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 (45) hide show
  1. package/README.md +44 -0
  2. package/README.zh-CN.md +44 -0
  3. package/dist/cjs/cli.js +12 -127
  4. package/dist/cjs/commands/init.d.ts +7 -0
  5. package/dist/cjs/commands/init.js +58 -0
  6. package/dist/cjs/commands/multi.d.ts +16 -0
  7. package/dist/cjs/commands/multi.js +172 -0
  8. package/dist/cjs/commands/single.d.ts +2 -0
  9. package/dist/cjs/commands/single.js +148 -0
  10. package/dist/cjs/formatters.d.ts +4 -4
  11. package/dist/cjs/formatters.js +268 -30
  12. package/dist/cjs/git-analyzer.d.ts +1 -0
  13. package/dist/cjs/git-analyzer.js +6 -0
  14. package/dist/cjs/i18n/locales/en.json +80 -1
  15. package/dist/cjs/i18n/locales/zh-CN.json +80 -1
  16. package/dist/cjs/multi/config-validator.d.ts +3 -0
  17. package/dist/cjs/multi/config-validator.js +130 -0
  18. package/dist/cjs/multi/config-wizard.d.ts +50 -0
  19. package/dist/cjs/multi/config-wizard.js +331 -0
  20. package/dist/cjs/multi/multi-repo-analyzer.d.ts +14 -0
  21. package/dist/cjs/multi/multi-repo-analyzer.js +210 -0
  22. package/dist/cjs/stats-aggregator.js +25 -0
  23. package/dist/cjs/types.d.ts +57 -0
  24. package/dist/esm/cli.js +43 -137
  25. package/dist/esm/commands/init.d.ts +7 -0
  26. package/dist/esm/commands/init.js +49 -0
  27. package/dist/esm/commands/multi.d.ts +16 -0
  28. package/dist/esm/commands/multi.js +192 -0
  29. package/dist/esm/commands/single.d.ts +2 -0
  30. package/dist/esm/commands/single.js +162 -0
  31. package/dist/esm/formatters.d.ts +4 -4
  32. package/dist/esm/formatters.js +361 -55
  33. package/dist/esm/git-analyzer.d.ts +1 -0
  34. package/dist/esm/git-analyzer.js +104 -77
  35. package/dist/esm/i18n/locales/en.json +80 -1
  36. package/dist/esm/i18n/locales/zh-CN.json +80 -1
  37. package/dist/esm/multi/config-validator.d.ts +3 -0
  38. package/dist/esm/multi/config-validator.js +109 -0
  39. package/dist/esm/multi/config-wizard.d.ts +50 -0
  40. package/dist/esm/multi/config-wizard.js +535 -0
  41. package/dist/esm/multi/multi-repo-analyzer.d.ts +14 -0
  42. package/dist/esm/multi/multi-repo-analyzer.js +446 -0
  43. package/dist/esm/stats-aggregator.js +29 -0
  44. package/dist/esm/types.d.ts +57 -0
  45. package/package.json +1 -1
@@ -18,6 +18,7 @@ export var OutputFormatter = /*#__PURE__*/function () {
18
18
  key: "formatTable",
19
19
  value: function formatTable(result) {
20
20
  var verbose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
21
+ var showContributors = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
21
22
  var output = '';
22
23
  output += chalk.bold(t('output.title'));
23
24
  output += chalk.gray(t('output.timeRange', {
@@ -34,14 +35,106 @@ export var OutputFormatter = /*#__PURE__*/function () {
34
35
  output += chalk.gray(t('output.totalCommits', {
35
36
  count: String(result.totalCommits)
36
37
  }));
38
+
39
+ // Proposal Summary Table
40
+ if (result.proposals.size > 0) {
41
+ output += chalk.bold.magenta("\n".concat(t('output.proposalSummary'), "\n"));
42
+ var proposalTable = new Table({
43
+ head: [chalk.magenta(t('table.proposal')), chalk.magenta(t('table.commits')), chalk.magenta(t('table.contributors')), chalk.magenta(t('table.codeFiles')), chalk.magenta(t('table.additions')), chalk.magenta(t('table.deletions')), chalk.magenta(t('table.netChanges'))],
44
+ style: {
45
+ head: [],
46
+ border: []
47
+ }
48
+ });
49
+ var sortedProposals = Array.from(result.proposals.values()).sort(function (a, b) {
50
+ return b.netChanges - a.netChanges;
51
+ });
52
+ var _iterator = _createForOfIteratorHelper(sortedProposals),
53
+ _step;
54
+ try {
55
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
56
+ var proposalStats = _step.value;
57
+ var contributors = Array.from(proposalStats.contributors).join(', ');
58
+ proposalTable.push([proposalStats.proposal, proposalStats.commits.toString(), contributors, proposalStats.codeFilesChanged.toString(), chalk.green("+".concat(proposalStats.additions)), chalk.red("-".concat(proposalStats.deletions)), proposalStats.netChanges >= 0 ? chalk.green("+".concat(proposalStats.netChanges)) : chalk.red("".concat(proposalStats.netChanges))]);
59
+ }
60
+ } catch (err) {
61
+ _iterator.e(err);
62
+ } finally {
63
+ _iterator.f();
64
+ }
65
+ output += proposalTable.toString() + '\n';
66
+
67
+ // Proposal summary totals
68
+ var totalProposals = result.proposals.size;
69
+ var totalProposalCommits = Array.from(result.proposals.values()).reduce(function (sum, p) {
70
+ return sum + p.commits;
71
+ }, 0);
72
+ var totalProposalFiles = Array.from(result.proposals.values()).reduce(function (sum, p) {
73
+ return sum + p.codeFilesChanged;
74
+ }, 0);
75
+ var totalProposalAdditions = Array.from(result.proposals.values()).reduce(function (sum, p) {
76
+ return sum + p.additions;
77
+ }, 0);
78
+ var totalProposalDeletions = Array.from(result.proposals.values()).reduce(function (sum, p) {
79
+ return sum + p.deletions;
80
+ }, 0);
81
+ var totalProposalNetChanges = Array.from(result.proposals.values()).reduce(function (sum, p) {
82
+ return sum + p.netChanges;
83
+ }, 0);
84
+ output += chalk.gray(t('output.proposalTotal', {
85
+ count: totalProposals.toString(),
86
+ commits: totalProposalCommits.toString(),
87
+ files: totalProposalFiles.toString(),
88
+ additions: totalProposalAdditions.toString(),
89
+ deletions: totalProposalDeletions.toString(),
90
+ netChanges: totalProposalNetChanges.toString()
91
+ }));
92
+ }
93
+ output += chalk.bold.cyan("\n".concat(t('output.authorSummary'), "\n"));
37
94
  var sortedAuthors = Array.from(result.authors.values()).sort(function (a, b) {
38
95
  return b.commits - a.commits;
39
96
  });
40
- var _iterator = _createForOfIteratorHelper(sortedAuthors),
41
- _step;
97
+ if (!showContributors) {
98
+ // Show only summary when showContributors is false
99
+ var totalAuthors = sortedAuthors.length;
100
+ var totalCommits = sortedAuthors.reduce(function (sum, s) {
101
+ return sum + s.commits;
102
+ }, 0);
103
+ var totalProposalsSet = new Set();
104
+ sortedAuthors.forEach(function (s) {
105
+ return s.openspecProposals.forEach(function (p) {
106
+ return totalProposalsSet.add(p);
107
+ });
108
+ });
109
+ var totalFiles = sortedAuthors.reduce(function (sum, s) {
110
+ return sum + s.codeFilesChanged;
111
+ }, 0);
112
+ var totalAdditions = sortedAuthors.reduce(function (sum, s) {
113
+ return sum + s.additions;
114
+ }, 0);
115
+ var totalDeletions = sortedAuthors.reduce(function (sum, s) {
116
+ return sum + s.deletions;
117
+ }, 0);
118
+ var totalNetChanges = sortedAuthors.reduce(function (sum, s) {
119
+ return sum + s.netChanges;
120
+ }, 0);
121
+ var summaryTable = new Table({
122
+ head: [chalk.cyan(t('table.contributors')), chalk.cyan(t('table.commits')), chalk.cyan(t('table.proposals')), chalk.cyan(t('table.codeFiles')), chalk.cyan(t('table.additions')), chalk.cyan(t('table.deletions')), chalk.cyan(t('table.netChanges'))],
123
+ style: {
124
+ head: [],
125
+ border: []
126
+ }
127
+ });
128
+ summaryTable.push([totalAuthors.toString(), totalCommits.toString(), totalProposalsSet.size.toString(), totalFiles.toString(), chalk.green("+".concat(totalAdditions)), chalk.red("-".concat(totalDeletions)), totalNetChanges >= 0 ? chalk.green("+".concat(totalNetChanges)) : chalk.red("".concat(totalNetChanges))]);
129
+ output += summaryTable.toString() + '\n';
130
+ output += chalk.gray(t('output.contributorHint')) + '\n';
131
+ return output;
132
+ }
133
+ var _iterator2 = _createForOfIteratorHelper(sortedAuthors),
134
+ _step2;
42
135
  try {
43
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
44
- var stats = _step.value;
136
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
137
+ var stats = _step2.value;
45
138
  output += chalk.bold.cyan("\n".concat(stats.author, "\n"));
46
139
  if (stats.branchStats && stats.branchStats.size > 0) {
47
140
  var branchTable = new Table({
@@ -54,17 +147,17 @@ export var OutputFormatter = /*#__PURE__*/function () {
54
147
  var sortedBranches = Array.from(stats.branchStats.values()).sort(function (a, b) {
55
148
  return b.commits - a.commits;
56
149
  });
57
- var _iterator2 = _createForOfIteratorHelper(sortedBranches),
58
- _step2;
150
+ var _iterator3 = _createForOfIteratorHelper(sortedBranches),
151
+ _step3;
59
152
  try {
60
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
61
- var branchStat = _step2.value;
153
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
154
+ var branchStat = _step3.value;
62
155
  branchTable.push([branchStat.branch, branchStat.commits.toString(), branchStat.openspecProposals.size.toString(), branchStat.codeFilesChanged.toString(), chalk.green("+".concat(branchStat.additions)), chalk.red("-".concat(branchStat.deletions)), branchStat.netChanges >= 0 ? chalk.green("+".concat(branchStat.netChanges)) : chalk.red("".concat(branchStat.netChanges))]);
63
156
  }
64
157
  } catch (err) {
65
- _iterator2.e(err);
158
+ _iterator3.e(err);
66
159
  } finally {
67
- _iterator2.f();
160
+ _iterator3.f();
68
161
  }
69
162
  branchTable.push([chalk.bold.yellow(t('table.totalDeduplicated')), chalk.bold(stats.commits.toString()), chalk.bold(stats.openspecProposals.size.toString()), chalk.bold(stats.codeFilesChanged.toString()), chalk.bold.green("+".concat(stats.additions)), chalk.bold.red("-".concat(stats.deletions)), stats.netChanges >= 0 ? chalk.bold.green("+".concat(stats.netChanges)) : chalk.bold.red("".concat(stats.netChanges))]);
70
163
  output += branchTable.toString() + '\n';
@@ -86,15 +179,17 @@ export var OutputFormatter = /*#__PURE__*/function () {
86
179
  }
87
180
  }
88
181
  } catch (err) {
89
- _iterator.e(err);
182
+ _iterator2.e(err);
90
183
  } finally {
91
- _iterator.f();
184
+ _iterator2.f();
92
185
  }
93
186
  return output;
94
187
  }
95
188
  }, {
96
189
  key: "formatJSON",
97
190
  value: function formatJSON(result) {
191
+ var showContributors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
192
+ var sortedAuthors = Array.from(result.authors.values());
98
193
  var data = {
99
194
  timeRange: {
100
195
  since: result.timeRange.since.toISOString(),
@@ -102,7 +197,41 @@ export var OutputFormatter = /*#__PURE__*/function () {
102
197
  },
103
198
  branches: result.branches,
104
199
  totalCommits: result.totalCommits,
105
- authors: Array.from(result.authors.values()).map(function (stats) {
200
+ proposals: {
201
+ items: Array.from(result.proposals.values()).map(function (stats) {
202
+ return {
203
+ proposal: stats.proposal,
204
+ commits: stats.commits,
205
+ contributors: Array.from(stats.contributors),
206
+ contributorCount: stats.contributors.size,
207
+ codeFilesChanged: stats.codeFilesChanged,
208
+ additions: stats.additions,
209
+ deletions: stats.deletions,
210
+ netChanges: stats.netChanges
211
+ };
212
+ }),
213
+ summary: {
214
+ totalProposals: result.proposals.size,
215
+ totalCommits: Array.from(result.proposals.values()).reduce(function (sum, p) {
216
+ return sum + p.commits;
217
+ }, 0),
218
+ totalCodeFiles: Array.from(result.proposals.values()).reduce(function (sum, p) {
219
+ return sum + p.codeFilesChanged;
220
+ }, 0),
221
+ totalAdditions: Array.from(result.proposals.values()).reduce(function (sum, p) {
222
+ return sum + p.additions;
223
+ }, 0),
224
+ totalDeletions: Array.from(result.proposals.values()).reduce(function (sum, p) {
225
+ return sum + p.deletions;
226
+ }, 0),
227
+ totalNetChanges: Array.from(result.proposals.values()).reduce(function (sum, p) {
228
+ return sum + p.netChanges;
229
+ }, 0)
230
+ }
231
+ }
232
+ };
233
+ if (showContributors) {
234
+ data.authors = sortedAuthors.map(function (stats) {
106
235
  var _stats$lastCommitDate;
107
236
  return {
108
237
  author: stats.author,
@@ -115,37 +244,137 @@ export var OutputFormatter = /*#__PURE__*/function () {
115
244
  netChanges: stats.netChanges,
116
245
  lastCommitDate: (_stats$lastCommitDate = stats.lastCommitDate) === null || _stats$lastCommitDate === void 0 ? void 0 : _stats$lastCommitDate.toISOString()
117
246
  };
118
- })
119
- };
247
+ });
248
+ } else {
249
+ var totalProposalsSet = new Set();
250
+ sortedAuthors.forEach(function (s) {
251
+ return s.openspecProposals.forEach(function (p) {
252
+ return totalProposalsSet.add(p);
253
+ });
254
+ });
255
+ data.authorsSummary = {
256
+ totalContributors: sortedAuthors.length,
257
+ totalCommits: sortedAuthors.reduce(function (sum, s) {
258
+ return sum + s.commits;
259
+ }, 0),
260
+ totalProposals: totalProposalsSet.size,
261
+ totalCodeFiles: sortedAuthors.reduce(function (sum, s) {
262
+ return sum + s.codeFilesChanged;
263
+ }, 0),
264
+ totalAdditions: sortedAuthors.reduce(function (sum, s) {
265
+ return sum + s.additions;
266
+ }, 0),
267
+ totalDeletions: sortedAuthors.reduce(function (sum, s) {
268
+ return sum + s.deletions;
269
+ }, 0),
270
+ totalNetChanges: sortedAuthors.reduce(function (sum, s) {
271
+ return sum + s.netChanges;
272
+ }, 0)
273
+ };
274
+ }
120
275
  return JSON.stringify(data, null, 2);
121
276
  }
122
277
  }, {
123
278
  key: "formatCSV",
124
279
  value: function formatCSV(result) {
280
+ var showContributors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
125
281
  var rows = [];
126
- rows.push("".concat(t('table.author'), ",").concat(t('table.period'), ",").concat(t('table.commits'), ",").concat(t('table.proposalsCount'), ",").concat(t('table.proposalsList'), ",").concat(t('table.codeFiles'), ",").concat(t('table.additions'), ",").concat(t('table.deletions'), ",").concat(t('table.netChanges'), ",").concat(t('table.lastCommitDate')));
127
- var sortedAuthors = Array.from(result.authors.values()).sort(function (a, b) {
128
- return b.commits - a.commits;
282
+
283
+ // Proposal summary section
284
+ rows.push("\n# ".concat(t('output.proposalSummary')));
285
+ rows.push("".concat(t('table.proposal'), ",").concat(t('table.commits'), ",").concat(t('table.contributors'), ",").concat(t('table.codeFiles'), ",").concat(t('table.additions'), ",").concat(t('table.deletions'), ",").concat(t('table.netChanges')));
286
+ var sortedProposals = Array.from(result.proposals.values()).sort(function (a, b) {
287
+ return b.netChanges - a.netChanges;
129
288
  });
130
- var _iterator3 = _createForOfIteratorHelper(sortedAuthors),
131
- _step3;
289
+ var _iterator4 = _createForOfIteratorHelper(sortedProposals),
290
+ _step4;
132
291
  try {
133
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
134
- var _stats$lastCommitDate2;
135
- var stats = _step3.value;
136
- var proposals = Array.from(stats.openspecProposals).join(';');
137
- rows.push([stats.author, stats.statisticsPeriod || '-', stats.commits, stats.openspecProposals.size, "\"".concat(proposals, "\""), stats.codeFilesChanged, stats.additions, stats.deletions, stats.netChanges, ((_stats$lastCommitDate2 = stats.lastCommitDate) === null || _stats$lastCommitDate2 === void 0 ? void 0 : _stats$lastCommitDate2.toISOString()) || ''].join(','));
292
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
293
+ var _stats = _step4.value;
294
+ var contributors = Array.from(_stats.contributors).join(';');
295
+ rows.push([_stats.proposal, _stats.commits, "\"".concat(contributors, "\""), _stats.codeFilesChanged, _stats.additions, _stats.deletions, _stats.netChanges].join(','));
138
296
  }
297
+
298
+ // Proposal totals
139
299
  } catch (err) {
140
- _iterator3.e(err);
300
+ _iterator4.e(err);
141
301
  } finally {
142
- _iterator3.f();
302
+ _iterator4.f();
303
+ }
304
+ var totalProposals = result.proposals.size;
305
+ var totalProposalCommits = Array.from(result.proposals.values()).reduce(function (sum, p) {
306
+ return sum + p.commits;
307
+ }, 0);
308
+ var totalProposalFiles = Array.from(result.proposals.values()).reduce(function (sum, p) {
309
+ return sum + p.codeFilesChanged;
310
+ }, 0);
311
+ var totalProposalAdditions = Array.from(result.proposals.values()).reduce(function (sum, p) {
312
+ return sum + p.additions;
313
+ }, 0);
314
+ var totalProposalDeletions = Array.from(result.proposals.values()).reduce(function (sum, p) {
315
+ return sum + p.deletions;
316
+ }, 0);
317
+ var totalProposalNetChanges = Array.from(result.proposals.values()).reduce(function (sum, p) {
318
+ return sum + p.netChanges;
319
+ }, 0);
320
+ rows.push('');
321
+ rows.push("# ".concat(t('output.proposalTotalLabel')));
322
+ rows.push("".concat(t('table.proposals'), ",").concat(totalProposals));
323
+ rows.push("".concat(t('table.commits'), ",").concat(totalProposalCommits));
324
+ rows.push("".concat(t('table.codeFiles'), ",").concat(totalProposalFiles));
325
+ rows.push("".concat(t('table.additions'), ",").concat(totalProposalAdditions));
326
+ rows.push("".concat(t('table.deletions'), ",").concat(totalProposalDeletions));
327
+ rows.push("".concat(t('table.netChanges'), ",").concat(totalProposalNetChanges));
328
+
329
+ // Author summary section
330
+ rows.push("\n# ".concat(t('output.authorSummary')));
331
+ var sortedAuthors = Array.from(result.authors.values()).sort(function (a, b) {
332
+ return b.commits - a.commits;
333
+ });
334
+ if (showContributors) {
335
+ rows.push("".concat(t('table.author'), ",").concat(t('table.period'), ",").concat(t('table.commits'), ",").concat(t('table.proposalsCount'), ",").concat(t('table.proposalsList'), ",").concat(t('table.codeFiles'), ",").concat(t('table.additions'), ",").concat(t('table.deletions'), ",").concat(t('table.netChanges'), ",").concat(t('table.lastCommitDate')));
336
+ var _iterator5 = _createForOfIteratorHelper(sortedAuthors),
337
+ _step5;
338
+ try {
339
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
340
+ var _stats$lastCommitDate2;
341
+ var stats = _step5.value;
342
+ var proposals = Array.from(stats.openspecProposals).join(';');
343
+ rows.push([stats.author, stats.statisticsPeriod || '-', stats.commits, stats.openspecProposals.size, "\"".concat(proposals, "\""), stats.codeFilesChanged, stats.additions, stats.deletions, stats.netChanges, ((_stats$lastCommitDate2 = stats.lastCommitDate) === null || _stats$lastCommitDate2 === void 0 ? void 0 : _stats$lastCommitDate2.toISOString()) || ''].join(','));
344
+ }
345
+ } catch (err) {
346
+ _iterator5.e(err);
347
+ } finally {
348
+ _iterator5.f();
349
+ }
350
+ } else {
351
+ rows.push("".concat(t('table.contributors'), ",").concat(t('table.commits'), ",").concat(t('table.proposals'), ",").concat(t('table.codeFiles'), ",").concat(t('table.additions'), ",").concat(t('table.deletions'), ",").concat(t('table.netChanges')));
352
+ var totalProposalsSet = new Set();
353
+ sortedAuthors.forEach(function (s) {
354
+ return s.openspecProposals.forEach(function (p) {
355
+ return totalProposalsSet.add(p);
356
+ });
357
+ });
358
+ rows.push([sortedAuthors.length, sortedAuthors.reduce(function (sum, s) {
359
+ return sum + s.commits;
360
+ }, 0), totalProposalsSet.size, sortedAuthors.reduce(function (sum, s) {
361
+ return sum + s.codeFilesChanged;
362
+ }, 0), sortedAuthors.reduce(function (sum, s) {
363
+ return sum + s.additions;
364
+ }, 0), sortedAuthors.reduce(function (sum, s) {
365
+ return sum + s.deletions;
366
+ }, 0), sortedAuthors.reduce(function (sum, s) {
367
+ return sum + s.netChanges;
368
+ }, 0)].join(','));
369
+ rows.push('');
370
+ rows.push("# ".concat(t('output.contributorHint')));
143
371
  }
144
372
  return rows.join('\n');
145
373
  }
146
374
  }, {
147
375
  key: "formatMarkdown",
148
376
  value: function formatMarkdown(result) {
377
+ var showContributors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
149
378
  var md = '';
150
379
  md += t('markdown.title');
151
380
  md += t('markdown.timeRange', {
@@ -162,43 +391,120 @@ export var OutputFormatter = /*#__PURE__*/function () {
162
391
  md += t('markdown.totalCommits', {
163
392
  count: String(result.totalCommits)
164
393
  });
165
- md += t('markdown.statistics');
166
- md += "| ".concat(t('table.author'), " | ").concat(t('table.period'), " | ").concat(t('table.commits'), " | ").concat(t('table.proposals'), " | ").concat(t('table.codeFiles'), " | ").concat(t('table.additions'), " | ").concat(t('table.deletions'), " | ").concat(t('table.netChanges'), " |\n");
167
- md += '|--------|--------|---------|-----------|------------|-----------|-----------|-------------|\n';
168
- var sortedAuthors = Array.from(result.authors.values()).sort(function (a, b) {
169
- return b.commits - a.commits;
394
+
395
+ // Proposal summary
396
+ md += "\n## ".concat(t('output.proposalSummary'), "\n\n");
397
+ md += "| ".concat(t('table.proposal'), " | ").concat(t('table.commits'), " | ").concat(t('table.contributors'), " | ").concat(t('table.codeFiles'), " | ").concat(t('table.additions'), " | ").concat(t('table.deletions'), " | ").concat(t('table.netChanges'), " |\n");
398
+ md += '|--------|---------|-------------|------------|-----------|-----------|-------------|\n';
399
+ var sortedProposals = Array.from(result.proposals.values()).sort(function (a, b) {
400
+ return b.netChanges - a.netChanges;
170
401
  });
171
- var _iterator4 = _createForOfIteratorHelper(sortedAuthors),
172
- _step4;
402
+ var _iterator6 = _createForOfIteratorHelper(sortedProposals),
403
+ _step6;
173
404
  try {
174
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
175
- var stats = _step4.value;
176
- md += "| ".concat(stats.author, " | ").concat(stats.statisticsPeriod || '-', " | ").concat(stats.commits, " | ").concat(stats.openspecProposals.size, " | ").concat(stats.codeFilesChanged, " | +").concat(stats.additions, " | -").concat(stats.deletions, " | ").concat(stats.netChanges >= 0 ? '+' : '').concat(stats.netChanges, " |\n");
405
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
406
+ var _stats3 = _step6.value;
407
+ var contributors = Array.from(_stats3.contributors).join(', ');
408
+ md += "| ".concat(_stats3.proposal, " | ").concat(_stats3.commits, " | ").concat(contributors, " | ").concat(_stats3.codeFilesChanged, " | +").concat(_stats3.additions, " | -").concat(_stats3.deletions, " | ").concat(_stats3.netChanges >= 0 ? '+' : '').concat(_stats3.netChanges, " |\n");
177
409
  }
410
+
411
+ // Proposal totals
178
412
  } catch (err) {
179
- _iterator4.e(err);
413
+ _iterator6.e(err);
180
414
  } finally {
181
- _iterator4.f();
415
+ _iterator6.f();
182
416
  }
183
- md += t('markdown.proposalDetails');
184
- var _iterator5 = _createForOfIteratorHelper(sortedAuthors),
185
- _step5;
186
- try {
187
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
188
- var _stats = _step5.value;
189
- if (_stats.openspecProposals.size > 0) {
190
- md += "### ".concat(_stats.author, "\n\n");
191
- for (var _i = 0, _Array$from = Array.from(_stats.openspecProposals); _i < _Array$from.length; _i++) {
192
- var proposal = _Array$from[_i];
193
- md += "- ".concat(proposal, "\n");
417
+ var totalProposals = result.proposals.size;
418
+ var totalProposalCommits = Array.from(result.proposals.values()).reduce(function (sum, p) {
419
+ return sum + p.commits;
420
+ }, 0);
421
+ var totalProposalFiles = Array.from(result.proposals.values()).reduce(function (sum, p) {
422
+ return sum + p.codeFilesChanged;
423
+ }, 0);
424
+ var totalProposalAdditions = Array.from(result.proposals.values()).reduce(function (sum, p) {
425
+ return sum + p.additions;
426
+ }, 0);
427
+ var totalProposalDeletions = Array.from(result.proposals.values()).reduce(function (sum, p) {
428
+ return sum + p.deletions;
429
+ }, 0);
430
+ var totalProposalNetChanges = Array.from(result.proposals.values()).reduce(function (sum, p) {
431
+ return sum + p.netChanges;
432
+ }, 0);
433
+ md += "\n**".concat(t('output.proposalTotalLabel'), "**\n");
434
+ md += "- ".concat(t('table.proposals'), ": ").concat(totalProposals, "\n");
435
+ md += "- ".concat(t('table.commits'), ": ").concat(totalProposalCommits, "\n");
436
+ md += "- ".concat(t('table.codeFiles'), ": ").concat(totalProposalFiles, "\n");
437
+ md += "- ".concat(t('table.additions'), ": +").concat(totalProposalAdditions, "\n");
438
+ md += "- ".concat(t('table.deletions'), ": -").concat(totalProposalDeletions, "\n");
439
+ md += "- ".concat(t('table.netChanges'), ": ").concat(totalProposalNetChanges >= 0 ? '+' : '').concat(totalProposalNetChanges, "\n");
440
+
441
+ // Author summary
442
+ md += "\n## ".concat(t('output.authorSummary'), "\n\n");
443
+ var sortedAuthors = Array.from(result.authors.values()).sort(function (a, b) {
444
+ return b.commits - a.commits;
445
+ });
446
+ if (showContributors) {
447
+ md += "| ".concat(t('table.author'), " | ").concat(t('table.period'), " | ").concat(t('table.commits'), " | ").concat(t('table.proposals'), " | ").concat(t('table.codeFiles'), " | ").concat(t('table.additions'), " | ").concat(t('table.deletions'), " | ").concat(t('table.netChanges'), " |\n");
448
+ md += '|--------|--------|---------|-----------|------------|-----------|-----------|-------------|\n';
449
+ var _iterator7 = _createForOfIteratorHelper(sortedAuthors),
450
+ _step7;
451
+ try {
452
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
453
+ var stats = _step7.value;
454
+ md += "| ".concat(stats.author, " | ").concat(stats.statisticsPeriod || '-', " | ").concat(stats.commits, " | ").concat(stats.openspecProposals.size, " | ").concat(stats.codeFilesChanged, " | +").concat(stats.additions, " | -").concat(stats.deletions, " | ").concat(stats.netChanges >= 0 ? '+' : '').concat(stats.netChanges, " |\n");
455
+ }
456
+ } catch (err) {
457
+ _iterator7.e(err);
458
+ } finally {
459
+ _iterator7.f();
460
+ }
461
+ md += t('markdown.proposalDetails');
462
+ var _iterator8 = _createForOfIteratorHelper(sortedAuthors),
463
+ _step8;
464
+ try {
465
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
466
+ var _stats2 = _step8.value;
467
+ if (_stats2.openspecProposals.size > 0) {
468
+ md += "### ".concat(_stats2.author, "\n\n");
469
+ for (var _i = 0, _Array$from = Array.from(_stats2.openspecProposals); _i < _Array$from.length; _i++) {
470
+ var proposal = _Array$from[_i];
471
+ md += "- ".concat(proposal, "\n");
472
+ }
473
+ md += '\n';
194
474
  }
195
- md += '\n';
196
475
  }
476
+ } catch (err) {
477
+ _iterator8.e(err);
478
+ } finally {
479
+ _iterator8.f();
197
480
  }
198
- } catch (err) {
199
- _iterator5.e(err);
200
- } finally {
201
- _iterator5.f();
481
+ } else {
482
+ md += "| ".concat(t('table.contributors'), " | ").concat(t('table.commits'), " | ").concat(t('table.proposals'), " | ").concat(t('table.codeFiles'), " | ").concat(t('table.additions'), " | ").concat(t('table.deletions'), " | ").concat(t('table.netChanges'), " |\n");
483
+ md += '|------------|---------|-----------|------------|-----------|-----------|-------------|\n';
484
+ var totalProposalsSet = new Set();
485
+ sortedAuthors.forEach(function (s) {
486
+ return s.openspecProposals.forEach(function (p) {
487
+ return totalProposalsSet.add(p);
488
+ });
489
+ });
490
+ var totalAuthors = sortedAuthors.length;
491
+ var totalCommits = sortedAuthors.reduce(function (sum, s) {
492
+ return sum + s.commits;
493
+ }, 0);
494
+ var totalFiles = sortedAuthors.reduce(function (sum, s) {
495
+ return sum + s.codeFilesChanged;
496
+ }, 0);
497
+ var totalAdditions = sortedAuthors.reduce(function (sum, s) {
498
+ return sum + s.additions;
499
+ }, 0);
500
+ var totalDeletions = sortedAuthors.reduce(function (sum, s) {
501
+ return sum + s.deletions;
502
+ }, 0);
503
+ var totalNetChanges = sortedAuthors.reduce(function (sum, s) {
504
+ return sum + s.netChanges;
505
+ }, 0);
506
+ md += "| ".concat(totalAuthors, " | ").concat(totalCommits, " | ").concat(totalProposalsSet.size, " | ").concat(totalFiles, " | +").concat(totalAdditions, " | -").concat(totalDeletions, " | ").concat(totalNetChanges >= 0 ? '+' : '').concat(totalNetChanges, " |\n");
507
+ md += "\n*".concat(t('output.contributorHint'), "*\n");
202
508
  }
203
509
  return md;
204
510
  }
@@ -3,6 +3,7 @@ export declare class GitAnalyzer {
3
3
  private git;
4
4
  private config;
5
5
  constructor(repoPath: string, config: Config);
6
+ fetchRemote(): Promise<void>;
6
7
  getCommits(since: Date, until: Date, branches: string[]): Promise<CommitInfo[]>;
7
8
  getCommitBranches(commitHash: string, targetBranches: string[]): Promise<string[]>;
8
9
  analyzeCommit(commit: CommitInfo): Promise<CommitAnalysis | null>;