g2log 1.4.5 → 1.5.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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "mcp__auggie-mcp__codebase-retrieval"
5
+ ]
6
+ }
7
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,169 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ `g2log` (AI-Git 用户日报生成工具) is a Node.js CLI tool that retrieves Git commit records for specified users within a time range and automatically generates work summaries using AI. It can be run via `npx` without installation or installed globally.
8
+
9
+ ## Common Commands
10
+
11
+ ### Installation and Setup
12
+ ```bash
13
+ # Global installation
14
+ npm install -g g2log
15
+
16
+ # Run via npx (no installation needed)
17
+ npx g2log [options]
18
+
19
+ # Direct execution
20
+ node git-user-log.js
21
+ ```
22
+
23
+ ### Configuration Management
24
+ ```bash
25
+ # Start interactive configuration wizard
26
+ g2log --config
27
+
28
+ # Set API key for AI summarization
29
+ g2log --set-api-key="YOUR_API_KEY"
30
+
31
+ # Set default author name
32
+ g2log --set-default-author="作者名"
33
+
34
+ # Add repository configuration
35
+ g2log --add-repo="别名" --path="/path/to/repo"
36
+
37
+ # List configured repositories
38
+ g2log --list-repos
39
+
40
+ # Fix configuration file format issues
41
+ g2log --fix-config
42
+ ```
43
+
44
+ ### Running the Tool
45
+ ```bash
46
+ # Generate daily summary using defaults
47
+ g2log
48
+
49
+ # Specify time range
50
+ g2log --since="2023-01-01" --until="2023-12-31"
51
+
52
+ # Use local repository only
53
+ g2log --local
54
+
55
+ # Save output to file
56
+ g2log --output="today-summary.md"
57
+ ```
58
+
59
+ ## Architecture
60
+
61
+ ### Entry Point and Core Structure
62
+
63
+ - **`git-user-log.js`** - Main CLI entry point (executable, ~1940 lines)
64
+ - Single-file architecture with all functionality inline
65
+ - Uses ES modules via dynamic `import()` for the `ora` spinner library
66
+ - No build process or transpilation required
67
+
68
+ ### Key Components
69
+
70
+ 1. **Configuration System** (`CONFIG_PATH = ~/.git-user-log-config.json`)
71
+ - `loadConfig()` - Merges user config with `DEFAULT_CONFIG`
72
+ - `saveConfig()` - Persists configuration
73
+ - Handles legacy field migrations (e.g., `deepseek_api_key` → `api_key`)
74
+ - Supports prompt template customization with variable substitution
75
+
76
+ 2. **Git Log Retrieval**
77
+ - Single repository: Uses `git -C "{path}" log` with author/time filters
78
+ - Multi-repository: `getLogsFromMultipleRepos()` aggregates from all configured repos
79
+ - Format: `alias | date | hash | message` or simple mode without hash
80
+
81
+ 3. **AI Integration**
82
+ - `summarizeWithAI()` - Main orchestrator
83
+ - `getOpenAIResponse()` - OpenAI API with streaming support
84
+ - `getDeepSeekResponse()` - DeepSeek API with streaming support
85
+ - Both use Server-Sent Events (SSE) for real-time output streaming
86
+
87
+ 4. **Interactive Configuration Wizard**
88
+ - `setupConfigInteractive()` - Step-by-step CLI prompts
89
+ - Uses Node.js `readline` module for user input
90
+ - Validates Git repository paths before adding
91
+
92
+ ### Configuration File Structure
93
+
94
+ ```json
95
+ {
96
+ "api_key": "sk-...",
97
+ "default_author": "用户名",
98
+ "default_since": "today",
99
+ "default_until": "today",
100
+ "model": "deepseek-chat",
101
+ "api_base_url": "https://api.deepseek.com",
102
+ "api_provider": "deepseek",
103
+ "repositories": {
104
+ "别名": "/path/to/repo"
105
+ },
106
+ "prompt_template": "自定义提示词模板,支持 {{GIT_LOGS}} 等变量"
107
+ }
108
+ ```
109
+
110
+ ### CLI Argument Parsing
111
+
112
+ Custom `parseArgs()` function handles:
113
+ - `--key=value` format
114
+ - `--key value` format
115
+ - Boolean flags like `--local`, `--no-color`
116
+ - Special handling for `--save` as alias for `--output`
117
+
118
+ ### Color Output System
119
+
120
+ Custom ANSI color implementation:
121
+ - Pre-checks for TTY and `--no-color` flag
122
+ - `colorize()` function wraps text with ANSI codes
123
+ - Custom `createSpinner()` with fallback when `ora` fails to load
124
+
125
+ ## Development Notes
126
+
127
+ ### Dynamic Import Pattern
128
+
129
+ The `ora` module is loaded dynamically to handle potential import failures:
130
+ ```javascript
131
+ let ora;
132
+ import('ora').then(module => { ora = module.default; }).catch(...);
133
+ ```
134
+ The spinner function checks if `ora` is loaded and provides a fallback.
135
+
136
+ ### Streaming Response Handling
137
+
138
+ Both `getOpenAIResponse()` and `getDeepSeekResponse()` implement SSE parsing:
139
+ - Buffer incomplete messages
140
+ - Split by `\n\n` delimiter
141
+ - Parse `data: {json}` lines
142
+ - Handle `[DONE]` termination signal
143
+
144
+ ### Variable Substitution in Prompts
145
+
146
+ The `prompt_template` supports multiple variable formats for compatibility:
147
+ - `{{GIT_LOGS}}` and `{log_content}` for git logs
148
+ - `{{AUTHOR}}` and `{author}` for author name
149
+ - `{{SINCE}}`/`{{UNTIL}}` and `{since}`/`{until}` for dates
150
+
151
+ ### NPX Detection
152
+
153
+ The tool detects NPX execution via environment variables:
154
+ ```javascript
155
+ const isRunningWithNpx = process.env.npm_lifecycle_event === 'npx' ||
156
+ process.env.npm_execpath?.includes('npx') ||
157
+ process.env.npm_command === 'exec';
158
+ ```
159
+
160
+ ## Version and Publishing
161
+
162
+ - Version is defined in `package.json` (currently 1.4.4)
163
+ - See `PUBLISH.md` for publishing workflow to npm
164
+ - Postinstall script sets executable permissions on `git-user-log.js`
165
+
166
+ ## Dependencies
167
+
168
+ - **ora** - CLI spinner for loading states (dynamically imported)
169
+ - **No build tools** - Pure Node.js with standard library modules
package/git-user-log.js CHANGED
@@ -77,7 +77,6 @@ function colorize(text, color) {
77
77
 
78
78
  // 配置文件路径
79
79
  const CONFIG_PATH = path.join(os.homedir(), '.git-user-log-config.json');
80
- console.log(CONFIG_PATH);
81
80
  // 默认配置
82
81
  const DEFAULT_CONFIG = {
83
82
  api_key: '',
@@ -89,21 +88,21 @@ const DEFAULT_CONFIG = {
89
88
  api_provider: 'deepseek', // API提供商: deepseek或openai
90
89
  repositories: {},
91
90
  prompt_template: `
92
- 请根据下面的Git提交记录,用3-5句话简洁地总结一天的工作内容。
91
+ 请根据下面的Git提交记录,用3-5句话简洁地总结工作内容。
93
92
 
94
93
  以下是Git提交记录:
95
94
 
96
95
  {{GIT_LOGS}}
97
96
 
98
97
  要求:
99
- 1. 按项目和日期组织内容
100
- 2. 每个项目每天的工作内容用3-5句话概括
98
+ 1. 按项目、日期和作者组织内容
99
+ 2. 每个项目每天每个作者的工作内容用3-5句话概括
101
100
  3. 使用清晰、专业但不晦涩的语言
102
101
  4. 突出重要的功能开发、问题修复和优化改进
103
102
  5. 适合放入工作日报的简洁描述
104
103
  6. 输出格式为:【日期】:
105
- 【项目名称】- 【工作内容概述】
106
- 【项目名称】- 【工作内容概述】
104
+ 【项目名称】 - 【作者】 - 【工作内容概述】
105
+ 【项目名称】 - 【作者】 - 【工作内容概述】
107
106
  7. 回复不要出现多余的内容,非必要不要用markdown格式
108
107
  `
109
108
  };
@@ -416,32 +415,38 @@ function showHelp() {
416
415
  --until <date> 结束日期 (默认: 今天)
417
416
  --days <number> 查询最近n天的记录 (默认: 7)
418
417
 
418
+ 过滤参数:
419
+ --author <name> 按作者过滤提交 (可选,不指定则获取所有作者)
420
+ --local 仅处理本地仓库
421
+
419
422
  显示设置:
420
423
  --no-color 禁用彩色输出
421
424
  --save 保存结果到文件
425
+ --output <file> 保存到指定文件
422
426
  --debug 显示调试信息
423
427
  --show-prompt 显示完整的prompt内容
424
428
  --version 显示当前版本号
425
429
 
426
430
  配置管理:
427
431
  --config 启动交互式配置向导
428
- --set-api-key 设置API密钥
432
+ --set-api-key 设置API密钥
429
433
  --set-api-provider 设置API提供商 (OpenAI/DeepSeek)
430
- --set-api-base-url 设置API基础URL
434
+ --set-api-url 设置API基础URL
431
435
  --set-ai-model 设置AI模型
432
- --set-default-author 设置默认作者
433
- --add-repo 添加仓库配置
434
- --remove-repo 移除仓库配置
435
- --list-repos 列出所有配置的仓库
436
- --uninstall 删除g2log配置文件 (~/.git-user-log-config.json)
436
+ --set-default-author 设置默认作者 (可选)
437
+ --add-repo <alias> --path <path> 添加仓库配置
438
+ --remove-repo <alias> 移除仓库配置
439
+ --list-repos 列出所有配置的仓库
440
+ --uninstall 删除g2log配置文件 (~/.git-user-log-config.json)
437
441
 
438
442
  示例:
443
+ g2log # 获取所有作者的提交
444
+ g2log --author "张三" # 只获取张三的提交
439
445
  g2log --since "2024-01-01" --until "2024-01-31"
440
- g2log --days 30
446
+ g2log --days 30 --local
441
447
  g2log --config
442
448
  g2log --set-api-key "your-api-key"
443
- g2log --add-repo "alias" "path/to/repo"
444
- g2log --remove-repo "alias"
449
+ g2log --add-repo "alias" --path "/path/to/repo"
445
450
  g2log --list-repos
446
451
  g2log --version
447
452
  `);
@@ -678,7 +683,7 @@ async function summarizeWithAI(gitLogs, author, since, until, spinner = null) {
678
683
  const apiProvider = config.api_provider || 'openai';
679
684
  const apiBaseURL = config.api_base_url || '';
680
685
 
681
- let prompt = config.prompt_template || `请根据以下Git提交记录,总结${author}在${since}到${until}期间的主要工作内容。
686
+ let prompt = config.prompt_template || `请根据以下Git提交记录,总结工作内容。
682
687
  按照类别进行归纳,突出重点任务和成就。
683
688
  用清晰的标题和小标题组织内容,确保总结全面且易于阅读。
684
689
 
@@ -686,10 +691,11 @@ Git提交记录:
686
691
  {{GIT_LOGS}}`;
687
692
 
688
693
  // 替换变量 - 支持多种变量格式以兼容用户自定义模板
694
+ const authorText = author || '所有作者';
689
695
  prompt = prompt.replace('{{GIT_LOGS}}', gitLogs)
690
696
  .replace('{log_content}', gitLogs) // 添加对{log_content}格式的支持
691
- .replace('{{AUTHOR}}', author)
692
- .replace('{author}', author)
697
+ .replace('{{AUTHOR}}', authorText)
698
+ .replace('{author}', authorText)
693
699
  .replace('{{SINCE}}', since)
694
700
  .replace('{since}', since)
695
701
  .replace('{{UNTIL}}', until)
@@ -710,7 +716,8 @@ Git提交记录:
710
716
  const providerLower = apiProvider.toLowerCase();
711
717
 
712
718
  // 输出AI总结的标题信息
713
- console.log(`\n${colorize('📊 ' + author + ' 的工作总结', 'bright')}`);
719
+ const summaryTitle = author ? `${author} 的工作总结` : '团队工作总结';
720
+ console.log(`\n${colorize('📊 ' + summaryTitle, 'bright')}`);
714
721
  console.log(`${colorize('📅 时间范围: ' + since + ' 至 ' + until, 'green')}`);
715
722
  console.log(`${colorize('🤖 使用模型: ' + modelName, 'cyan')}`);
716
723
  console.log(`${colorize('=' .repeat(30), 'bright')}\n`);
@@ -1108,8 +1115,13 @@ async function getLogsFromMultipleRepos(author, since, until, options) {
1108
1115
  spinner.update(`🔍 正在检查仓库 ${alias} (${repoPath})...`);
1109
1116
  execSync(`git -C "${repoPath}" rev-parse --is-inside-work-tree`, { stdio: 'ignore' });
1110
1117
 
1111
- // 构建Git命令
1112
- let command = `git -C "${repoPath}" log --author="${author}" --since="${since}" --until="${until}" --date=format:"%Y-%m-%d %H:%M:%S"`;
1118
+ // 构建Git命令(author 现在是可选的)
1119
+ let command = `git -C "${repoPath}" log --since="${since}" --until="${until}" --date=format:"%Y-%m-%d %H:%M:%S"`;
1120
+
1121
+ // 如果指定了 author,则添加过滤器
1122
+ if (author && author.trim()) {
1123
+ command = `git -C "${repoPath}" log --author="${author}" --since="${since}" --until="${until}" --date=format:"%Y-%m-%d %H:%M:%S"`;
1124
+ }
1113
1125
 
1114
1126
  // 添加选项
1115
1127
  if (options.noMerges) {
@@ -1145,7 +1157,8 @@ async function getLogsFromMultipleRepos(author, since, until, options) {
1145
1157
  if (logCount > 0) {
1146
1158
  spinner.stop(`✅ 从仓库 ${repos > 1 ? `${repos} 个仓库` : Object.keys(config.repositories)[0]} 获取到 ${logCount} 条提交`);
1147
1159
  } else {
1148
- spinner.stop(`📭 未找到 ${author} ${since} ${until} 期间的提交记录`);
1160
+ const authorText = author ? author : '所有作者';
1161
+ spinner.stop(`📭 未找到 ${authorText} 在 ${since} 至 ${until} 期间的提交记录`);
1149
1162
  }
1150
1163
 
1151
1164
  return allLogs;
@@ -1222,7 +1235,7 @@ function checkConfig(silent = false) {
1222
1235
  if (!silent) console.log(colorize('⚠️ 检测到配置缺失: 配置文件不存在', 'red'));
1223
1236
  return {
1224
1237
  needsConfig: true,
1225
- missingConfig: ['api_key', 'default_author'],
1238
+ missingConfig: ['api_key'],
1226
1239
  reason: '配置文件不存在',
1227
1240
  currentConfig: null
1228
1241
  };
@@ -1232,14 +1245,12 @@ function checkConfig(silent = false) {
1232
1245
  const config = loadConfig();
1233
1246
  const missingConfig = [];
1234
1247
 
1235
- // 检查关键配置是否存在
1248
+ // 检查关键配置是否存在(default_author 现在是可选的)
1236
1249
  if (!config.api_key) {
1237
1250
  missingConfig.push('api_key');
1238
1251
  }
1239
-
1240
- if (!config.default_author) {
1241
- missingConfig.push('default_author');
1242
- }
1252
+
1253
+ // default_author 现在是可选的,不再强制要求
1243
1254
 
1244
1255
  // 设置默认时间范围(如果不存在)
1245
1256
  if (!config.default_since) {
@@ -1281,7 +1292,7 @@ function checkConfig(silent = false) {
1281
1292
  }
1282
1293
  return {
1283
1294
  needsConfig: true,
1284
- missingConfig: ['api_key', 'default_author'],
1295
+ missingConfig: ['api_key'],
1285
1296
  reason: `配置文件解析错误: ${error.message}`,
1286
1297
  currentConfig: null
1287
1298
  };
@@ -1313,45 +1324,45 @@ async function setupConfigInteractive() {
1313
1324
  console.log(colorize('ℹ️ 检测到现有配置,将在其基础上进行修改。', 'blue'));
1314
1325
  } else {
1315
1326
  console.log(colorize('ℹ️ 未检测到配置文件,将创建新配置。', 'blue'));
1316
- config = {
1327
+ config = {
1317
1328
  repositories: {},
1318
- prompt_template: `请根据下面的Git提交记录,用3-5句话简洁地总结一天的工作内容。
1329
+ prompt_template: `请根据下面的Git提交记录,用3-5句话简洁地总结工作内容。
1319
1330
 
1320
1331
  以下是Git提交记录:
1321
1332
 
1322
1333
  {log_content}
1323
1334
 
1324
1335
  要求:
1325
- 1. 按项目和日期组织内容
1326
- 2. 每个项目每天的工作内容用3-5句话概括
1336
+ 1. 按项目、日期和作者组织内容
1337
+ 2. 每个项目每天每个作者的工作内容用3-5句话概括
1327
1338
  3. 使用清晰、专业但不晦涩的语言
1328
1339
  4. 突出重要的功能开发、问题修复和优化改进
1329
1340
  5. 适合放入工作日报的简洁描述
1330
1341
  6. 输出格式为:【日期】:
1331
- 【项目名称】- 【工作内容概述】
1332
- 【项目名称】- 【工作内容概述】
1342
+ 【项目名称】 - 【作者】 - 【工作内容概述】
1343
+ 【项目名称】 - 【作者】 - 【工作内容概述】
1333
1344
  7. 回复不要出现多余的内容,非必要不要用markdown格式`
1334
1345
  };
1335
1346
  }
1336
1347
  } catch (error) {
1337
1348
  console.log(colorize('⚠️ 读取配置文件时出错,将创建新配置。', 'yellow'));
1338
- config = {
1349
+ config = {
1339
1350
  repositories: {},
1340
- prompt_template: `请根据下面的Git提交记录,用3-5句话简洁地总结一天的工作内容。
1351
+ prompt_template: `请根据下面的Git提交记录,用3-5句话简洁地总结工作内容。
1341
1352
 
1342
1353
  以下是Git提交记录:
1343
1354
 
1344
1355
  {log_content}
1345
1356
 
1346
1357
  要求:
1347
- 1. 按项目和日期组织内容
1348
- 2. 每个项目每天的工作内容用3-5句话概括
1358
+ 1. 按项目、日期和作者组织内容
1359
+ 2. 每个项目每天每个作者的工作内容用3-5句话概括
1349
1360
  3. 使用清晰、专业但不晦涩的语言
1350
1361
  4. 突出重要的功能开发、问题修复和优化改进
1351
1362
  5. 适合放入工作日报的简洁描述
1352
1363
  6. 输出格式为:【日期】:
1353
- 【项目名称】- 【工作内容概述】
1354
- 【项目名称】- 【工作内容概述】
1364
+ 【项目名称】 - 【作者】 - 【工作内容概述】
1365
+ 【项目名称】 - 【作者】 - 【工作内容概述】
1355
1366
  7. 回复不要出现多余的内容,非必要不要用markdown格式`
1356
1367
  };
1357
1368
  }
@@ -1427,13 +1438,19 @@ async function setupConfigInteractive() {
1427
1438
  console.log(colorize(' ℹ️ API密钥保持不变', 'blue'));
1428
1439
  }
1429
1440
 
1430
- // 步骤5: 设置默认作者
1431
- console.log(colorize('\n👤 步骤5: 设置默认作者', 'yellow'));
1441
+ // 步骤5: 设置默认作者(可选)
1442
+ console.log(colorize('\n👤 步骤5: 设置默认作者(可选)', 'yellow'));
1432
1443
  console.log(colorize(' (示例: 张三, user@example.com, 或Git提交时使用的用户名)', 'cyan'));
1444
+ console.log(colorize(' (留空则不过滤,获取所有作者的提交记录)', 'cyan'));
1433
1445
  const existingAuthor = config.default_author || '';
1434
- const authorInput = await question(colorize(` 请输入默认作者名称 [${existingAuthor}]: `, 'green'));
1435
- config.default_author = authorInput.trim() || existingAuthor;
1436
- console.log(colorize(` ✅ 默认作者已设置为: ${config.default_author}`, 'green'));
1446
+ const authorInput = await question(colorize(` 请输入默认作者名称 [${existingAuthor || '留空'}] (可选,按Enter跳过): `, 'green'));
1447
+ if (authorInput.trim() !== '') {
1448
+ config.default_author = authorInput.trim();
1449
+ console.log(colorize(` ✅ 默认作者已设置为: ${config.default_author}`, 'green'));
1450
+ } else {
1451
+ config.default_author = '';
1452
+ console.log(colorize(` ℹ️ 未设置默认作者,将获取所有作者的提交`, 'blue'));
1453
+ }
1437
1454
 
1438
1455
  // 步骤6: 设置默认时间范围(可选)
1439
1456
  console.log(colorize('\n🕒 步骤6: 设置默认时间范围(可选)', 'yellow'));
@@ -1582,42 +1599,21 @@ async function getGitLogs() {
1582
1599
  if (isRunningWithNpx || !fs.existsSync(CONFIG_PATH)) {
1583
1600
  // 对于NPX运行或首次使用(无配置文件),显示提示并询问是否配置
1584
1601
  console.log(colorize('\n⚠️ 检测到配置缺失: ' + configStatus.reason, 'yellow'));
1585
- if (configStatus.missingConfig.includes('default_author')) {
1586
- console.log(colorize('❗ 必须设置默认作者才能使用此工具。', 'red'));
1587
- }
1588
-
1602
+
1589
1603
  // 创建readline接口进行简单询问
1590
1604
  const rl = readline.createInterface({
1591
1605
  input: process.stdin,
1592
1606
  output: process.stdout
1593
1607
  });
1594
-
1608
+
1595
1609
  const question = (query) => new Promise((resolve) => rl.question(query, resolve));
1596
1610
  const answer = await question(colorize('❓ 是否现在进行配置?(y/n): ', 'cyan'));
1597
1611
  rl.close();
1598
-
1612
+
1599
1613
  if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
1600
1614
  // 启动配置向导
1601
1615
  await setupConfigInteractive();
1602
- // 配置完成后,重新加载配置
1603
- const config = loadConfig();
1604
-
1605
- // 如果依然缺少必要配置项,提示并退出
1606
- if (!config.default_author || config.default_author === '') {
1607
- console.log(colorize('\n❌ 错误: 未设置默认作者,这是必需的。', 'red'));
1608
- console.log(colorize('💡 请使用 g2log --set-default-author="用户名" 进行设置后再试。', 'yellow'));
1609
- process.exit(1);
1610
- }
1611
- } else if (configStatus.missingConfig.includes('default_author')) {
1612
- // 如果用户拒绝配置且缺少必要的default_author,提示并退出
1613
- console.log(colorize('\n❌ 错误: 未设置默认作者,这是必需的。', 'red'));
1614
- console.log(colorize('💡 请使用 g2log --set-default-author="用户名" 进行设置后再试。', 'yellow'));
1615
- process.exit(1);
1616
1616
  }
1617
- } else if (configStatus.missingConfig.includes('default_author')) {
1618
- // 对于非NPX运行但缺少必要default_author的情况,直接错误提示
1619
- console.error(colorize('❌ 错误: 配置文件中未设置默认作者。请使用 --set-default-author="用户名" 设置默认作者', 'red'));
1620
- process.exit(1);
1621
1617
  }
1622
1618
  }
1623
1619
  }
@@ -1765,22 +1761,18 @@ async function getGitLogs() {
1765
1761
  // 显示NPX运行信息
1766
1762
  showNpxInfo();
1767
1763
 
1768
- // 使用参数值或默认配置
1764
+ // 使用参数值或默认配置(author 现在是可选的)
1769
1765
  const useLocalRepo = args.local === true;
1770
- const author = config.default_author;
1766
+ const author = args.author || config.default_author || ''; // 支持命令行参数,可为空
1771
1767
  const since = args.since || config.default_since;
1772
1768
  const until = args.until || config.default_until;
1773
-
1769
+
1774
1770
  // 其他参数从配置文件获取
1775
1771
  const simpleMode = true; // 总是使用简单模式
1776
1772
  const aiSummary = true; // 总是使用AI总结
1777
1773
  const outputFile = args.output;
1778
-
1779
- // 参数验证
1780
- if (!author) {
1781
- console.error(colorize('错误: 配置文件中未设置默认作者。请使用 --set-default-author="用户名" 设置默认作者', 'red'));
1782
- process.exit(1);
1783
- }
1774
+
1775
+ // author 现在是可选的,不再强制验证
1784
1776
 
1785
1777
  // 多仓库处理 - 如果不是--local模式,尝试处理配置中的所有仓库
1786
1778
  if (!useLocalRepo) {
@@ -1832,15 +1824,21 @@ async function getGitLogs() {
1832
1824
  }
1833
1825
 
1834
1826
  // 获取简化格式的日志
1835
- const logSpinner = spinner.start(`🔍 正在获取 ${author} ${since} 至 ${until} 期间的提交记录...`);
1836
- const simpleCommand = `git -C "${repoPath}" log --author="${author}" --since="${since}" --until="${until}" --pretty=format:"%ad: %s%n%b%n" --date=format:"%Y-%m-%d %H:%M:%S" --no-merges`;
1827
+ const authorText = author ? author : '所有作者';
1828
+ const logSpinner = spinner.start(`🔍 正在获取 ${authorText} ${since} ${until} 期间的提交记录...`);
1829
+
1830
+ // 构建Git命令(author 现在是可选的)
1831
+ let simpleCommand = `git -C "${repoPath}" log --since="${since}" --until="${until}" --pretty=format:"%ad: %s%n%b%n" --date=format:"%Y-%m-%d %H:%M:%S" --no-merges`;
1832
+ if (author && author.trim()) {
1833
+ simpleCommand = `git -C "${repoPath}" log --author="${author}" --since="${since}" --until="${until}" --pretty=format:"%ad: %s%n%b%n" --date=format:"%Y-%m-%d %H:%M:%S" --no-merges`;
1834
+ }
1837
1835
 
1838
1836
  try {
1839
1837
  const result = execSync(simpleCommand, { encoding: 'utf-8' });
1840
1838
  logSpinner.stop(`✅ 找到提交记录`);
1841
1839
 
1842
1840
  if (!result.trim()) {
1843
- const message = `📭 在指定时间范围内没有找到 ${author} 的提交记录。`;
1841
+ const message = `📭 在指定时间范围内没有找到 ${authorText} 的提交记录。`;
1844
1842
  console.log(colorize(message, 'yellow'));
1845
1843
 
1846
1844
  if (outputFile) {
@@ -1861,20 +1859,22 @@ async function getGitLogs() {
1861
1859
  // 如果指定了输出文件,保存AI总结结果
1862
1860
  if (outputFile) {
1863
1861
  const fileSpinner = spinner.start(`💾 正在保存AI总结到文件: ${outputFile}`);
1864
- fs.writeFileSync(outputFile, `# ${author} 的工作总结 (${since} ${until})\n\n${aiSummaryResult}`, 'utf-8');
1862
+ const summaryTitle = author ? `${author} 的工作总结` : '团队工作总结';
1863
+ fs.writeFileSync(outputFile, `# ${summaryTitle} (${since} 至 ${until})\n\n${aiSummaryResult}`, 'utf-8');
1865
1864
  fileSpinner.stop(`✅ AI总结已保存到文件: ${outputFile}`);
1866
1865
  return;
1867
1866
  }
1868
1867
  } catch (error) {
1869
1868
  console.error(colorize(`❌ AI总结失败: ${error.message}`, 'red'));
1870
1869
  // 如果AI总结失败,输出原始日志
1871
- console.log(`\n📋 ${author} 的Git提交日志 (${since} 至 ${until})\n`);
1870
+ console.log(`\n📋 ${authorText} 的Git提交日志 (${since} 至 ${until})\n`);
1872
1871
  console.log(result);
1873
-
1872
+
1874
1873
  // 如果指定了输出文件,保存结果
1875
1874
  if (outputFile) {
1876
1875
  const fileSpinner = spinner.start(`💾 正在保存结果到文件: ${outputFile}`);
1877
- const outputContent = `# ${author} 的Git提交日志 (${since} 至 ${until})\n\n${result}`;
1876
+ const summaryTitle = author ? `${author} 的Git提交日志` : 'Git提交日志';
1877
+ const outputContent = `# ${summaryTitle} (${since} 至 ${until})\n\n${result}`;
1878
1878
  fs.writeFileSync(outputFile, outputContent, 'utf-8');
1879
1879
  fileSpinner.stop(`✅ 结果已保存到文件: ${outputFile}`);
1880
1880
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "g2log",
3
- "version": "1.4.5",
4
- "description": "查询特定用户和时间范围的Git提交记录并通过AI进行总结,可通过npx直接运行",
3
+ "version": "1.5.0",
4
+ "description": "查询Git提交记录并通过AI进行总结,支持多作者、多仓库,可通过npx直接运行",
5
5
  "main": "git-user-log.js",
6
6
  "bin": {
7
7
  "g2log": "./git-user-log.js"