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
@@ -13,27 +13,27 @@
13
13
  "cli.option.verbose": "Verbose output mode",
14
14
  "cli.option.lang": "Language for output (en, zh-CN)",
15
15
 
16
- "loading.config": "🔍 Loading configuration...",
17
- "loading.activeUsers": "🔍 Fetching active users...",
18
- "loading.analyzing": "🔍 Analyzing commit history...",
19
- "loading.fetching": "🔄 Fetching remote branches...",
16
+ "loading.config": "Loading configuration...",
17
+ "loading.activeUsers": "Fetching active users...",
18
+ "loading.analyzing": "Analyzing commit history...",
19
+ "loading.fetching": "Fetching remote branches...",
20
20
 
21
- "info.timeRange": "📅 Time Range: {{since}} ~ {{until}}",
22
- "info.branches": "🌿 Branches: {{branches}}",
21
+ "info.timeRange": "Time Range: {{since}} ~ {{until}}",
22
+ "info.branches": "Branches: {{branches}}",
23
23
  "info.allBranches": "All branches",
24
24
  "info.activeUsers": " Active users (within {{weeks}} weeks): {{users}}",
25
- "info.foundCommits": "📝 Found {{count}} commits, analyzing...",
25
+ "info.foundCommits": "Found {{count}} commits, analyzing...",
26
26
  "info.analysisProgress": " Analysis progress: {{current}}/{{total}}",
27
- "info.qualifyingCommits": "Found {{count}} qualifying commits (containing OpenSpec proposals and code changes)",
27
+ "info.qualifyingCommits": "Found {{count}} qualifying commits (containing OpenSpec proposals and code changes)",
28
28
 
29
- "warning.noCommits": "⚠️ No commits found matching the criteria",
30
- "warning.noQualifyingCommits": "⚠️ No commits found containing both OpenSpec proposals and code changes",
31
- "warning.noBranches": "⚠️ No remote branches found",
32
- "warning.noBranchesSelected": "⚠️ No branches selected. Please select at least one branch to analyze.",
29
+ "warning.noCommits": "No commits found matching the criteria",
30
+ "warning.noQualifyingCommits": "No commits found containing both OpenSpec proposals and code changes",
31
+ "warning.noBranches": "No remote branches found",
32
+ "warning.noBranchesSelected": "No branches selected. Please select at least one branch to analyze.",
33
33
 
34
- "error.prefix": "Error:",
34
+ "error.prefix": "Error:",
35
35
 
36
- "branch.fetching": "\n🔍 Fetching active branches...",
36
+ "branch.fetching": "\nFetching active branches...",
37
37
  "branch.selectMode": "How would you like to select branches?",
38
38
  "branch.mode.select": "Select from active branches",
39
39
  "branch.mode.default": "Use default branches from config",
@@ -42,21 +42,21 @@
42
42
  "branch.customInput": "Enter branch names (comma-separated):",
43
43
  "branch.additionalInput": "Enter additional branch names (comma-separated):",
44
44
  "branch.customSeparator": "--- Custom input ---",
45
- "branch.selected": "\n✓ Selected branches:",
45
+ "branch.selected": "\nSelected branches:",
46
46
  "branch.lastCommit": "last commit: {{date}}",
47
47
 
48
- "output.title": "\n📊 OpenSpec Statistics Report\n",
48
+ "output.title": "\nOpenSpec Statistics Report\n",
49
49
  "output.timeRange": "Time Range: {{since}} ~ {{until}}\n",
50
50
  "output.branches": "Branches: {{branches}}\n",
51
51
  "output.totalCommits": "Total Commits: {{count}}\n\n",
52
52
  "output.proposals": " Proposals: {{proposals}}\n",
53
- "output.proposalSummary": "📋 Proposal Summary (by proposal)",
54
- "output.proposalTotal": " 📊 Total: {{count}} proposals | {{commits}} commits | {{files}} files | +{{additions}}/-{{deletions}} lines (net: {{netChanges}})\n",
53
+ "output.proposalSummary": "Proposal Summary (by proposal)",
54
+ "output.proposalTotal": " Total: {{count}} proposals | {{commits}} commits | {{files}} files | +{{additions}}/-{{deletions}} lines (net: {{netChanges}})\n",
55
55
  "output.proposalTotalLabel": "Proposal Summary Total",
56
56
  "output.multiProposalWarning": "Note: Some proposals contain commits shared with other proposals. Code changes have been evenly distributed among proposals.",
57
57
  "output.sharedWithOthers": "shared with other proposals",
58
- "output.authorSummary": "👥 Author Summary (by contributor)",
59
- "output.contributorHint": "💡 Use --show-contributors to see detailed statistics for each contributor",
58
+ "output.authorSummary": "Author Summary (by contributor)",
59
+ "output.contributorHint": "Use --show-contributors to see detailed statistics for each contributor",
60
60
 
61
61
  "table.branch": "Branch",
62
62
  "table.period": "Period",
@@ -81,31 +81,31 @@
81
81
  "markdown.statistics": "## Statistics\n\n",
82
82
  "markdown.proposalDetails": "\n## Proposal Details\n\n",
83
83
 
84
- "multi.beta.warning": "⚠️ BETA: Multi-repository mode is experimental",
84
+ "multi.beta.warning": "BETA: Multi-repository mode is experimental",
85
85
  "multi.beta.feedback": " Please report issues at: https://github.com/Orchardxyz/openspec-stat/issues",
86
- "multi.loading.config": "🔍 Loading multi-repository configuration...",
87
- "multi.repo.cloning": "☁️ Cloning {{repo}}...",
88
- "multi.repo.cloned": "Successfully cloned {{repo}}",
89
- "multi.repo.fetching": "🔄 Fetching remote branches for {{repo}}...",
90
- "multi.repo.analyzing": "📊 Analyzing {{repo}} ({{type}})...",
91
- "multi.repo.completed": "Completed {{repo}}: {{commits}} commits",
92
- "multi.repo.failed": "Failed {{repo}}: {{error}}",
93
- "multi.repo.skipped": "⏭️ Skipped {{repo}}: disabled",
94
- "multi.cleanup.start": "🧹 Cleaning up temporary directories...",
95
- "multi.cleanup.done": "Cleanup completed",
96
- "multi.summary.title": "\n📦 Multi-Repository Summary\n",
86
+ "multi.loading.config": "Loading multi-repository configuration...",
87
+ "multi.repo.cloning": "Cloning {{repo}}...",
88
+ "multi.repo.cloned": "Successfully cloned {{repo}}",
89
+ "multi.repo.fetching": "Fetching remote branches for {{repo}}...",
90
+ "multi.repo.analyzing": "Analyzing {{repo}} ({{type}})...",
91
+ "multi.repo.completed": "Completed {{repo}}: {{commits}} commits",
92
+ "multi.repo.failed": "Failed {{repo}}: {{error}}",
93
+ "multi.repo.skipped": "Skipped {{repo}}: disabled",
94
+ "multi.cleanup.start": "Cleaning up temporary directories...",
95
+ "multi.cleanup.done": "Cleanup completed",
96
+ "multi.summary.title": "\nMulti-Repository Summary\n",
97
97
  "multi.summary.repos": "Repositories: {{total}} ({{success}} succeeded, {{failed}} failed)",
98
98
  "multi.progress.batch": "Processing batch {{current}}/{{total}}...",
99
99
  "multi.table.repository": "Repository",
100
100
  "multi.table.type": "Type",
101
101
 
102
- "init.welcome": "\n📋 OpenSpec Configuration Wizard\n",
103
- "init.welcomeMulti": "\n📋 OpenSpec Multi-Repository Configuration Wizard (BETA)\n",
102
+ "init.welcome": "\nOpenSpec Configuration Wizard\n",
103
+ "init.welcomeMulti": "\nOpenSpec Multi-Repository Configuration Wizard (BETA)\n",
104
104
  "init.configName": "Configuration file name:",
105
- "init.addRepository": "\n📦 Repository {{number}}",
105
+ "init.addRepository": "\nRepository {{number}}",
106
106
  "init.repoType": "Repository type:",
107
- "init.repoType.local": "📁 Local - I have this repository on my machine",
108
- "init.repoType.remote": "☁️ Remote - Clone from remote URL",
107
+ "init.repoType.local": "Local - I have this repository on my machine",
108
+ "init.repoType.remote": "Remote - Clone from remote URL",
109
109
  "init.repoName": "Repository name (for display):",
110
110
  "init.repoPath": "Local path (absolute or relative):",
111
111
  "init.repoUrl": "Git URL (e.g., git@github.com:org/repo.git):",
@@ -114,11 +114,11 @@
114
114
  "init.cloneDepth": "Clone depth (number of commits):",
115
115
  "init.branches": "Branches to analyze (comma-separated):",
116
116
  "init.addMore": "Add another repository?",
117
- "init.timeConfig": "\n⏰ Time Range Configuration",
117
+ "init.timeConfig": "\nTime Range Configuration",
118
118
  "init.useDefaultTime": "Use default time range (yesterday 20:00 - today 20:00)?",
119
119
  "init.sinceHours": "Start time offset (hours, negative for past):",
120
120
  "init.untilHours": "End time (hour of day, 0-23):",
121
- "init.advanced": "\n⚙️ Advanced Options",
121
+ "init.advanced": "\nAdvanced Options",
122
122
  "init.configureAdvanced": "Configure advanced options?",
123
123
  "init.openspecDir": "OpenSpec directory path:",
124
124
  "init.maxConcurrent": "Maximum concurrent repository operations:",
@@ -127,11 +127,11 @@
127
127
  "init.gitIdentity": "Git identity (name or email):",
128
128
  "init.unifiedName": "Unified name for \"{{identity}}\":",
129
129
  "init.addMoreMapping": "Add another mapping?",
130
- "init.preview": "\n✅ Configuration Preview:\n",
130
+ "init.preview": "\nConfiguration Preview:\n",
131
131
  "init.save": "\nSave this configuration?",
132
- "init.saved": "\n✅ Configuration saved to {{path}}",
132
+ "init.saved": "\nConfiguration saved to {{path}}",
133
133
  "init.runCommand": "\nRun: openspec-stat multi -c {{path}}",
134
- "init.templateCreated": "Template created at {{path}}",
134
+ "init.templateCreated": "Template created at {{path}}",
135
135
  "init.templateEdit": "Please edit the file and configure your repositories.",
136
136
 
137
137
  "config.validation.noRepos": "Invalid config: \"repositories\" must be an array",
@@ -141,7 +141,7 @@
141
141
  "config.validation.noPath": "Repository \"{{name}}\": \"path\" is required for local type",
142
142
  "config.validation.noUrl": "Repository \"{{name}}\": \"url\" is required for remote type",
143
143
  "config.validation.noBranches": "Repository \"{{name}}\": at least one branch is required",
144
- "config.summary.title": "\n📋 Configuration Summary\n",
144
+ "config.summary.title": "\nConfiguration Summary\n",
145
145
  "config.summary.repositories": "Repositories:",
146
146
  "config.summary.timeRange": "\nTime Range:",
147
147
  "config.summary.since": " Since: {{hours}} hours",
@@ -13,27 +13,27 @@
13
13
  "cli.option.verbose": "详细输出模式",
14
14
  "cli.option.lang": "输出语言(en, zh-CN)",
15
15
 
16
- "loading.config": "🔍 正在加载配置...",
17
- "loading.activeUsers": "🔍 正在获取活跃用户...",
18
- "loading.analyzing": "🔍 正在分析提交历史...",
19
- "loading.fetching": "🔄 正在拉取远程分支...",
16
+ "loading.config": "正在加载配置...",
17
+ "loading.activeUsers": "正在获取活跃用户...",
18
+ "loading.analyzing": "正在分析提交历史...",
19
+ "loading.fetching": "正在拉取远程分支...",
20
20
 
21
- "info.timeRange": "📅 时间范围:{{since}} ~ {{until}}",
22
- "info.branches": "🌿 分支:{{branches}}",
21
+ "info.timeRange": "时间范围:{{since}} ~ {{until}}",
22
+ "info.branches": "分支:{{branches}}",
23
23
  "info.allBranches": "所有分支",
24
24
  "info.activeUsers": " 活跃用户({{weeks}} 周内):{{users}}",
25
- "info.foundCommits": "📝 找到 {{count}} 个提交,正在分析...",
25
+ "info.foundCommits": "找到 {{count}} 个提交,正在分析...",
26
26
  "info.analysisProgress": " 分析进度:{{current}}/{{total}}",
27
- "info.qualifyingCommits": "找到 {{count}} 个符合条件的提交(包含 OpenSpec 提案和代码变更)",
27
+ "info.qualifyingCommits": "找到 {{count}} 个符合条件的提交(包含 OpenSpec 提案和代码变更)",
28
28
 
29
- "warning.noCommits": "⚠️ 未找到符合条件的提交",
30
- "warning.noQualifyingCommits": "⚠️ 未找到同时包含 OpenSpec 提案和代码变更的提交",
31
- "warning.noBranches": "⚠️ 未找到远程分支",
32
- "warning.noBranchesSelected": "⚠️ 未选择任何分支。请至少选择一个分支进行分析。",
29
+ "warning.noCommits": "未找到符合条件的提交",
30
+ "warning.noQualifyingCommits": "未找到同时包含 OpenSpec 提案和代码变更的提交",
31
+ "warning.noBranches": "未找到远程分支",
32
+ "warning.noBranchesSelected": "未选择任何分支。请至少选择一个分支进行分析。",
33
33
 
34
- "error.prefix": "错误:",
34
+ "error.prefix": "错误:",
35
35
 
36
- "branch.fetching": "\n🔍 正在获取活跃分支...",
36
+ "branch.fetching": "\n正在获取活跃分支...",
37
37
  "branch.selectMode": "您想如何选择分支?",
38
38
  "branch.mode.select": "从活跃分支中选择",
39
39
  "branch.mode.default": "使用配置文件中的默认分支",
@@ -42,21 +42,21 @@
42
42
  "branch.customInput": "输入分支名称(逗号分隔):",
43
43
  "branch.additionalInput": "输入额外的分支名称(逗号分隔):",
44
44
  "branch.customSeparator": "--- 自定义输入 ---",
45
- "branch.selected": "\n已选择的分支:",
45
+ "branch.selected": "\n已选择的分支:",
46
46
  "branch.lastCommit": "最后提交:{{date}}",
47
47
 
48
- "output.title": "\n📊 OpenSpec 统计报告\n",
48
+ "output.title": "\nOpenSpec 统计报告\n",
49
49
  "output.timeRange": "时间范围:{{since}} ~ {{until}}\n",
50
50
  "output.branches": "分支:{{branches}}\n",
51
51
  "output.totalCommits": "总提交数:{{count}}\n\n",
52
52
  "output.proposals": " 提案:{{proposals}}\n",
53
- "output.proposalSummary": "📋 提案汇总(按提案统计)",
54
- "output.proposalTotal": " 📊 总计:{{count}} 个提案 | {{commits}} 次提交 | {{files}} 个文件 | +{{additions}}/-{{deletions}} 行(净变更:{{netChanges}})\n",
53
+ "output.proposalSummary": "提案汇总(按提案统计)",
54
+ "output.proposalTotal": " 总计:{{count}} 个提案 | {{commits}} 次提交 | {{files}} 个文件 | +{{additions}}/-{{deletions}} 行(净变更:{{netChanges}})\n",
55
55
  "output.proposalTotalLabel": "提案汇总总计",
56
56
  "output.multiProposalWarning": "注意:部分提案包含多提案共享的 commit,代码变更已按提案数量平均分配",
57
57
  "output.sharedWithOthers": "与其他提案共享",
58
- "output.authorSummary": "👥 作者汇总(按贡献者统计)",
59
- "output.contributorHint": "💡 使用 --show-contributors 选项可查看每个贡献者的详细统计信息",
58
+ "output.authorSummary": "作者汇总(按贡献者统计)",
59
+ "output.contributorHint": "使用 --show-contributors 选项可查看每个贡献者的详细统计信息",
60
60
 
61
61
  "table.branch": "分支",
62
62
  "table.period": "周期",
@@ -81,31 +81,31 @@
81
81
  "markdown.statistics": "## 统计数据\n\n",
82
82
  "markdown.proposalDetails": "\n## 提案详情\n\n",
83
83
 
84
- "multi.beta.warning": "⚠️ 测试版:多仓库模式为实验性功能",
84
+ "multi.beta.warning": "测试版:多仓库模式为实验性功能",
85
85
  "multi.beta.feedback": " 请反馈问题至:https://github.com/Orchardxyz/openspec-stat/issues",
86
- "multi.loading.config": "🔍 正在加载多仓库配置...",
87
- "multi.repo.cloning": "☁️ 正在克隆 {{repo}}...",
88
- "multi.repo.cloned": "成功克隆 {{repo}}",
89
- "multi.repo.fetching": "🔄 正在拉取 {{repo}} 的远程分支...",
90
- "multi.repo.analyzing": "📊 正在分析 {{repo}} ({{type}})...",
91
- "multi.repo.completed": "完成 {{repo}}:{{commits}} 次提交",
92
- "multi.repo.failed": "失败 {{repo}}:{{error}}",
93
- "multi.repo.skipped": "⏭️ 跳过 {{repo}}:已禁用",
94
- "multi.cleanup.start": "🧹 正在清理临时目录...",
95
- "multi.cleanup.done": "清理完成",
96
- "multi.summary.title": "\n📦 多仓库汇总\n",
86
+ "multi.loading.config": "正在加载多仓库配置...",
87
+ "multi.repo.cloning": "正在克隆 {{repo}}...",
88
+ "multi.repo.cloned": "成功克隆 {{repo}}",
89
+ "multi.repo.fetching": "正在拉取 {{repo}} 的远程分支...",
90
+ "multi.repo.analyzing": "正在分析 {{repo}} ({{type}})...",
91
+ "multi.repo.completed": "完成 {{repo}}:{{commits}} 次提交",
92
+ "multi.repo.failed": "失败 {{repo}}:{{error}}",
93
+ "multi.repo.skipped": "跳过 {{repo}}:已禁用",
94
+ "multi.cleanup.start": "正在清理临时目录...",
95
+ "multi.cleanup.done": "清理完成",
96
+ "multi.summary.title": "\n多仓库汇总\n",
97
97
  "multi.summary.repos": "仓库:{{total}} 个({{success}} 成功,{{failed}} 失败)",
98
98
  "multi.progress.batch": "正在处理批次 {{current}}/{{total}}...",
99
99
  "multi.table.repository": "仓库",
100
100
  "multi.table.type": "类型",
101
101
 
102
- "init.welcome": "\n📋 OpenSpec 配置向导\n",
103
- "init.welcomeMulti": "\n📋 OpenSpec 多仓库配置向导(测试版)\n",
102
+ "init.welcome": "\nOpenSpec 配置向导\n",
103
+ "init.welcomeMulti": "\nOpenSpec 多仓库配置向导(测试版)\n",
104
104
  "init.configName": "配置文件名:",
105
- "init.addRepository": "\n📦 仓库 {{number}}",
105
+ "init.addRepository": "\n仓库 {{number}}",
106
106
  "init.repoType": "仓库类型:",
107
- "init.repoType.local": "📁 本地 - 我的机器上已有此仓库",
108
- "init.repoType.remote": "☁️ 远程 - 从远程 URL 克隆",
107
+ "init.repoType.local": "本地 - 我的机器上已有此仓库",
108
+ "init.repoType.remote": "远程 - 从远程 URL 克隆",
109
109
  "init.repoName": "仓库名称(用于显示):",
110
110
  "init.repoPath": "本地路径(绝对或相对路径):",
111
111
  "init.repoUrl": "Git URL(例如:git@github.com:org/repo.git):",
@@ -114,11 +114,11 @@
114
114
  "init.cloneDepth": "克隆深度(提交数量):",
115
115
  "init.branches": "要分析的分支(逗号分隔):",
116
116
  "init.addMore": "添加另一个仓库?",
117
- "init.timeConfig": "\n时间范围配置",
117
+ "init.timeConfig": "\n时间范围配置",
118
118
  "init.useDefaultTime": "使用默认时间范围(昨天 20:00 - 今天 20:00)?",
119
119
  "init.sinceHours": "开始时间偏移(小时,负数表示过去):",
120
120
  "init.untilHours": "结束时间(一天中的小时,0-23):",
121
- "init.advanced": "\n⚙️ 高级选项",
121
+ "init.advanced": "\n高级选项",
122
122
  "init.configureAdvanced": "配置高级选项?",
123
123
  "init.openspecDir": "OpenSpec 目录路径:",
124
124
  "init.maxConcurrent": "最大并发仓库操作数:",
@@ -127,11 +127,11 @@
127
127
  "init.gitIdentity": "Git 身份(名称或邮箱):",
128
128
  "init.unifiedName": "\"{{identity}}\" 的统一名称:",
129
129
  "init.addMoreMapping": "添加另一个映射?",
130
- "init.preview": "\n配置预览:\n",
130
+ "init.preview": "\n配置预览:\n",
131
131
  "init.save": "\n保存此配置?",
132
- "init.saved": "\n配置已保存至 {{path}}",
132
+ "init.saved": "\n配置已保存至 {{path}}",
133
133
  "init.runCommand": "\n运行:openspec-stat multi -c {{path}}",
134
- "init.templateCreated": "模板已创建于 {{path}}",
134
+ "init.templateCreated": "模板已创建于 {{path}}",
135
135
  "init.templateEdit": "请编辑文件并配置您的仓库。",
136
136
 
137
137
  "config.validation.noRepos": "无效配置:\"repositories\" 必须是数组",
@@ -141,7 +141,7 @@
141
141
  "config.validation.noPath": "仓库 \"{{name}}\":本地类型需要 \"path\"",
142
142
  "config.validation.noUrl": "仓库 \"{{name}}\":远程类型需要 \"url\"",
143
143
  "config.validation.noBranches": "仓库 \"{{name}}\":至少需要一个分支",
144
- "config.summary.title": "\n📋 配置摘要\n",
144
+ "config.summary.title": "\n配置摘要\n",
145
145
  "config.summary.repositories": "仓库:",
146
146
  "config.summary.timeRange": "\n时间范围:",
147
147
  "config.summary.since": " 开始:{{hours}} 小时",
@@ -1,3 +1,3 @@
1
1
  import { MultiRepoConfig } from '../types.js';
2
- export declare function validateAndFillDefaults(config: any): MultiRepoConfig;
2
+ export declare function validateAndFillDefaults(config: unknown): MultiRepoConfig;
3
3
  export declare function printConfigSummary(config: MultiRepoConfig): void;
@@ -1,12 +1,6 @@
1
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
- function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
- function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
1
  import chalk from 'chalk';
8
2
  import { t } from "../i18n/index.js";
9
- var DEFAULT_MULTI_REPO_CONFIG = {
3
+ const DEFAULT_MULTI_REPO_CONFIG = {
10
4
  mode: 'multi-repo',
11
5
  defaultSinceHours: -30,
12
6
  defaultUntilHours: 20,
@@ -25,16 +19,15 @@ var DEFAULT_MULTI_REPO_CONFIG = {
25
19
  cleanupOnError: true
26
20
  }
27
21
  };
28
-
29
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
22
  export function validateAndFillDefaults(config) {
31
- if (!config.repositories || !Array.isArray(config.repositories)) {
23
+ const rawConfig = config;
24
+ if (!rawConfig.repositories || !Array.isArray(rawConfig.repositories)) {
32
25
  throw new Error(t('config.validation.noRepos'));
33
26
  }
34
- if (config.repositories.length === 0) {
27
+ if (rawConfig.repositories.length === 0) {
35
28
  throw new Error(t('config.validation.emptyRepos'));
36
29
  }
37
- config.repositories.forEach(function (repo, index) {
30
+ rawConfig.repositories.forEach((repo, index) => {
38
31
  if (!repo.name) {
39
32
  throw new Error(t('config.validation.noName', {
40
33
  index: String(index + 1)
@@ -70,22 +63,28 @@ export function validateAndFillDefaults(config) {
70
63
  };
71
64
  }
72
65
  });
73
- var mergedConfig = _objectSpread(_objectSpread(_objectSpread({}, DEFAULT_MULTI_REPO_CONFIG), config), {}, {
74
- parallelism: _objectSpread(_objectSpread({}, DEFAULT_MULTI_REPO_CONFIG.parallelism), config.parallelism),
75
- remoteCache: _objectSpread(_objectSpread({}, DEFAULT_MULTI_REPO_CONFIG.remoteCache), config.remoteCache)
76
- });
66
+ const mergedConfig = {
67
+ ...DEFAULT_MULTI_REPO_CONFIG,
68
+ ...rawConfig,
69
+ parallelism: {
70
+ ...DEFAULT_MULTI_REPO_CONFIG.parallelism,
71
+ ...rawConfig.parallelism
72
+ },
73
+ remoteCache: {
74
+ ...DEFAULT_MULTI_REPO_CONFIG.remoteCache,
75
+ ...rawConfig.remoteCache
76
+ }
77
+ };
77
78
  return mergedConfig;
78
79
  }
79
80
  export function printConfigSummary(config) {
80
- var _config$repositories, _config$parallelism, _config$remoteCache, _config$remoteCache2;
81
81
  console.log(chalk.blue(t('config.summary.title')));
82
82
  console.log(chalk.cyan(t('config.summary.repositories')));
83
- (_config$repositories = config.repositories) === null || _config$repositories === void 0 || _config$repositories.forEach(function (repo, i) {
84
- var icon = repo.type === 'local' ? '📁' : '☁️';
85
- var location = repo.type === 'local' ? repo.path : repo.url;
86
- console.log(" ".concat(i + 1, ". ").concat(icon, " ").concat(chalk.bold(repo.name), " (").concat(repo.type, ")"));
87
- console.log(" ".concat(chalk.gray(location)));
88
- console.log(" ".concat(chalk.gray('Branches:'), " ").concat(repo.branches.join(', ')));
83
+ config.repositories?.forEach((repo, i) => {
84
+ const location = repo.type === 'local' ? repo.path : repo.url;
85
+ console.log(` ${i + 1}. ${chalk.bold(repo.name)} (${repo.type})`);
86
+ console.log(` ${chalk.gray(location)}`);
87
+ console.log(` ${chalk.gray('Branches:')} ${repo.branches.join(', ')}`);
89
88
  });
90
89
  console.log(chalk.cyan(t('config.summary.timeRange')));
91
90
  console.log(t('config.summary.since', {
@@ -96,14 +95,14 @@ export function printConfigSummary(config) {
96
95
  }));
97
96
  console.log(chalk.cyan(t('config.summary.parallelism')));
98
97
  console.log(t('config.summary.maxConcurrent', {
99
- count: String(((_config$parallelism = config.parallelism) === null || _config$parallelism === void 0 ? void 0 : _config$parallelism.maxConcurrent) || 3)
98
+ count: String(config.parallelism?.maxConcurrent || 3)
100
99
  }));
101
100
  console.log(chalk.cyan(t('config.summary.remoteCache')));
102
101
  console.log(t('config.summary.cacheDir', {
103
- dir: ((_config$remoteCache = config.remoteCache) === null || _config$remoteCache === void 0 ? void 0 : _config$remoteCache.dir) || '/tmp/openspec-stat-cache'
102
+ dir: config.remoteCache?.dir || '/tmp/openspec-stat-cache'
104
103
  }));
105
104
  console.log(t('config.summary.autoCleanup', {
106
- enabled: (_config$remoteCache2 = config.remoteCache) !== null && _config$remoteCache2 !== void 0 && _config$remoteCache2.cleanupOnComplete ? 'Yes' : 'No'
105
+ enabled: config.remoteCache?.cleanupOnComplete ? 'Yes' : 'No'
107
106
  }));
108
107
  console.log();
109
108
  }