commitect 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.
Files changed (55) hide show
  1. package/.github/workflows/publish.yml +39 -0
  2. package/LICENSE +21 -0
  3. package/README.md +176 -0
  4. package/dist/commands/analyze.d.ts +2 -0
  5. package/dist/commands/analyze.d.ts.map +1 -0
  6. package/dist/commands/analyze.js +40 -0
  7. package/dist/commands/analyze.js.map +1 -0
  8. package/dist/commands/clear-cache.d.ts +2 -0
  9. package/dist/commands/clear-cache.d.ts.map +1 -0
  10. package/dist/commands/clear-cache.js +23 -0
  11. package/dist/commands/clear-cache.js.map +1 -0
  12. package/dist/commands/commit.d.ts +2 -0
  13. package/dist/commands/commit.d.ts.map +1 -0
  14. package/dist/commands/commit.js +42 -0
  15. package/dist/commands/commit.js.map +1 -0
  16. package/dist/commands/copy.d.ts +2 -0
  17. package/dist/commands/copy.d.ts.map +1 -0
  18. package/dist/commands/copy.js +42 -0
  19. package/dist/commands/copy.js.map +1 -0
  20. package/dist/commands/help.d.ts +2 -0
  21. package/dist/commands/help.d.ts.map +1 -0
  22. package/dist/commands/help.js +129 -0
  23. package/dist/commands/help.js.map +1 -0
  24. package/dist/commands/history.d.ts +2 -0
  25. package/dist/commands/history.d.ts.map +1 -0
  26. package/dist/commands/history.js +58 -0
  27. package/dist/commands/history.js.map +1 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +44 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/services/llm.d.ts +6 -0
  33. package/dist/services/llm.d.ts.map +1 -0
  34. package/dist/services/llm.js +94 -0
  35. package/dist/services/llm.js.map +1 -0
  36. package/dist/utils/cache.d.ts +61 -0
  37. package/dist/utils/cache.d.ts.map +1 -0
  38. package/dist/utils/cache.js +141 -0
  39. package/dist/utils/cache.js.map +1 -0
  40. package/dist/utils/git.d.ts +5 -0
  41. package/dist/utils/git.d.ts.map +1 -0
  42. package/dist/utils/git.js +69 -0
  43. package/dist/utils/git.js.map +1 -0
  44. package/package.json +38 -0
  45. package/src/commands/analyze.ts +44 -0
  46. package/src/commands/clear-cache.ts +23 -0
  47. package/src/commands/commit.ts +48 -0
  48. package/src/commands/copy.ts +48 -0
  49. package/src/commands/help.ts +143 -0
  50. package/src/commands/history.ts +62 -0
  51. package/src/index.ts +53 -0
  52. package/src/services/llm.ts +123 -0
  53. package/src/utils/cache.ts +170 -0
  54. package/src/utils/git.ts +74 -0
  55. package/tsconfig.json +20 -0
@@ -0,0 +1,58 @@
1
+ import { commitCache } from '../utils/cache.js';
2
+ import chalk from 'chalk';
3
+ export function historyCommand() {
4
+ try {
5
+ const history = commitCache.getHistory();
6
+ if (history.length === 0) {
7
+ console.log(chalk.yellow('ℹ No commit history found'));
8
+ console.log(chalk.gray(' Generate some commits first using commitect analyze/copy/commit'));
9
+ return;
10
+ }
11
+ console.log('');
12
+ console.log(chalk.bold.cyan('📜 COMMIT HISTORY'));
13
+ console.log(chalk.gray('─'.repeat(70)));
14
+ console.log('');
15
+ history.forEach((entry, index) => {
16
+ const date = new Date(entry.timestamp);
17
+ const timeAgo = getTimeAgo(entry.timestamp);
18
+ // Format: [1] Feature: Add user authentication
19
+ console.log(chalk.bold.white(`[${index + 1}]`) + ' ' + chalk.green(`${entry.intent}: ${entry.message}`));
20
+ console.log(chalk.gray(` 📁 ${entry.folder}`));
21
+ console.log(chalk.gray(` 🕒 ${date.toLocaleString()} (${timeAgo})`));
22
+ console.log('');
23
+ });
24
+ console.log(chalk.gray('─'.repeat(70)));
25
+ console.log(chalk.gray(`Total: ${history.length} cached commit message${history.length !== 1 ? 's' : ''}`));
26
+ console.log('');
27
+ }
28
+ catch (error) {
29
+ if (error instanceof Error) {
30
+ console.error(chalk.red('❌ ' + error.message));
31
+ }
32
+ else {
33
+ console.error(chalk.red('❌ Failed to load history'));
34
+ }
35
+ process.exit(1);
36
+ }
37
+ }
38
+ function getTimeAgo(timestamp) {
39
+ const now = Date.now();
40
+ const diff = now - timestamp;
41
+ const seconds = Math.floor(diff / 1000);
42
+ const minutes = Math.floor(seconds / 60);
43
+ const hours = Math.floor(minutes / 60);
44
+ const days = Math.floor(hours / 24);
45
+ if (days > 0) {
46
+ return `${days} day${days !== 1 ? 's' : ''} ago`;
47
+ }
48
+ else if (hours > 0) {
49
+ return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
50
+ }
51
+ else if (minutes > 0) {
52
+ return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
53
+ }
54
+ else {
55
+ return 'just now';
56
+ }
57
+ }
58
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,44 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { analyzeCommand } from './commands/analyze.js';
4
+ import { copyCommand } from './commands/copy.js';
5
+ import { commitCommand } from './commands/commit.js';
6
+ import { clearCacheCommand } from './commands/clear-cache.js';
7
+ import { historyCommand } from './commands/history.js';
8
+ import { helpCommand } from './commands/help.js';
9
+ const program = new Command();
10
+ program
11
+ .name('commitect')
12
+ .description('Zero-config Git Commit Assistant')
13
+ .version('1.0.0');
14
+ program
15
+ .command('analyze')
16
+ .description('Analyze changes and suggest a commit message')
17
+ .action(analyzeCommand);
18
+ program
19
+ .command('copy')
20
+ .description('Generate commit message and copy to clipboard')
21
+ .action(copyCommand);
22
+ program
23
+ .command('commit')
24
+ .description('Generate and execute git commit')
25
+ .action(commitCommand);
26
+ program
27
+ .command('history')
28
+ .description('Show cached commit message history')
29
+ .action(historyCommand);
30
+ program
31
+ .command('clear-cache')
32
+ .description('Clear the commit message cache')
33
+ .action(clearCacheCommand);
34
+ program
35
+ .command('help')
36
+ .description('Show detailed help and examples')
37
+ .action(helpCommand);
38
+ // Show help by default if no command is provided
39
+ if (process.argv.length === 2) {
40
+ helpCommand();
41
+ process.exit(0);
42
+ }
43
+ program.parse();
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,+CAA+C,CAAC;KAC5D,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAE7B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,iDAAiD;AACjD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC9B,WAAW,EAAE,CAAC;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface CommitSuggestion {
2
+ intent: string;
3
+ message: string;
4
+ }
5
+ export declare function generateCommitMessage(diff: string): Promise<CommitSuggestion>;
6
+ //# sourceMappingURL=llm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/services/llm.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmFnF"}
@@ -0,0 +1,94 @@
1
+ import axios from 'axios';
2
+ import { commitCache } from '../utils/cache.js';
3
+ const API_ENDPOINT = 'http://commitintentdetector.runasp.net/api/Commit/analyze';
4
+ export async function generateCommitMessage(diff) {
5
+ // Check cache first
6
+ const cached = commitCache.get(diff);
7
+ if (cached) {
8
+ return cached;
9
+ }
10
+ const maxRetries = 3;
11
+ let lastError = null;
12
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
13
+ try {
14
+ const response = await axios.post(API_ENDPOINT, { diff }, {
15
+ headers: {
16
+ 'Content-Type': 'application/json'
17
+ },
18
+ timeout: 30000 // 30 second timeout
19
+ });
20
+ // API returns: { intent: "Intent: Feature\nMessage: Add subtraction support function" }
21
+ const data = response.data;
22
+ if (!data || !data.intent) {
23
+ throw new Error('Invalid response format from API');
24
+ }
25
+ const result = parseResponse(data.intent);
26
+ // Cache the result
27
+ commitCache.set(diff, result.intent, result.message);
28
+ return result;
29
+ }
30
+ catch (error) {
31
+ lastError = error;
32
+ if (axios.isAxiosError(error)) {
33
+ const axiosError = error;
34
+ // Handle rate limiting (429)
35
+ if (axiosError.response?.status === 429) {
36
+ if (attempt < maxRetries) {
37
+ await sleep(1000 * attempt); // Exponential backoff
38
+ continue;
39
+ }
40
+ throw new Error('API rate limit reached. Please try again later.');
41
+ }
42
+ // Handle server errors (5xx) - retry
43
+ if (axiosError.response?.status && axiosError.response.status >= 500) {
44
+ if (attempt < maxRetries) {
45
+ await sleep(1000 * attempt);
46
+ continue;
47
+ }
48
+ }
49
+ // Handle network errors - retry
50
+ if (axiosError.code === 'ECONNREFUSED' || axiosError.code === 'ETIMEDOUT') {
51
+ if (attempt < maxRetries) {
52
+ await sleep(1000 * attempt);
53
+ continue;
54
+ }
55
+ throw new Error('Unable to connect to API. Please check your network connection.');
56
+ }
57
+ }
58
+ // Don't retry on client errors (4xx) except 429
59
+ if (axios.isAxiosError(error) && error.response?.status && error.response.status < 500 && error.response.status !== 429) {
60
+ break;
61
+ }
62
+ // Retry on other errors
63
+ if (attempt < maxRetries) {
64
+ await sleep(1000 * attempt);
65
+ continue;
66
+ }
67
+ }
68
+ }
69
+ throw new Error('Failed to generate commit message. Please check your API configuration.');
70
+ }
71
+ function parseResponse(response) {
72
+ const lines = response.trim().split('\n');
73
+ let intent = '';
74
+ let message = '';
75
+ for (const line of lines) {
76
+ if (line.startsWith('Intent:')) {
77
+ intent = line.replace('Intent:', '').trim();
78
+ }
79
+ else if (line.startsWith('Message:')) {
80
+ message = line.replace('Message:', '').trim();
81
+ }
82
+ }
83
+ if (!intent || !message) {
84
+ throw new Error('Invalid response format from LLM');
85
+ }
86
+ if (message.length > 70) {
87
+ message = message.substring(0, 67) + '...';
88
+ }
89
+ return { intent, message };
90
+ }
91
+ function sleep(ms) {
92
+ return new Promise(resolve => setTimeout(resolve, ms));
93
+ }
94
+ //# sourceMappingURL=llm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/services/llm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ interface CacheEntry {
2
+ hash: string;
3
+ intent: string;
4
+ message: string;
5
+ timestamp: number;
6
+ folder: string;
7
+ }
8
+ declare class CommitCache {
9
+ private cache;
10
+ constructor();
11
+ /**
12
+ * Generate a hash from the git diff
13
+ */
14
+ private hashDiff;
15
+ /**
16
+ * Get current folder name
17
+ */
18
+ private getCurrentFolder;
19
+ /**
20
+ * Load cache from disk
21
+ */
22
+ private loadCache;
23
+ /**
24
+ * Save cache to disk
25
+ */
26
+ private saveCache;
27
+ /**
28
+ * Get cached commit message for a diff
29
+ */
30
+ get(diff: string): {
31
+ intent: string;
32
+ message: string;
33
+ folder: string;
34
+ } | null;
35
+ /**
36
+ * Store a commit message in cache
37
+ */
38
+ set(diff: string, intent: string, message: string): void;
39
+ /**
40
+ * Clear all cache
41
+ */
42
+ clear(): void;
43
+ /**
44
+ * Get cache statistics
45
+ */
46
+ getStats(): {
47
+ size: number;
48
+ oldestEntry: number | null;
49
+ };
50
+ /**
51
+ * Get all cache entries sorted by timestamp (newest first)
52
+ */
53
+ getHistory(): CacheEntry[];
54
+ /**
55
+ * Get cache entries for a specific folder
56
+ */
57
+ getHistoryByFolder(folder: string): CacheEntry[];
58
+ }
59
+ export declare const commitCache: CommitCache;
60
+ export {};
61
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAKA,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,cAAM,WAAW;IACf,OAAO,CAAC,KAAK,CAA0B;;IAOvC;;OAEG;IACH,OAAO,CAAC,QAAQ;IAIhB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACH,OAAO,CAAC,SAAS;IAwBjB;;OAEG;IACH,OAAO,CAAC,SAAS;IAcjB;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAuB7E;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAcxD;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;IAYxD;;OAEG;IACH,UAAU,IAAI,UAAU,EAAE;IAK1B;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;CAMjD;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -0,0 +1,141 @@
1
+ import { createHash } from 'crypto';
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
3
+ import { homedir } from 'os';
4
+ import { join, basename } from 'path';
5
+ const CACHE_DIR = join(homedir(), '.commitect');
6
+ const CACHE_FILE = join(CACHE_DIR, 'cache.json');
7
+ const CACHE_MAX_AGE = 30 * 24 * 60 * 60 * 1000; // 30 days in milliseconds
8
+ class CommitCache {
9
+ constructor() {
10
+ this.cache = new Map();
11
+ this.loadCache();
12
+ }
13
+ /**
14
+ * Generate a hash from the git diff
15
+ */
16
+ hashDiff(diff) {
17
+ return createHash('sha256').update(diff.trim()).digest('hex');
18
+ }
19
+ /**
20
+ * Get current folder name
21
+ */
22
+ getCurrentFolder() {
23
+ return basename(process.cwd());
24
+ }
25
+ /**
26
+ * Load cache from disk
27
+ */
28
+ loadCache() {
29
+ try {
30
+ if (!existsSync(CACHE_DIR)) {
31
+ mkdirSync(CACHE_DIR, { recursive: true });
32
+ }
33
+ if (existsSync(CACHE_FILE)) {
34
+ const data = readFileSync(CACHE_FILE, 'utf-8');
35
+ const entries = JSON.parse(data);
36
+ // Load valid entries (not expired)
37
+ const now = Date.now();
38
+ entries.forEach(entry => {
39
+ if (now - entry.timestamp < CACHE_MAX_AGE) {
40
+ this.cache.set(entry.hash, entry);
41
+ }
42
+ });
43
+ }
44
+ }
45
+ catch (error) {
46
+ // If cache is corrupted, start fresh
47
+ this.cache.clear();
48
+ }
49
+ }
50
+ /**
51
+ * Save cache to disk
52
+ */
53
+ saveCache() {
54
+ try {
55
+ if (!existsSync(CACHE_DIR)) {
56
+ mkdirSync(CACHE_DIR, { recursive: true });
57
+ }
58
+ const entries = Array.from(this.cache.values());
59
+ writeFileSync(CACHE_FILE, JSON.stringify(entries, null, 2), 'utf-8');
60
+ }
61
+ catch (error) {
62
+ // Silently fail - caching is optional
63
+ console.warn('Warning: Failed to save cache');
64
+ }
65
+ }
66
+ /**
67
+ * Get cached commit message for a diff
68
+ */
69
+ get(diff) {
70
+ const hash = this.hashDiff(diff);
71
+ const entry = this.cache.get(hash);
72
+ if (!entry) {
73
+ return null;
74
+ }
75
+ // Check if entry is still valid
76
+ const now = Date.now();
77
+ if (now - entry.timestamp > CACHE_MAX_AGE) {
78
+ this.cache.delete(hash);
79
+ this.saveCache();
80
+ return null;
81
+ }
82
+ return {
83
+ intent: entry.intent,
84
+ message: entry.message,
85
+ folder: entry.folder
86
+ };
87
+ }
88
+ /**
89
+ * Store a commit message in cache
90
+ */
91
+ set(diff, intent, message) {
92
+ const hash = this.hashDiff(diff);
93
+ this.cache.set(hash, {
94
+ hash,
95
+ intent,
96
+ message,
97
+ timestamp: Date.now(),
98
+ folder: this.getCurrentFolder()
99
+ });
100
+ this.saveCache();
101
+ }
102
+ /**
103
+ * Clear all cache
104
+ */
105
+ clear() {
106
+ this.cache.clear();
107
+ this.saveCache();
108
+ }
109
+ /**
110
+ * Get cache statistics
111
+ */
112
+ getStats() {
113
+ const entries = Array.from(this.cache.values());
114
+ const oldestEntry = entries.length > 0
115
+ ? Math.min(...entries.map(e => e.timestamp))
116
+ : null;
117
+ return {
118
+ size: this.cache.size,
119
+ oldestEntry
120
+ };
121
+ }
122
+ /**
123
+ * Get all cache entries sorted by timestamp (newest first)
124
+ */
125
+ getHistory() {
126
+ const entries = Array.from(this.cache.values());
127
+ return entries.sort((a, b) => b.timestamp - a.timestamp);
128
+ }
129
+ /**
130
+ * Get cache entries for a specific folder
131
+ */
132
+ getHistoryByFolder(folder) {
133
+ const entries = Array.from(this.cache.values());
134
+ return entries
135
+ .filter(entry => entry.folder === folder)
136
+ .sort((a, b) => b.timestamp - a.timestamp);
137
+ }
138
+ }
139
+ // Singleton instance
140
+ export const commitCache = new CommitCache();
141
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function isGitRepository(): boolean;
2
+ export declare function getGitDiff(): string;
3
+ export declare function hasChanges(): boolean;
4
+ export declare function executeCommit(message: string): void;
5
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAWA,wBAAgB,eAAe,IAAI,OAAO,CAOzC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAYnC;AAED,wBAAgB,UAAU,IAAI,OAAO,CASpC;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAQnD"}
@@ -0,0 +1,69 @@
1
+ import { execSync } from 'child_process';
2
+ const IGNORED_PATHS = [
3
+ 'node_modules/',
4
+ 'bin/',
5
+ 'obj/',
6
+ 'dist/',
7
+ 'build/',
8
+ '.git/'
9
+ ];
10
+ export function isGitRepository() {
11
+ try {
12
+ execSync('git rev-parse --git-dir', { stdio: 'pipe' });
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ export function getGitDiff() {
20
+ try {
21
+ // Get both staged and unstaged changes
22
+ const diff = execSync('git diff HEAD', {
23
+ encoding: 'utf-8',
24
+ maxBuffer: 10 * 1024 * 1024 // 10MB buffer
25
+ });
26
+ return filterIgnoredPaths(diff);
27
+ }
28
+ catch (error) {
29
+ throw new Error('Failed to read git diff');
30
+ }
31
+ }
32
+ export function hasChanges() {
33
+ try {
34
+ const status = execSync('git status --porcelain', {
35
+ encoding: 'utf-8'
36
+ });
37
+ return status.trim().length > 0;
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ export function executeCommit(message) {
44
+ try {
45
+ execSync(`git commit -m "${message.replace(/"/g, '\\"')}"`, {
46
+ stdio: 'inherit'
47
+ });
48
+ }
49
+ catch (error) {
50
+ throw new Error('Git commit failed');
51
+ }
52
+ }
53
+ function filterIgnoredPaths(diff) {
54
+ const lines = diff.split('\n');
55
+ const filteredLines = [];
56
+ let skipFile = false;
57
+ for (const line of lines) {
58
+ // Check if this is a file header
59
+ if (line.startsWith('diff --git')) {
60
+ const path = line.split(' b/')[1];
61
+ skipFile = IGNORED_PATHS.some(ignored => path?.startsWith(ignored));
62
+ }
63
+ if (!skipFile) {
64
+ filteredLines.push(line);
65
+ }
66
+ }
67
+ return filteredLines.join('\n');
68
+ }
69
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,aAAa,GAAG;IACpB,eAAe;IACf,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;CACR,CAAC;AAEF,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,QAAQ,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,uCAAuC;QACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,EAAE;YACrC,QAAQ,EAAE,OAAO;YACjB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,cAAc;SAC3C,CAAC,CAAC;QAEH,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,wBAAwB,EAAE;YAChD,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,CAAC;QACH,QAAQ,CAAC,kBAAkB,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE;YAC1D,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,iCAAiC;QACjC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "commitect",
3
+ "version": "1.0.0",
4
+ "description": "Zero-config Git Commit Assistant CLI",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "commitect": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "ts-node src/index.ts",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "keywords": [
16
+ "git",
17
+ "commit",
18
+ "cli",
19
+ "ai",
20
+ "assistant"
21
+ ],
22
+ "author": "",
23
+ "license": "MIT",
24
+ "dependencies": {
25
+ "commander": "^11.1.0",
26
+ "chalk": "^4.1.2",
27
+ "clipboardy": "^3.0.0",
28
+ "axios": "^1.6.2"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^20.10.5",
32
+ "typescript": "^5.3.3",
33
+ "ts-node": "^10.9.2"
34
+ },
35
+ "engines": {
36
+ "node": ">=16.0.0"
37
+ }
38
+ }
@@ -0,0 +1,44 @@
1
+ import { isGitRepository, getGitDiff, hasChanges } from '../utils/git.js';
2
+ import { generateCommitMessage } from '../services/llm.js';
3
+ import chalk from 'chalk';
4
+
5
+ export async function analyzeCommand(): Promise<void> {
6
+ try {
7
+ // Validate git repository
8
+ if (!isGitRepository()) {
9
+ console.error(chalk.red('❌ Not a git repository'));
10
+ process.exit(1);
11
+ }
12
+
13
+ // Check for changes
14
+ if (!hasChanges()) {
15
+ console.log(chalk.yellow('⚠ No changes detected'));
16
+ process.exit(0);
17
+ }
18
+
19
+ // Get diff
20
+ const diff = getGitDiff();
21
+
22
+ if (!diff.trim()) {
23
+ console.log(chalk.yellow('⚠ No changes to analyze'));
24
+ process.exit(0);
25
+ }
26
+
27
+ // Generate commit message
28
+ console.log(chalk.blue('🔍 Analyzing changes...'));
29
+ const suggestion = await generateCommitMessage(diff);
30
+
31
+ // Print result
32
+ console.log('');
33
+ console.log(chalk.green(`${suggestion.intent}: ${suggestion.message}`));
34
+ console.log('');
35
+
36
+ } catch (error) {
37
+ if (error instanceof Error) {
38
+ console.error(chalk.red('❌ ' + error.message));
39
+ } else {
40
+ console.error(chalk.red('❌ An unexpected error occurred'));
41
+ }
42
+ process.exit(1);
43
+ }
44
+ }
@@ -0,0 +1,23 @@
1
+ import { commitCache } from '../utils/cache.js';
2
+ import chalk from 'chalk';
3
+
4
+ export function clearCacheCommand(): void {
5
+ try {
6
+ const stats = commitCache.getStats();
7
+
8
+ if (stats.size === 0) {
9
+ console.log(chalk.yellow('ℹ Cache is already empty'));
10
+ return;
11
+ }
12
+
13
+ commitCache.clear();
14
+ console.log(chalk.green(`✔ Cache cleared (${stats.size} entries removed)`));
15
+ } catch (error) {
16
+ if (error instanceof Error) {
17
+ console.error(chalk.red('❌ ' + error.message));
18
+ } else {
19
+ console.error(chalk.red('❌ Failed to clear cache'));
20
+ }
21
+ process.exit(1);
22
+ }
23
+ }