openspec-stat 1.3.4 → 1.4.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 (57) hide show
  1. package/README.md +2 -1
  2. package/README.zh-CN.md +2 -1
  3. package/dist/esm/branch-selector.js +87 -214
  4. package/dist/esm/cli.js +14 -64
  5. package/dist/esm/commands/init.js +17 -44
  6. package/dist/esm/commands/multi.js +123 -180
  7. package/dist/esm/commands/single.js +143 -152
  8. package/dist/esm/config.js +22 -64
  9. package/dist/esm/formatters.js +285 -520
  10. package/dist/esm/git-analyzer.js +116 -354
  11. package/dist/esm/i18n/index.js +22 -10
  12. package/dist/esm/i18n/locales/en.json +43 -43
  13. package/dist/esm/i18n/locales/zh-CN.json +43 -43
  14. package/dist/esm/multi/config-validator.d.ts +1 -1
  15. package/dist/esm/multi/config-validator.js +25 -26
  16. package/dist/esm/multi/config-wizard.js +217 -459
  17. package/dist/esm/multi/multi-repo-analyzer.d.ts +11 -1
  18. package/dist/esm/multi/multi-repo-analyzer.js +228 -426
  19. package/dist/esm/stats-aggregator.js +115 -193
  20. package/dist/esm/time-utils.js +11 -17
  21. package/dist/esm/ui/spinner.d.ts +12 -0
  22. package/dist/esm/ui/spinner.js +38 -0
  23. package/package.json +21 -7
  24. package/dist/cjs/branch-selector.d.ts +0 -7
  25. package/dist/cjs/branch-selector.js +0 -128
  26. package/dist/cjs/cli.d.ts +0 -2
  27. package/dist/cjs/cli.js +0 -19
  28. package/dist/cjs/commands/init.d.ts +0 -7
  29. package/dist/cjs/commands/init.js +0 -58
  30. package/dist/cjs/commands/multi.d.ts +0 -16
  31. package/dist/cjs/commands/multi.js +0 -172
  32. package/dist/cjs/commands/single.d.ts +0 -2
  33. package/dist/cjs/commands/single.js +0 -148
  34. package/dist/cjs/config.d.ts +0 -3
  35. package/dist/cjs/config.js +0 -66
  36. package/dist/cjs/formatters.d.ts +0 -7
  37. package/dist/cjs/formatters.js +0 -482
  38. package/dist/cjs/git-analyzer.d.ts +0 -11
  39. package/dist/cjs/git-analyzer.js +0 -165
  40. package/dist/cjs/i18n/index.d.ts +0 -7
  41. package/dist/cjs/i18n/index.js +0 -84
  42. package/dist/cjs/i18n/locales/en.json +0 -154
  43. package/dist/cjs/i18n/locales/zh-CN.json +0 -154
  44. package/dist/cjs/index.d.ts +0 -6
  45. package/dist/cjs/index.js +0 -50
  46. package/dist/cjs/multi/config-validator.d.ts +0 -3
  47. package/dist/cjs/multi/config-validator.js +0 -130
  48. package/dist/cjs/multi/config-wizard.d.ts +0 -50
  49. package/dist/cjs/multi/config-wizard.js +0 -331
  50. package/dist/cjs/multi/multi-repo-analyzer.d.ts +0 -14
  51. package/dist/cjs/multi/multi-repo-analyzer.js +0 -210
  52. package/dist/cjs/stats-aggregator.d.ts +0 -7
  53. package/dist/cjs/stats-aggregator.js +0 -155
  54. package/dist/cjs/time-utils.d.ts +0 -6
  55. package/dist/cjs/time-utils.js +0 -55
  56. package/dist/cjs/types.d.ts +0 -136
  57. package/dist/cjs/types.js +0 -17
@@ -1,155 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
-
19
- // src/stats-aggregator.ts
20
- var stats_aggregator_exports = {};
21
- __export(stats_aggregator_exports, {
22
- StatsAggregator: () => StatsAggregator
23
- });
24
- module.exports = __toCommonJS(stats_aggregator_exports);
25
- var import_config = require("./config.js");
26
- var StatsAggregator = class {
27
- constructor(config, activeAuthors) {
28
- this.config = config;
29
- this.activeAuthors = activeAuthors;
30
- }
31
- aggregate(analyses, since, until, branches, filterAuthor) {
32
- const authorStatsMap = /* @__PURE__ */ new Map();
33
- const proposalStatsMap = /* @__PURE__ */ new Map();
34
- for (const analysis of analyses) {
35
- const normalizedAuthor = (0, import_config.normalizeAuthor)(analysis.commit.author, this.config.authorMapping);
36
- if (this.activeAuthors && !this.activeAuthors.has(normalizedAuthor)) {
37
- continue;
38
- }
39
- if (filterAuthor && normalizedAuthor !== filterAuthor) {
40
- continue;
41
- }
42
- let stats = authorStatsMap.get(normalizedAuthor);
43
- if (!stats) {
44
- stats = {
45
- author: normalizedAuthor,
46
- commits: 0,
47
- openspecProposals: /* @__PURE__ */ new Set(),
48
- codeFilesChanged: 0,
49
- additions: 0,
50
- deletions: 0,
51
- netChanges: 0,
52
- branchStats: /* @__PURE__ */ new Map()
53
- };
54
- authorStatsMap.set(normalizedAuthor, stats);
55
- }
56
- stats.commits++;
57
- stats.additions += analysis.totalAdditions;
58
- stats.deletions += analysis.totalDeletions;
59
- stats.netChanges += analysis.netChanges;
60
- stats.codeFilesChanged += analysis.codeFiles.length;
61
- for (const proposal of analysis.openspecProposals) {
62
- stats.openspecProposals.add(proposal);
63
- let proposalStats = proposalStatsMap.get(proposal);
64
- if (!proposalStats) {
65
- proposalStats = {
66
- proposal,
67
- commits: 0,
68
- contributors: /* @__PURE__ */ new Set(),
69
- codeFilesChanged: 0,
70
- additions: 0,
71
- deletions: 0,
72
- netChanges: 0,
73
- commitHashes: /* @__PURE__ */ new Set(),
74
- multiProposalCommits: 0,
75
- sharedCommitHashes: /* @__PURE__ */ new Set()
76
- };
77
- proposalStatsMap.set(proposal, proposalStats);
78
- }
79
- if (!proposalStats.commitHashes.has(analysis.commit.hash)) {
80
- proposalStats.commitHashes.add(analysis.commit.hash);
81
- proposalStats.commits++;
82
- proposalStats.contributors.add(normalizedAuthor);
83
- const proposalCount = analysis.openspecProposals.size;
84
- const isMultiProposal = proposalCount > 1;
85
- if (isMultiProposal) {
86
- proposalStats.multiProposalCommits++;
87
- proposalStats.sharedCommitHashes.add(analysis.commit.hash);
88
- }
89
- proposalStats.codeFilesChanged += Math.floor(analysis.codeFiles.length / proposalCount);
90
- proposalStats.additions += Math.floor(analysis.totalAdditions / proposalCount);
91
- proposalStats.deletions += Math.floor(analysis.totalDeletions / proposalCount);
92
- proposalStats.netChanges += Math.floor(analysis.netChanges / proposalCount);
93
- }
94
- }
95
- if (!stats.lastCommitDate || analysis.commit.date > stats.lastCommitDate) {
96
- stats.lastCommitDate = analysis.commit.date;
97
- }
98
- if (!stats.firstCommitDate || analysis.commit.date < stats.firstCommitDate) {
99
- stats.firstCommitDate = analysis.commit.date;
100
- }
101
- if (analysis.commit.branches && stats.branchStats) {
102
- for (const branch of analysis.commit.branches) {
103
- let branchStat = stats.branchStats.get(branch);
104
- if (!branchStat) {
105
- branchStat = {
106
- branch,
107
- commits: 0,
108
- openspecProposals: /* @__PURE__ */ new Set(),
109
- codeFilesChanged: 0,
110
- additions: 0,
111
- deletions: 0,
112
- netChanges: 0
113
- };
114
- stats.branchStats.set(branch, branchStat);
115
- }
116
- branchStat.commits++;
117
- branchStat.additions += analysis.totalAdditions;
118
- branchStat.deletions += analysis.totalDeletions;
119
- branchStat.netChanges += analysis.netChanges;
120
- branchStat.codeFilesChanged += analysis.codeFiles.length;
121
- for (const proposal of analysis.openspecProposals) {
122
- branchStat.openspecProposals.add(proposal);
123
- }
124
- }
125
- }
126
- }
127
- for (const stats of authorStatsMap.values()) {
128
- if (stats.firstCommitDate && stats.lastCommitDate) {
129
- const days = Math.ceil(
130
- (stats.lastCommitDate.getTime() - stats.firstCommitDate.getTime()) / (1e3 * 60 * 60 * 24)
131
- );
132
- stats.statisticsPeriod = days === 0 ? "1 day" : `${days + 1} days`;
133
- }
134
- }
135
- const actualBranches = /* @__PURE__ */ new Set();
136
- for (const stats of authorStatsMap.values()) {
137
- if (stats.branchStats) {
138
- for (const branch of stats.branchStats.keys()) {
139
- actualBranches.add(branch);
140
- }
141
- }
142
- }
143
- return {
144
- timeRange: { since, until },
145
- branches: actualBranches.size > 0 ? Array.from(actualBranches) : branches,
146
- authors: authorStatsMap,
147
- proposals: proposalStatsMap,
148
- totalCommits: analyses.length
149
- };
150
- }
151
- };
152
- // Annotate the CommonJS export names for ESM import in node:
153
- 0 && (module.exports = {
154
- StatsAggregator
155
- });
@@ -1,6 +0,0 @@
1
- export declare function getDefaultTimeRange(sinceHours?: number, untilHours?: number): {
2
- since: Date;
3
- until: Date;
4
- };
5
- export declare function parseDateTime(dateStr: string): Date;
6
- export declare function parseBranches(branchesStr?: string): string[];
@@ -1,55 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
-
19
- // src/time-utils.ts
20
- var time_utils_exports = {};
21
- __export(time_utils_exports, {
22
- getDefaultTimeRange: () => getDefaultTimeRange,
23
- parseBranches: () => parseBranches,
24
- parseDateTime: () => parseDateTime
25
- });
26
- module.exports = __toCommonJS(time_utils_exports);
27
- function getDefaultTimeRange(sinceHours = -30, untilHours = 20) {
28
- const now = /* @__PURE__ */ new Date();
29
- const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
30
- const yesterday = new Date(today);
31
- yesterday.setDate(yesterday.getDate() - 1);
32
- const since = new Date(yesterday);
33
- since.setHours(untilHours, 0, 0, 0);
34
- const until = new Date(today);
35
- until.setHours(untilHours, 0, 0, 0);
36
- return { since, until };
37
- }
38
- function parseDateTime(dateStr) {
39
- const date = new Date(dateStr);
40
- if (isNaN(date.getTime())) {
41
- throw new Error(`Invalid date format: ${dateStr}`);
42
- }
43
- return date;
44
- }
45
- function parseBranches(branchesStr) {
46
- if (!branchesStr)
47
- return [];
48
- return branchesStr.split(",").map((b) => b.trim()).filter((b) => b);
49
- }
50
- // Annotate the CommonJS export names for ESM import in node:
51
- 0 && (module.exports = {
52
- getDefaultTimeRange,
53
- parseBranches,
54
- parseDateTime
55
- });
@@ -1,136 +0,0 @@
1
- export interface Config {
2
- defaultBranches?: string[];
3
- defaultSinceHours?: number;
4
- defaultUntilHours?: number;
5
- authorMapping?: Record<string, string>;
6
- openspecDir?: string;
7
- codeFileExtensions?: string[];
8
- excludeExtensions?: string[];
9
- activeUserWeeks?: number;
10
- autoFetch?: boolean;
11
- }
12
- export interface CliOptions {
13
- repo: string;
14
- branches?: string;
15
- since?: string;
16
- until?: string;
17
- author?: string;
18
- json?: boolean;
19
- csv?: boolean;
20
- markdown?: boolean;
21
- config?: string;
22
- verbose?: boolean;
23
- interactive?: boolean;
24
- lang?: string;
25
- noFetch?: boolean;
26
- }
27
- export interface CommitInfo {
28
- hash: string;
29
- author: string;
30
- email: string;
31
- date: Date;
32
- message: string;
33
- branches?: string[];
34
- }
35
- export interface FileChange {
36
- path: string;
37
- additions: number;
38
- deletions: number;
39
- status: string;
40
- }
41
- export interface CommitAnalysis {
42
- commit: CommitInfo;
43
- openspecProposals: Set<string>;
44
- codeFiles: FileChange[];
45
- totalAdditions: number;
46
- totalDeletions: number;
47
- netChanges: number;
48
- }
49
- export interface AuthorStats {
50
- author: string;
51
- commits: number;
52
- openspecProposals: Set<string>;
53
- codeFilesChanged: number;
54
- additions: number;
55
- deletions: number;
56
- netChanges: number;
57
- lastCommitDate?: Date;
58
- firstCommitDate?: Date;
59
- statisticsPeriod?: string;
60
- branchStats?: Map<string, BranchStats>;
61
- }
62
- export interface BranchStats {
63
- branch: string;
64
- commits: number;
65
- openspecProposals: Set<string>;
66
- codeFilesChanged: number;
67
- additions: number;
68
- deletions: number;
69
- netChanges: number;
70
- }
71
- export interface ProposalStats {
72
- proposal: string;
73
- commits: number;
74
- contributors: Set<string>;
75
- codeFilesChanged: number;
76
- additions: number;
77
- deletions: number;
78
- netChanges: number;
79
- commitHashes: Set<string>;
80
- multiProposalCommits: number;
81
- sharedCommitHashes: Set<string>;
82
- }
83
- export interface StatsResult {
84
- timeRange: {
85
- since: Date;
86
- until: Date;
87
- };
88
- branches: string[];
89
- authors: Map<string, AuthorStats>;
90
- proposals: Map<string, ProposalStats>;
91
- totalCommits: number;
92
- }
93
- export interface RepositoryConfig {
94
- name: string;
95
- type: 'local' | 'remote';
96
- path?: string;
97
- url?: string;
98
- cloneOptions?: {
99
- depth?: number | null;
100
- singleBranch?: boolean;
101
- };
102
- branches: string[];
103
- enabled?: boolean;
104
- }
105
- export interface RemoteCacheConfig {
106
- dir: string;
107
- autoCleanup: boolean;
108
- cleanupOnComplete: boolean;
109
- cleanupOnError: boolean;
110
- }
111
- export interface ParallelismConfig {
112
- maxConcurrent: number;
113
- timeout: number;
114
- }
115
- export interface MultiRepoConfig extends Config {
116
- mode: 'single-repo' | 'multi-repo';
117
- repositories?: RepositoryConfig[];
118
- remoteCache?: RemoteCacheConfig;
119
- parallelism?: ParallelismConfig;
120
- }
121
- export interface RepositoryResult {
122
- repository: string;
123
- type: 'local' | 'remote';
124
- path: string;
125
- analyses: CommitAnalysis[];
126
- success: boolean;
127
- error?: string;
128
- }
129
- export interface MultiRepoStatsResult extends StatsResult {
130
- repositories: string[];
131
- repositoryDetails: Map<string, {
132
- type: 'local' | 'remote';
133
- commits: number;
134
- error?: string;
135
- }>;
136
- }
package/dist/cjs/types.js DELETED
@@ -1,17 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __copyProps = (to, from, except, desc) => {
6
- if (from && typeof from === "object" || typeof from === "function") {
7
- for (let key of __getOwnPropNames(from))
8
- if (!__hasOwnProp.call(to, key) && key !== except)
9
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
- }
11
- return to;
12
- };
13
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
14
-
15
- // src/types.ts
16
- var types_exports = {};
17
- module.exports = __toCommonJS(types_exports);