@ksw8954/git-ai-commit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +38 -0
- package/CRUSH.md +28 -0
- package/Makefile +32 -0
- package/README.md +145 -0
- package/dist/commands/ai.d.ts +35 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +206 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/commit.d.ts +17 -0
- package/dist/commands/commit.d.ts.map +1 -0
- package/dist/commands/commit.js +126 -0
- package/dist/commands/commit.js.map +1 -0
- package/dist/commands/config.d.ts +33 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +141 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/configCommand.d.ts +20 -0
- package/dist/commands/configCommand.d.ts.map +1 -0
- package/dist/commands/configCommand.js +108 -0
- package/dist/commands/configCommand.js.map +1 -0
- package/dist/commands/git.d.ts +26 -0
- package/dist/commands/git.d.ts.map +1 -0
- package/dist/commands/git.js +150 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/loadEnv.d.ts +2 -0
- package/dist/commands/loadEnv.d.ts.map +1 -0
- package/dist/commands/loadEnv.js +11 -0
- package/dist/commands/loadEnv.js.map +1 -0
- package/dist/commands/prCommand.d.ts +16 -0
- package/dist/commands/prCommand.d.ts.map +1 -0
- package/dist/commands/prCommand.js +61 -0
- package/dist/commands/prCommand.js.map +1 -0
- package/dist/commands/tag.d.ts +17 -0
- package/dist/commands/tag.d.ts.map +1 -0
- package/dist/commands/tag.js +127 -0
- package/dist/commands/tag.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/commit.d.ts +3 -0
- package/dist/prompts/commit.d.ts.map +1 -0
- package/dist/prompts/commit.js +101 -0
- package/dist/prompts/commit.js.map +1 -0
- package/dist/prompts/pr.d.ts +3 -0
- package/dist/prompts/pr.d.ts.map +1 -0
- package/dist/prompts/pr.js +58 -0
- package/dist/prompts/pr.js.map +1 -0
- package/dist/prompts/tag.d.ts +3 -0
- package/dist/prompts/tag.d.ts.map +1 -0
- package/dist/prompts/tag.js +42 -0
- package/dist/prompts/tag.js.map +1 -0
- package/eslint.config.js +35 -0
- package/jest.config.js +16 -0
- package/package.json +51 -0
- package/src/__tests__/ai.test.ts +185 -0
- package/src/__tests__/commitCommand.test.ts +155 -0
- package/src/__tests__/config.test.ts +238 -0
- package/src/__tests__/git.test.ts +88 -0
- package/src/__tests__/integration.test.ts +138 -0
- package/src/__tests__/prCommand.test.ts +121 -0
- package/src/__tests__/tagCommand.test.ts +197 -0
- package/src/commands/ai.ts +266 -0
- package/src/commands/commit.ts +215 -0
- package/src/commands/config.ts +182 -0
- package/src/commands/configCommand.ts +139 -0
- package/src/commands/git.ts +174 -0
- package/src/commands/history.ts +82 -0
- package/src/commands/loadEnv.ts +5 -0
- package/src/commands/log.ts +71 -0
- package/src/commands/prCommand.ts +108 -0
- package/src/commands/tag.ts +230 -0
- package/src/index.ts +29 -0
- package/src/prompts/commit.ts +105 -0
- package/src/prompts/pr.ts +64 -0
- package/src/prompts/tag.ts +48 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../src/commands/tag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAU;;IAgBzB,OAAO,CAAC,eAAe;YAoBT,SAAS;YAkFT,cAAc;IAgB5B,UAAU,IAAI,OAAO;CAGtB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TagCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const readline_1 = __importDefault(require("readline"));
|
|
9
|
+
const ai_1 = require("./ai");
|
|
10
|
+
const config_1 = require("./config");
|
|
11
|
+
const git_1 = require("./git");
|
|
12
|
+
class TagCommand {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.program = new commander_1.Command('tag')
|
|
15
|
+
.description('Create an annotated git tag with optional AI-generated notes')
|
|
16
|
+
.argument('<name>', 'Tag name to create')
|
|
17
|
+
.option('-k, --api-key <key>', 'OpenAI API key (overrides env var)')
|
|
18
|
+
.option('--base-url <url>', 'Custom API base URL (overrides env var)')
|
|
19
|
+
.option('-m, --model <model>', 'Model to use (overrides env var)')
|
|
20
|
+
.option('--message <message>', 'Tag message to use directly (skips AI generation)')
|
|
21
|
+
.option('-t, --base-tag <tag>', 'Existing tag to diff against when generating notes')
|
|
22
|
+
.action(async (tagName, options) => {
|
|
23
|
+
await this.handleTag(tagName, options);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
resolveAIConfig(options) {
|
|
27
|
+
const storedConfig = config_1.ConfigService.getConfig();
|
|
28
|
+
const mergedApiKey = options.apiKey || storedConfig.apiKey;
|
|
29
|
+
const mergedBaseURL = options.baseUrl || storedConfig.baseURL;
|
|
30
|
+
const mergedModel = options.model || storedConfig.model;
|
|
31
|
+
config_1.ConfigService.validateConfig({
|
|
32
|
+
apiKey: mergedApiKey,
|
|
33
|
+
language: storedConfig.language
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
apiKey: mergedApiKey,
|
|
37
|
+
baseURL: mergedBaseURL,
|
|
38
|
+
model: mergedModel,
|
|
39
|
+
language: storedConfig.language
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async handleTag(tagName, options) {
|
|
43
|
+
const trimmedName = tagName?.trim();
|
|
44
|
+
if (!trimmedName) {
|
|
45
|
+
console.error('Tag name is required.');
|
|
46
|
+
process.exit(1);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
let tagMessage = options.message?.trim();
|
|
50
|
+
if (!tagMessage) {
|
|
51
|
+
console.log('Collecting commit history for tag notes...');
|
|
52
|
+
let baseTag = options.baseTag?.trim();
|
|
53
|
+
if (!baseTag) {
|
|
54
|
+
const latestTagResult = await git_1.GitService.getLatestTag();
|
|
55
|
+
if (latestTagResult.success && latestTagResult.tag) {
|
|
56
|
+
baseTag = latestTagResult.tag;
|
|
57
|
+
console.log(`Using latest tag ${baseTag} as base.`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.log('No existing tag found; using entire commit history.');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const historyResult = await git_1.GitService.getCommitSummariesSince(baseTag);
|
|
64
|
+
if (!historyResult.success || !historyResult.log) {
|
|
65
|
+
console.error('Error:', historyResult.error ?? 'Unable to read commit history.');
|
|
66
|
+
process.exit(1);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
let aiConfig;
|
|
70
|
+
try {
|
|
71
|
+
aiConfig = this.resolveAIConfig(options);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const aiService = new ai_1.AIService(aiConfig);
|
|
79
|
+
const aiResult = await aiService.generateTagNotes(trimmedName, historyResult.log);
|
|
80
|
+
if (!aiResult.success || !aiResult.notes) {
|
|
81
|
+
console.error('Error:', aiResult.error ?? 'Failed to generate tag notes.');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
tagMessage = aiResult.notes;
|
|
86
|
+
}
|
|
87
|
+
console.log(`Creating annotated tag ${trimmedName}...`);
|
|
88
|
+
const created = await git_1.GitService.createAnnotatedTag(trimmedName, tagMessage);
|
|
89
|
+
if (!created) {
|
|
90
|
+
console.error('❌ Failed to create tag');
|
|
91
|
+
process.exit(1);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
console.log(`✅ Tag ${trimmedName} created successfully!`);
|
|
95
|
+
console.log('\nTag message:\n');
|
|
96
|
+
console.log(tagMessage);
|
|
97
|
+
const shouldPush = await this.confirmTagPush(trimmedName);
|
|
98
|
+
if (shouldPush) {
|
|
99
|
+
console.log(`Pushing tag ${trimmedName} to remote...`);
|
|
100
|
+
const pushSuccess = await git_1.GitService.pushTag(trimmedName);
|
|
101
|
+
if (pushSuccess) {
|
|
102
|
+
console.log(`✅ Tag ${trimmedName} pushed successfully!`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
console.error('❌ Failed to push tag to remote');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async confirmTagPush(tagName) {
|
|
111
|
+
const rl = readline_1.default.createInterface({
|
|
112
|
+
input: process.stdin,
|
|
113
|
+
output: process.stdout
|
|
114
|
+
});
|
|
115
|
+
const answer = await new Promise(resolve => {
|
|
116
|
+
rl.question(`Push tag ${tagName} to remote? (y/n): `, resolve);
|
|
117
|
+
});
|
|
118
|
+
rl.close();
|
|
119
|
+
const normalized = answer.trim().toLowerCase();
|
|
120
|
+
return normalized === 'y' || normalized === 'yes';
|
|
121
|
+
}
|
|
122
|
+
getCommand() {
|
|
123
|
+
return this.program;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.TagCommand = TagCommand;
|
|
127
|
+
//# sourceMappingURL=tag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag.js","sourceRoot":"","sources":["../../src/commands/tag.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const commit_1 = require("./commands/commit");
|
|
6
|
+
const configCommand_1 = require("./commands/configCommand");
|
|
7
|
+
const prCommand_1 = require("./commands/prCommand");
|
|
8
|
+
const tag_1 = require("./commands/tag");
|
|
9
|
+
const program = new commander_1.Command();
|
|
10
|
+
program
|
|
11
|
+
.name('git-ai-commit')
|
|
12
|
+
.description('AI-powered git commit message generator')
|
|
13
|
+
.version('1.0.0');
|
|
14
|
+
const commitCommand = new commit_1.CommitCommand();
|
|
15
|
+
const configCommand = new configCommand_1.ConfigCommand();
|
|
16
|
+
const pullRequestCommand = new prCommand_1.PullRequestCommand();
|
|
17
|
+
const tagCommand = new tag_1.TagCommand();
|
|
18
|
+
program.addCommand(commitCommand.getCommand());
|
|
19
|
+
program.addCommand(configCommand.getCommand());
|
|
20
|
+
program.addCommand(pullRequestCommand.getCommand());
|
|
21
|
+
program.addCommand(tagCommand.getCommand());
|
|
22
|
+
program.parse();
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,8CAAkD;AAClD,4DAAyD;AACzD,oDAA0D;AAC1D,wCAA4C;AAE5C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,yCAAyC,CAAC;KACtD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,MAAM,aAAa,GAAG,IAAI,sBAAa,EAAE,CAAC;AAC1C,MAAM,aAAa,GAAG,IAAI,6BAAa,EAAE,CAAC;AAC1C,MAAM,kBAAkB,GAAG,IAAI,8BAAkB,EAAE,CAAC;AACpD,MAAM,UAAU,GAAG,IAAI,gBAAU,EAAE,CAAC;AAEpC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC;AAC/C,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC;AAC/C,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,UAAU,EAAE,CAAC,CAAC;AACpD,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;AAE5C,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +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,MAkGF,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateCommitPrompt = void 0;
|
|
4
|
+
const generateCommitPrompt = (gitContext, customInstructions = '', language = 'ko') => {
|
|
5
|
+
const languageRequirement = language === 'ko'
|
|
6
|
+
? `## Korean Language Requirement
|
|
7
|
+
- All commit messages MUST be written in Korean (한글)
|
|
8
|
+
- Description, body, and footer text must use Korean
|
|
9
|
+
- Keep Korean messages concise`
|
|
10
|
+
: `## English Language Requirement
|
|
11
|
+
- All commit messages MUST be written in English
|
|
12
|
+
- Description, body, and footer text must use English
|
|
13
|
+
- Keep the tone concise and professional`;
|
|
14
|
+
const bodyGuidelines = language === 'ko'
|
|
15
|
+
? `### Body Guidelines (Optional)
|
|
16
|
+
- Insert one blank line after the description and express additional details as
|
|
17
|
+
markdown bullet points (\`- \`) written in Korean.
|
|
18
|
+
- Each bullet should explain the "what" and "why", not the "how".
|
|
19
|
+
- Wrap at 72 characters per line and keep bullets concise.
|
|
20
|
+
- Use the bullet body only for complex changes that need clarification; omit it
|
|
21
|
+
when the summary line is sufficient.`
|
|
22
|
+
: `### Body Guidelines (Optional)
|
|
23
|
+
- Insert one blank line after the description and use markdown bullet points (\`- \`) in English.
|
|
24
|
+
- Each bullet should explain the "what" and "why", not the "how".
|
|
25
|
+
- Wrap at 72 characters per line and keep bullets concise.
|
|
26
|
+
- Include a body only for complex changes that need clarification.`;
|
|
27
|
+
const footerGuidelines = language === 'ko'
|
|
28
|
+
? `### Footer Guidelines (Optional)
|
|
29
|
+
- Start one blank line after body
|
|
30
|
+
- **Breaking Changes**: \`BREAKING CHANGE: description\``
|
|
31
|
+
: `### Footer Guidelines (Optional)
|
|
32
|
+
- Start one blank line after the body
|
|
33
|
+
- **Breaking Changes**: \`BREAKING CHANGE: description\``;
|
|
34
|
+
return `# Conventional Commit Message Generator
|
|
35
|
+
## System Instructions
|
|
36
|
+
You are an expert Git commit message generator that creates conventional commit messages based on staged changes. Analyze the provided git diff output and generate appropriate conventional commit messages following the specification.
|
|
37
|
+
|
|
38
|
+
${customInstructions}
|
|
39
|
+
|
|
40
|
+
## CRITICAL: Commit Message Output Rules
|
|
41
|
+
- DO NOT include any memory bank status indicators like "[Memory Bank: Active]" or "[Memory Bank: Missing]"
|
|
42
|
+
- DO NOT include any task-specific formatting or artifacts from other rules
|
|
43
|
+
- ONLY Generate a clean conventional commit message as specified below
|
|
44
|
+
|
|
45
|
+
${gitContext}
|
|
46
|
+
|
|
47
|
+
## Conventional Commits Format
|
|
48
|
+
Generate commit messages following this exact structure:
|
|
49
|
+
\n<type>[optional scope]: <description>
|
|
50
|
+
[optional body]
|
|
51
|
+
[optional footer(s)]
|
|
52
|
+
|
|
53
|
+
### Core Types (Required)
|
|
54
|
+
- **feat**: New feature or functionality (MINOR version bump)
|
|
55
|
+
- **fix**: Bug fix or error correction (PATCH version bump)
|
|
56
|
+
|
|
57
|
+
### Additional Types (Extended)
|
|
58
|
+
- **docs**: Documentation changes only
|
|
59
|
+
- **style**: Code style changes (whitespace, formatting, semicolons, etc.)
|
|
60
|
+
- **refactor**: Code refactoring without feature changes or bug fixes
|
|
61
|
+
- **perf**: Performance improvements
|
|
62
|
+
- **test**: Adding or fixing tests
|
|
63
|
+
- **build**: Build system or external dependency changes
|
|
64
|
+
- **ci**: CI/CD configuration changes
|
|
65
|
+
- **chore**: Maintenance tasks, tooling changes
|
|
66
|
+
- **revert**: Reverting previous commits
|
|
67
|
+
|
|
68
|
+
### Scope Guidelines
|
|
69
|
+
- Use parentheses: \`feat(api):\`, \`fix(ui):\`
|
|
70
|
+
- Common scopes: \`api\`, \`ui\`, \`auth\`, \`db\`, \`config\`, \`deps\`, \`docs\`
|
|
71
|
+
- For monorepos: package or module names
|
|
72
|
+
- Keep scope concise and lowercase
|
|
73
|
+
|
|
74
|
+
### Description Rules
|
|
75
|
+
- Use imperative mood ("add" not "added" or "adds")
|
|
76
|
+
- Start with lowercase letter
|
|
77
|
+
- No period at the end
|
|
78
|
+
- Be concise but descriptive
|
|
79
|
+
- Must be written as a single line without line breaks
|
|
80
|
+
|
|
81
|
+
${languageRequirement}
|
|
82
|
+
|
|
83
|
+
${bodyGuidelines}
|
|
84
|
+
|
|
85
|
+
${footerGuidelines}
|
|
86
|
+
|
|
87
|
+
## Analysis Instructions
|
|
88
|
+
When analyzing staged changes:
|
|
89
|
+
1. Determine Primary Type based on the nature of changes
|
|
90
|
+
2. Identify Scope from modified directories or modules
|
|
91
|
+
3. Craft Description focusing on the most significant change
|
|
92
|
+
4. Determine if there are Breaking Changes
|
|
93
|
+
5. For complex changes, include a detailed body explaining what and why
|
|
94
|
+
6. Add appropriate footers for issue references or breaking changes
|
|
95
|
+
|
|
96
|
+
For significant changes, include a detailed body explaining the changes.
|
|
97
|
+
|
|
98
|
+
Return ONLY the commit message in the conventional format, nothing else.`;
|
|
99
|
+
};
|
|
100
|
+
exports.generateCommitPrompt = generateCommitPrompt;
|
|
101
|
+
//# sourceMappingURL=commit.js.map
|
|
@@ -0,0 +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;;;;;;;EAOlB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCV,mBAAmB;;EAEnB,cAAc;;EAEd,gBAAgB;;;;;;;;;;;;;yEAauD,CAAC;AAC1E,CAAC,CAAC;AAtGW,QAAA,oBAAoB,wBAsG/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../src/prompts/pr.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpD,eAAO,MAAM,yBAAyB,GACpC,YAAY,MAAM,EAClB,eAAe,MAAM,EACrB,2BAAuB,EACvB,WAAU,yBAAgC,KACzC,MAwDF,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generatePullRequestPrompt = void 0;
|
|
4
|
+
const generatePullRequestPrompt = (baseBranch, compareBranch, customInstructions = '', language = 'ko') => {
|
|
5
|
+
const languageRequirement = language === 'ko'
|
|
6
|
+
? 'Write the entire pull request title and body in Korean.'
|
|
7
|
+
: 'Write the entire pull request title and body in English.';
|
|
8
|
+
const titleGuidelines = language === 'ko'
|
|
9
|
+
? `### 제목 작성 규칙
|
|
10
|
+
- 한 줄짜리 명령형 문장으로 작성합니다 (예: "Refactor validator 로직 정리").
|
|
11
|
+
- 접두사는 사용하지 않습니다 (예: "Feat:" 금지).
|
|
12
|
+
- 72자를 넘지 않도록 합니다.`
|
|
13
|
+
: `### Title Guidelines
|
|
14
|
+
- Use a single imperative sentence (e.g., "Refactor validator handling").
|
|
15
|
+
- Do not prefix with labels like "Feat:".
|
|
16
|
+
- Keep the title under 72 characters.`;
|
|
17
|
+
const summaryGuidelines = language === 'ko'
|
|
18
|
+
? `### 본문 구성
|
|
19
|
+
- "## Summary" 헤딩 아래에 핵심 변경 사항을 강조하는 불릿 리스트를 작성합니다.
|
|
20
|
+
- 각 불릿은 "무엇을"과 "왜"를 포함하고, 한국어로 1줄 내로 작성합니다.
|
|
21
|
+
- 영향이 큰 변경은 별도의 불릿으로 구분합니다.`
|
|
22
|
+
: `### Body Structure
|
|
23
|
+
- Under a "## Summary" heading, add bullet points that explain what changed and why.
|
|
24
|
+
- Keep each bullet to a single concise English sentence.
|
|
25
|
+
- Separate large areas of impact into individual bullets.`;
|
|
26
|
+
const testingGuidelines = language === 'ko'
|
|
27
|
+
? `### 테스트 정보
|
|
28
|
+
- "## Testing" 헤딩 아래에 검증 방법을 불릿으로 정리합니다.
|
|
29
|
+
- 수동 테스트, 자동 테스트, 혹은 "테스트 필요 없음"을 명시합니다.`
|
|
30
|
+
: `### Testing Details
|
|
31
|
+
- Under a "## Testing" heading, list how the changes were verified.
|
|
32
|
+
- Call out manual steps, automated checks, or "Not tested" when applicable.`;
|
|
33
|
+
return `You are an expert software engineer preparing a pull request description.
|
|
34
|
+
Compare the git history and code changes between the base branch "${baseBranch}" and the compare branch "${compareBranch}" and summarise the meaningful differences in a PR-friendly format.
|
|
35
|
+
|
|
36
|
+
${customInstructions}
|
|
37
|
+
|
|
38
|
+
## Output Contract
|
|
39
|
+
- Return ONLY markdown suitable for pasting into a pull request form.
|
|
40
|
+
- First line MUST be the pull request title, adhering to the title guidelines below.
|
|
41
|
+
- After one blank line, include the sections exactly as shown:
|
|
42
|
+
- "## Summary"
|
|
43
|
+
- "## Testing"
|
|
44
|
+
- If a section has no content, provide a single bullet: "- 없음" in Korean or "- None" in English (use language-appropriate wording).
|
|
45
|
+
- Do not invent changes that are not present in the provided diff.
|
|
46
|
+
|
|
47
|
+
${languageRequirement}
|
|
48
|
+
|
|
49
|
+
${titleGuidelines}
|
|
50
|
+
|
|
51
|
+
${summaryGuidelines}
|
|
52
|
+
|
|
53
|
+
${testingGuidelines}
|
|
54
|
+
|
|
55
|
+
Focus on user-facing impact, breaking changes, and notable refactors. Avoid raw diff dumps.`;
|
|
56
|
+
};
|
|
57
|
+
exports.generatePullRequestPrompt = generatePullRequestPrompt;
|
|
58
|
+
//# sourceMappingURL=pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/prompts/pr.ts"],"names":[],"mappings":";;;AAEO,MAAM,yBAAyB,GAAG,CACvC,UAAkB,EAClB,aAAqB,EACrB,kBAAkB,GAAG,EAAE,EACvB,WAAsC,IAAI,EAClC,EAAE;IACV,MAAM,mBAAmB,GAAG,QAAQ,KAAK,IAAI;QAC3C,CAAC,CAAC,yDAAyD;QAC3D,CAAC,CAAC,0DAA0D,CAAC;IAE/D,MAAM,eAAe,GAAG,QAAQ,KAAK,IAAI;QACvC,CAAC,CAAC;;;mBAGa;QACf,CAAC,CAAC;;;sCAGgC,CAAC;IAErC,MAAM,iBAAiB,GAAG,QAAQ,KAAK,IAAI;QACzC,CAAC,CAAC;;;4BAGsB;QACxB,CAAC,CAAC;;;0DAGoD,CAAC;IAEzD,MAAM,iBAAiB,GAAG,QAAQ,KAAK,IAAI;QACzC,CAAC,CAAC;;yCAEmC;QACrC,CAAC,CAAC;;4EAEsE,CAAC;IAE3E,OAAO;oEAC2D,UAAU,6BAA6B,aAAa;;EAEtH,kBAAkB;;;;;;;;;;;EAWlB,mBAAmB;;EAEnB,eAAe;;EAEf,iBAAiB;;EAEjB,iBAAiB;;4FAEyE,CAAC;AAC7F,CAAC,CAAC;AA7DW,QAAA,yBAAyB,6BA6DpC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../src/prompts/tag.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,2BAAuB,EACvB,WAAU,iBAAwB,KACjC,MAyCF,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateTagPrompt = void 0;
|
|
4
|
+
const generateTagPrompt = (tagName, customInstructions = '', language = 'ko') => {
|
|
5
|
+
const summaryInstruction = language === 'ko'
|
|
6
|
+
? 'Begin with a short summary sentence (in Korean) that captures the overall impact of the release.'
|
|
7
|
+
: 'Begin with a short summary sentence (in English) that captures the overall impact of the release.';
|
|
8
|
+
const listInstruction = language === 'ko'
|
|
9
|
+
? 'After the summary, list every change as a markdown bullet (-) grouped by category: 사용자 기능, 버그 수정, 유지 보수.'
|
|
10
|
+
: 'After the summary, list every change as a markdown bullet (-) grouped by category: User Features, Bug Fixes, Maintenance.';
|
|
11
|
+
const emptyCategoryInstruction = language === 'ko'
|
|
12
|
+
? 'If a category has no changes, include a bullet stating - 해당 사항 없음.'
|
|
13
|
+
: 'If a category has no changes, include a bullet stating - None.';
|
|
14
|
+
const noChangesInstruction = language === 'ko'
|
|
15
|
+
? 'If no changes exist at all, state "변경 사항 없음" plainly.'
|
|
16
|
+
: 'If no changes exist at all, state "No changes to report." plainly.';
|
|
17
|
+
const outputLanguageLine = language === 'ko'
|
|
18
|
+
? 'Write the release notes in Korean using concise markdown.'
|
|
19
|
+
: 'Write the release notes in English using concise markdown.';
|
|
20
|
+
return `You are an experienced release manager. Produce clear, user-facing release notes that describe the differences between the previous tag and ${tagName}.
|
|
21
|
+
|
|
22
|
+
## Objective
|
|
23
|
+
Summarize the meaningful changes that occurred between the prior release tag and ${tagName}. Treat the commit log provided by the user message as the complete history of changes since the previous tag.
|
|
24
|
+
|
|
25
|
+
## Input Context
|
|
26
|
+
- Target tag to publish: ${tagName}
|
|
27
|
+
- Commit history between the previous tag and ${tagName} will be supplied in the user message (most recent first).
|
|
28
|
+
|
|
29
|
+
${customInstructions}
|
|
30
|
+
|
|
31
|
+
## Output Requirements
|
|
32
|
+
- ${outputLanguageLine}
|
|
33
|
+
- ${summaryInstruction}
|
|
34
|
+
- ${listInstruction}
|
|
35
|
+
- Use short phrases for each bullet and include scope/component names when helpful, without copying commit messages verbatim.
|
|
36
|
+
- ${emptyCategoryInstruction}
|
|
37
|
+
- ${noChangesInstruction}
|
|
38
|
+
- Do not invent work beyond what appears in the commit log.
|
|
39
|
+
- Return only the release notes content with no surrounding commentary.`;
|
|
40
|
+
};
|
|
41
|
+
exports.generateTagPrompt = generateTagPrompt;
|
|
42
|
+
//# sourceMappingURL=tag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag.js","sourceRoot":"","sources":["../../src/prompts/tag.ts"],"names":[],"mappings":";;;AAEO,MAAM,iBAAiB,GAAG,CAC/B,OAAe,EACf,kBAAkB,GAAG,EAAE,EACvB,WAA8B,IAAI,EAC1B,EAAE;IACV,MAAM,kBAAkB,GAAG,QAAQ,KAAK,IAAI;QAC1C,CAAC,CAAC,kGAAkG;QACpG,CAAC,CAAC,mGAAmG,CAAC;IAExG,MAAM,eAAe,GAAG,QAAQ,KAAK,IAAI;QACvC,CAAC,CAAC,0GAA0G;QAC5G,CAAC,CAAC,2HAA2H,CAAC;IAEhI,MAAM,wBAAwB,GAAG,QAAQ,KAAK,IAAI;QAChD,CAAC,CAAC,oEAAoE;QACtE,CAAC,CAAC,gEAAgE,CAAC;IAErE,MAAM,oBAAoB,GAAG,QAAQ,KAAK,IAAI;QAC5C,CAAC,CAAC,uDAAuD;QACzD,CAAC,CAAC,oEAAoE,CAAC;IAEzE,MAAM,kBAAkB,GAAG,QAAQ,KAAK,IAAI;QAC1C,CAAC,CAAC,2DAA2D;QAC7D,CAAC,CAAC,4DAA4D,CAAC;IAEjE,OAAO,+IAA+I,OAAO;;;mFAG5E,OAAO;;;2BAG/D,OAAO;gDACc,OAAO;;EAErD,kBAAkB;;;IAGhB,kBAAkB;IAClB,kBAAkB;IAClB,eAAe;;IAEf,wBAAwB;IACxB,oBAAoB;;wEAEgD,CAAC;AACzE,CAAC,CAAC;AA7CW,QAAA,iBAAiB,qBA6C5B"}
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const js = require('@eslint/js');
|
|
2
|
+
const tsPlugin = require('@typescript-eslint/eslint-plugin');
|
|
3
|
+
const tsParser = require('@typescript-eslint/parser');
|
|
4
|
+
const globals = require('globals');
|
|
5
|
+
|
|
6
|
+
module.exports = [
|
|
7
|
+
{
|
|
8
|
+
ignores: ['dist/**', 'coverage/**', 'node_modules/**'],
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
files: ['**/*.ts'],
|
|
12
|
+
languageOptions: {
|
|
13
|
+
parser: tsParser,
|
|
14
|
+
parserOptions: {
|
|
15
|
+
ecmaVersion: 'latest',
|
|
16
|
+
sourceType: 'module',
|
|
17
|
+
},
|
|
18
|
+
globals: {
|
|
19
|
+
...globals.node,
|
|
20
|
+
...globals.es2021,
|
|
21
|
+
...globals.jest,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
plugins: {
|
|
25
|
+
'@typescript-eslint': tsPlugin,
|
|
26
|
+
},
|
|
27
|
+
rules: {
|
|
28
|
+
...js.configs.recommended.rules,
|
|
29
|
+
...tsPlugin.configs.recommended.rules,
|
|
30
|
+
'@typescript-eslint/no-unused-vars': 'error',
|
|
31
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
32
|
+
'no-console': 'warn',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
];
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
preset: 'ts-jest',
|
|
3
|
+
testEnvironment: 'node',
|
|
4
|
+
roots: ['<rootDir>/src'],
|
|
5
|
+
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
|
|
6
|
+
transform: {
|
|
7
|
+
'^.+\\.ts$': 'ts-jest',
|
|
8
|
+
},
|
|
9
|
+
collectCoverageFrom: [
|
|
10
|
+
'src/**/*.ts',
|
|
11
|
+
'!src/**/*.d.ts',
|
|
12
|
+
'!src/index.ts',
|
|
13
|
+
],
|
|
14
|
+
coverageDirectory: 'coverage',
|
|
15
|
+
coverageReporters: ['text', 'lcov', 'html'],
|
|
16
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ksw8954/git-ai-commit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI-powered git commit message generator",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"git-ai-commit": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "ts-node src/index.ts",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"test:file": "jest",
|
|
14
|
+
"test:watch": "jest --watch",
|
|
15
|
+
"test:coverage": "jest --coverage",
|
|
16
|
+
"lint": "eslint src/**/*.ts",
|
|
17
|
+
"typecheck": "tsc --noEmit"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/onaries/git-ai-commit.git"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/onaries/git-ai-commit/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/onaries/git-ai-commit#readme",
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/dotenv": "^6.1.1",
|
|
35
|
+
"@types/jest": "^30.0.0",
|
|
36
|
+
"@types/node": "^24.3.3",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^8.43.0",
|
|
38
|
+
"@typescript-eslint/parser": "^8.43.0",
|
|
39
|
+
"dotenv": "^17.2.2",
|
|
40
|
+
"eslint": "^9.35.0",
|
|
41
|
+
"jest": "^30.1.3",
|
|
42
|
+
"nodemon": "^3.1.10",
|
|
43
|
+
"ts-jest": "^29.4.1",
|
|
44
|
+
"ts-node": "^10.9.2",
|
|
45
|
+
"typescript": "^5.9.2"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"commander": "^14.0.1",
|
|
49
|
+
"openai": "^5.20.2"
|
|
50
|
+
}
|
|
51
|
+
}
|