openspec-stat 1.4.3 → 1.4.5
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 +66 -218
- package/README.zh-CN.md +66 -216
- package/dist/esm/cli.js +2 -2
- package/dist/esm/commands/multi.js +193 -99
- package/dist/esm/i18n/locales/en.json +4 -0
- package/dist/esm/i18n/locales/zh-CN.json +4 -0
- package/dist/esm/multi/cache-path.js +12 -0
- package/dist/esm/multi/config-validator.js +5 -4
- package/dist/esm/multi/multi-repo-analyzer.js +131 -22
- package/package.json +1 -2
- package/dist/esm/branch-selector.d.ts +0 -7
- package/dist/esm/cli.d.ts +0 -2
- package/dist/esm/commands/init.d.ts +0 -7
- package/dist/esm/commands/multi.d.ts +0 -16
- package/dist/esm/commands/single.d.ts +0 -2
- package/dist/esm/config.d.ts +0 -3
- package/dist/esm/formatters.d.ts +0 -7
- package/dist/esm/git-analyzer.d.ts +0 -11
- package/dist/esm/i18n/index.d.ts +0 -7
- package/dist/esm/index.d.ts +0 -6
- package/dist/esm/multi/config-validator.d.ts +0 -3
- package/dist/esm/multi/config-wizard.d.ts +0 -50
- package/dist/esm/multi/multi-repo-analyzer.d.ts +0 -24
- package/dist/esm/stats-aggregator.d.ts +0 -7
- package/dist/esm/time-utils.d.ts +0 -6
- package/dist/esm/types.d.ts +0 -136
- package/dist/esm/ui/spinner.d.ts +0 -12
package/README.zh-CN.md
CHANGED
|
@@ -4,280 +4,130 @@
|
|
|
4
4
|
[](https://npmjs.com/package/openspec-stat)
|
|
5
5
|
[](https://github.com/Orchardxyz/openspec-stat/actions/workflows/ci.yml)
|
|
6
6
|
|
|
7
|
-
用于追踪团队成员在 Git 仓库中的 OpenSpec
|
|
7
|
+
用于追踪团队成员在 Git 仓库中的 OpenSpec 提案与代码变更的命令行工具。
|
|
8
8
|
|
|
9
9
|
[English](./README.md) | 简体中文
|
|
10
10
|
|
|
11
|
-
## 功能特性
|
|
12
|
-
|
|
13
|
-
- ✅ 追踪指定时间范围内的 Git 提交
|
|
14
|
-
- ✅ 识别同时包含 OpenSpec 提案和代码变更的提交
|
|
15
|
-
- ✅ **提案维度统计汇总** - 按提案聚合统计,避免 merge commit 导致的统计偏差
|
|
16
|
-
- ✅ 按作者分组统计(提交数、提案数、代码变更)
|
|
17
|
-
- ✅ 支持多分支和通配符过滤
|
|
18
|
-
- ✅ 作者名称映射(处理同一人的多个 Git 账号)
|
|
19
|
-
- ✅ 仅追踪最近活跃的成员(默认:2 周)
|
|
20
|
-
- ✅ 多种输出格式:表格、JSON、CSV、Markdown
|
|
21
|
-
- ✅ 国际化支持:英文和中文
|
|
22
|
-
- ✅ **🆕 多仓库模式(BETA)** - 一次运行分析多个本地/远程仓库
|
|
23
|
-
|
|
24
11
|
## 安装
|
|
25
12
|
|
|
26
|
-
### 全局安装
|
|
27
|
-
|
|
28
13
|
```bash
|
|
14
|
+
# 全局安装
|
|
29
15
|
npm install -g openspec-stat
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 本地项目安装
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
npm install openspec-stat --save-dev
|
|
38
|
-
# 或
|
|
39
|
-
pnpm add -D openspec-stat
|
|
16
|
+
# 或项目内开发依赖
|
|
17
|
+
npm install -D openspec-stat
|
|
40
18
|
```
|
|
41
19
|
|
|
42
|
-
##
|
|
43
|
-
|
|
44
|
-
### 基本用法
|
|
20
|
+
## 快速开始
|
|
45
21
|
|
|
46
|
-
|
|
22
|
+
默认时间窗口:昨天 20:00 → 今天 20:00。
|
|
47
23
|
|
|
48
24
|
```bash
|
|
25
|
+
# 基础运行
|
|
49
26
|
openspec-stat
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
这将追踪默认时间范围内的提交(昨天 20:00 ~ 今天 20:00)。
|
|
53
|
-
|
|
54
|
-
### 多仓库模式(BETA)
|
|
55
|
-
|
|
56
|
-
⚠️ **实验性功能**:多仓库模式允许在单次运行中分析多个仓库(本地或远程)。
|
|
57
27
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
openspec-stat init --multi
|
|
28
|
+
# 自定义时间范围
|
|
29
|
+
openspec-stat --since "2024-01-01 00:00:00" --until "2024-01-31 23:59:59"
|
|
61
30
|
|
|
62
|
-
#
|
|
31
|
+
# 多仓库(需配置文件)
|
|
63
32
|
openspec-stat multi -c .openspec-stats.multi.json
|
|
64
|
-
|
|
65
|
-
# 运行并显示详细的贡献者统计
|
|
66
|
-
openspec-stat multi -c .openspec-stats.multi.json --show-contributors
|
|
67
|
-
|
|
68
|
-
# 生成配置模板
|
|
69
|
-
openspec-stat init --template multi -o config.json
|
|
70
33
|
```
|
|
71
34
|
|
|
72
|
-
|
|
73
|
-
- 拥有后端仓库的本地访问权限,但没有前端仓库
|
|
74
|
-
- 需要跨多个仓库追踪贡献情况
|
|
75
|
-
- 希望获得合并统计结果,而无需运行多个命令
|
|
35
|
+
## 关键特性
|
|
76
36
|
|
|
77
|
-
|
|
37
|
+
- 按时间窗口与分支过滤追踪 Git 提交
|
|
38
|
+
- 识别同时包含 OpenSpec 提案与代码变更的提交
|
|
39
|
+
- 提案维度聚合,避免 merge commit 统计偏差
|
|
40
|
+
- 作者分组与名称映射(合并多个 Git 身份)
|
|
41
|
+
- 多分支通配与 **多仓库模式(BETA)**
|
|
42
|
+
- 输出:表格、JSON、CSV、Markdown;语言:en / zh-CN
|
|
78
43
|
|
|
79
|
-
|
|
44
|
+
## 常用参数(完整见 `openspec-stat --help`)
|
|
80
45
|
|
|
81
|
-
|
|
46
|
+
- `-r, --repo <path>`:仓库路径(默认当前目录)
|
|
47
|
+
- `-b, --branches <list>`:逗号分隔分支,支持通配
|
|
48
|
+
- `-s, --since` / `-u, --until`:时间范围
|
|
49
|
+
- `-a, --author <name>`:按作者过滤
|
|
50
|
+
- `-c, --config <path>`:配置文件
|
|
51
|
+
- `--json | --csv | --markdown`:输出格式
|
|
52
|
+
- `-l, --lang <language>`:`en` 或 `zh-CN`
|
|
53
|
+
- `-v, --verbose`:详细模式
|
|
82
54
|
|
|
83
|
-
|
|
84
|
-
openspec-stat [选项]
|
|
85
|
-
|
|
86
|
-
选项:
|
|
87
|
-
-r, --repo <path> 仓库路径(默认:当前目录)
|
|
88
|
-
-b, --branches <branches> 分支列表,逗号分隔(例如:origin/master,origin/release/v1.0)
|
|
89
|
-
-s, --since <datetime> 开始时间(默认:昨天 20:00)
|
|
90
|
-
-u, --until <datetime> 结束时间(默认:今天 20:00)
|
|
91
|
-
-a, --author <name> 按特定作者筛选
|
|
92
|
-
--json 以 JSON 格式输出
|
|
93
|
-
--csv 以 CSV 格式输出
|
|
94
|
-
--markdown 以 Markdown 格式输出
|
|
95
|
-
-c, --config <path> 配置文件路径
|
|
96
|
-
-v, --verbose 详细输出模式
|
|
97
|
-
-l, --lang <language> 输出语言(en, zh-CN)(默认:"en")
|
|
98
|
-
-V, --version 显示版本号
|
|
99
|
-
-h, --help 显示帮助信息
|
|
100
|
-
```
|
|
55
|
+
## 多仓库模式(BETA)
|
|
101
56
|
|
|
102
|
-
|
|
57
|
+
一次运行分析多个本地/远程仓库。
|
|
103
58
|
|
|
104
59
|
```bash
|
|
105
|
-
#
|
|
106
|
-
openspec-stat
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
openspec-stat --since "2024-01-01 00:00:00" --until "2024-01-31 23:59:59"
|
|
110
|
-
|
|
111
|
-
# 追踪特定分支
|
|
112
|
-
openspec-stat --branches "origin/master,origin/release/v1.0"
|
|
113
|
-
|
|
114
|
-
# 追踪特定作者
|
|
115
|
-
openspec-stat --author "张三"
|
|
116
|
-
|
|
117
|
-
# 输出 JSON 格式
|
|
118
|
-
openspec-stat --json > stats.json
|
|
119
|
-
|
|
120
|
-
# 输出 Markdown 报告
|
|
121
|
-
openspec-stat --markdown > report.md
|
|
122
|
-
|
|
123
|
-
# 详细输出模式
|
|
124
|
-
openspec-stat --verbose
|
|
60
|
+
openspec-stat init --multi # 交互式初始化
|
|
61
|
+
openspec-stat multi -c .openspec-stats.multi.json # 聚合视图
|
|
62
|
+
openspec-stat multi -c .openspec-stats.multi.json --show-contributors
|
|
63
|
+
```
|
|
125
64
|
|
|
126
|
-
|
|
127
|
-
openspec-stat --config ./my-config.json
|
|
65
|
+
详见 [多仓库模式指南](./MULTI_REPO_GUIDE.md)。
|
|
128
66
|
|
|
129
|
-
|
|
130
|
-
openspec-stat
|
|
67
|
+
**远程缓存**:远程仓库会首次克隆后复用,路径为
|
|
68
|
+
`~/.openspec-stat/cached/repos/<仓库名>-<哈希>`。使用 `--cache-mode temporary`
|
|
69
|
+
可改为一次性克隆,或用 `--force-clone` 在单次运行中强制重新克隆。
|
|
131
70
|
|
|
132
|
-
|
|
133
|
-
openspec-stat --lang zh-CN --verbose
|
|
134
|
-
```
|
|
71
|
+
## 配置(简版)
|
|
135
72
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
在项目根目录创建 `.openspec-stats.json` 或 `openspec-stats.config.json`:
|
|
73
|
+
在仓库根目录创建 `.openspec-stats.json` 或 `openspec-stats.config.json`。
|
|
139
74
|
|
|
140
75
|
```json
|
|
141
76
|
{
|
|
142
|
-
"defaultBranches": [
|
|
143
|
-
"origin/master",
|
|
144
|
-
"origin/main",
|
|
145
|
-
"origin/release/*"
|
|
146
|
-
],
|
|
77
|
+
"defaultBranches": ["origin/master", "origin/main", "origin/release/*"],
|
|
147
78
|
"defaultSinceHours": -30,
|
|
148
79
|
"defaultUntilHours": 18,
|
|
149
|
-
"authorMapping": {
|
|
150
|
-
"张三": "张三",
|
|
151
|
-
"zhangsan@company.com": "张三",
|
|
152
|
-
"zs": "张三"
|
|
153
|
-
},
|
|
80
|
+
"authorMapping": {"zhangsan@company.com": "张三"},
|
|
154
81
|
"openspecDir": "openspec/",
|
|
155
|
-
"excludeExtensions": [
|
|
156
|
-
".md",
|
|
157
|
-
".txt",
|
|
158
|
-
".png",
|
|
159
|
-
".jpg",
|
|
160
|
-
".jpeg",
|
|
161
|
-
".gif",
|
|
162
|
-
".svg",
|
|
163
|
-
".ico",
|
|
164
|
-
".webp"
|
|
165
|
-
],
|
|
82
|
+
"excludeExtensions": [".md", ".txt", ".png", ".jpg", "..."],
|
|
166
83
|
"activeUserWeeks": 2
|
|
167
84
|
}
|
|
168
85
|
```
|
|
169
86
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
- **defaultBranches**:默认追踪的分支(支持通配符)
|
|
173
|
-
- **defaultSinceHours**:默认开始时间偏移(小时,负数表示往前推)
|
|
174
|
-
- **defaultUntilHours**:默认结束时间(当天的小时数)
|
|
175
|
-
- **authorMapping**:作者名称映射,用于统一同一人的多个 Git 账号
|
|
176
|
-
- **openspecDir**:OpenSpec 提案目录(默认:`openspec/`)
|
|
177
|
-
- **excludeExtensions**:排除的文件扩展名(不计入代码变更)
|
|
178
|
-
- **activeUserWeeks**:活跃用户时间窗口(周,默认:2)
|
|
179
|
-
|
|
180
|
-
## 统计逻辑
|
|
181
|
-
|
|
182
|
-
工具会识别同时满足以下两个条件的提交:
|
|
183
|
-
|
|
184
|
-
1. 包含 `openspec/` 目录中的文件变更(OpenSpec 提案)
|
|
185
|
-
2. 包含代码文件变更(排除文档文件)
|
|
186
|
-
|
|
187
|
-
统计内容包括:
|
|
188
|
-
|
|
189
|
-
- **提交数**:符合条件的提交总数
|
|
190
|
-
- **OpenSpec 提案**:按 `openspec/changes/{提案名称}` 目录统计
|
|
191
|
-
- **代码文件**:修改的代码文件数量
|
|
192
|
-
- **新增行数**:新增的代码行数
|
|
193
|
-
- **删除行数**:删除的代码行数
|
|
194
|
-
- **净变更**:新增行数 - 删除行数
|
|
195
|
-
|
|
196
|
-
工具提供两个统计视角:
|
|
87
|
+
关键字段:默认分支/时间窗口、作者映射(合并身份)、OpenSpec 目录、排除扩展名、活跃用户窗口。
|
|
197
88
|
|
|
198
|
-
|
|
199
|
-
2. **作者汇总**:按贡献者分组统计,显示各个作者的个人贡献情况
|
|
200
|
-
|
|
201
|
-
## 输出格式
|
|
202
|
-
|
|
203
|
-
### 表格格式(默认)
|
|
89
|
+
## 输出示例
|
|
204
90
|
|
|
205
91
|
```
|
|
206
|
-
📊 OpenSpec
|
|
207
|
-
|
|
92
|
+
📊 OpenSpec 统计
|
|
93
|
+
时间:2024-01-01 00:00:00 ~ 2024-01-31 23:59:59
|
|
208
94
|
分支:origin/master
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
│ 提案 │ 提交数 │
|
|
214
|
-
|
|
215
|
-
│ feature-123 │ 5 │
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
│
|
|
223
|
-
|
|
224
|
-
│ 张三 │ 8 │ 3 │ 45 │ +1234 │ -567 │ +667 │
|
|
225
|
-
│ 李四 │ 7 │ 2 │ 32 │ +890 │ -234 │ +656 │
|
|
226
|
-
└──────────┴─────────┴──────────────────┴────────────┴───────────┴───────────┴─────────────┘
|
|
95
|
+
提交总数:8
|
|
96
|
+
|
|
97
|
+
提案汇总
|
|
98
|
+
┌──────────────┬─────────┬───────────┬───────────┐
|
|
99
|
+
│ 提案 │ 提交数 │ 文件数 │ 净变更 │
|
|
100
|
+
├──────────────┼─────────┼───────────┼───────────┤
|
|
101
|
+
│ feature-123 │ 5 │ 30 │ +656 │
|
|
102
|
+
└──────────────┴─────────┴───────────┴───────────┘
|
|
103
|
+
|
|
104
|
+
作者汇总
|
|
105
|
+
┌─────────┬─────────┬───────────┬───────────┐
|
|
106
|
+
│ 作者 │ 提交数 │ 提案数 │ 净变更 │
|
|
107
|
+
├─────────┼─────────┼───────────┼───────────┤
|
|
108
|
+
│ 张三 │ 8 │ 3 │ +667 │
|
|
109
|
+
└─────────┴─────────┴───────────┴───────────┘
|
|
227
110
|
```
|
|
228
111
|
|
|
229
|
-
|
|
112
|
+
更多格式:`--markdown`、`--json`、`--csv`。
|
|
230
113
|
|
|
231
|
-
|
|
232
|
-
openspec-stat --json
|
|
233
|
-
```
|
|
114
|
+
## 语言
|
|
234
115
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
```bash
|
|
238
|
-
openspec-stat --csv > stats.csv
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Markdown 格式
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
openspec-stat --markdown > report.md
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## 语言支持
|
|
248
|
-
|
|
249
|
-
工具支持英文和中文输出。您可以使用 `--lang` 选项指定语言:
|
|
250
|
-
|
|
251
|
-
```bash
|
|
252
|
-
# 英文输出(默认)
|
|
253
|
-
openspec-stat --lang en
|
|
254
|
-
|
|
255
|
-
# 中文输出
|
|
256
|
-
openspec-stat --lang zh-CN
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
工具还会自动检测您的系统语言。如果您的系统区域设置为中文,输出将默认使用中文。
|
|
116
|
+
`--lang en`(默认)或 `--lang zh-CN`,支持按系统语言自动选择。
|
|
260
117
|
|
|
261
118
|
## 开发
|
|
262
119
|
|
|
263
120
|
```bash
|
|
264
|
-
# 安装依赖
|
|
265
121
|
pnpm install
|
|
266
|
-
|
|
267
|
-
# 开发模式
|
|
268
122
|
pnpm dev
|
|
269
|
-
|
|
270
|
-
# 构建
|
|
271
123
|
pnpm build
|
|
272
|
-
|
|
273
|
-
# 本地测试
|
|
274
124
|
node dist/cjs/cli.js
|
|
275
125
|
```
|
|
276
126
|
|
|
277
|
-
##
|
|
127
|
+
## 贡献与发布
|
|
278
128
|
|
|
279
|
-
-
|
|
280
|
-
-
|
|
129
|
+
- 参见 [CONTRIBUTING.md](./CONTRIBUTING.md) 获取开发与 PR 规范。
|
|
130
|
+
- 参见 [RELEASE.md](./RELEASE.md) 了解基于 Changesets 的发布流程。
|
|
281
131
|
|
|
282
132
|
## 许可证
|
|
283
133
|
|
package/dist/esm/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { runSingleRepoCommand } from "./commands/single.js";
|
|
|
4
4
|
import { runMultiRepoCommand } from "./commands/multi.js";
|
|
5
5
|
import { runInitCommand } from "./commands/init.js";
|
|
6
6
|
const program = new Command();
|
|
7
|
-
program.name('openspec-stat').description("Track team members' OpenSpec proposals and code changes in Git repositories").version("1.4.
|
|
7
|
+
program.name('openspec-stat').description("Track team members' OpenSpec proposals and code changes in Git repositories").version("1.4.5").enablePositionalOptions().passThroughOptions();
|
|
8
8
|
|
|
9
9
|
// Default command for single-repository mode (for backward compatibility)
|
|
10
10
|
program.argument('[repo]', 'Repository path', '.').option('-r, --repo <path>', 'Repository path (alternative)', '.').option('-b, --branches <branches>', 'Branch list, comma-separated').option('--no-interactive', 'Disable interactive branch selection').option('-s, --since <datetime>', 'Start time (default: yesterday 20:00)').option('-u, --until <datetime>', 'End time (default: today 20:00)').option('-a, --author <name>', 'Filter by specific author').option('--json', 'Output in JSON format').option('--csv', 'Output in CSV format').option('--markdown', 'Output in Markdown format').option('-c, --config <path>', 'Configuration file path').option('-v, --verbose', 'Verbose output mode').option('-l, --lang <language>', 'Language for output (en, zh-CN)', 'en').option('--no-fetch', 'Skip fetching remote branches').action(async (repo, options) => {
|
|
@@ -13,7 +13,7 @@ program.argument('[repo]', 'Repository path', '.').option('-r, --repo <path>', '
|
|
|
13
13
|
repo: repo || options.repo || '.'
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
|
-
program.command('multi').description('Multi-repository analysis mode (BETA)').option('-c, --config <path>', 'Configuration file path', '.openspec-stats.multi.json').option('-s, --since <datetime>', 'Override start time').option('-u, --until <datetime>', 'Override end time').option('-a, --author <name>', 'Filter by specific author').option('--json', 'Output in JSON format').option('--csv', 'Output in CSV format').option('--markdown', 'Output in Markdown format').option('-v, --verbose', 'Verbose output mode').option('-l, --lang <language>', 'Language (en, zh-CN)', 'en').option('--no-cleanup', 'Do not cleanup temporary directories').option('--show-contributors', 'Show detailed contributor statistics (default: only show summary)').option('--no-fetch', 'Skip fetching remote branches for local repositories').action(async options => {
|
|
16
|
+
program.command('multi').description('Multi-repository analysis mode (BETA)').option('-c, --config <path>', 'Configuration file path', '.openspec-stats.multi.json').option('-s, --since <datetime>', 'Override start time').option('-u, --until <datetime>', 'Override end time').option('-a, --author <name>', 'Filter by specific author').option('--json', 'Output in JSON format').option('--csv', 'Output in CSV format').option('--markdown', 'Output in Markdown format').option('-v, --verbose', 'Verbose output mode').option('-l, --lang <language>', 'Language (en, zh-CN)', 'en').option('--no-cleanup', 'Do not cleanup temporary directories').option('--cache-mode <mode>', 'Cache mode for remote repositories: persistent|temporary').option('--cache-max-age <ms>', 'Max cache age in milliseconds (optional)').option('--force-clone', 'Force fresh clone even if cache exists').option('--show-contributors', 'Show detailed contributor statistics (default: only show summary)').option('--no-fetch', 'Skip fetching remote branches for local repositories').action(async options => {
|
|
17
17
|
await runMultiRepoCommand(options);
|
|
18
18
|
});
|
|
19
19
|
program.command('init').description('Initialize configuration file').option('--multi', 'Create multi-repository configuration (interactive)').option('--template <type>', 'Generate template (single|multi)').option('-o, --output <path>', 'Output file path').action(async options => {
|