@ksw8954/git-ai-commit 1.0.6 → 1.0.7
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/dist/commands/ai.d.ts.map +1 -1
- package/dist/commands/ai.js +11 -0
- package/dist/commands/ai.js.map +1 -1
- package/dist/commands/commit.d.ts +2 -1
- package/dist/commands/commit.d.ts.map +1 -1
- package/dist/commands/commit.js +140 -59
- package/dist/commands/commit.js.map +1 -1
- package/dist/prompts/commit.d.ts.map +1 -1
- package/dist/prompts/commit.js +3 -1
- package/dist/prompts/commit.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/ai.test.ts +38 -0
- package/src/__tests__/preCommit.test.ts +146 -0
- package/src/commands/ai.ts +13 -0
- package/src/commands/commit.ts +168 -69
- package/src/prompts/commit.ts +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,EAAE,eAAe;IAUnC,OAAO,CAAC,QAAQ;IAMhB;;OAEG;IACH,OAAO,CAAC,YAAY;
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,EAAE,eAAe;IAUnC,OAAO,CAAC,QAAQ;IAMhB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6Bd,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAiKhG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAuD9G,0BAA0B,CAC9B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,2BAA2B,CAAC;CAsDxC"}
|
package/dist/commands/ai.js
CHANGED
|
@@ -39,6 +39,10 @@ class AIService {
|
|
|
39
39
|
cleaned = cleaned.replace(/<\/?\s*thinking\b[^>]*>/gi, '');
|
|
40
40
|
// Remove any remaining XML/HTML-like tags
|
|
41
41
|
cleaned = cleaned.replace(/<[^>]+>/g, '');
|
|
42
|
+
// Strip common Markdown emphasis so headers remain plain text
|
|
43
|
+
cleaned = cleaned.replace(/\*\*(.*?)\*\*/g, '$1');
|
|
44
|
+
cleaned = cleaned.replace(/__(.*?)__/g, '$1');
|
|
45
|
+
cleaned = cleaned.replace(/`([^`]+)`/g, '$1');
|
|
42
46
|
// Normalize whitespace
|
|
43
47
|
cleaned = cleaned.replace(/[\t\r]+/g, '');
|
|
44
48
|
cleaned = cleaned.replace(/\n{3,}/g, '\n\n').trim();
|
|
@@ -167,6 +171,13 @@ class AIService {
|
|
|
167
171
|
lines.splice(1, blankCount - 1);
|
|
168
172
|
}
|
|
169
173
|
}
|
|
174
|
+
// Drop additional commit headers to enforce a single conventional commit
|
|
175
|
+
if (lines.length > 0) {
|
|
176
|
+
const nextHeaderIdx = lines.slice(1).findIndex(l => headerPattern.test(l));
|
|
177
|
+
if (nextHeaderIdx >= 0) {
|
|
178
|
+
lines = lines.slice(0, nextHeaderIdx + 1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
170
181
|
finalMessage = lines.join('\n').trim();
|
|
171
182
|
return {
|
|
172
183
|
success: true,
|
package/dist/commands/ai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Command } from
|
|
1
|
+
import { Command } from "commander";
|
|
2
2
|
export interface CommitOptions {
|
|
3
3
|
apiKey?: string;
|
|
4
4
|
baseURL?: string;
|
|
@@ -10,6 +10,7 @@ export interface CommitOptions {
|
|
|
10
10
|
export declare class CommitCommand {
|
|
11
11
|
private program;
|
|
12
12
|
constructor();
|
|
13
|
+
private runPreCommitHook;
|
|
13
14
|
private handleCommit;
|
|
14
15
|
private confirmCommit;
|
|
15
16
|
getCommand(): Command;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAU;;YAuBX,gBAAgB;YAkFhB,YAAY;YAyKZ,aAAa;IAgB3B,UAAU,IAAI,OAAO;CAGtB"}
|
package/dist/commands/commit.js
CHANGED
|
@@ -6,29 +6,110 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.CommitCommand = void 0;
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const readline_1 = __importDefault(require("readline"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
9
12
|
const git_1 = require("./git");
|
|
10
13
|
const ai_1 = require("./ai");
|
|
11
14
|
const config_1 = require("./config");
|
|
12
15
|
const log_1 = require("./log");
|
|
13
16
|
class CommitCommand {
|
|
14
17
|
constructor() {
|
|
15
|
-
this.program = new commander_1.Command(
|
|
16
|
-
.description(
|
|
17
|
-
.option(
|
|
18
|
-
.option(
|
|
19
|
-
.option(
|
|
20
|
-
.option(
|
|
21
|
-
.option(
|
|
22
|
-
.option(
|
|
18
|
+
this.program = new commander_1.Command("commit")
|
|
19
|
+
.description("Generate AI-powered commit message")
|
|
20
|
+
.option("-k, --api-key <key>", "OpenAI API key (overrides env var)")
|
|
21
|
+
.option("-b, --base-url <url>", "Custom API base URL (overrides env var)")
|
|
22
|
+
.option("--model <model>", "Model to use (overrides env var)")
|
|
23
|
+
.option("-m, --message-only", "Output only the generated commit message and skip git actions")
|
|
24
|
+
.option("-p, --push", "Push current branch after creating the commit (implies --commit)")
|
|
25
|
+
.option("--prompt <text>", "Additional instructions to append to the AI prompt for this commit")
|
|
23
26
|
.action(this.handleCommit.bind(this));
|
|
24
27
|
}
|
|
28
|
+
async runPreCommitHook() {
|
|
29
|
+
// 1. Check for npm pre-commit script
|
|
30
|
+
const packageJsonPath = path_1.default.resolve(process.cwd(), "package.json");
|
|
31
|
+
if (fs_1.default.existsSync(packageJsonPath)) {
|
|
32
|
+
try {
|
|
33
|
+
const raw = fs_1.default.readFileSync(packageJsonPath, "utf-8");
|
|
34
|
+
const pkg = JSON.parse(raw);
|
|
35
|
+
if (pkg.scripts && pkg.scripts["pre-commit"]) {
|
|
36
|
+
console.log("Running npm pre-commit script...");
|
|
37
|
+
await new Promise((resolve, reject) => {
|
|
38
|
+
const child = (0, child_process_1.spawn)("npm", ["run", "pre-commit"], {
|
|
39
|
+
stdio: "inherit",
|
|
40
|
+
shell: true,
|
|
41
|
+
});
|
|
42
|
+
child.on("close", (code) => {
|
|
43
|
+
if (code === 0) {
|
|
44
|
+
console.log("✅ npm pre-commit script passed");
|
|
45
|
+
resolve();
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.error(`❌ npm pre-commit script failed with code ${code}`);
|
|
49
|
+
reject(new Error(`npm pre-commit script failed with code ${code}`));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
child.on("error", (err) => {
|
|
53
|
+
reject(err);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (!(error instanceof SyntaxError)) {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// 2. Check for .pre-commit-config.yaml (Python/General pre-commit)
|
|
65
|
+
const preCommitConfigPath = path_1.default.resolve(process.cwd(), ".pre-commit-config.yaml");
|
|
66
|
+
if (fs_1.default.existsSync(preCommitConfigPath)) {
|
|
67
|
+
console.log("Found .pre-commit-config.yaml, running pre-commit hooks...");
|
|
68
|
+
try {
|
|
69
|
+
await new Promise((resolve, reject) => {
|
|
70
|
+
const child = (0, child_process_1.spawn)("pre-commit", ["run"], {
|
|
71
|
+
stdio: "inherit",
|
|
72
|
+
shell: true,
|
|
73
|
+
});
|
|
74
|
+
child.on("close", (code) => {
|
|
75
|
+
if (code === 0) {
|
|
76
|
+
console.log("✅ pre-commit hooks passed");
|
|
77
|
+
resolve();
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
console.error(`❌ pre-commit hooks failed with code ${code}`);
|
|
81
|
+
reject(new Error(`pre-commit hooks failed with code ${code}`));
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
child.on("error", (err) => {
|
|
85
|
+
// If pre-commit is not installed/found, we might want to warn instead of fail?
|
|
86
|
+
// But usually 'error' event on spawn (with shell:true) is rare for command not found (it usually exits with 127).
|
|
87
|
+
// However, if it fails to spawn, we reject.
|
|
88
|
+
reject(err);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
// If the error suggests command not found, we might warn.
|
|
94
|
+
// But since we use shell:true, 'command not found' usually results in exit code 127, which goes to 'close' event.
|
|
95
|
+
// So we catch the error from the promise rejection above.
|
|
96
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
97
|
+
if (msg.includes("code 127") || msg.includes("ENOENT")) {
|
|
98
|
+
console.warn("⚠️ 'pre-commit' command not found, skipping hooks despite configuration file presence.");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
25
105
|
async handleCommit(options) {
|
|
26
106
|
const start = Date.now();
|
|
27
107
|
const safeArgs = {
|
|
28
108
|
...options,
|
|
29
|
-
apiKey: options.apiKey ?
|
|
109
|
+
apiKey: options.apiKey ? "***" : undefined,
|
|
30
110
|
};
|
|
31
111
|
try {
|
|
112
|
+
await this.runPreCommitHook();
|
|
32
113
|
const existingConfig = config_1.ConfigService.getConfig();
|
|
33
114
|
const mergedApiKey = options.apiKey || existingConfig.apiKey;
|
|
34
115
|
const mergedBaseURL = options.baseURL || existingConfig.baseURL;
|
|
@@ -41,129 +122,129 @@ class CommitCommand {
|
|
|
41
122
|
};
|
|
42
123
|
config_1.ConfigService.validateConfig({
|
|
43
124
|
apiKey: mergedApiKey,
|
|
44
|
-
language: existingConfig.language
|
|
125
|
+
language: existingConfig.language,
|
|
45
126
|
});
|
|
46
127
|
const aiConfig = {
|
|
47
128
|
apiKey: mergedApiKey,
|
|
48
129
|
baseURL: mergedBaseURL,
|
|
49
130
|
model: mergedModel,
|
|
50
131
|
language: existingConfig.language,
|
|
51
|
-
verbose: !messageOnly
|
|
132
|
+
verbose: !messageOnly,
|
|
52
133
|
};
|
|
53
|
-
log(
|
|
134
|
+
log("Getting staged changes...");
|
|
54
135
|
const diffResult = await git_1.GitService.getStagedDiff();
|
|
55
136
|
if (!diffResult.success) {
|
|
56
|
-
console.error(
|
|
137
|
+
console.error("Error:", diffResult.error);
|
|
57
138
|
await log_1.LogService.append({
|
|
58
|
-
command:
|
|
139
|
+
command: "commit",
|
|
59
140
|
args: safeArgs,
|
|
60
|
-
status:
|
|
141
|
+
status: "failure",
|
|
61
142
|
details: diffResult.error,
|
|
62
|
-
durationMs: Date.now() - start
|
|
143
|
+
durationMs: Date.now() - start,
|
|
63
144
|
});
|
|
64
145
|
process.exit(1);
|
|
65
146
|
}
|
|
66
|
-
log(
|
|
147
|
+
log("Generating commit message...");
|
|
67
148
|
const aiService = new ai_1.AIService(aiConfig);
|
|
68
149
|
const aiResult = await aiService.generateCommitMessage(diffResult.diff, options.prompt);
|
|
69
150
|
if (!aiResult.success) {
|
|
70
|
-
console.error(
|
|
151
|
+
console.error("Error:", aiResult.error);
|
|
71
152
|
await log_1.LogService.append({
|
|
72
|
-
command:
|
|
153
|
+
command: "commit",
|
|
73
154
|
args: safeArgs,
|
|
74
|
-
status:
|
|
155
|
+
status: "failure",
|
|
75
156
|
details: aiResult.error,
|
|
76
|
-
durationMs: Date.now() - start
|
|
157
|
+
durationMs: Date.now() - start,
|
|
77
158
|
});
|
|
78
159
|
process.exit(1);
|
|
79
160
|
}
|
|
80
|
-
if (typeof aiResult.message !==
|
|
81
|
-
console.error(
|
|
161
|
+
if (typeof aiResult.message !== "string") {
|
|
162
|
+
console.error("Error: Failed to generate commit message");
|
|
82
163
|
process.exit(1);
|
|
83
164
|
}
|
|
84
165
|
if (messageOnly) {
|
|
85
166
|
console.log(aiResult.message);
|
|
86
167
|
await log_1.LogService.append({
|
|
87
|
-
command:
|
|
168
|
+
command: "commit",
|
|
88
169
|
args: { ...safeArgs, messageOnly: true },
|
|
89
|
-
status:
|
|
90
|
-
details:
|
|
91
|
-
durationMs: Date.now() - start
|
|
170
|
+
status: "success",
|
|
171
|
+
details: "message-only output",
|
|
172
|
+
durationMs: Date.now() - start,
|
|
92
173
|
});
|
|
93
174
|
return;
|
|
94
175
|
}
|
|
95
|
-
console.log(
|
|
176
|
+
console.log("\nGenerated commit message:");
|
|
96
177
|
console.log(aiResult.message);
|
|
97
178
|
const confirmed = await this.confirmCommit();
|
|
98
179
|
if (!confirmed) {
|
|
99
|
-
console.log(
|
|
180
|
+
console.log("Commit cancelled by user.");
|
|
100
181
|
await log_1.LogService.append({
|
|
101
|
-
command:
|
|
182
|
+
command: "commit",
|
|
102
183
|
args: safeArgs,
|
|
103
|
-
status:
|
|
104
|
-
details:
|
|
105
|
-
durationMs: Date.now() - start
|
|
184
|
+
status: "cancelled",
|
|
185
|
+
details: "user declined commit",
|
|
186
|
+
durationMs: Date.now() - start,
|
|
106
187
|
});
|
|
107
188
|
return;
|
|
108
189
|
}
|
|
109
|
-
console.log(
|
|
190
|
+
console.log("\nCreating commit...");
|
|
110
191
|
const commitSuccess = await git_1.GitService.createCommit(aiResult.message);
|
|
111
192
|
if (commitSuccess) {
|
|
112
|
-
console.log(
|
|
193
|
+
console.log("✅ Commit created successfully!");
|
|
113
194
|
const pushRequested = Boolean(options.push);
|
|
114
195
|
const pushFromConfig = !pushRequested && existingConfig.autoPush;
|
|
115
196
|
const shouldPush = pushRequested || pushFromConfig;
|
|
116
197
|
if (shouldPush) {
|
|
117
198
|
if (pushFromConfig) {
|
|
118
|
-
console.log(
|
|
199
|
+
console.log("Auto push enabled in config; pushing to remote...");
|
|
119
200
|
}
|
|
120
201
|
else {
|
|
121
|
-
console.log(
|
|
202
|
+
console.log("Pushing to remote...");
|
|
122
203
|
}
|
|
123
204
|
const pushSuccess = await git_1.GitService.push();
|
|
124
205
|
if (pushSuccess) {
|
|
125
|
-
console.log(
|
|
206
|
+
console.log("✅ Push completed successfully!");
|
|
126
207
|
}
|
|
127
208
|
else {
|
|
128
|
-
console.error(
|
|
209
|
+
console.error("❌ Failed to push to remote");
|
|
129
210
|
await log_1.LogService.append({
|
|
130
|
-
command:
|
|
211
|
+
command: "commit",
|
|
131
212
|
args: { ...safeArgs, push: true },
|
|
132
|
-
status:
|
|
133
|
-
details:
|
|
134
|
-
durationMs: Date.now() - start
|
|
213
|
+
status: "failure",
|
|
214
|
+
details: "push failed",
|
|
215
|
+
durationMs: Date.now() - start,
|
|
135
216
|
});
|
|
136
217
|
process.exit(1);
|
|
137
218
|
}
|
|
138
219
|
}
|
|
139
220
|
}
|
|
140
221
|
else {
|
|
141
|
-
console.error(
|
|
222
|
+
console.error("❌ Failed to create commit");
|
|
142
223
|
await log_1.LogService.append({
|
|
143
|
-
command:
|
|
224
|
+
command: "commit",
|
|
144
225
|
args: safeArgs,
|
|
145
|
-
status:
|
|
146
|
-
details:
|
|
147
|
-
durationMs: Date.now() - start
|
|
226
|
+
status: "failure",
|
|
227
|
+
details: "git commit failed",
|
|
228
|
+
durationMs: Date.now() - start,
|
|
148
229
|
});
|
|
149
230
|
process.exit(1);
|
|
150
231
|
}
|
|
151
232
|
await log_1.LogService.append({
|
|
152
|
-
command:
|
|
233
|
+
command: "commit",
|
|
153
234
|
args: safeArgs,
|
|
154
|
-
status:
|
|
155
|
-
durationMs: Date.now() - start
|
|
235
|
+
status: "success",
|
|
236
|
+
durationMs: Date.now() - start,
|
|
156
237
|
});
|
|
157
238
|
}
|
|
158
239
|
catch (error) {
|
|
159
240
|
const message = error instanceof Error ? error.message : String(error);
|
|
160
|
-
console.error(
|
|
241
|
+
console.error("Error:", message);
|
|
161
242
|
await log_1.LogService.append({
|
|
162
|
-
command:
|
|
243
|
+
command: "commit",
|
|
163
244
|
args: safeArgs,
|
|
164
|
-
status:
|
|
245
|
+
status: "failure",
|
|
165
246
|
details: message,
|
|
166
|
-
durationMs: Date.now() - start
|
|
247
|
+
durationMs: Date.now() - start,
|
|
167
248
|
});
|
|
168
249
|
process.exit(1);
|
|
169
250
|
}
|
|
@@ -171,14 +252,14 @@ class CommitCommand {
|
|
|
171
252
|
async confirmCommit() {
|
|
172
253
|
const rl = readline_1.default.createInterface({
|
|
173
254
|
input: process.stdin,
|
|
174
|
-
output: process.stdout
|
|
255
|
+
output: process.stdout,
|
|
175
256
|
});
|
|
176
|
-
const answer = await new Promise(resolve => {
|
|
177
|
-
rl.question(
|
|
257
|
+
const answer = await new Promise((resolve) => {
|
|
258
|
+
rl.question("Proceed with git commit? (y/n): ", resolve);
|
|
178
259
|
});
|
|
179
260
|
rl.close();
|
|
180
261
|
const normalized = answer.trim().toLowerCase();
|
|
181
|
-
return normalized ===
|
|
262
|
+
return normalized === "y" || normalized === "yes";
|
|
182
263
|
}
|
|
183
264
|
getCommand() {
|
|
184
265
|
return this.program;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAoC;AACpC,wDAAgC;AAChC,+BAAkD;AAClD,6BAAkD;AAClD,qCAAyC;AACzC,+BAAmC;AAWnC,MAAa,aAAa;IAGxB;QACE,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC;aACjC,WAAW,CAAC,oCAAoC,CAAC;aACjD,MAAM,CAAC,qBAAqB,EAAE,oCAAoC,CAAC;aACnE,MAAM,CAAC,sBAAsB,EAAE,yCAAyC,CAAC;aACzE,MAAM,CAAC,iBAAiB,EAAE,kCAAkC,CAAC;aAC7D,MAAM,
|
|
1
|
+
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/prompts/commit.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,EAClB,2BAAuB,EACvB,WAAU,oBAA2B,KACpC,
|
|
1
|
+
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/prompts/commit.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,EAClB,2BAAuB,EACvB,WAAU,oBAA2B,KACpC,MAoGF,CAAC"}
|
package/dist/prompts/commit.js
CHANGED
|
@@ -40,7 +40,9 @@ ${customInstructions}
|
|
|
40
40
|
## CRITICAL: Commit Message Output Rules
|
|
41
41
|
- DO NOT include any memory bank status indicators like "[Memory Bank: Active]" or "[Memory Bank: Missing]"
|
|
42
42
|
- DO NOT include any task-specific formatting or artifacts from other rules
|
|
43
|
+
- DO NOT use any Markdown styling (no **bold**, __underline__, \`code\`, links, or emojis) in the commit header, body, or footer
|
|
43
44
|
- ONLY Generate a clean conventional commit message as specified below
|
|
45
|
+
- Output exactly ONE conventional commit message. Choose a single primary type; never return multiple headers or multiple type prefixes.
|
|
44
46
|
|
|
45
47
|
${gitContext}
|
|
46
48
|
|
|
@@ -86,7 +88,7 @@ ${footerGuidelines}
|
|
|
86
88
|
|
|
87
89
|
## Analysis Instructions
|
|
88
90
|
When analyzing staged changes:
|
|
89
|
-
1. Determine Primary Type based on the nature of changes
|
|
91
|
+
1. Determine a single Primary Type based on the dominant nature of the changes (if multiple types apply, pick the most impactful one and stick to it)
|
|
90
92
|
2. Identify Scope from modified directories or modules
|
|
91
93
|
3. Craft Description focusing on the most significant change
|
|
92
94
|
4. Determine if there are Breaking Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/prompts/commit.ts"],"names":[],"mappings":";;;AAEO,MAAM,oBAAoB,GAAG,CAClC,UAAkB,EAClB,kBAAkB,GAAG,EAAE,EACvB,WAAiC,IAAI,EAC7B,EAAE;IACV,MAAM,mBAAmB,GAAG,QAAQ,KAAK,IAAI;QAC3C,CAAC,CAAC;;;+BAGyB;QAC3B,CAAC,CAAC;;;yCAGmC,CAAC;IAExC,MAAM,cAAc,GAAG,QAAQ,KAAK,IAAI;QACtC,CAAC,CAAC;;;;;;uCAMiC;QACnC,CAAC,CAAC;;;;mEAI6D,CAAC;IAElE,MAAM,gBAAgB,GAAG,QAAQ,KAAK,IAAI;QACxC,CAAC,CAAC;;yDAEmD;QACrD,CAAC,CAAC;;yDAEmD,CAAC;IAExD,OAAO;;;;EAIP,kBAAkB
|
|
1
|
+
{"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/prompts/commit.ts"],"names":[],"mappings":";;;AAEO,MAAM,oBAAoB,GAAG,CAClC,UAAkB,EAClB,kBAAkB,GAAG,EAAE,EACvB,WAAiC,IAAI,EAC7B,EAAE;IACV,MAAM,mBAAmB,GAAG,QAAQ,KAAK,IAAI;QAC3C,CAAC,CAAC;;;+BAGyB;QAC3B,CAAC,CAAC;;;yCAGmC,CAAC;IAExC,MAAM,cAAc,GAAG,QAAQ,KAAK,IAAI;QACtC,CAAC,CAAC;;;;;;uCAMiC;QACnC,CAAC,CAAC;;;;mEAI6D,CAAC;IAElE,MAAM,gBAAgB,GAAG,QAAQ,KAAK,IAAI;QACxC,CAAC,CAAC;;yDAEmD;QACrD,CAAC,CAAC;;yDAEmD,CAAC;IAExD,OAAO;;;;EAIP,kBAAkB;;;;;;;;;EASlB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCV,mBAAmB;;EAEnB,cAAc;;EAEd,gBAAgB;;;;;;;;;;;;;yEAauD,CAAC;AAC1E,CAAC,CAAC;AAxGW,QAAA,oBAAoB,wBAwG/B"}
|
package/package.json
CHANGED
package/src/__tests__/ai.test.ts
CHANGED
|
@@ -104,6 +104,44 @@ describe('AIService', () => {
|
|
|
104
104
|
});
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
+
it('should strip markdown formatting from commit header', async () => {
|
|
108
|
+
const mockResponse = {
|
|
109
|
+
choices: [{
|
|
110
|
+
message: {
|
|
111
|
+
content: '**chore(track_object): 불필요한 줄바꿈 제거하여 가독성 개선**'
|
|
112
|
+
}
|
|
113
|
+
}]
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
(mockOpenai.chat.completions.create as jest.Mock).mockResolvedValue(mockResponse);
|
|
117
|
+
|
|
118
|
+
const result = await aiService.generateCommitMessage('diff --git a/file b/file');
|
|
119
|
+
|
|
120
|
+
expect(result).toEqual({
|
|
121
|
+
success: true,
|
|
122
|
+
message: 'chore(track_object): 불필요한 줄바꿈 제거하여 가독성 개선'
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should keep only the first commit header when multiple are returned', async () => {
|
|
127
|
+
const mockResponse = {
|
|
128
|
+
choices: [{
|
|
129
|
+
message: {
|
|
130
|
+
content: 'feat: add payment API\nchore: update dependencies'
|
|
131
|
+
}
|
|
132
|
+
}]
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
(mockOpenai.chat.completions.create as jest.Mock).mockResolvedValue(mockResponse);
|
|
136
|
+
|
|
137
|
+
const result = await aiService.generateCommitMessage('diff --git a/file b/file');
|
|
138
|
+
|
|
139
|
+
expect(result).toEqual({
|
|
140
|
+
success: true,
|
|
141
|
+
message: 'feat: add payment API'
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
107
145
|
it('should use default model when not specified', () => {
|
|
108
146
|
const aiServiceWithDefaults = new AIService({
|
|
109
147
|
apiKey: 'test-api-key'
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { CommitCommand } from '../commands/commit';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { spawn } from 'child_process';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
|
|
7
|
+
// Mock dependencies
|
|
8
|
+
jest.mock('fs');
|
|
9
|
+
jest.mock('child_process', () => ({
|
|
10
|
+
spawn: jest.fn()
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock('../commands/git', () => ({
|
|
14
|
+
GitService: {
|
|
15
|
+
getStagedDiff: jest.fn().mockResolvedValue({ success: true, diff: 'diff' }),
|
|
16
|
+
createCommit: jest.fn().mockResolvedValue(true),
|
|
17
|
+
push: jest.fn().mockResolvedValue(true)
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
jest.mock('../commands/ai', () => ({
|
|
22
|
+
AIService: jest.fn().mockImplementation(() => ({
|
|
23
|
+
generateCommitMessage: jest.fn().mockResolvedValue({ success: true, message: 'test commit' })
|
|
24
|
+
}))
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
jest.mock('../commands/config', () => ({
|
|
28
|
+
ConfigService: {
|
|
29
|
+
getConfig: jest.fn().mockReturnValue({ apiKey: 'key', language: 'en' }),
|
|
30
|
+
validateConfig: jest.fn()
|
|
31
|
+
}
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
jest.mock('../commands/log', () => ({
|
|
35
|
+
LogService: {
|
|
36
|
+
append: jest.fn().mockResolvedValue(undefined)
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
describe('Pre-commit Hook Tests', () => {
|
|
41
|
+
let command: CommitCommand;
|
|
42
|
+
let mockSpawn: jest.Mock;
|
|
43
|
+
let mockFsExists: jest.Mock;
|
|
44
|
+
let mockFsRead: jest.Mock;
|
|
45
|
+
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
jest.clearAllMocks();
|
|
48
|
+
command = new CommitCommand();
|
|
49
|
+
|
|
50
|
+
mockSpawn = spawn as unknown as jest.Mock;
|
|
51
|
+
mockFsExists = fs.existsSync as unknown as jest.Mock;
|
|
52
|
+
mockFsRead = fs.readFileSync as unknown as jest.Mock;
|
|
53
|
+
|
|
54
|
+
// Default: no hooks found
|
|
55
|
+
mockFsExists.mockReturnValue(false);
|
|
56
|
+
|
|
57
|
+
// Default spawn behavior: succeed immediately
|
|
58
|
+
mockSpawn.mockImplementation((cmd, args) => {
|
|
59
|
+
console.log(`Mock spawn called: ${cmd} ${args}`);
|
|
60
|
+
const child = new EventEmitter();
|
|
61
|
+
(child as any).stdout = new EventEmitter();
|
|
62
|
+
(child as any).stderr = new EventEmitter();
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
child.emit('close', 0);
|
|
65
|
+
}, 10);
|
|
66
|
+
return child;
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should run npm pre-commit script if present', async () => {
|
|
71
|
+
mockFsExists.mockImplementation((p: string) => p.endsWith('package.json'));
|
|
72
|
+
mockFsRead.mockReturnValue(JSON.stringify({
|
|
73
|
+
scripts: {
|
|
74
|
+
'pre-commit': 'echo test'
|
|
75
|
+
}
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
jest.spyOn(command as any, 'confirmCommit').mockResolvedValue(true);
|
|
79
|
+
|
|
80
|
+
await (command as any).handleCommit({});
|
|
81
|
+
|
|
82
|
+
expect(mockSpawn).toHaveBeenCalledWith('npm', ['run', 'pre-commit'], expect.anything());
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should run pre-commit hooks if .pre-commit-config.yaml is present', async () => {
|
|
86
|
+
mockFsExists.mockImplementation((p: string) => p.endsWith('.pre-commit-config.yaml'));
|
|
87
|
+
|
|
88
|
+
jest.spyOn(command as any, 'confirmCommit').mockResolvedValue(true);
|
|
89
|
+
|
|
90
|
+
await (command as any).handleCommit({});
|
|
91
|
+
|
|
92
|
+
expect(mockSpawn).toHaveBeenCalledWith('pre-commit', ['run'], expect.anything());
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should fail commit if npm pre-commit script fails', async () => {
|
|
96
|
+
mockFsExists.mockImplementation((p: string) => p.endsWith('package.json'));
|
|
97
|
+
mockFsRead.mockReturnValue(JSON.stringify({
|
|
98
|
+
scripts: { 'pre-commit': 'fail' }
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
mockSpawn.mockImplementation(() => {
|
|
102
|
+
const child = new EventEmitter();
|
|
103
|
+
setTimeout(() => child.emit('close', 1), 10);
|
|
104
|
+
return child;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const exitSpy = jest.spyOn(process, 'exit').mockImplementation((() => {}) as any);
|
|
108
|
+
|
|
109
|
+
await (command as any).handleCommit({});
|
|
110
|
+
|
|
111
|
+
expect(mockSpawn).toHaveBeenCalled();
|
|
112
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should fail commit if pre-commit hooks fail', async () => {
|
|
116
|
+
mockFsExists.mockImplementation((p: string) => p.endsWith('.pre-commit-config.yaml'));
|
|
117
|
+
|
|
118
|
+
mockSpawn.mockImplementation(() => {
|
|
119
|
+
const child = new EventEmitter();
|
|
120
|
+
setTimeout(() => child.emit('close', 1), 10);
|
|
121
|
+
return child;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const exitSpy = jest.spyOn(process, 'exit').mockImplementation((() => {}) as any);
|
|
125
|
+
|
|
126
|
+
await (command as any).handleCommit({});
|
|
127
|
+
|
|
128
|
+
expect(mockSpawn).toHaveBeenCalled();
|
|
129
|
+
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should run both hooks if both exist', async () => {
|
|
133
|
+
mockFsExists.mockReturnValue(true);
|
|
134
|
+
mockFsRead.mockReturnValue(JSON.stringify({
|
|
135
|
+
scripts: { 'pre-commit': 'test' }
|
|
136
|
+
}));
|
|
137
|
+
|
|
138
|
+
jest.spyOn(command as any, 'confirmCommit').mockResolvedValue(true);
|
|
139
|
+
|
|
140
|
+
await (command as any).handleCommit({});
|
|
141
|
+
|
|
142
|
+
expect(mockSpawn).toHaveBeenCalledTimes(2);
|
|
143
|
+
expect(mockSpawn).toHaveBeenCalledWith('npm', ['run', 'pre-commit'], expect.anything());
|
|
144
|
+
expect(mockSpawn).toHaveBeenCalledWith('pre-commit', ['run'], expect.anything());
|
|
145
|
+
});
|
|
146
|
+
});
|
package/src/commands/ai.ts
CHANGED
|
@@ -72,6 +72,11 @@ export class AIService {
|
|
|
72
72
|
// Remove any remaining XML/HTML-like tags
|
|
73
73
|
cleaned = cleaned.replace(/<[^>]+>/g, '');
|
|
74
74
|
|
|
75
|
+
// Strip common Markdown emphasis so headers remain plain text
|
|
76
|
+
cleaned = cleaned.replace(/\*\*(.*?)\*\*/g, '$1');
|
|
77
|
+
cleaned = cleaned.replace(/__(.*?)__/g, '$1');
|
|
78
|
+
cleaned = cleaned.replace(/`([^`]+)`/g, '$1');
|
|
79
|
+
|
|
75
80
|
// Normalize whitespace
|
|
76
81
|
cleaned = cleaned.replace(/[\t\r]+/g, '');
|
|
77
82
|
cleaned = cleaned.replace(/\n{3,}/g, '\n\n').trim();
|
|
@@ -217,6 +222,14 @@ export class AIService {
|
|
|
217
222
|
}
|
|
218
223
|
}
|
|
219
224
|
|
|
225
|
+
// Drop additional commit headers to enforce a single conventional commit
|
|
226
|
+
if (lines.length > 0) {
|
|
227
|
+
const nextHeaderIdx = lines.slice(1).findIndex(l => headerPattern.test(l));
|
|
228
|
+
if (nextHeaderIdx >= 0) {
|
|
229
|
+
lines = lines.slice(0, nextHeaderIdx + 1);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
220
233
|
finalMessage = lines.join('\n').trim();
|
|
221
234
|
|
|
222
235
|
return {
|
package/src/commands/commit.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { Command } from
|
|
2
|
-
import readline from
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import readline from "readline";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { spawn } from "child_process";
|
|
6
|
+
import { GitService, GitDiffResult } from "./git";
|
|
7
|
+
import { AIService, AIServiceConfig } from "./ai";
|
|
8
|
+
import { ConfigService } from "./config";
|
|
9
|
+
import { LogService } from "./log";
|
|
7
10
|
|
|
8
11
|
export interface CommitOptions {
|
|
9
12
|
apiKey?: string;
|
|
@@ -18,24 +21,117 @@ export class CommitCommand {
|
|
|
18
21
|
private program: Command;
|
|
19
22
|
|
|
20
23
|
constructor() {
|
|
21
|
-
this.program = new Command(
|
|
22
|
-
.description(
|
|
23
|
-
.option(
|
|
24
|
-
.option(
|
|
25
|
-
.option(
|
|
26
|
-
.option(
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
this.program = new Command("commit")
|
|
25
|
+
.description("Generate AI-powered commit message")
|
|
26
|
+
.option("-k, --api-key <key>", "OpenAI API key (overrides env var)")
|
|
27
|
+
.option("-b, --base-url <url>", "Custom API base URL (overrides env var)")
|
|
28
|
+
.option("--model <model>", "Model to use (overrides env var)")
|
|
29
|
+
.option(
|
|
30
|
+
"-m, --message-only",
|
|
31
|
+
"Output only the generated commit message and skip git actions"
|
|
32
|
+
)
|
|
33
|
+
.option(
|
|
34
|
+
"-p, --push",
|
|
35
|
+
"Push current branch after creating the commit (implies --commit)"
|
|
36
|
+
)
|
|
37
|
+
.option(
|
|
38
|
+
"--prompt <text>",
|
|
39
|
+
"Additional instructions to append to the AI prompt for this commit"
|
|
40
|
+
)
|
|
29
41
|
.action(this.handleCommit.bind(this));
|
|
30
42
|
}
|
|
31
43
|
|
|
44
|
+
private async runPreCommitHook(): Promise<void> {
|
|
45
|
+
// 1. Check for npm pre-commit script
|
|
46
|
+
const packageJsonPath = path.resolve(process.cwd(), "package.json");
|
|
47
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
48
|
+
try {
|
|
49
|
+
const raw = fs.readFileSync(packageJsonPath, "utf-8");
|
|
50
|
+
const pkg = JSON.parse(raw);
|
|
51
|
+
|
|
52
|
+
if (pkg.scripts && pkg.scripts["pre-commit"]) {
|
|
53
|
+
console.log("Running npm pre-commit script...");
|
|
54
|
+
|
|
55
|
+
await new Promise<void>((resolve, reject) => {
|
|
56
|
+
const child = spawn("npm", ["run", "pre-commit"], {
|
|
57
|
+
stdio: "inherit",
|
|
58
|
+
shell: true,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
child.on("close", (code) => {
|
|
62
|
+
if (code === 0) {
|
|
63
|
+
console.log("✅ npm pre-commit script passed");
|
|
64
|
+
resolve();
|
|
65
|
+
} else {
|
|
66
|
+
console.error(`❌ npm pre-commit script failed with code ${code}`);
|
|
67
|
+
reject(new Error(`npm pre-commit script failed with code ${code}`));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
child.on("error", (err) => {
|
|
72
|
+
reject(err);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (!(error instanceof SyntaxError)) {
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 2. Check for .pre-commit-config.yaml (Python/General pre-commit)
|
|
84
|
+
const preCommitConfigPath = path.resolve(process.cwd(), ".pre-commit-config.yaml");
|
|
85
|
+
if (fs.existsSync(preCommitConfigPath)) {
|
|
86
|
+
console.log("Found .pre-commit-config.yaml, running pre-commit hooks...");
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
await new Promise<void>((resolve, reject) => {
|
|
90
|
+
const child = spawn("pre-commit", ["run"], {
|
|
91
|
+
stdio: "inherit",
|
|
92
|
+
shell: true,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
child.on("close", (code) => {
|
|
96
|
+
if (code === 0) {
|
|
97
|
+
console.log("✅ pre-commit hooks passed");
|
|
98
|
+
resolve();
|
|
99
|
+
} else {
|
|
100
|
+
console.error(`❌ pre-commit hooks failed with code ${code}`);
|
|
101
|
+
reject(new Error(`pre-commit hooks failed with code ${code}`));
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
child.on("error", (err) => {
|
|
106
|
+
// If pre-commit is not installed/found, we might want to warn instead of fail?
|
|
107
|
+
// But usually 'error' event on spawn (with shell:true) is rare for command not found (it usually exits with 127).
|
|
108
|
+
// However, if it fails to spawn, we reject.
|
|
109
|
+
reject(err);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
} catch (error) {
|
|
113
|
+
// If the error suggests command not found, we might warn.
|
|
114
|
+
// But since we use shell:true, 'command not found' usually results in exit code 127, which goes to 'close' event.
|
|
115
|
+
// So we catch the error from the promise rejection above.
|
|
116
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
117
|
+
if (msg.includes("code 127") || msg.includes("ENOENT")) {
|
|
118
|
+
console.warn("⚠️ 'pre-commit' command not found, skipping hooks despite configuration file presence.");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
32
126
|
private async handleCommit(options: CommitOptions) {
|
|
33
127
|
const start = Date.now();
|
|
34
128
|
const safeArgs = {
|
|
35
129
|
...options,
|
|
36
|
-
apiKey: options.apiKey ?
|
|
130
|
+
apiKey: options.apiKey ? "***" : undefined,
|
|
37
131
|
} as Record<string, unknown>;
|
|
38
132
|
try {
|
|
133
|
+
await this.runPreCommitHook();
|
|
134
|
+
|
|
39
135
|
const existingConfig = ConfigService.getConfig();
|
|
40
136
|
|
|
41
137
|
const mergedApiKey = options.apiKey || existingConfig.apiKey;
|
|
@@ -51,7 +147,7 @@ export class CommitCommand {
|
|
|
51
147
|
|
|
52
148
|
ConfigService.validateConfig({
|
|
53
149
|
apiKey: mergedApiKey,
|
|
54
|
-
language: existingConfig.language
|
|
150
|
+
language: existingConfig.language,
|
|
55
151
|
});
|
|
56
152
|
|
|
57
153
|
const aiConfig: AIServiceConfig = {
|
|
@@ -59,81 +155,84 @@ export class CommitCommand {
|
|
|
59
155
|
baseURL: mergedBaseURL,
|
|
60
156
|
model: mergedModel,
|
|
61
157
|
language: existingConfig.language,
|
|
62
|
-
verbose: !messageOnly
|
|
158
|
+
verbose: !messageOnly,
|
|
63
159
|
};
|
|
64
160
|
|
|
65
|
-
log(
|
|
66
|
-
|
|
161
|
+
log("Getting staged changes...");
|
|
162
|
+
|
|
67
163
|
const diffResult: GitDiffResult = await GitService.getStagedDiff();
|
|
68
|
-
|
|
164
|
+
|
|
69
165
|
if (!diffResult.success) {
|
|
70
|
-
console.error(
|
|
166
|
+
console.error("Error:", diffResult.error);
|
|
71
167
|
await LogService.append({
|
|
72
|
-
command:
|
|
168
|
+
command: "commit",
|
|
73
169
|
args: safeArgs,
|
|
74
|
-
status:
|
|
170
|
+
status: "failure",
|
|
75
171
|
details: diffResult.error,
|
|
76
|
-
durationMs: Date.now() - start
|
|
172
|
+
durationMs: Date.now() - start,
|
|
77
173
|
});
|
|
78
174
|
process.exit(1);
|
|
79
175
|
}
|
|
80
176
|
|
|
81
|
-
log(
|
|
82
|
-
|
|
177
|
+
log("Generating commit message...");
|
|
178
|
+
|
|
83
179
|
const aiService = new AIService(aiConfig);
|
|
84
|
-
const aiResult = await aiService.generateCommitMessage(
|
|
180
|
+
const aiResult = await aiService.generateCommitMessage(
|
|
181
|
+
diffResult.diff!,
|
|
182
|
+
options.prompt
|
|
183
|
+
);
|
|
85
184
|
|
|
86
185
|
if (!aiResult.success) {
|
|
87
|
-
console.error(
|
|
186
|
+
console.error("Error:", aiResult.error);
|
|
88
187
|
await LogService.append({
|
|
89
|
-
command:
|
|
188
|
+
command: "commit",
|
|
90
189
|
args: safeArgs,
|
|
91
|
-
status:
|
|
190
|
+
status: "failure",
|
|
92
191
|
details: aiResult.error,
|
|
93
|
-
durationMs: Date.now() - start
|
|
192
|
+
durationMs: Date.now() - start,
|
|
94
193
|
});
|
|
95
194
|
process.exit(1);
|
|
96
195
|
}
|
|
97
196
|
|
|
98
|
-
if (typeof aiResult.message !==
|
|
99
|
-
console.error(
|
|
197
|
+
if (typeof aiResult.message !== "string") {
|
|
198
|
+
console.error("Error: Failed to generate commit message");
|
|
100
199
|
process.exit(1);
|
|
101
200
|
}
|
|
102
201
|
|
|
103
202
|
if (messageOnly) {
|
|
104
203
|
console.log(aiResult.message);
|
|
105
204
|
await LogService.append({
|
|
106
|
-
command:
|
|
205
|
+
command: "commit",
|
|
107
206
|
args: { ...safeArgs, messageOnly: true },
|
|
108
|
-
status:
|
|
109
|
-
details:
|
|
110
|
-
durationMs: Date.now() - start
|
|
207
|
+
status: "success",
|
|
208
|
+
details: "message-only output",
|
|
209
|
+
durationMs: Date.now() - start,
|
|
111
210
|
});
|
|
112
211
|
return;
|
|
113
212
|
}
|
|
114
213
|
|
|
115
|
-
console.log(
|
|
214
|
+
console.log("\nGenerated commit message:");
|
|
116
215
|
console.log(aiResult.message);
|
|
117
216
|
|
|
118
217
|
const confirmed = await this.confirmCommit();
|
|
119
218
|
|
|
120
219
|
if (!confirmed) {
|
|
121
|
-
console.log(
|
|
220
|
+
console.log("Commit cancelled by user.");
|
|
122
221
|
await LogService.append({
|
|
123
|
-
command:
|
|
222
|
+
command: "commit",
|
|
124
223
|
args: safeArgs,
|
|
125
|
-
status:
|
|
126
|
-
details:
|
|
127
|
-
durationMs: Date.now() - start
|
|
224
|
+
status: "cancelled",
|
|
225
|
+
details: "user declined commit",
|
|
226
|
+
durationMs: Date.now() - start,
|
|
128
227
|
});
|
|
129
228
|
return;
|
|
130
229
|
}
|
|
131
230
|
|
|
132
|
-
console.log(
|
|
231
|
+
console.log("\nCreating commit...");
|
|
133
232
|
const commitSuccess = await GitService.createCommit(aiResult.message!);
|
|
134
233
|
|
|
135
234
|
if (commitSuccess) {
|
|
136
|
-
console.log(
|
|
235
|
+
console.log("✅ Commit created successfully!");
|
|
137
236
|
|
|
138
237
|
const pushRequested = Boolean(options.push);
|
|
139
238
|
const pushFromConfig = !pushRequested && existingConfig.autoPush;
|
|
@@ -141,53 +240,53 @@ export class CommitCommand {
|
|
|
141
240
|
|
|
142
241
|
if (shouldPush) {
|
|
143
242
|
if (pushFromConfig) {
|
|
144
|
-
console.log(
|
|
243
|
+
console.log("Auto push enabled in config; pushing to remote...");
|
|
145
244
|
} else {
|
|
146
|
-
console.log(
|
|
245
|
+
console.log("Pushing to remote...");
|
|
147
246
|
}
|
|
148
247
|
|
|
149
248
|
const pushSuccess = await GitService.push();
|
|
150
249
|
|
|
151
250
|
if (pushSuccess) {
|
|
152
|
-
console.log(
|
|
251
|
+
console.log("✅ Push completed successfully!");
|
|
153
252
|
} else {
|
|
154
|
-
console.error(
|
|
253
|
+
console.error("❌ Failed to push to remote");
|
|
155
254
|
await LogService.append({
|
|
156
|
-
command:
|
|
255
|
+
command: "commit",
|
|
157
256
|
args: { ...safeArgs, push: true },
|
|
158
|
-
status:
|
|
159
|
-
details:
|
|
160
|
-
durationMs: Date.now() - start
|
|
257
|
+
status: "failure",
|
|
258
|
+
details: "push failed",
|
|
259
|
+
durationMs: Date.now() - start,
|
|
161
260
|
});
|
|
162
261
|
process.exit(1);
|
|
163
262
|
}
|
|
164
263
|
}
|
|
165
264
|
} else {
|
|
166
|
-
console.error(
|
|
265
|
+
console.error("❌ Failed to create commit");
|
|
167
266
|
await LogService.append({
|
|
168
|
-
command:
|
|
267
|
+
command: "commit",
|
|
169
268
|
args: safeArgs,
|
|
170
|
-
status:
|
|
171
|
-
details:
|
|
172
|
-
durationMs: Date.now() - start
|
|
269
|
+
status: "failure",
|
|
270
|
+
details: "git commit failed",
|
|
271
|
+
durationMs: Date.now() - start,
|
|
173
272
|
});
|
|
174
273
|
process.exit(1);
|
|
175
274
|
}
|
|
176
275
|
await LogService.append({
|
|
177
|
-
command:
|
|
276
|
+
command: "commit",
|
|
178
277
|
args: safeArgs,
|
|
179
|
-
status:
|
|
180
|
-
durationMs: Date.now() - start
|
|
278
|
+
status: "success",
|
|
279
|
+
durationMs: Date.now() - start,
|
|
181
280
|
});
|
|
182
281
|
} catch (error) {
|
|
183
282
|
const message = error instanceof Error ? error.message : String(error);
|
|
184
|
-
console.error(
|
|
283
|
+
console.error("Error:", message);
|
|
185
284
|
await LogService.append({
|
|
186
|
-
command:
|
|
285
|
+
command: "commit",
|
|
187
286
|
args: safeArgs,
|
|
188
|
-
status:
|
|
287
|
+
status: "failure",
|
|
189
288
|
details: message,
|
|
190
|
-
durationMs: Date.now() - start
|
|
289
|
+
durationMs: Date.now() - start,
|
|
191
290
|
});
|
|
192
291
|
process.exit(1);
|
|
193
292
|
}
|
|
@@ -196,17 +295,17 @@ export class CommitCommand {
|
|
|
196
295
|
private async confirmCommit(): Promise<boolean> {
|
|
197
296
|
const rl = readline.createInterface({
|
|
198
297
|
input: process.stdin,
|
|
199
|
-
output: process.stdout
|
|
298
|
+
output: process.stdout,
|
|
200
299
|
});
|
|
201
300
|
|
|
202
|
-
const answer: string = await new Promise(resolve => {
|
|
203
|
-
rl.question(
|
|
301
|
+
const answer: string = await new Promise((resolve) => {
|
|
302
|
+
rl.question("Proceed with git commit? (y/n): ", resolve);
|
|
204
303
|
});
|
|
205
304
|
|
|
206
305
|
rl.close();
|
|
207
306
|
|
|
208
307
|
const normalized = answer.trim().toLowerCase();
|
|
209
|
-
return normalized ===
|
|
308
|
+
return normalized === "y" || normalized === "yes";
|
|
210
309
|
}
|
|
211
310
|
|
|
212
311
|
getCommand(): Command {
|
package/src/prompts/commit.ts
CHANGED
|
@@ -46,7 +46,9 @@ ${customInstructions}
|
|
|
46
46
|
## CRITICAL: Commit Message Output Rules
|
|
47
47
|
- DO NOT include any memory bank status indicators like "[Memory Bank: Active]" or "[Memory Bank: Missing]"
|
|
48
48
|
- DO NOT include any task-specific formatting or artifacts from other rules
|
|
49
|
+
- DO NOT use any Markdown styling (no **bold**, __underline__, \`code\`, links, or emojis) in the commit header, body, or footer
|
|
49
50
|
- ONLY Generate a clean conventional commit message as specified below
|
|
51
|
+
- Output exactly ONE conventional commit message. Choose a single primary type; never return multiple headers or multiple type prefixes.
|
|
50
52
|
|
|
51
53
|
${gitContext}
|
|
52
54
|
|
|
@@ -92,7 +94,7 @@ ${footerGuidelines}
|
|
|
92
94
|
|
|
93
95
|
## Analysis Instructions
|
|
94
96
|
When analyzing staged changes:
|
|
95
|
-
1. Determine Primary Type based on the nature of changes
|
|
97
|
+
1. Determine a single Primary Type based on the dominant nature of the changes (if multiple types apply, pick the most impactful one and stick to it)
|
|
96
98
|
2. Identify Scope from modified directories or modules
|
|
97
99
|
3. Craft Description focusing on the most significant change
|
|
98
100
|
4. Determine if there are Breaking Changes
|