@dongowu/git-ai-cli 1.0.1 → 1.0.4

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 CHANGED
@@ -69,6 +69,9 @@ git-ai
69
69
  | 🏠 **本地部署** | 支持 Ollama、LM Studio,数据不出本机 |
70
70
  | 🔍 **智能 Diff** | 自动过滤 lock 文件,Token 优化截断 |
71
71
  | 💬 **交互式** | 提交 / 编辑 / 重新生成 / 取消 |
72
+ | ⚡ **一键提交** | `-y` 参数跳过确认,CI/CD 友好 |
73
+ | 🎯 **多条候选** | `-n 3` 生成多条消息供选择 |
74
+ | 🪝 **Git Hook** | 自动集成到 git commit 流程 |
72
75
  | 📝 **规范化** | 遵循 Conventional Commits 标准 |
73
76
  | 🌍 **中英双语** | 支持中文和英文输出 |
74
77
 
@@ -124,6 +127,45 @@ git-ai config
124
127
 
125
128
  ## 🔧 高级功能
126
129
 
130
+ ### 命令行选项
131
+
132
+ ```bash
133
+ # 一键提交(跳过确认,CI/CD 友好)
134
+ git-ai -y
135
+ git-ai --yes
136
+
137
+ # 生成多条候选消息
138
+ git-ai -n 3
139
+ git-ai --num 3
140
+
141
+ # 组合使用
142
+ git-ai -y -n 3 # 生成 3 条,自动选择第一条提交
143
+ ```
144
+
145
+ ### Git Hook 集成
146
+
147
+ 自动集成到 `git commit` 流程,无需手动运行 `git-ai`:
148
+
149
+ ```bash
150
+ # 安装 hook
151
+ git-ai hook install
152
+
153
+ # 查看状态
154
+ git-ai hook status
155
+
156
+ # 移除 hook
157
+ git-ai hook remove
158
+ ```
159
+
160
+ 安装后,直接运行 `git commit`(不带 `-m`)会自动生成 commit message:
161
+
162
+ ```bash
163
+ git add .
164
+ git commit # 自动调用 git-ai 生成消息
165
+ ```
166
+
167
+ > 💡 跳过 hook: `git commit --no-verify`
168
+
127
169
  ### 自动忽略的文件
128
170
 
129
171
  以下文件会自动从 Diff 分析中排除,避免浪费 Token:
@@ -166,8 +208,26 @@ git-ai
166
208
  - **Local deployment**: Ollama, LM Studio - keep your data private
167
209
  - **Smart diff**: Auto-filter lock files, token optimization
168
210
  - **Interactive**: Commit / Edit / Regenerate / Cancel
211
+ - **One-click commit**: `-y` flag for CI/CD pipelines
212
+ - **Multiple choices**: `-n 3` to generate multiple options
213
+ - **Git Hook**: Auto-integrate with `git commit`
169
214
  - **Conventional Commits**: Standard commit message format
170
215
 
216
+ ### CLI Options
217
+
218
+ ```bash
219
+ # Auto commit (skip confirmation)
220
+ git-ai -y
221
+
222
+ # Generate multiple choices
223
+ git-ai -n 3
224
+
225
+ # Git Hook
226
+ git-ai hook install # Install hook
227
+ git-ai hook remove # Remove hook
228
+ git-ai hook status # Check status
229
+ ```
230
+
171
231
  ### Workflow
172
232
 
173
233
  ```
package/dist/cli.js CHANGED
@@ -1,14 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
  import { cac } from 'cac';
3
3
  import chalk from 'chalk';
4
+ import { createRequire } from 'node:module';
4
5
  import { runConfig } from './commands/config.js';
5
6
  import { runCommit } from './commands/commit.js';
7
+ import { runHook } from './commands/hook.js';
8
+ const require = createRequire(import.meta.url);
9
+ const pkg = require('../package.json');
6
10
  const cli = cac('git-ai');
7
11
  cli
8
12
  .command('', 'Generate AI-powered commit message')
9
- .action(async () => {
13
+ .option('-y, --yes', 'Skip confirmation and commit directly')
14
+ .option('-n, --num <count>', 'Generate multiple commit messages to choose from', { default: 1 })
15
+ .action(async (options) => {
10
16
  try {
11
- await runCommit();
17
+ await runCommit({
18
+ autoCommit: options.yes ?? false,
19
+ numChoices: Math.min(Math.max(Number(options.num) || 1, 1), 5),
20
+ });
12
21
  }
13
22
  catch (error) {
14
23
  const message = error instanceof Error ? error.message : 'Unknown error';
@@ -28,7 +37,19 @@ cli
28
37
  process.exit(1);
29
38
  }
30
39
  });
40
+ cli
41
+ .command('hook <action>', 'Manage Git hooks (install/remove)')
42
+ .action(async (action) => {
43
+ try {
44
+ await runHook(action);
45
+ }
46
+ catch (error) {
47
+ const message = error instanceof Error ? error.message : 'Unknown error';
48
+ console.error(chalk.red(`\n❌ Error: ${message}\n`));
49
+ process.exit(1);
50
+ }
51
+ });
31
52
  cli.help();
32
- cli.version('1.0.0');
53
+ cli.version(pkg.version || '0.0.0');
33
54
  cli.parse();
34
55
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;AAE1B,GAAG;KACA,OAAO,CAAC,EAAE,EAAE,oCAAoC,CAAC;KACjD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,SAAS,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,OAAO,IAAI,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,GAAG;KACA,OAAO,CAAC,QAAQ,EAAE,gCAAgC,CAAC;KACnD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,SAAS,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,OAAO,IAAI,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,GAAG,CAAC,IAAI,EAAE,CAAC;AACX,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAErB,GAAG,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,6 @@
1
- export declare function runCommit(): Promise<void>;
1
+ export interface CommitOptions {
2
+ autoCommit?: boolean;
3
+ numChoices?: number;
4
+ }
5
+ export declare function runCommit(options?: CommitOptions): Promise<void>;
2
6
  //# sourceMappingURL=commit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAeA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAyF/C"}
1
+ {"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAUD,wBAAsB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0H1E"}
@@ -3,29 +3,31 @@ import chalk from 'chalk';
3
3
  import ora from 'ora';
4
4
  import { getConfig } from '../utils/config.js';
5
5
  import { isGitInstalled, isInGitRepo, getStagedFiles, getFilteredDiff, commit, } from '../utils/git.js';
6
- import { createAIClient, generateCommitMessage } from '../utils/ai.js';
7
- export async function runCommit() {
6
+ import { createAIClient, generateCommitMessage, } from '../utils/ai.js';
7
+ function exitWithError(message, hint) {
8
+ console.error(chalk.red(`❌ ${message}`));
9
+ if (hint) {
10
+ console.log(chalk.gray(` ${hint}`));
11
+ }
12
+ process.exit(1);
13
+ }
14
+ export async function runCommit(options = {}) {
15
+ const { autoCommit = false, numChoices = 1 } = options;
8
16
  // Environment checks
9
17
  if (!(await isGitInstalled())) {
10
- console.error(chalk.red('Git is not installed. Please install git first.'));
11
- process.exit(1);
18
+ exitWithError('Git is not installed. Please install git first.');
12
19
  }
13
20
  if (!(await isInGitRepo())) {
14
- console.error(chalk.red('Not in a git repository.'));
15
- process.exit(1);
21
+ exitWithError('Not in a git repository.');
16
22
  }
17
23
  const stagedFiles = await getStagedFiles();
18
24
  if (stagedFiles.length === 0) {
19
- console.error(chalk.red('No staged changes found.'));
20
- console.log(chalk.gray(' Use `git add <files>` to stage your changes first.'));
21
- process.exit(1);
25
+ exitWithError('No staged changes found.', 'Use `git add <files>` to stage your changes first.');
22
26
  }
23
27
  // Check config
24
28
  const config = getConfig();
25
29
  if (!config) {
26
- console.error(chalk.red('Configuration not found.'));
27
- console.log(chalk.gray(' Run `git ai config` to set up your AI provider.'));
28
- process.exit(1);
30
+ exitWithError('Configuration not found.', 'Run `git-ai config` to set up your AI provider.');
29
31
  }
30
32
  // Show staged files
31
33
  console.log(chalk.cyan('\n📁 Staged files:'));
@@ -33,13 +35,41 @@ export async function runCommit() {
33
35
  console.log(chalk.gray(` ${file}`));
34
36
  });
35
37
  // Get filtered diff
36
- const { diff, truncated } = await getFilteredDiff();
38
+ const { diff, truncated, ignoredFiles } = await getFilteredDiff(stagedFiles);
39
+ if (ignoredFiles.length > 0) {
40
+ const preview = ignoredFiles.slice(0, 8).join(', ');
41
+ const more = ignoredFiles.length > 8 ? ` (+${ignoredFiles.length - 8} more)` : '';
42
+ console.log(chalk.gray(`\n🧹 Ignored from diff (token optimization): ${preview}${more}`));
43
+ }
37
44
  if (truncated) {
38
45
  console.log(chalk.yellow('\n⚠️ Diff was truncated due to size limits.'));
39
46
  }
40
47
  // Create AI client
41
48
  const client = createAIClient(config);
42
- let commitMessage = await generateWithSpinner(client, diff, config);
49
+ const input = { diff, stagedFiles, ignoredFiles, truncated };
50
+ // Generate commit message(s)
51
+ let commitMessage;
52
+ if (numChoices > 1) {
53
+ // Generate multiple choices
54
+ const messages = await generateMultipleWithSpinner(client, input, config, numChoices);
55
+ if (autoCommit) {
56
+ // Auto mode: use first message
57
+ commitMessage = messages[0];
58
+ }
59
+ else {
60
+ commitMessage = await selectFromChoices(messages);
61
+ }
62
+ }
63
+ else {
64
+ commitMessage = await generateWithSpinner(client, input, config);
65
+ }
66
+ // Auto commit mode
67
+ if (autoCommit) {
68
+ console.log(chalk.green('\n✨ Generated commit message:\n'));
69
+ console.log(chalk.white.bold(` ${commitMessage.split('\n').join('\n ')}`));
70
+ await performCommit(commitMessage);
71
+ return;
72
+ }
43
73
  // Interactive loop
44
74
  while (true) {
45
75
  console.log(chalk.green('\n✨ Generated commit message:\n'));
@@ -78,7 +108,13 @@ export async function runCommit() {
78
108
  }
79
109
  }
80
110
  else if (action === 'regenerate') {
81
- commitMessage = await generateWithSpinner(client, diff, config);
111
+ if (numChoices > 1) {
112
+ const messages = await generateMultipleWithSpinner(client, input, config, numChoices);
113
+ commitMessage = await selectFromChoices(messages);
114
+ }
115
+ else {
116
+ commitMessage = await generateWithSpinner(client, input, config);
117
+ }
82
118
  }
83
119
  else {
84
120
  console.log(chalk.gray('\n👋 Commit cancelled.\n'));
@@ -86,21 +122,56 @@ export async function runCommit() {
86
122
  }
87
123
  }
88
124
  }
89
- async function generateWithSpinner(client, diff, config) {
125
+ async function selectFromChoices(messages) {
126
+ if (messages.length === 1) {
127
+ return messages[0];
128
+ }
129
+ const { selected } = await inquirer.prompt([
130
+ {
131
+ type: 'list',
132
+ name: 'selected',
133
+ message: 'Select a commit message:',
134
+ choices: messages.map((msg, i) => ({
135
+ name: `${i + 1}. ${msg.split('\n')[0]}`,
136
+ value: msg,
137
+ })),
138
+ },
139
+ ]);
140
+ return selected;
141
+ }
142
+ async function generateWithSpinner(client, input, config) {
90
143
  const spinner = ora({
91
144
  text: 'Generating commit message...',
92
145
  color: 'cyan',
93
146
  }).start();
94
147
  try {
95
- const message = await generateCommitMessage(client, diff, config);
148
+ const message = await generateCommitMessage(client, input, config);
96
149
  spinner.succeed('Commit message generated!');
97
150
  return message;
98
151
  }
99
152
  catch (error) {
100
153
  spinner.fail('Failed to generate commit message');
101
154
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
102
- console.error(chalk.red(`\n❌ Error: ${errorMessage}`));
103
- process.exit(1);
155
+ exitWithError(errorMessage);
156
+ }
157
+ }
158
+ async function generateMultipleWithSpinner(client, input, config, count) {
159
+ const spinner = ora({
160
+ text: `Generating ${count} commit messages...`,
161
+ color: 'cyan',
162
+ }).start();
163
+ try {
164
+ const promises = Array.from({ length: count }, () => generateCommitMessage(client, input, config));
165
+ const messages = await Promise.all(promises);
166
+ // Dedupe
167
+ const unique = [...new Set(messages)];
168
+ spinner.succeed(`Generated ${unique.length} commit message(s)!`);
169
+ return unique;
170
+ }
171
+ catch (error) {
172
+ spinner.fail('Failed to generate commit messages');
173
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
174
+ exitWithError(errorMessage);
104
175
  }
105
176
  }
106
177
  async function performCommit(message) {
@@ -116,8 +187,7 @@ async function performCommit(message) {
116
187
  catch (error) {
117
188
  spinner.fail('Failed to create commit');
118
189
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
119
- console.error(chalk.red(`\n❌ Error: ${errorMessage}`));
120
- process.exit(1);
190
+ exitWithError(errorMessage);
121
191
  }
122
192
  }
123
193
  //# sourceMappingURL=commit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"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"}
@@ -91,6 +91,6 @@ export async function runConfig() {
91
91
  setConfig(config);
92
92
  console.log(chalk.green('\n✅ Configuration saved successfully!'));
93
93
  console.log(chalk.gray(` Config file: ${getConfigPath()}`));
94
- console.log(chalk.cyan('\n💡 You can now use `git ai` to generate commit messages.\n'));
94
+ console.log(chalk.cyan('\n💡 You can now use `git-ai` to generate commit messages.\n'));
95
95
  }
96
96
  //# sourceMappingURL=config.js.map
@@ -0,0 +1,2 @@
1
+ export declare function runHook(action: string): Promise<void>;
2
+ //# sourceMappingURL=hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"AA0DA,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB3D"}
@@ -0,0 +1,147 @@
1
+ import chalk from 'chalk';
2
+ import { execa } from 'execa';
3
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ const HOOK_NAME = 'prepare-commit-msg';
6
+ const HOOK_SCRIPT = `#!/bin/sh
7
+ # git-ai hook - auto-generate commit message
8
+ # To disable temporarily: git commit --no-verify
9
+
10
+ COMMIT_MSG_FILE=$1
11
+ COMMIT_SOURCE=$2
12
+
13
+ # Only run for regular commits (not merge, squash, etc.)
14
+ if [ -z "$COMMIT_SOURCE" ]; then
15
+ # Check if there's already a message (e.g., from -m flag)
16
+ if [ -s "$COMMIT_MSG_FILE" ]; then
17
+ EXISTING_MSG=$(cat "$COMMIT_MSG_FILE" | grep -v "^#" | tr -d '[:space:]')
18
+ if [ -n "$EXISTING_MSG" ]; then
19
+ exit 0
20
+ fi
21
+ fi
22
+
23
+ # Generate commit message using git-ai
24
+ if command -v git-ai >/dev/null 2>&1; then
25
+ echo "🤖 Generating commit message with git-ai..."
26
+ MSG=$(git-ai --yes 2>/dev/null | grep -A 100 "Generated commit message:" | tail -n +2 | head -n 1 | sed 's/^[[:space:]]*//')
27
+ if [ -n "$MSG" ]; then
28
+ echo "$MSG" > "$COMMIT_MSG_FILE"
29
+ fi
30
+ fi
31
+ fi
32
+
33
+ exit 0
34
+ `;
35
+ async function getGitHooksPath() {
36
+ try {
37
+ // Check if custom hooks path is configured
38
+ const { stdout } = await execa('git', ['config', '--get', 'core.hooksPath']);
39
+ return stdout.trim();
40
+ }
41
+ catch {
42
+ // Default to .git/hooks
43
+ const { stdout } = await execa('git', ['rev-parse', '--git-dir']);
44
+ return join(stdout.trim(), 'hooks');
45
+ }
46
+ }
47
+ async function isInGitRepo() {
48
+ try {
49
+ await execa('git', ['rev-parse', '--is-inside-work-tree']);
50
+ return true;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ export async function runHook(action) {
57
+ if (!['install', 'remove', 'status'].includes(action)) {
58
+ console.error(chalk.red(`❌ Unknown action: ${action}`));
59
+ console.log(chalk.gray(' Available actions: install, remove, status'));
60
+ process.exit(1);
61
+ }
62
+ if (!(await isInGitRepo())) {
63
+ console.error(chalk.red('❌ Not in a git repository.'));
64
+ process.exit(1);
65
+ }
66
+ const hooksPath = await getGitHooksPath();
67
+ const hookFile = join(hooksPath, HOOK_NAME);
68
+ if (action === 'status') {
69
+ await showStatus(hookFile);
70
+ }
71
+ else if (action === 'install') {
72
+ await installHook(hookFile, hooksPath);
73
+ }
74
+ else if (action === 'remove') {
75
+ await removeHook(hookFile);
76
+ }
77
+ }
78
+ async function showStatus(hookFile) {
79
+ if (existsSync(hookFile)) {
80
+ const content = readFileSync(hookFile, 'utf-8');
81
+ if (content.includes('git-ai')) {
82
+ console.log(chalk.green('✅ git-ai hook is installed'));
83
+ console.log(chalk.gray(` Location: ${hookFile}`));
84
+ }
85
+ else {
86
+ console.log(chalk.yellow('⚠️ A prepare-commit-msg hook exists but is not from git-ai'));
87
+ console.log(chalk.gray(` Location: ${hookFile}`));
88
+ }
89
+ }
90
+ else {
91
+ console.log(chalk.gray('❌ git-ai hook is not installed'));
92
+ }
93
+ }
94
+ async function installHook(hookFile, hooksPath) {
95
+ // Check if hook already exists
96
+ if (existsSync(hookFile)) {
97
+ const content = readFileSync(hookFile, 'utf-8');
98
+ if (content.includes('git-ai')) {
99
+ console.log(chalk.yellow('⚠️ git-ai hook is already installed'));
100
+ return;
101
+ }
102
+ // Backup existing hook
103
+ const backupFile = `${hookFile}.backup`;
104
+ writeFileSync(backupFile, content);
105
+ console.log(chalk.gray(` Existing hook backed up to: ${backupFile}`));
106
+ }
107
+ // Ensure hooks directory exists
108
+ if (!existsSync(hooksPath)) {
109
+ await execa('mkdir', ['-p', hooksPath]);
110
+ }
111
+ // Write hook script
112
+ writeFileSync(hookFile, HOOK_SCRIPT);
113
+ chmodSync(hookFile, 0o755);
114
+ console.log(chalk.green('✅ git-ai hook installed successfully!'));
115
+ console.log(chalk.gray(` Location: ${hookFile}`));
116
+ console.log('');
117
+ console.log(chalk.cyan('📝 How it works:'));
118
+ console.log(chalk.gray(' When you run `git commit` without -m flag,'));
119
+ console.log(chalk.gray(' git-ai will auto-generate a commit message.'));
120
+ console.log('');
121
+ console.log(chalk.cyan('💡 Tips:'));
122
+ console.log(chalk.gray(' • Skip hook: git commit --no-verify'));
123
+ console.log(chalk.gray(' • Remove hook: git-ai hook remove'));
124
+ }
125
+ async function removeHook(hookFile) {
126
+ if (!existsSync(hookFile)) {
127
+ console.log(chalk.gray('❌ No hook to remove'));
128
+ return;
129
+ }
130
+ const content = readFileSync(hookFile, 'utf-8');
131
+ if (!content.includes('git-ai')) {
132
+ console.log(chalk.yellow('⚠️ The existing hook is not from git-ai, skipping removal'));
133
+ return;
134
+ }
135
+ unlinkSync(hookFile);
136
+ // Restore backup if exists
137
+ const backupFile = `${hookFile}.backup`;
138
+ if (existsSync(backupFile)) {
139
+ const backupContent = readFileSync(backupFile, 'utf-8');
140
+ writeFileSync(hookFile, backupContent);
141
+ chmodSync(hookFile, 0o755);
142
+ unlinkSync(backupFile);
143
+ console.log(chalk.gray(' Previous hook restored from backup'));
144
+ }
145
+ console.log(chalk.green('✅ git-ai hook removed successfully!'));
146
+ }
147
+ //# sourceMappingURL=hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,SAAS,GAAG,oBAAoB,CAAC;AAEvC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BnB,CAAC;AAEF,KAAK,UAAU,eAAe;IAC5B,IAAI,CAAC;QACH,2CAA2C;QAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC7E,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;QACxB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAc;IAC1C,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,WAAW,EAAE,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,eAAe,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAE5C,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;SAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,6DAA6D,CAAC,CAAC,CAAC;YACzF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,SAAiB;IAC5D,+BAA+B;IAC/B,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sCAAsC,CAAC,CAAC,CAAC;YAClE,OAAO;QACT,CAAC;QAED,uBAAuB;QACvB,MAAM,UAAU,GAAG,GAAG,QAAQ,SAAS,CAAC;QACxC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,gCAAgC;IAChC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,oBAAoB;IACpB,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACrC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAE3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,4DAA4D,CAAC,CAAC,CAAC;QACxF,OAAO;IACT,CAAC;IAED,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErB,2BAA2B;IAC3B,MAAM,UAAU,GAAG,GAAG,QAAQ,SAAS,CAAC;IACxC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,aAAa,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACxD,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACvC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC3B,UAAU,CAAC,UAAU,CAAC,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;AAClE,CAAC"}
@@ -1,5 +1,11 @@
1
1
  import OpenAI from 'openai';
2
2
  import type { AIConfig } from '../types.js';
3
3
  export declare function createAIClient(config: AIConfig): OpenAI;
4
- export declare function generateCommitMessage(client: OpenAI, diff: string, config: AIConfig): Promise<string>;
4
+ export interface CommitMessageGenerationInput {
5
+ diff: string;
6
+ stagedFiles?: string[];
7
+ ignoredFiles?: string[];
8
+ truncated?: boolean;
9
+ }
10
+ export declare function generateCommitMessage(client: OpenAI, input: CommitMessageGenerationInput, config: AIConfig): Promise<string>;
5
11
  //# sourceMappingURL=ai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/utils/ai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA8B5C,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAKvD;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,GACf,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/utils/ai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA8B5C,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAKvD;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,4BAA4B,EACnC,MAAM,EAAE,QAAQ,GACf,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
package/dist/utils/ai.js CHANGED
@@ -31,14 +31,33 @@ export function createAIClient(config) {
31
31
  baseURL: config.baseUrl,
32
32
  });
33
33
  }
34
- export async function generateCommitMessage(client, diff, config) {
34
+ export async function generateCommitMessage(client, input, config) {
35
35
  const systemPrompt = config.customPrompt ||
36
36
  (config.locale === 'zh' ? DEFAULT_SYSTEM_PROMPT_ZH : DEFAULT_SYSTEM_PROMPT_EN);
37
+ const isZh = config.locale === 'zh';
38
+ const lines = [];
39
+ if (input.stagedFiles?.length) {
40
+ const header = isZh ? '已暂存文件:' : 'Staged files:';
41
+ lines.push(`${header}\n${input.stagedFiles.map((f) => `- ${f}`).join('\n')}`);
42
+ }
43
+ if (input.ignoredFiles?.length) {
44
+ const header = isZh
45
+ ? '以下文件为节省 Token 已忽略 Diff:'
46
+ : 'Ignored files (diff omitted for token optimization):';
47
+ lines.push(`${header}\n${input.ignoredFiles.map((f) => `- ${f}`).join('\n')}`);
48
+ }
49
+ if (input.truncated) {
50
+ lines.push(isZh
51
+ ? '注意:Diff 内容已因长度限制被截断。'
52
+ : 'Note: The diff was truncated due to size limits.');
53
+ }
54
+ const diffHeader = isZh ? 'Git Diff:' : 'Git diff:';
55
+ lines.push(`${diffHeader}\n\n${input.diff || '(empty)'}`);
37
56
  const response = await client.chat.completions.create({
38
57
  model: config.model,
39
58
  messages: [
40
59
  { role: 'system', content: systemPrompt },
41
- { role: 'user', content: `Here is the git diff:\n\n${diff}` },
60
+ { role: 'user', content: lines.join('\n\n') },
42
61
  ],
43
62
  temperature: 0.7,
44
63
  max_tokens: 500,
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/utils/ai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,wBAAwB,GAAG;;;;;;;;;;;;8CAYa,CAAC;AAE/C,MAAM,wBAAwB,GAAG;;;;;;;;;;;;6BAYJ,CAAC;AAE9B,MAAM,UAAU,cAAc,CAAC,MAAgB;IAC7C,OAAO,IAAI,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ;QACjC,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAc,EACd,IAAY,EACZ,MAAgB;IAEhB,MAAM,YAAY,GAChB,MAAM,CAAC,YAAY;QACnB,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC;IAEjF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QACpD,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE;YACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;YACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,4BAA4B,IAAI,EAAE,EAAE;SAC9D;QACD,WAAW,EAAE,GAAG;QAChB,UAAU,EAAE,GAAG;KAChB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/utils/ai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,wBAAwB,GAAG;;;;;;;;;;;;8CAYa,CAAC;AAE/C,MAAM,wBAAwB,GAAG;;;;;;;;;;;;6BAYJ,CAAC;AAE9B,MAAM,UAAU,cAAc,CAAC,MAAgB;IAC7C,OAAO,IAAI,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ;QACjC,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAC;AACL,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAc,EACd,KAAmC,EACnC,MAAgB;IAEhB,MAAM,YAAY,GAChB,MAAM,CAAC,YAAY;QACnB,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC;IAEjF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI;YACjB,CAAC,CAAC,yBAAyB;YAC3B,CAAC,CAAC,sDAAsD,CAAC;QAC3D,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CACR,IAAI;YACF,CAAC,CAAC,sBAAsB;YACxB,CAAC,CAAC,kDAAkD,CACvD,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,OAAO,KAAK,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;IAE1D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QACpD,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE;YACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;YACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;SAC9C;QACD,WAAW,EAAE,GAAG;QAChB,UAAU,EAAE,GAAG;KAChB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -3,9 +3,10 @@ export declare function isInGitRepo(): Promise<boolean>;
3
3
  export declare function getStagedDiff(): Promise<string>;
4
4
  export declare function getStagedFiles(): Promise<string[]>;
5
5
  export declare function isBlacklisted(filename: string): boolean;
6
- export declare function getFilteredDiff(): Promise<{
6
+ export declare function getFilteredDiff(files: string[]): Promise<{
7
7
  diff: string;
8
8
  truncated: boolean;
9
+ ignoredFiles: string[];
9
10
  }>;
10
11
  export declare function commit(message: string): Promise<void>;
11
12
  //# sourceMappingURL=git.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAGA,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAOvD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAOpD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAGrD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAGxD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAWvD;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CA2BrF;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3D"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAGA,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAOvD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAOpD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAGrD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAGxD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAWvD;AAkCD,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA0BvE;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3D"}
package/dist/utils/git.js CHANGED
@@ -38,20 +38,42 @@ export function isBlacklisted(filename) {
38
38
  return filename === pattern || filename.endsWith(`/${pattern}`);
39
39
  });
40
40
  }
41
- export async function getFilteredDiff() {
42
- const files = await getStagedFiles();
43
- const diffParts = [];
44
- for (const file of files) {
45
- if (isBlacklisted(file)) {
46
- diffParts.push(`[File: ${file}] (content ignored - blacklisted)`);
47
- continue;
41
+ function chunkArgsByLength(args, options) {
42
+ const batches = [];
43
+ let current = [];
44
+ let currentChars = 0;
45
+ for (const arg of args) {
46
+ const argLen = arg.length + 1;
47
+ const shouldStartNewBatch = current.length >= options.maxItems || currentChars + argLen > options.maxChars;
48
+ if (shouldStartNewBatch) {
49
+ if (current.length > 0) {
50
+ batches.push(current);
51
+ }
52
+ current = [];
53
+ currentChars = 0;
48
54
  }
55
+ current.push(arg);
56
+ currentChars += argLen;
57
+ }
58
+ if (current.length > 0) {
59
+ batches.push(current);
60
+ }
61
+ return batches;
62
+ }
63
+ export async function getFilteredDiff(files) {
64
+ const ignoredFiles = files.filter(isBlacklisted);
65
+ const allowedFiles = files.filter((file) => !isBlacklisted(file));
66
+ const diffParts = [];
67
+ const fileBatches = chunkArgsByLength(allowedFiles, { maxItems: 50, maxChars: 6000 });
68
+ for (const batch of fileBatches) {
49
69
  try {
50
- const { stdout } = await execa('git', ['diff', '--cached', '--', file]);
51
- diffParts.push(stdout);
70
+ const { stdout } = await execa('git', ['diff', '--cached', '--', ...batch]);
71
+ if (stdout) {
72
+ diffParts.push(stdout);
73
+ }
52
74
  }
53
75
  catch {
54
- diffParts.push(`[File: ${file}] (unable to get diff)`);
76
+ diffParts.push(`[Diff unavailable for ${batch.length} file(s)]`);
55
77
  }
56
78
  }
57
79
  let fullDiff = diffParts.join('\n');
@@ -60,7 +82,7 @@ export async function getFilteredDiff() {
60
82
  fullDiff = fullDiff.slice(0, MAX_DIFF_LENGTH) + '\n\n...[Diff Truncated]';
61
83
  truncated = true;
62
84
  }
63
- return { diff: fullDiff, truncated };
85
+ return { diff: fullDiff, truncated, ignoredFiles };
64
86
  }
65
87
  export async function commit(message) {
66
88
  await execa('git', ['commit', '-m', message]);
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dongowu/git-ai-cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.4",
4
4
  "description": "Fast, privacy-first, bring-your-own-model Git commit message generator",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
@@ -11,7 +11,13 @@
11
11
  "build": "tsc",
12
12
  "dev": "tsc --watch",
13
13
  "start": "node dist/cli.js",
14
- "prepublishOnly": "npm run build"
14
+ "prepublishOnly": "npm run build",
15
+ "release": "npm version patch && git push && git push --tags && npm publish --access=public",
16
+ "release:minor": "npm version minor && git push && git push --tags && npm publish --access=public",
17
+ "release:major": "npm version major && git push && git push --tags && npm publish --access=public",
18
+ "tag": "npm version patch && git push && git push --tags",
19
+ "tag:minor": "npm version minor && git push && git push --tags",
20
+ "tag:major": "npm version major && git push && git push --tags"
15
21
  },
16
22
  "keywords": [
17
23
  "git",
@@ -0,0 +1,34 @@
1
+ #!/bin/bash
2
+ # release.sh - 自动发布脚本
3
+
4
+ set -e
5
+
6
+ # 颜色
7
+ GREEN='\033[0;32m'
8
+ YELLOW='\033[1;33m'
9
+ NC='\033[0m'
10
+
11
+ # 获取版本类型
12
+ VERSION_TYPE=${1:-patch}
13
+
14
+ echo -e "${GREEN}🚀 Starting release...${NC}"
15
+
16
+ # 1. 构建
17
+ echo -e "${YELLOW}📦 Building...${NC}"
18
+ npm run build
19
+
20
+ # 2. 更新版本
21
+ echo -e "${YELLOW}📝 Bumping ${VERSION_TYPE} version...${NC}"
22
+ npm version $VERSION_TYPE
23
+
24
+ # 3. 推送到 GitHub
25
+ echo -e "${YELLOW}📤 Pushing to GitHub...${NC}"
26
+ git push
27
+ git push --tags
28
+
29
+ # 4. 发布到 npm
30
+ echo -e "${YELLOW}📦 Publishing to npm...${NC}"
31
+ read -p "Enter OTP code: " OTP
32
+ npm publish --access=public --otp=$OTP
33
+
34
+ echo -e "${GREEN}✅ Release complete!${NC}"