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.
- package/README.md +2 -1
- package/README.zh-CN.md +2 -1
- package/dist/esm/branch-selector.js +87 -214
- package/dist/esm/cli.js +14 -64
- package/dist/esm/commands/init.js +17 -44
- package/dist/esm/commands/multi.js +123 -180
- package/dist/esm/commands/single.js +143 -152
- package/dist/esm/config.js +22 -64
- package/dist/esm/formatters.js +285 -520
- package/dist/esm/git-analyzer.js +116 -354
- package/dist/esm/i18n/index.js +22 -10
- package/dist/esm/i18n/locales/en.json +43 -43
- package/dist/esm/i18n/locales/zh-CN.json +43 -43
- package/dist/esm/multi/config-validator.d.ts +1 -1
- package/dist/esm/multi/config-validator.js +25 -26
- package/dist/esm/multi/config-wizard.js +217 -459
- package/dist/esm/multi/multi-repo-analyzer.d.ts +11 -1
- package/dist/esm/multi/multi-repo-analyzer.js +228 -426
- package/dist/esm/stats-aggregator.js +115 -193
- package/dist/esm/time-utils.js +11 -17
- package/dist/esm/ui/spinner.d.ts +12 -0
- package/dist/esm/ui/spinner.js +38 -0
- package/package.json +21 -7
- package/dist/cjs/branch-selector.d.ts +0 -7
- package/dist/cjs/branch-selector.js +0 -128
- package/dist/cjs/cli.d.ts +0 -2
- package/dist/cjs/cli.js +0 -19
- package/dist/cjs/commands/init.d.ts +0 -7
- package/dist/cjs/commands/init.js +0 -58
- package/dist/cjs/commands/multi.d.ts +0 -16
- package/dist/cjs/commands/multi.js +0 -172
- package/dist/cjs/commands/single.d.ts +0 -2
- package/dist/cjs/commands/single.js +0 -148
- package/dist/cjs/config.d.ts +0 -3
- package/dist/cjs/config.js +0 -66
- package/dist/cjs/formatters.d.ts +0 -7
- package/dist/cjs/formatters.js +0 -482
- package/dist/cjs/git-analyzer.d.ts +0 -11
- package/dist/cjs/git-analyzer.js +0 -165
- package/dist/cjs/i18n/index.d.ts +0 -7
- package/dist/cjs/i18n/index.js +0 -84
- package/dist/cjs/i18n/locales/en.json +0 -154
- package/dist/cjs/i18n/locales/zh-CN.json +0 -154
- package/dist/cjs/index.d.ts +0 -6
- package/dist/cjs/index.js +0 -50
- package/dist/cjs/multi/config-validator.d.ts +0 -3
- package/dist/cjs/multi/config-validator.js +0 -130
- package/dist/cjs/multi/config-wizard.d.ts +0 -50
- package/dist/cjs/multi/config-wizard.js +0 -331
- package/dist/cjs/multi/multi-repo-analyzer.d.ts +0 -14
- package/dist/cjs/multi/multi-repo-analyzer.js +0 -210
- package/dist/cjs/stats-aggregator.d.ts +0 -7
- package/dist/cjs/stats-aggregator.js +0 -155
- package/dist/cjs/time-utils.d.ts +0 -6
- package/dist/cjs/time-utils.js +0 -55
- package/dist/cjs/types.d.ts +0 -136
- 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
|
-
});
|
package/dist/cjs/time-utils.d.ts
DELETED
package/dist/cjs/time-utils.js
DELETED
|
@@ -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
|
-
});
|
package/dist/cjs/types.d.ts
DELETED
|
@@ -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);
|