@ksw8954/git-ai-commit 1.0.6 → 1.0.8
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 +3 -1
- package/dist/commands/commit.d.ts.map +1 -1
- package/dist/commands/commit.js +143 -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 +175 -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;
|
|
@@ -6,10 +6,12 @@ export interface CommitOptions {
|
|
|
6
6
|
push?: boolean;
|
|
7
7
|
messageOnly?: boolean;
|
|
8
8
|
prompt?: string;
|
|
9
|
+
noVerify?: boolean;
|
|
9
10
|
}
|
|
10
11
|
export declare class CommitCommand {
|
|
11
12
|
private program;
|
|
12
13
|
constructor();
|
|
14
|
+
private runPreCommitHook;
|
|
13
15
|
private handleCommit;
|
|
14
16
|
private confirmCommit;
|
|
15
17
|
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;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAU;;YA2BX,gBAAgB;YAkFhB,YAAY;YA2KZ,aAAa;IAgB3B,UAAU,IAAI,OAAO;CAGtB"}
|
package/dist/commands/commit.js
CHANGED
|
@@ -6,29 +6,113 @@ 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")
|
|
26
|
+
.option("--no-verify", "Skip pre-commit hooks")
|
|
23
27
|
.action(this.handleCommit.bind(this));
|
|
24
28
|
}
|
|
29
|
+
async runPreCommitHook() {
|
|
30
|
+
// 1. Check for npm pre-commit script
|
|
31
|
+
const packageJsonPath = path_1.default.resolve(process.cwd(), "package.json");
|
|
32
|
+
if (fs_1.default.existsSync(packageJsonPath)) {
|
|
33
|
+
try {
|
|
34
|
+
const raw = fs_1.default.readFileSync(packageJsonPath, "utf-8");
|
|
35
|
+
const pkg = JSON.parse(raw);
|
|
36
|
+
if (pkg.scripts && pkg.scripts["pre-commit"]) {
|
|
37
|
+
console.log("Running npm pre-commit script...");
|
|
38
|
+
await new Promise((resolve, reject) => {
|
|
39
|
+
const child = (0, child_process_1.spawn)("npm", ["run", "pre-commit"], {
|
|
40
|
+
stdio: "inherit",
|
|
41
|
+
shell: true,
|
|
42
|
+
});
|
|
43
|
+
child.on("close", (code) => {
|
|
44
|
+
if (code === 0) {
|
|
45
|
+
console.log("✅ npm pre-commit script passed");
|
|
46
|
+
resolve();
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.error(`❌ npm pre-commit script failed with code ${code}`);
|
|
50
|
+
reject(new Error(`npm pre-commit script failed with code ${code}`));
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
child.on("error", (err) => {
|
|
54
|
+
reject(err);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (!(error instanceof SyntaxError)) {
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// 2. Check for .pre-commit-config.yaml (Python/General pre-commit)
|
|
66
|
+
const preCommitConfigPath = path_1.default.resolve(process.cwd(), ".pre-commit-config.yaml");
|
|
67
|
+
if (fs_1.default.existsSync(preCommitConfigPath)) {
|
|
68
|
+
console.log("Found .pre-commit-config.yaml, running pre-commit hooks...");
|
|
69
|
+
try {
|
|
70
|
+
await new Promise((resolve, reject) => {
|
|
71
|
+
const child = (0, child_process_1.spawn)("pre-commit", ["run"], {
|
|
72
|
+
stdio: "inherit",
|
|
73
|
+
shell: true,
|
|
74
|
+
});
|
|
75
|
+
child.on("close", (code) => {
|
|
76
|
+
if (code === 0) {
|
|
77
|
+
console.log("✅ pre-commit hooks passed");
|
|
78
|
+
resolve();
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.error(`❌ pre-commit hooks failed with code ${code}`);
|
|
82
|
+
reject(new Error(`pre-commit hooks failed with code ${code}`));
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
child.on("error", (err) => {
|
|
86
|
+
// If pre-commit is not installed/found, we might want to warn instead of fail?
|
|
87
|
+
// But usually 'error' event on spawn (with shell:true) is rare for command not found (it usually exits with 127).
|
|
88
|
+
// However, if it fails to spawn, we reject.
|
|
89
|
+
reject(err);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// If the error suggests command not found, we might warn.
|
|
95
|
+
// But since we use shell:true, 'command not found' usually results in exit code 127, which goes to 'close' event.
|
|
96
|
+
// So we catch the error from the promise rejection above.
|
|
97
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
98
|
+
if (msg.includes("code 127") || msg.includes("ENOENT")) {
|
|
99
|
+
console.warn("⚠️ 'pre-commit' command not found, skipping hooks despite configuration file presence.");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
25
106
|
async handleCommit(options) {
|
|
26
107
|
const start = Date.now();
|
|
27
108
|
const safeArgs = {
|
|
28
109
|
...options,
|
|
29
|
-
apiKey: options.apiKey ?
|
|
110
|
+
apiKey: options.apiKey ? "***" : undefined,
|
|
30
111
|
};
|
|
31
112
|
try {
|
|
113
|
+
if (!options.noVerify) {
|
|
114
|
+
await this.runPreCommitHook();
|
|
115
|
+
}
|
|
32
116
|
const existingConfig = config_1.ConfigService.getConfig();
|
|
33
117
|
const mergedApiKey = options.apiKey || existingConfig.apiKey;
|
|
34
118
|
const mergedBaseURL = options.baseURL || existingConfig.baseURL;
|
|
@@ -41,129 +125,129 @@ class CommitCommand {
|
|
|
41
125
|
};
|
|
42
126
|
config_1.ConfigService.validateConfig({
|
|
43
127
|
apiKey: mergedApiKey,
|
|
44
|
-
language: existingConfig.language
|
|
128
|
+
language: existingConfig.language,
|
|
45
129
|
});
|
|
46
130
|
const aiConfig = {
|
|
47
131
|
apiKey: mergedApiKey,
|
|
48
132
|
baseURL: mergedBaseURL,
|
|
49
133
|
model: mergedModel,
|
|
50
134
|
language: existingConfig.language,
|
|
51
|
-
verbose: !messageOnly
|
|
135
|
+
verbose: !messageOnly,
|
|
52
136
|
};
|
|
53
|
-
log(
|
|
137
|
+
log("Getting staged changes...");
|
|
54
138
|
const diffResult = await git_1.GitService.getStagedDiff();
|
|
55
139
|
if (!diffResult.success) {
|
|
56
|
-
console.error(
|
|
140
|
+
console.error("Error:", diffResult.error);
|
|
57
141
|
await log_1.LogService.append({
|
|
58
|
-
command:
|
|
142
|
+
command: "commit",
|
|
59
143
|
args: safeArgs,
|
|
60
|
-
status:
|
|
144
|
+
status: "failure",
|
|
61
145
|
details: diffResult.error,
|
|
62
|
-
durationMs: Date.now() - start
|
|
146
|
+
durationMs: Date.now() - start,
|
|
63
147
|
});
|
|
64
148
|
process.exit(1);
|
|
65
149
|
}
|
|
66
|
-
log(
|
|
150
|
+
log("Generating commit message...");
|
|
67
151
|
const aiService = new ai_1.AIService(aiConfig);
|
|
68
152
|
const aiResult = await aiService.generateCommitMessage(diffResult.diff, options.prompt);
|
|
69
153
|
if (!aiResult.success) {
|
|
70
|
-
console.error(
|
|
154
|
+
console.error("Error:", aiResult.error);
|
|
71
155
|
await log_1.LogService.append({
|
|
72
|
-
command:
|
|
156
|
+
command: "commit",
|
|
73
157
|
args: safeArgs,
|
|
74
|
-
status:
|
|
158
|
+
status: "failure",
|
|
75
159
|
details: aiResult.error,
|
|
76
|
-
durationMs: Date.now() - start
|
|
160
|
+
durationMs: Date.now() - start,
|
|
77
161
|
});
|
|
78
162
|
process.exit(1);
|
|
79
163
|
}
|
|
80
|
-
if (typeof aiResult.message !==
|
|
81
|
-
console.error(
|
|
164
|
+
if (typeof aiResult.message !== "string") {
|
|
165
|
+
console.error("Error: Failed to generate commit message");
|
|
82
166
|
process.exit(1);
|
|
83
167
|
}
|
|
84
168
|
if (messageOnly) {
|
|
85
169
|
console.log(aiResult.message);
|
|
86
170
|
await log_1.LogService.append({
|
|
87
|
-
command:
|
|
171
|
+
command: "commit",
|
|
88
172
|
args: { ...safeArgs, messageOnly: true },
|
|
89
|
-
status:
|
|
90
|
-
details:
|
|
91
|
-
durationMs: Date.now() - start
|
|
173
|
+
status: "success",
|
|
174
|
+
details: "message-only output",
|
|
175
|
+
durationMs: Date.now() - start,
|
|
92
176
|
});
|
|
93
177
|
return;
|
|
94
178
|
}
|
|
95
|
-
console.log(
|
|
179
|
+
console.log("\nGenerated commit message:");
|
|
96
180
|
console.log(aiResult.message);
|
|
97
181
|
const confirmed = await this.confirmCommit();
|
|
98
182
|
if (!confirmed) {
|
|
99
|
-
console.log(
|
|
183
|
+
console.log("Commit cancelled by user.");
|
|
100
184
|
await log_1.LogService.append({
|
|
101
|
-
command:
|
|
185
|
+
command: "commit",
|
|
102
186
|
args: safeArgs,
|
|
103
|
-
status:
|
|
104
|
-
details:
|
|
105
|
-
durationMs: Date.now() - start
|
|
187
|
+
status: "cancelled",
|
|
188
|
+
details: "user declined commit",
|
|
189
|
+
durationMs: Date.now() - start,
|
|
106
190
|
});
|
|
107
191
|
return;
|
|
108
192
|
}
|
|
109
|
-
console.log(
|
|
193
|
+
console.log("\nCreating commit...");
|
|
110
194
|
const commitSuccess = await git_1.GitService.createCommit(aiResult.message);
|
|
111
195
|
if (commitSuccess) {
|
|
112
|
-
console.log(
|
|
196
|
+
console.log("✅ Commit created successfully!");
|
|
113
197
|
const pushRequested = Boolean(options.push);
|
|
114
198
|
const pushFromConfig = !pushRequested && existingConfig.autoPush;
|
|
115
199
|
const shouldPush = pushRequested || pushFromConfig;
|
|
116
200
|
if (shouldPush) {
|
|
117
201
|
if (pushFromConfig) {
|
|
118
|
-
console.log(
|
|
202
|
+
console.log("Auto push enabled in config; pushing to remote...");
|
|
119
203
|
}
|
|
120
204
|
else {
|
|
121
|
-
console.log(
|
|
205
|
+
console.log("Pushing to remote...");
|
|
122
206
|
}
|
|
123
207
|
const pushSuccess = await git_1.GitService.push();
|
|
124
208
|
if (pushSuccess) {
|
|
125
|
-
console.log(
|
|
209
|
+
console.log("✅ Push completed successfully!");
|
|
126
210
|
}
|
|
127
211
|
else {
|
|
128
|
-
console.error(
|
|
212
|
+
console.error("❌ Failed to push to remote");
|
|
129
213
|
await log_1.LogService.append({
|
|
130
|
-
command:
|
|
214
|
+
command: "commit",
|
|
131
215
|
args: { ...safeArgs, push: true },
|
|
132
|
-
status:
|
|
133
|
-
details:
|
|
134
|
-
durationMs: Date.now() - start
|
|
216
|
+
status: "failure",
|
|
217
|
+
details: "push failed",
|
|
218
|
+
durationMs: Date.now() - start,
|
|
135
219
|
});
|
|
136
220
|
process.exit(1);
|
|
137
221
|
}
|
|
138
222
|
}
|
|
139
223
|
}
|
|
140
224
|
else {
|
|
141
|
-
console.error(
|
|
225
|
+
console.error("❌ Failed to create commit");
|
|
142
226
|
await log_1.LogService.append({
|
|
143
|
-
command:
|
|
227
|
+
command: "commit",
|
|
144
228
|
args: safeArgs,
|
|
145
|
-
status:
|
|
146
|
-
details:
|
|
147
|
-
durationMs: Date.now() - start
|
|
229
|
+
status: "failure",
|
|
230
|
+
details: "git commit failed",
|
|
231
|
+
durationMs: Date.now() - start,
|
|
148
232
|
});
|
|
149
233
|
process.exit(1);
|
|
150
234
|
}
|
|
151
235
|
await log_1.LogService.append({
|
|
152
|
-
command:
|
|
236
|
+
command: "commit",
|
|
153
237
|
args: safeArgs,
|
|
154
|
-
status:
|
|
155
|
-
durationMs: Date.now() - start
|
|
238
|
+
status: "success",
|
|
239
|
+
durationMs: Date.now() - start,
|
|
156
240
|
});
|
|
157
241
|
}
|
|
158
242
|
catch (error) {
|
|
159
243
|
const message = error instanceof Error ? error.message : String(error);
|
|
160
|
-
console.error(
|
|
244
|
+
console.error("Error:", message);
|
|
161
245
|
await log_1.LogService.append({
|
|
162
|
-
command:
|
|
246
|
+
command: "commit",
|
|
163
247
|
args: safeArgs,
|
|
164
|
-
status:
|
|
248
|
+
status: "failure",
|
|
165
249
|
details: message,
|
|
166
|
-
durationMs: Date.now() - start
|
|
250
|
+
durationMs: Date.now() - start,
|
|
167
251
|
});
|
|
168
252
|
process.exit(1);
|
|
169
253
|
}
|
|
@@ -171,14 +255,14 @@ class CommitCommand {
|
|
|
171
255
|
async confirmCommit() {
|
|
172
256
|
const rl = readline_1.default.createInterface({
|
|
173
257
|
input: process.stdin,
|
|
174
|
-
output: process.stdout
|
|
258
|
+
output: process.stdout,
|
|
175
259
|
});
|
|
176
|
-
const answer = await new Promise(resolve => {
|
|
177
|
-
rl.question(
|
|
260
|
+
const answer = await new Promise((resolve) => {
|
|
261
|
+
rl.question("Proceed with git commit? (y/n): ", resolve);
|
|
178
262
|
});
|
|
179
263
|
rl.close();
|
|
180
264
|
const normalized = answer.trim().toLowerCase();
|
|
181
|
-
return normalized ===
|
|
265
|
+
return normalized === "y" || normalized === "yes";
|
|
182
266
|
}
|
|
183
267
|
getCommand() {
|
|
184
268
|
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;
|
|
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;
|
|
@@ -12,30 +15,130 @@ export interface CommitOptions {
|
|
|
12
15
|
push?: boolean;
|
|
13
16
|
messageOnly?: boolean;
|
|
14
17
|
prompt?: string;
|
|
18
|
+
noVerify?: boolean;
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
export class CommitCommand {
|
|
18
22
|
private program: Command;
|
|
19
23
|
|
|
20
24
|
constructor() {
|
|
21
|
-
this.program = new Command(
|
|
22
|
-
.description(
|
|
23
|
-
.option(
|
|
24
|
-
.option(
|
|
25
|
-
.option(
|
|
26
|
-
.option(
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
this.program = new Command("commit")
|
|
26
|
+
.description("Generate AI-powered commit message")
|
|
27
|
+
.option("-k, --api-key <key>", "OpenAI API key (overrides env var)")
|
|
28
|
+
.option("-b, --base-url <url>", "Custom API base URL (overrides env var)")
|
|
29
|
+
.option("--model <model>", "Model to use (overrides env var)")
|
|
30
|
+
.option(
|
|
31
|
+
"-m, --message-only",
|
|
32
|
+
"Output only the generated commit message and skip git actions"
|
|
33
|
+
)
|
|
34
|
+
.option(
|
|
35
|
+
"-p, --push",
|
|
36
|
+
"Push current branch after creating the commit (implies --commit)"
|
|
37
|
+
)
|
|
38
|
+
.option(
|
|
39
|
+
"--prompt <text>",
|
|
40
|
+
"Additional instructions to append to the AI prompt for this commit"
|
|
41
|
+
)
|
|
42
|
+
.option(
|
|
43
|
+
"--no-verify",
|
|
44
|
+
"Skip pre-commit hooks"
|
|
45
|
+
)
|
|
29
46
|
.action(this.handleCommit.bind(this));
|
|
30
47
|
}
|
|
31
48
|
|
|
49
|
+
private async runPreCommitHook(): Promise<void> {
|
|
50
|
+
// 1. Check for npm pre-commit script
|
|
51
|
+
const packageJsonPath = path.resolve(process.cwd(), "package.json");
|
|
52
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
53
|
+
try {
|
|
54
|
+
const raw = fs.readFileSync(packageJsonPath, "utf-8");
|
|
55
|
+
const pkg = JSON.parse(raw);
|
|
56
|
+
|
|
57
|
+
if (pkg.scripts && pkg.scripts["pre-commit"]) {
|
|
58
|
+
console.log("Running npm pre-commit script...");
|
|
59
|
+
|
|
60
|
+
await new Promise<void>((resolve, reject) => {
|
|
61
|
+
const child = spawn("npm", ["run", "pre-commit"], {
|
|
62
|
+
stdio: "inherit",
|
|
63
|
+
shell: true,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
child.on("close", (code) => {
|
|
67
|
+
if (code === 0) {
|
|
68
|
+
console.log("✅ npm pre-commit script passed");
|
|
69
|
+
resolve();
|
|
70
|
+
} else {
|
|
71
|
+
console.error(`❌ npm pre-commit script failed with code ${code}`);
|
|
72
|
+
reject(new Error(`npm pre-commit script failed with code ${code}`));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
child.on("error", (err) => {
|
|
77
|
+
reject(err);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (!(error instanceof SyntaxError)) {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 2. Check for .pre-commit-config.yaml (Python/General pre-commit)
|
|
89
|
+
const preCommitConfigPath = path.resolve(process.cwd(), ".pre-commit-config.yaml");
|
|
90
|
+
if (fs.existsSync(preCommitConfigPath)) {
|
|
91
|
+
console.log("Found .pre-commit-config.yaml, running pre-commit hooks...");
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
await new Promise<void>((resolve, reject) => {
|
|
95
|
+
const child = spawn("pre-commit", ["run"], {
|
|
96
|
+
stdio: "inherit",
|
|
97
|
+
shell: true,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
child.on("close", (code) => {
|
|
101
|
+
if (code === 0) {
|
|
102
|
+
console.log("✅ pre-commit hooks passed");
|
|
103
|
+
resolve();
|
|
104
|
+
} else {
|
|
105
|
+
console.error(`❌ pre-commit hooks failed with code ${code}`);
|
|
106
|
+
reject(new Error(`pre-commit hooks failed with code ${code}`));
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
child.on("error", (err) => {
|
|
111
|
+
// If pre-commit is not installed/found, we might want to warn instead of fail?
|
|
112
|
+
// But usually 'error' event on spawn (with shell:true) is rare for command not found (it usually exits with 127).
|
|
113
|
+
// However, if it fails to spawn, we reject.
|
|
114
|
+
reject(err);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
} catch (error) {
|
|
118
|
+
// If the error suggests command not found, we might warn.
|
|
119
|
+
// But since we use shell:true, 'command not found' usually results in exit code 127, which goes to 'close' event.
|
|
120
|
+
// So we catch the error from the promise rejection above.
|
|
121
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
122
|
+
if (msg.includes("code 127") || msg.includes("ENOENT")) {
|
|
123
|
+
console.warn("⚠️ 'pre-commit' command not found, skipping hooks despite configuration file presence.");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
32
131
|
private async handleCommit(options: CommitOptions) {
|
|
33
132
|
const start = Date.now();
|
|
34
133
|
const safeArgs = {
|
|
35
134
|
...options,
|
|
36
|
-
apiKey: options.apiKey ?
|
|
135
|
+
apiKey: options.apiKey ? "***" : undefined,
|
|
37
136
|
} as Record<string, unknown>;
|
|
38
137
|
try {
|
|
138
|
+
if (!options.noVerify) {
|
|
139
|
+
await this.runPreCommitHook();
|
|
140
|
+
}
|
|
141
|
+
|
|
39
142
|
const existingConfig = ConfigService.getConfig();
|
|
40
143
|
|
|
41
144
|
const mergedApiKey = options.apiKey || existingConfig.apiKey;
|
|
@@ -51,7 +154,7 @@ export class CommitCommand {
|
|
|
51
154
|
|
|
52
155
|
ConfigService.validateConfig({
|
|
53
156
|
apiKey: mergedApiKey,
|
|
54
|
-
language: existingConfig.language
|
|
157
|
+
language: existingConfig.language,
|
|
55
158
|
});
|
|
56
159
|
|
|
57
160
|
const aiConfig: AIServiceConfig = {
|
|
@@ -59,81 +162,84 @@ export class CommitCommand {
|
|
|
59
162
|
baseURL: mergedBaseURL,
|
|
60
163
|
model: mergedModel,
|
|
61
164
|
language: existingConfig.language,
|
|
62
|
-
verbose: !messageOnly
|
|
165
|
+
verbose: !messageOnly,
|
|
63
166
|
};
|
|
64
167
|
|
|
65
|
-
log(
|
|
66
|
-
|
|
168
|
+
log("Getting staged changes...");
|
|
169
|
+
|
|
67
170
|
const diffResult: GitDiffResult = await GitService.getStagedDiff();
|
|
68
|
-
|
|
171
|
+
|
|
69
172
|
if (!diffResult.success) {
|
|
70
|
-
console.error(
|
|
173
|
+
console.error("Error:", diffResult.error);
|
|
71
174
|
await LogService.append({
|
|
72
|
-
command:
|
|
175
|
+
command: "commit",
|
|
73
176
|
args: safeArgs,
|
|
74
|
-
status:
|
|
177
|
+
status: "failure",
|
|
75
178
|
details: diffResult.error,
|
|
76
|
-
durationMs: Date.now() - start
|
|
179
|
+
durationMs: Date.now() - start,
|
|
77
180
|
});
|
|
78
181
|
process.exit(1);
|
|
79
182
|
}
|
|
80
183
|
|
|
81
|
-
log(
|
|
82
|
-
|
|
184
|
+
log("Generating commit message...");
|
|
185
|
+
|
|
83
186
|
const aiService = new AIService(aiConfig);
|
|
84
|
-
const aiResult = await aiService.generateCommitMessage(
|
|
187
|
+
const aiResult = await aiService.generateCommitMessage(
|
|
188
|
+
diffResult.diff!,
|
|
189
|
+
options.prompt
|
|
190
|
+
);
|
|
85
191
|
|
|
86
192
|
if (!aiResult.success) {
|
|
87
|
-
console.error(
|
|
193
|
+
console.error("Error:", aiResult.error);
|
|
88
194
|
await LogService.append({
|
|
89
|
-
command:
|
|
195
|
+
command: "commit",
|
|
90
196
|
args: safeArgs,
|
|
91
|
-
status:
|
|
197
|
+
status: "failure",
|
|
92
198
|
details: aiResult.error,
|
|
93
|
-
durationMs: Date.now() - start
|
|
199
|
+
durationMs: Date.now() - start,
|
|
94
200
|
});
|
|
95
201
|
process.exit(1);
|
|
96
202
|
}
|
|
97
203
|
|
|
98
|
-
if (typeof aiResult.message !==
|
|
99
|
-
console.error(
|
|
204
|
+
if (typeof aiResult.message !== "string") {
|
|
205
|
+
console.error("Error: Failed to generate commit message");
|
|
100
206
|
process.exit(1);
|
|
101
207
|
}
|
|
102
208
|
|
|
103
209
|
if (messageOnly) {
|
|
104
210
|
console.log(aiResult.message);
|
|
105
211
|
await LogService.append({
|
|
106
|
-
command:
|
|
212
|
+
command: "commit",
|
|
107
213
|
args: { ...safeArgs, messageOnly: true },
|
|
108
|
-
status:
|
|
109
|
-
details:
|
|
110
|
-
durationMs: Date.now() - start
|
|
214
|
+
status: "success",
|
|
215
|
+
details: "message-only output",
|
|
216
|
+
durationMs: Date.now() - start,
|
|
111
217
|
});
|
|
112
218
|
return;
|
|
113
219
|
}
|
|
114
220
|
|
|
115
|
-
console.log(
|
|
221
|
+
console.log("\nGenerated commit message:");
|
|
116
222
|
console.log(aiResult.message);
|
|
117
223
|
|
|
118
224
|
const confirmed = await this.confirmCommit();
|
|
119
225
|
|
|
120
226
|
if (!confirmed) {
|
|
121
|
-
console.log(
|
|
227
|
+
console.log("Commit cancelled by user.");
|
|
122
228
|
await LogService.append({
|
|
123
|
-
command:
|
|
229
|
+
command: "commit",
|
|
124
230
|
args: safeArgs,
|
|
125
|
-
status:
|
|
126
|
-
details:
|
|
127
|
-
durationMs: Date.now() - start
|
|
231
|
+
status: "cancelled",
|
|
232
|
+
details: "user declined commit",
|
|
233
|
+
durationMs: Date.now() - start,
|
|
128
234
|
});
|
|
129
235
|
return;
|
|
130
236
|
}
|
|
131
237
|
|
|
132
|
-
console.log(
|
|
238
|
+
console.log("\nCreating commit...");
|
|
133
239
|
const commitSuccess = await GitService.createCommit(aiResult.message!);
|
|
134
240
|
|
|
135
241
|
if (commitSuccess) {
|
|
136
|
-
console.log(
|
|
242
|
+
console.log("✅ Commit created successfully!");
|
|
137
243
|
|
|
138
244
|
const pushRequested = Boolean(options.push);
|
|
139
245
|
const pushFromConfig = !pushRequested && existingConfig.autoPush;
|
|
@@ -141,53 +247,53 @@ export class CommitCommand {
|
|
|
141
247
|
|
|
142
248
|
if (shouldPush) {
|
|
143
249
|
if (pushFromConfig) {
|
|
144
|
-
console.log(
|
|
250
|
+
console.log("Auto push enabled in config; pushing to remote...");
|
|
145
251
|
} else {
|
|
146
|
-
console.log(
|
|
252
|
+
console.log("Pushing to remote...");
|
|
147
253
|
}
|
|
148
254
|
|
|
149
255
|
const pushSuccess = await GitService.push();
|
|
150
256
|
|
|
151
257
|
if (pushSuccess) {
|
|
152
|
-
console.log(
|
|
258
|
+
console.log("✅ Push completed successfully!");
|
|
153
259
|
} else {
|
|
154
|
-
console.error(
|
|
260
|
+
console.error("❌ Failed to push to remote");
|
|
155
261
|
await LogService.append({
|
|
156
|
-
command:
|
|
262
|
+
command: "commit",
|
|
157
263
|
args: { ...safeArgs, push: true },
|
|
158
|
-
status:
|
|
159
|
-
details:
|
|
160
|
-
durationMs: Date.now() - start
|
|
264
|
+
status: "failure",
|
|
265
|
+
details: "push failed",
|
|
266
|
+
durationMs: Date.now() - start,
|
|
161
267
|
});
|
|
162
268
|
process.exit(1);
|
|
163
269
|
}
|
|
164
270
|
}
|
|
165
271
|
} else {
|
|
166
|
-
console.error(
|
|
272
|
+
console.error("❌ Failed to create commit");
|
|
167
273
|
await LogService.append({
|
|
168
|
-
command:
|
|
274
|
+
command: "commit",
|
|
169
275
|
args: safeArgs,
|
|
170
|
-
status:
|
|
171
|
-
details:
|
|
172
|
-
durationMs: Date.now() - start
|
|
276
|
+
status: "failure",
|
|
277
|
+
details: "git commit failed",
|
|
278
|
+
durationMs: Date.now() - start,
|
|
173
279
|
});
|
|
174
280
|
process.exit(1);
|
|
175
281
|
}
|
|
176
282
|
await LogService.append({
|
|
177
|
-
command:
|
|
283
|
+
command: "commit",
|
|
178
284
|
args: safeArgs,
|
|
179
|
-
status:
|
|
180
|
-
durationMs: Date.now() - start
|
|
285
|
+
status: "success",
|
|
286
|
+
durationMs: Date.now() - start,
|
|
181
287
|
});
|
|
182
288
|
} catch (error) {
|
|
183
289
|
const message = error instanceof Error ? error.message : String(error);
|
|
184
|
-
console.error(
|
|
290
|
+
console.error("Error:", message);
|
|
185
291
|
await LogService.append({
|
|
186
|
-
command:
|
|
292
|
+
command: "commit",
|
|
187
293
|
args: safeArgs,
|
|
188
|
-
status:
|
|
294
|
+
status: "failure",
|
|
189
295
|
details: message,
|
|
190
|
-
durationMs: Date.now() - start
|
|
296
|
+
durationMs: Date.now() - start,
|
|
191
297
|
});
|
|
192
298
|
process.exit(1);
|
|
193
299
|
}
|
|
@@ -196,17 +302,17 @@ export class CommitCommand {
|
|
|
196
302
|
private async confirmCommit(): Promise<boolean> {
|
|
197
303
|
const rl = readline.createInterface({
|
|
198
304
|
input: process.stdin,
|
|
199
|
-
output: process.stdout
|
|
305
|
+
output: process.stdout,
|
|
200
306
|
});
|
|
201
307
|
|
|
202
|
-
const answer: string = await new Promise(resolve => {
|
|
203
|
-
rl.question(
|
|
308
|
+
const answer: string = await new Promise((resolve) => {
|
|
309
|
+
rl.question("Proceed with git commit? (y/n): ", resolve);
|
|
204
310
|
});
|
|
205
311
|
|
|
206
312
|
rl.close();
|
|
207
313
|
|
|
208
314
|
const normalized = answer.trim().toLowerCase();
|
|
209
|
-
return normalized ===
|
|
315
|
+
return normalized === "y" || normalized === "yes";
|
|
210
316
|
}
|
|
211
317
|
|
|
212
318
|
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
|