openspec-stat 1.0.0 → 1.2.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 +18 -0
- package/README.zh-CN.md +16 -0
- package/dist/cjs/cli.js +20 -37
- package/dist/cjs/formatters.js +151 -13
- package/dist/cjs/git-analyzer.js +10 -23
- package/dist/cjs/i18n/index.js +1 -1
- package/dist/cjs/i18n/locales/en.json +14 -8
- package/dist/cjs/i18n/locales/zh-CN.json +14 -8
- package/dist/cjs/stats-aggregator.js +35 -5
- package/dist/cjs/types.d.ts +11 -0
- package/dist/esm/cli.js +1 -1
- package/dist/esm/formatters.js +222 -37
- package/dist/esm/git-analyzer.js +5 -3
- package/dist/esm/i18n/index.js +1 -1
- package/dist/esm/i18n/locales/en.json +14 -8
- package/dist/esm/i18n/locales/zh-CN.json +14 -8
- package/dist/esm/stats-aggregator.js +74 -19
- package/dist/esm/types.d.ts +11 -0
- package/package.json +35 -3
|
@@ -21,6 +21,7 @@ export var StatsAggregator = /*#__PURE__*/function () {
|
|
|
21
21
|
key: "aggregate",
|
|
22
22
|
value: function aggregate(analyses, since, until, branches, filterAuthor) {
|
|
23
23
|
var authorStatsMap = new Map();
|
|
24
|
+
var proposalStatsMap = new Map();
|
|
24
25
|
var _iterator = _createForOfIteratorHelper(analyses),
|
|
25
26
|
_step;
|
|
26
27
|
try {
|
|
@@ -52,17 +53,44 @@ export var StatsAggregator = /*#__PURE__*/function () {
|
|
|
52
53
|
stats.deletions += analysis.totalDeletions;
|
|
53
54
|
stats.netChanges += analysis.netChanges;
|
|
54
55
|
stats.codeFilesChanged += analysis.codeFiles.length;
|
|
55
|
-
var
|
|
56
|
-
|
|
56
|
+
var _iterator4 = _createForOfIteratorHelper(analysis.openspecProposals),
|
|
57
|
+
_step4;
|
|
57
58
|
try {
|
|
58
|
-
for (
|
|
59
|
-
var _proposal =
|
|
59
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
60
|
+
var _proposal = _step4.value;
|
|
60
61
|
stats.openspecProposals.add(_proposal);
|
|
62
|
+
|
|
63
|
+
// Aggregate by proposal
|
|
64
|
+
var proposalStats = proposalStatsMap.get(_proposal);
|
|
65
|
+
if (!proposalStats) {
|
|
66
|
+
proposalStats = {
|
|
67
|
+
proposal: _proposal,
|
|
68
|
+
commits: 0,
|
|
69
|
+
contributors: new Set(),
|
|
70
|
+
codeFilesChanged: 0,
|
|
71
|
+
additions: 0,
|
|
72
|
+
deletions: 0,
|
|
73
|
+
netChanges: 0,
|
|
74
|
+
commitHashes: new Set()
|
|
75
|
+
};
|
|
76
|
+
proposalStatsMap.set(_proposal, proposalStats);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Only count each commit once per proposal
|
|
80
|
+
if (!proposalStats.commitHashes.has(analysis.commit.hash)) {
|
|
81
|
+
proposalStats.commitHashes.add(analysis.commit.hash);
|
|
82
|
+
proposalStats.commits++;
|
|
83
|
+
proposalStats.contributors.add(normalizedAuthor);
|
|
84
|
+
proposalStats.codeFilesChanged += analysis.codeFiles.length;
|
|
85
|
+
proposalStats.additions += analysis.totalAdditions;
|
|
86
|
+
proposalStats.deletions += analysis.totalDeletions;
|
|
87
|
+
proposalStats.netChanges += analysis.netChanges;
|
|
88
|
+
}
|
|
61
89
|
}
|
|
62
90
|
} catch (err) {
|
|
63
|
-
|
|
91
|
+
_iterator4.e(err);
|
|
64
92
|
} finally {
|
|
65
|
-
|
|
93
|
+
_iterator4.f();
|
|
66
94
|
}
|
|
67
95
|
if (!stats.lastCommitDate || analysis.commit.date > stats.lastCommitDate) {
|
|
68
96
|
stats.lastCommitDate = analysis.commit.date;
|
|
@@ -71,11 +99,11 @@ export var StatsAggregator = /*#__PURE__*/function () {
|
|
|
71
99
|
stats.firstCommitDate = analysis.commit.date;
|
|
72
100
|
}
|
|
73
101
|
if (analysis.commit.branches && stats.branchStats) {
|
|
74
|
-
var
|
|
75
|
-
|
|
102
|
+
var _iterator5 = _createForOfIteratorHelper(analysis.commit.branches),
|
|
103
|
+
_step5;
|
|
76
104
|
try {
|
|
77
|
-
for (
|
|
78
|
-
var branch =
|
|
105
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
106
|
+
var branch = _step5.value;
|
|
79
107
|
var branchStat = stats.branchStats.get(branch);
|
|
80
108
|
if (!branchStat) {
|
|
81
109
|
branchStat = {
|
|
@@ -94,23 +122,23 @@ export var StatsAggregator = /*#__PURE__*/function () {
|
|
|
94
122
|
branchStat.deletions += analysis.totalDeletions;
|
|
95
123
|
branchStat.netChanges += analysis.netChanges;
|
|
96
124
|
branchStat.codeFilesChanged += analysis.codeFiles.length;
|
|
97
|
-
var
|
|
98
|
-
|
|
125
|
+
var _iterator6 = _createForOfIteratorHelper(analysis.openspecProposals),
|
|
126
|
+
_step6;
|
|
99
127
|
try {
|
|
100
|
-
for (
|
|
101
|
-
var proposal =
|
|
128
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
129
|
+
var proposal = _step6.value;
|
|
102
130
|
branchStat.openspecProposals.add(proposal);
|
|
103
131
|
}
|
|
104
132
|
} catch (err) {
|
|
105
|
-
|
|
133
|
+
_iterator6.e(err);
|
|
106
134
|
} finally {
|
|
107
|
-
|
|
135
|
+
_iterator6.f();
|
|
108
136
|
}
|
|
109
137
|
}
|
|
110
138
|
} catch (err) {
|
|
111
|
-
|
|
139
|
+
_iterator5.e(err);
|
|
112
140
|
} finally {
|
|
113
|
-
|
|
141
|
+
_iterator5.f();
|
|
114
142
|
}
|
|
115
143
|
}
|
|
116
144
|
}
|
|
@@ -134,13 +162,40 @@ export var StatsAggregator = /*#__PURE__*/function () {
|
|
|
134
162
|
} finally {
|
|
135
163
|
_iterator2.f();
|
|
136
164
|
}
|
|
165
|
+
var actualBranches = new Set();
|
|
166
|
+
var _iterator3 = _createForOfIteratorHelper(authorStatsMap.values()),
|
|
167
|
+
_step3;
|
|
168
|
+
try {
|
|
169
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
170
|
+
var _stats2 = _step3.value;
|
|
171
|
+
if (_stats2.branchStats) {
|
|
172
|
+
var _iterator7 = _createForOfIteratorHelper(_stats2.branchStats.keys()),
|
|
173
|
+
_step7;
|
|
174
|
+
try {
|
|
175
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
176
|
+
var _branch = _step7.value;
|
|
177
|
+
actualBranches.add(_branch);
|
|
178
|
+
}
|
|
179
|
+
} catch (err) {
|
|
180
|
+
_iterator7.e(err);
|
|
181
|
+
} finally {
|
|
182
|
+
_iterator7.f();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
} catch (err) {
|
|
187
|
+
_iterator3.e(err);
|
|
188
|
+
} finally {
|
|
189
|
+
_iterator3.f();
|
|
190
|
+
}
|
|
137
191
|
return {
|
|
138
192
|
timeRange: {
|
|
139
193
|
since: since,
|
|
140
194
|
until: until
|
|
141
195
|
},
|
|
142
|
-
branches: branches,
|
|
196
|
+
branches: actualBranches.size > 0 ? Array.from(actualBranches) : branches,
|
|
143
197
|
authors: authorStatsMap,
|
|
198
|
+
proposals: proposalStatsMap,
|
|
144
199
|
totalCommits: analyses.length
|
|
145
200
|
};
|
|
146
201
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -66,6 +66,16 @@ export interface BranchStats {
|
|
|
66
66
|
deletions: number;
|
|
67
67
|
netChanges: number;
|
|
68
68
|
}
|
|
69
|
+
export interface ProposalStats {
|
|
70
|
+
proposal: string;
|
|
71
|
+
commits: number;
|
|
72
|
+
contributors: Set<string>;
|
|
73
|
+
codeFilesChanged: number;
|
|
74
|
+
additions: number;
|
|
75
|
+
deletions: number;
|
|
76
|
+
netChanges: number;
|
|
77
|
+
commitHashes: Set<string>;
|
|
78
|
+
}
|
|
69
79
|
export interface StatsResult {
|
|
70
80
|
timeRange: {
|
|
71
81
|
since: Date;
|
|
@@ -73,5 +83,6 @@ export interface StatsResult {
|
|
|
73
83
|
};
|
|
74
84
|
branches: string[];
|
|
75
85
|
authors: Map<string, AuthorStats>;
|
|
86
|
+
proposals: Map<string, ProposalStats>;
|
|
76
87
|
totalCommits: number;
|
|
77
88
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openspec-stat",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Track team members' OpenSpec proposals and code changes in Git repositories",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"types": "dist/cjs/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"packageManager": "pnpm@10.12.1",
|
|
8
9
|
"bin": {
|
|
9
10
|
"openspec-stat": "dist/esm/cli.js"
|
|
10
11
|
},
|
|
@@ -14,7 +15,20 @@
|
|
|
14
15
|
"build:deps": "father prebundle",
|
|
15
16
|
"prepublishOnly": "father doctor && npm run build",
|
|
16
17
|
"test:cli": "node dist/esm/cli.js --help",
|
|
17
|
-
"link:global": "npm link"
|
|
18
|
+
"link:global": "npm link",
|
|
19
|
+
"link:local": "pnpm run build && chmod +x dist/esm/cli.js && npm link .",
|
|
20
|
+
"unlink": "npm unlink -g openspec-stat",
|
|
21
|
+
"lint": "eslint src --ext .ts,.tsx",
|
|
22
|
+
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
23
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
24
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
25
|
+
"prepare": "husky",
|
|
26
|
+
"changeset": "changeset",
|
|
27
|
+
"changeset:add": "changeset add",
|
|
28
|
+
"version": "changeset version && git add . && git commit -m 'chore: version packages'",
|
|
29
|
+
"release": "pnpm run release:version && pnpm run release:tag",
|
|
30
|
+
"release:version": "pnpm changeset version && git add . && git commit -m 'chore: version packages' && git push origin main",
|
|
31
|
+
"release:tag": "git tag v$(node -p \"require('./package.json').version\") && git push origin v$(node -p \"require('./package.json').version\")"
|
|
18
32
|
},
|
|
19
33
|
"keywords": [
|
|
20
34
|
"openspec",
|
|
@@ -43,8 +57,26 @@
|
|
|
43
57
|
"access": "public"
|
|
44
58
|
},
|
|
45
59
|
"devDependencies": {
|
|
60
|
+
"@changesets/cli": "^2.27.1",
|
|
46
61
|
"@types/node": "^25.0.3",
|
|
47
|
-
"
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
63
|
+
"@typescript-eslint/parser": "^6.21.0",
|
|
64
|
+
"eslint": "^8.56.0",
|
|
65
|
+
"eslint-config-prettier": "^9.1.0",
|
|
66
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
67
|
+
"father": "^4.6.13",
|
|
68
|
+
"husky": "^9.0.11",
|
|
69
|
+
"lint-staged": "^15.2.2",
|
|
70
|
+
"prettier": "^3.2.5"
|
|
71
|
+
},
|
|
72
|
+
"lint-staged": {
|
|
73
|
+
"*.{ts,tsx}": [
|
|
74
|
+
"eslint --fix",
|
|
75
|
+
"prettier --write"
|
|
76
|
+
],
|
|
77
|
+
"*.{js,jsx,json,md}": [
|
|
78
|
+
"prettier --write"
|
|
79
|
+
]
|
|
48
80
|
},
|
|
49
81
|
"dependencies": {
|
|
50
82
|
"@inquirer/prompts": "^8.1.0",
|