commitect 1.0.2 → 1.1.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/README.md CHANGED
@@ -21,7 +21,7 @@
21
21
  ## Installation
22
22
 
23
23
  ```bash
24
- npm install -g commitect
24
+ npm install commitect
25
25
  ```
26
26
 
27
27
  ## Usage
@@ -49,7 +49,7 @@ commitect copy
49
49
 
50
50
  **Output:**
51
51
  ```
52
- Commit message copied to clipboard
52
+ Commit message copied to clipboard
53
53
  ```
54
54
 
55
55
  ### Auto-Commit
@@ -62,7 +62,7 @@ commitect commit
62
62
 
63
63
  **Output:**
64
64
  ```
65
- Committed: Feature: Add user authentication with JWT tokens
65
+ Committed: Feature: Add user authentication with JWT tokens
66
66
  ```
67
67
 
68
68
  ### View History
@@ -100,7 +100,7 @@ commitect clear-cache
100
100
 
101
101
  **Output:**
102
102
  ```
103
- Cache cleared (15 entries removed)
103
+ Cache cleared (15 entries removed)
104
104
  ```
105
105
 
106
106
  ## How It Works
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAuCpD"}
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAqCpD"}
@@ -5,34 +5,32 @@ export async function analyzeCommand() {
5
5
  try {
6
6
  // Validate git repository
7
7
  if (!isGitRepository()) {
8
- console.error(chalk.red('Not a git repository'));
8
+ console.error(chalk.red('Not a git repository'));
9
9
  process.exit(1);
10
10
  }
11
11
  // Check for changes
12
12
  if (!hasChanges()) {
13
- console.log(chalk.yellow('⚠ No changes detected'));
13
+ console.log(chalk.yellow('⚠ No changes detected'));
14
14
  process.exit(0);
15
15
  }
16
16
  // Get diff
17
17
  const diff = getGitDiff();
18
18
  if (!diff.trim()) {
19
- console.log(chalk.yellow('⚠ No changes to analyze'));
19
+ console.log(chalk.yellow('⚠ No changes to analyze'));
20
20
  process.exit(0);
21
21
  }
22
22
  // Generate commit message
23
- console.log(chalk.blue('🔍 Analyzing changes...'));
23
+ console.log(chalk.blue('🔎︎ Analyzing changes...'));
24
24
  const suggestion = await generateCommitMessage(diff);
25
25
  // Print result
26
- console.log('');
27
26
  console.log(chalk.green(`${suggestion.intent}: ${suggestion.message}`));
28
- console.log('');
29
27
  }
30
28
  catch (error) {
31
29
  if (error instanceof Error) {
32
- console.error(chalk.red('' + error.message));
30
+ console.error(chalk.red('' + error.message));
33
31
  }
34
32
  else {
35
- console.error(chalk.red('An unexpected error occurred'));
33
+ console.error(chalk.red('An unexpected error occurred'));
36
34
  }
37
35
  process.exit(1);
38
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QACH,0BAA0B;QAC1B,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,WAAW;QACX,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAErD,eAAe;QACf,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAElB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC;QACH,0BAA0B;QAC1B,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,WAAW;QACX,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAErD,eAAe;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAE1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -4,18 +4,18 @@ export function clearCacheCommand() {
4
4
  try {
5
5
  const stats = commitCache.getStats();
6
6
  if (stats.size === 0) {
7
- console.log(chalk.yellow('ℹ Cache is already empty'));
7
+ console.log(chalk.yellow('ℹ Cache is already empty'));
8
8
  return;
9
9
  }
10
10
  commitCache.clear();
11
- console.log(chalk.green(`✔ Cache cleared (${stats.size} entries removed)`));
11
+ console.log(chalk.green(`✓ Cache cleared (${stats.size} entries removed)`));
12
12
  }
13
13
  catch (error) {
14
14
  if (error instanceof Error) {
15
- console.error(chalk.red('' + error.message));
15
+ console.error(chalk.red('' + error.message));
16
16
  }
17
17
  else {
18
- console.error(chalk.red('Failed to clear cache'));
18
+ console.error(chalk.red('Failed to clear cache'));
19
19
  }
20
20
  process.exit(1);
21
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"clear-cache.js","sourceRoot":"","sources":["../../src/commands/clear-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC;QAErC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,KAAK,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"clear-cache.js","sourceRoot":"","sources":["../../src/commands/clear-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC;QAErC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QAED,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,KAAK,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC;IAC/E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -5,36 +5,36 @@ export async function commitCommand() {
5
5
  try {
6
6
  // Validate git repository
7
7
  if (!isGitRepository()) {
8
- console.error(chalk.red('Not a git repository'));
8
+ console.error(chalk.red('Not a git repository'));
9
9
  process.exit(1);
10
10
  }
11
11
  // Check for changes
12
12
  if (!hasChanges()) {
13
- console.log(chalk.yellow('⚠ No changes to commit'));
13
+ console.log(chalk.yellow('⚠ No changes to commit'));
14
14
  process.exit(0);
15
15
  }
16
16
  // Get diff
17
17
  const diff = getGitDiff();
18
18
  if (!diff.trim()) {
19
- console.log(chalk.yellow('⚠ No changes to commit'));
19
+ console.log(chalk.yellow('⚠ No changes to commit'));
20
20
  process.exit(0);
21
21
  }
22
22
  // Generate commit message
23
- console.log(chalk.blue('🔍 Generating commit message...'));
23
+ console.log(chalk.blue('🔎︎ Generating commit message...'));
24
24
  const suggestion = await generateCommitMessage(diff);
25
25
  // Build commit message as "intent: message"
26
26
  const commitMessage = `${suggestion.intent}: ${suggestion.message}`;
27
27
  // Execute git commit
28
- console.log(chalk.blue('💾 Committing changes...'));
28
+ console.log(chalk.blue('🖫 Committing changes...'));
29
29
  executeCommit(commitMessage);
30
- console.log(chalk.green('Committed: ') + commitMessage);
30
+ console.log(chalk.green('Committed: ') + commitMessage);
31
31
  }
32
32
  catch (error) {
33
33
  if (error instanceof Error) {
34
- console.error(chalk.red('' + error.message));
34
+ console.error(chalk.red('' + error.message));
35
35
  }
36
36
  else {
37
- console.error(chalk.red('An unexpected error occurred'));
37
+ console.error(chalk.red('An unexpected error occurred'));
38
38
  }
39
39
  process.exit(1);
40
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,0BAA0B;QAC1B,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,WAAW;QACX,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAC3D,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAErD,4CAA4C;QAC5C,MAAM,aAAa,GAAG,GAAG,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;QAEpE,qBAAqB;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACpD,aAAa,CAAC,aAAa,CAAC,CAAC;QAE7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC,CAAC;IAE5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"commit.js","sourceRoot":"","sources":["../../src/commands/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,0BAA0B;QAC1B,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,WAAW;QACX,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAErD,4CAA4C;QAC5C,MAAM,aAAa,GAAG,GAAG,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;QAEpE,qBAAqB;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACrD,aAAa,CAAC,aAAa,CAAC,CAAC;QAE7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,aAAa,CAAC,CAAC;IAE7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -6,35 +6,35 @@ export async function copyCommand() {
6
6
  try {
7
7
  // Validate git repository
8
8
  if (!isGitRepository()) {
9
- console.error(chalk.red('Not a git repository'));
9
+ console.error(chalk.red('Not a git repository'));
10
10
  process.exit(1);
11
11
  }
12
12
  // Check for changes
13
13
  if (!hasChanges()) {
14
- console.log(chalk.yellow('⚠ No changes detected'));
14
+ console.log(chalk.yellow('⚠ No changes detected'));
15
15
  process.exit(0);
16
16
  }
17
17
  // Get diff
18
18
  const diff = getGitDiff();
19
19
  if (!diff.trim()) {
20
- console.log(chalk.yellow('⚠ No changes to analyze'));
20
+ console.log(chalk.yellow('⚠ No changes to analyze'));
21
21
  process.exit(0);
22
22
  }
23
23
  // Generate commit message
24
- console.log(chalk.blue('🔍 Generating commit message...'));
24
+ console.log(chalk.blue('🔎︎ Generating commit message...'));
25
25
  const suggestion = await generateCommitMessage(diff);
26
26
  // Build commit message as "intent: message"
27
27
  const commitMessage = `${suggestion.intent}: ${suggestion.message}`;
28
28
  // Copy to clipboard
29
29
  await clipboardy.write(commitMessage);
30
- console.log(chalk.green('Commit message copied to clipboard'));
30
+ console.log(chalk.green('Commit message copied to clipboard'));
31
31
  }
32
32
  catch (error) {
33
33
  if (error instanceof Error) {
34
- console.error(chalk.red('' + error.message));
34
+ console.error(chalk.red('' + error.message));
35
35
  }
36
36
  else {
37
- console.error(chalk.red('An unexpected error occurred'));
37
+ console.error(chalk.red('An unexpected error occurred'));
38
38
  }
39
39
  process.exit(1);
40
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/commands/copy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,0BAA0B;QAC1B,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,WAAW;QACX,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAC3D,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAErD,4CAA4C;QAC5C,MAAM,aAAa,GAAG,GAAG,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;QAEpE,oBAAoB;QACpB,MAAM,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAEtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC;IAEnE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/commands/copy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,0BAA0B;QAC1B,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,WAAW;QACX,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAErD,4CAA4C;QAC5C,MAAM,aAAa,GAAG,GAAG,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;QAEpE,oBAAoB;QACpB,MAAM,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAEtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;IAEpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import chalk from 'chalk';
2
- const VERSION = '1.0.1';
3
- const GITHUB_REPO = 'https://github.com/Mohammed_3tef/CommiTect_CLI';
2
+ const VERSION = '1.1.0';
3
+ const GITHUB_REPO = 'https://github.com/Mohammed-3tef/CommiTect_CLI';
4
4
  const ISSUES_URL = GITHUB_REPO + '/issues';
5
5
  export function helpCommand() {
6
6
  console.log('');
@@ -27,10 +27,10 @@ export function historyCommand() {
27
27
  }
28
28
  catch (error) {
29
29
  if (error instanceof Error) {
30
- console.error(chalk.red('' + error.message));
30
+ console.error(chalk.red('' + error.message));
31
31
  }
32
32
  else {
33
- console.error(chalk.red('Failed to load history'));
33
+ console.error(chalk.red('Failed to load history'));
34
34
  }
35
35
  process.exit(1);
36
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC;QAEzC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC,CAAC;YAC7F,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC/B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAE5C,+CAA+C;YAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACzG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,cAAc,EAAE,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC;YACxE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,MAAM,yBAAyB,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5G,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAElB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,SAAiB;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,GAAG,GAAG,SAAS,CAAC;IAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAEpC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACnD,CAAC;SAAM,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACtD,CAAC;SAAM,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,OAAO,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,OAAO,UAAU,CAAC;IACpB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/commands/history.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ const program = new Command();
10
10
  program
11
11
  .name('commitect')
12
12
  .description('Zero-config Git Commit Assistant')
13
- .version('1.0.0');
13
+ .version('1.1.0');
14
14
  program
15
15
  .command('analyze')
16
16
  .description('Analyze changes and suggest a commit message')
@@ -2,5 +2,10 @@ export interface CommitSuggestion {
2
2
  intent: string;
3
3
  message: string;
4
4
  }
5
- export declare function generateCommitMessage(diff: string): Promise<CommitSuggestion>;
5
+ interface ChangeSummary {
6
+ total?: number;
7
+ renamed?: number;
8
+ }
9
+ export declare function generateCommitMessage(diff: string, summary?: ChangeSummary): Promise<CommitSuggestion>;
10
+ export {};
6
11
  //# sourceMappingURL=llm.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/services/llm.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAyBD,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsF5G"}
@@ -1,9 +1,11 @@
1
1
  import axios from 'axios';
2
+ import crypto from 'crypto';
2
3
  import { commitCache } from '../utils/cache.js';
3
4
  const API_ENDPOINT = 'http://commitintentdetector.runasp.net/api/Commit/analyze';
4
- export async function generateCommitMessage(diff) {
5
+ export async function generateCommitMessage(diff, summary) {
6
+ const diffHash = crypto.createHash('sha1').update(diff).digest('hex');
5
7
  // Check cache first
6
- const cached = commitCache.get(diff);
8
+ const cached = commitCache.get(diffHash);
7
9
  if (cached) {
8
10
  return cached;
9
11
  }
@@ -15,7 +17,7 @@ export async function generateCommitMessage(diff) {
15
17
  headers: {
16
18
  'Content-Type': 'application/json'
17
19
  },
18
- timeout: 30000 // 30 second timeout
20
+ timeout: 10000
19
21
  });
20
22
  // API returns: { intent: "Intent: Feature\nMessage: Add subtraction support function" }
21
23
  const data = response.data;
@@ -24,7 +26,7 @@ export async function generateCommitMessage(diff) {
24
26
  }
25
27
  const result = parseResponse(data.intent);
26
28
  // Cache the result
27
- commitCache.set(diff, result.intent, result.message);
29
+ commitCache.set(diffHash, result.intent, result.message);
28
30
  return result;
29
31
  }
30
32
  catch (error) {
@@ -34,25 +36,24 @@ export async function generateCommitMessage(diff) {
34
36
  // Handle rate limiting (429)
35
37
  if (axiosError.response?.status === 429) {
36
38
  if (attempt < maxRetries) {
37
- await sleep(1000 * attempt); // Exponential backoff
39
+ await sleep(500 * Math.pow(2, attempt));
38
40
  continue;
39
41
  }
40
- throw new Error('API rate limit reached. Please try again later.');
42
+ break;
41
43
  }
42
44
  // Handle server errors (5xx) - retry
43
45
  if (axiosError.response?.status && axiosError.response.status >= 500) {
44
46
  if (attempt < maxRetries) {
45
- await sleep(1000 * attempt);
47
+ await sleep(500 * Math.pow(2, attempt));
46
48
  continue;
47
49
  }
48
50
  }
49
51
  // Handle network errors - retry
50
52
  if (axiosError.code === 'ECONNREFUSED' || axiosError.code === 'ETIMEDOUT') {
51
53
  if (attempt < maxRetries) {
52
- await sleep(1000 * attempt);
54
+ await sleep(500 * Math.pow(2, attempt));
53
55
  continue;
54
56
  }
55
- throw new Error('Unable to connect to API. Please check your network connection.');
56
57
  }
57
58
  }
58
59
  // Don't retry on client errors (4xx) except 429
@@ -61,12 +62,13 @@ export async function generateCommitMessage(diff) {
61
62
  }
62
63
  // Retry on other errors
63
64
  if (attempt < maxRetries) {
64
- await sleep(1000 * attempt);
65
+ await sleep(500 * Math.pow(2, attempt));
65
66
  continue;
66
67
  }
67
68
  }
68
69
  }
69
- throw new Error('Failed to generate commit message. Please check your API configuration.');
70
+ console.warn('⚠ AI service unavailable, using fallback commit message.');
71
+ return generateFallbackCommit(diff, summary);
70
72
  }
71
73
  function parseResponse(response) {
72
74
  const lines = response.trim().split('\n');
@@ -88,6 +90,184 @@ function parseResponse(response) {
88
90
  }
89
91
  return { intent, message };
90
92
  }
93
+ function extractFilesFromDiff(diff) {
94
+ const files = new Set();
95
+ const regex = /^diff --git a\/(.+?) b\/(.+)$/gm;
96
+ let match;
97
+ while ((match = regex.exec(diff))) {
98
+ files.add(match[2]);
99
+ }
100
+ return [...files];
101
+ }
102
+ function isTrivialWhitespace(lines) {
103
+ return lines.every(l => /^[+-]\s*$/.test(l) ||
104
+ /^[+-]\s*[{}();,]*\s*$/.test(l));
105
+ }
106
+ /**
107
+ * Analyze the diff content for patterns
108
+ * @param diff - The git diff string
109
+ * @param summary - Optional summary with file change counts
110
+ * @returns Analysis results with detected patterns
111
+ */
112
+ function analyzeDiff(diff, summary = {}) {
113
+ const lines = diff.split('\n');
114
+ const lowerDiff = diff.toLowerCase();
115
+ const files = extractFilesFromDiff(diff);
116
+ const addedLines = lines.filter(l => l.startsWith('+') && !l.startsWith('+++'));
117
+ const removedLines = lines.filter(l => l.startsWith('-') && !l.startsWith('---'));
118
+ const additions = addedLines.length;
119
+ const deletions = removedLines.length;
120
+ const matchesAny = (patterns, text) => patterns.some(p => p.test(text));
121
+ const patterns = {
122
+ bugFix: [/\b(fix(e[ds])?|bug|error|issue|crash|incorrect|fault)\b/i],
123
+ testFix: [/\b(fix|repair|correct).*(test|spec)\b/i],
124
+ refactor: [/\b(refactor|cleanup|simplify|restructure|reorganize)\b/i],
125
+ style: [/\b(format|lint|prettier|indent)\b/i]
126
+ };
127
+ const hasDocsChange = files.some(f => /\.(md|rst|txt)$/i.test(f) || /readme/i.test(f));
128
+ const hasTestChange = files.some(f => /(__tests__|\.test\.|\.spec\.)/i.test(f));
129
+ const hasConfigChange = files.some(f => /\.(json|ya?ml|env|toml)$/i.test(f));
130
+ const hasDependencyChange = files.some(f => /(package(-lock)?\.json|requirements\.txt|go\.mod|pom\.xml)/i.test(f));
131
+ const hasNewFunction = addedLines.some(l => /^\+\s*(export\s+)?(async\s+)?function\s+\w+/.test(l) ||
132
+ /^\+\s*(export\s+)?const\s+\w+\s*=\s*(async\s*)?\(/.test(l));
133
+ const hasNewClass = addedLines.some(l => /^\+\s*(export\s+)?class\s+\w+/.test(l));
134
+ const hasNewEndpoint = addedLines.some(l => /\b(app|router)\.(get|post|put|delete|patch)\b/i.test(l)) ||
135
+ /^\+\s*@(Get|Post|Put|Delete|Patch)\b/m.test(diff);
136
+ const hasNewComponent = files.some(f => /\.(jsx|tsx)$/i.test(f)) &&
137
+ addedLines.some(l => /^\+\s*(export\s+)?(function|const)\s+[A-Z]\w*/.test(l));
138
+ const hasWhitespaceOnly = additions + deletions > 0 &&
139
+ isTrivialWhitespace([...addedLines, ...removedLines]);
140
+ return {
141
+ hasBugFix: matchesAny(patterns.bugFix, diff),
142
+ hasTestFix: hasTestChange && matchesAny(patterns.testFix, diff),
143
+ hasNewFunction,
144
+ hasNewClass,
145
+ hasNewEndpoint,
146
+ hasNewComponent,
147
+ hasRefactor: matchesAny(patterns.refactor, diff),
148
+ hasRename: (summary.renamed ?? 0) > 0,
149
+ hasMovedCode: (summary.renamed ?? 0) > 0 && additions > 0 && deletions > 0,
150
+ hasDocsChange,
151
+ hasCommentChange: addedLines.some(l => /^\+\s*(\/\/|\/\*|\*)/.test(l)),
152
+ hasTestChange,
153
+ hasDeletions: deletions > 0,
154
+ hasStyleChange: matchesAny(patterns.style, diff),
155
+ hasWhitespaceOnly,
156
+ hasConfigChange,
157
+ hasDependencyChange,
158
+ additions,
159
+ deletions,
160
+ hasChanges: additions + deletions > 0
161
+ };
162
+ }
163
+ /**
164
+ * Determine the commit intent type based on analysis
165
+ * @param analysis - Analysis results from analyzeDiff
166
+ * @param summary - Changes summary
167
+ * @returns The intent type string
168
+ */
169
+ function determineIntent(analysis, summary = {}) {
170
+ if (!analysis.hasChanges)
171
+ return 'Chore';
172
+ if (analysis.hasBugFix || analysis.hasTestFix)
173
+ return 'Bug Fix';
174
+ if (analysis.hasTestChange && !analysis.hasBugFix)
175
+ return 'Test';
176
+ if (analysis.hasDocsChange)
177
+ return 'Documentation';
178
+ if (analysis.hasRefactor ||
179
+ analysis.hasMovedCode ||
180
+ (analysis.deletions > analysis.additions * 2))
181
+ return 'Refactor';
182
+ if (analysis.hasNewFunction ||
183
+ analysis.hasNewClass ||
184
+ analysis.hasNewComponent ||
185
+ analysis.hasNewEndpoint)
186
+ return 'Feature';
187
+ if (analysis.hasDependencyChange || analysis.hasConfigChange)
188
+ return 'Chore';
189
+ if (analysis.hasStyleChange || analysis.hasWhitespaceOnly)
190
+ return 'Style';
191
+ return 'Update';
192
+ }
193
+ /**
194
+ * Generate a descriptive commit message based on analysis
195
+ * @param analysis - Analysis results from analyzeDiff
196
+ * @param intent - The determined intent type
197
+ * @returns A commit message string
198
+ */
199
+ function generateMessage(analysis, intent, summary = {}) {
200
+ const fileCount = summary.total;
201
+ const hasFileCount = typeof fileCount === 'number' && fileCount > 0;
202
+ const fileWord = fileCount === 1 ? 'file' : 'files';
203
+ switch (intent) {
204
+ case 'Bug Fix':
205
+ return analysis.hasTestFix
206
+ ? hasFileCount
207
+ ? `fix failing tests in ${fileCount} ${fileWord}`
208
+ : 'fix failing tests'
209
+ : hasFileCount
210
+ ? `fix issues in ${fileCount} ${fileWord}`
211
+ : 'fix issues';
212
+ case 'Feature':
213
+ if (analysis.hasNewEndpoint)
214
+ return 'add new API endpoints';
215
+ if (analysis.hasNewComponent)
216
+ return 'add new components';
217
+ if (analysis.hasNewClass || analysis.hasNewFunction)
218
+ return hasFileCount
219
+ ? `add new functionality to ${fileCount} ${fileWord}`
220
+ : 'add new functionality';
221
+ return hasFileCount
222
+ ? `implement new features in ${fileCount} ${fileWord}`
223
+ : 'implement new features';
224
+ case 'Refactor':
225
+ if (analysis.hasMovedCode)
226
+ return hasFileCount
227
+ ? `restructure code in ${fileCount} ${fileWord}`
228
+ : 'restructure code';
229
+ if (analysis.deletions > analysis.additions * 2)
230
+ return hasFileCount
231
+ ? `remove unused code from ${fileCount} ${fileWord}`
232
+ : 'remove unused code';
233
+ return hasFileCount
234
+ ? `refactor code in ${fileCount} ${fileWord}`
235
+ : 'refactor code';
236
+ case 'Test':
237
+ return hasFileCount
238
+ ? `add/update tests in ${fileCount} ${fileWord}`
239
+ : 'add/update tests';
240
+ case 'Chore':
241
+ if (analysis.hasDependencyChange)
242
+ return 'update dependencies';
243
+ if (analysis.hasConfigChange)
244
+ return 'update configuration files';
245
+ return 'update project configuration';
246
+ case 'Style':
247
+ return hasFileCount
248
+ ? `format and style ${fileCount} ${fileWord}`
249
+ : 'format and style code';
250
+ case 'Documentation':
251
+ return hasFileCount
252
+ ? fileCount === 1
253
+ ? 'update documentation'
254
+ : `update documentation in ${fileCount} ${fileWord}`
255
+ : 'update documentation';
256
+ default:
257
+ return hasFileCount
258
+ ? `update ${fileCount} ${fileWord}`
259
+ : 'update code';
260
+ }
261
+ }
262
+ function generateFallbackCommit(diff, summary) {
263
+ const diffHash = crypto.createHash('sha1').update(diff).digest('hex');
264
+ const analysis = analyzeDiff(diff, summary);
265
+ const intent = determineIntent(analysis, summary);
266
+ const message = generateMessage(analysis, intent, summary);
267
+ const result = { intent, message };
268
+ commitCache.set(diffHash, intent, message);
269
+ return result;
270
+ }
91
271
  function sleep(ms) {
92
272
  return new Promise(resolve => setTimeout(resolve, ms));
93
273
  }
@@ -1 +1 @@
1
- {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/services/llm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/services/llm.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commitect",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Zero-config Git Commit Assistant CLI",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
Binary file
@@ -6,13 +6,13 @@ export async function analyzeCommand(): Promise<void> {
6
6
  try {
7
7
  // Validate git repository
8
8
  if (!isGitRepository()) {
9
- console.error(chalk.red('Not a git repository'));
9
+ console.error(chalk.red('Not a git repository'));
10
10
  process.exit(1);
11
11
  }
12
12
 
13
13
  // Check for changes
14
14
  if (!hasChanges()) {
15
- console.log(chalk.yellow('⚠ No changes detected'));
15
+ console.log(chalk.yellow('⚠ No changes detected'));
16
16
  process.exit(0);
17
17
  }
18
18
 
@@ -20,24 +20,22 @@ export async function analyzeCommand(): Promise<void> {
20
20
  const diff = getGitDiff();
21
21
 
22
22
  if (!diff.trim()) {
23
- console.log(chalk.yellow('⚠ No changes to analyze'));
23
+ console.log(chalk.yellow('⚠ No changes to analyze'));
24
24
  process.exit(0);
25
25
  }
26
26
 
27
27
  // Generate commit message
28
- console.log(chalk.blue('🔍 Analyzing changes...'));
28
+ console.log(chalk.blue('🔎︎ Analyzing changes...'));
29
29
  const suggestion = await generateCommitMessage(diff);
30
30
 
31
31
  // Print result
32
- console.log('');
33
32
  console.log(chalk.green(`${suggestion.intent}: ${suggestion.message}`));
34
- console.log('');
35
33
 
36
34
  } catch (error) {
37
35
  if (error instanceof Error) {
38
- console.error(chalk.red('' + error.message));
36
+ console.error(chalk.red('' + error.message));
39
37
  } else {
40
- console.error(chalk.red('An unexpected error occurred'));
38
+ console.error(chalk.red('An unexpected error occurred'));
41
39
  }
42
40
  process.exit(1);
43
41
  }
@@ -6,17 +6,17 @@ export function clearCacheCommand(): void {
6
6
  const stats = commitCache.getStats();
7
7
 
8
8
  if (stats.size === 0) {
9
- console.log(chalk.yellow('ℹ Cache is already empty'));
9
+ console.log(chalk.yellow('ℹ Cache is already empty'));
10
10
  return;
11
11
  }
12
12
 
13
13
  commitCache.clear();
14
- console.log(chalk.green(`✔ Cache cleared (${stats.size} entries removed)`));
14
+ console.log(chalk.green(`✓ Cache cleared (${stats.size} entries removed)`));
15
15
  } catch (error) {
16
16
  if (error instanceof Error) {
17
- console.error(chalk.red('' + error.message));
17
+ console.error(chalk.red('' + error.message));
18
18
  } else {
19
- console.error(chalk.red('Failed to clear cache'));
19
+ console.error(chalk.red('Failed to clear cache'));
20
20
  }
21
21
  process.exit(1);
22
22
  }
@@ -6,13 +6,13 @@ export async function commitCommand(): Promise<void> {
6
6
  try {
7
7
  // Validate git repository
8
8
  if (!isGitRepository()) {
9
- console.error(chalk.red('Not a git repository'));
9
+ console.error(chalk.red('Not a git repository'));
10
10
  process.exit(1);
11
11
  }
12
12
 
13
13
  // Check for changes
14
14
  if (!hasChanges()) {
15
- console.log(chalk.yellow('⚠ No changes to commit'));
15
+ console.log(chalk.yellow('⚠ No changes to commit'));
16
16
  process.exit(0);
17
17
  }
18
18
 
@@ -20,28 +20,28 @@ export async function commitCommand(): Promise<void> {
20
20
  const diff = getGitDiff();
21
21
 
22
22
  if (!diff.trim()) {
23
- console.log(chalk.yellow('⚠ No changes to commit'));
23
+ console.log(chalk.yellow('⚠ No changes to commit'));
24
24
  process.exit(0);
25
25
  }
26
26
 
27
27
  // Generate commit message
28
- console.log(chalk.blue('🔍 Generating commit message...'));
28
+ console.log(chalk.blue('🔎︎ Generating commit message...'));
29
29
  const suggestion = await generateCommitMessage(diff);
30
30
 
31
31
  // Build commit message as "intent: message"
32
32
  const commitMessage = `${suggestion.intent}: ${suggestion.message}`;
33
33
 
34
34
  // Execute git commit
35
- console.log(chalk.blue('💾 Committing changes...'));
35
+ console.log(chalk.blue('🖫 Committing changes...'));
36
36
  executeCommit(commitMessage);
37
37
 
38
- console.log(chalk.green('Committed: ') + commitMessage);
38
+ console.log(chalk.green('Committed: ') + commitMessage);
39
39
 
40
40
  } catch (error) {
41
41
  if (error instanceof Error) {
42
- console.error(chalk.red('' + error.message));
42
+ console.error(chalk.red('' + error.message));
43
43
  } else {
44
- console.error(chalk.red('An unexpected error occurred'));
44
+ console.error(chalk.red('An unexpected error occurred'));
45
45
  }
46
46
  process.exit(1);
47
47
  }
@@ -7,13 +7,13 @@ export async function copyCommand(): Promise<void> {
7
7
  try {
8
8
  // Validate git repository
9
9
  if (!isGitRepository()) {
10
- console.error(chalk.red('Not a git repository'));
10
+ console.error(chalk.red('Not a git repository'));
11
11
  process.exit(1);
12
12
  }
13
13
 
14
14
  // Check for changes
15
15
  if (!hasChanges()) {
16
- console.log(chalk.yellow('⚠ No changes detected'));
16
+ console.log(chalk.yellow('⚠ No changes detected'));
17
17
  process.exit(0);
18
18
  }
19
19
 
@@ -21,12 +21,12 @@ export async function copyCommand(): Promise<void> {
21
21
  const diff = getGitDiff();
22
22
 
23
23
  if (!diff.trim()) {
24
- console.log(chalk.yellow('⚠ No changes to analyze'));
24
+ console.log(chalk.yellow('⚠ No changes to analyze'));
25
25
  process.exit(0);
26
26
  }
27
27
 
28
28
  // Generate commit message
29
- console.log(chalk.blue('🔍 Generating commit message...'));
29
+ console.log(chalk.blue('🔎︎ Generating commit message...'));
30
30
  const suggestion = await generateCommitMessage(diff);
31
31
 
32
32
  // Build commit message as "intent: message"
@@ -35,13 +35,13 @@ export async function copyCommand(): Promise<void> {
35
35
  // Copy to clipboard
36
36
  await clipboardy.write(commitMessage);
37
37
 
38
- console.log(chalk.green('Commit message copied to clipboard'));
38
+ console.log(chalk.green('Commit message copied to clipboard'));
39
39
 
40
40
  } catch (error) {
41
41
  if (error instanceof Error) {
42
- console.error(chalk.red('' + error.message));
42
+ console.error(chalk.red('' + error.message));
43
43
  } else {
44
- console.error(chalk.red('An unexpected error occurred'));
44
+ console.error(chalk.red('An unexpected error occurred'));
45
45
  }
46
46
  process.exit(1);
47
47
  }
@@ -1,7 +1,7 @@
1
1
  import chalk from 'chalk';
2
2
 
3
- const VERSION = '1.0.1';
4
- const GITHUB_REPO = 'https://github.com/Mohammed_3tef/CommiTect_CLI';
3
+ const VERSION = '1.1.0';
4
+ const GITHUB_REPO = 'https://github.com/Mohammed-3tef/CommiTect_CLI';
5
5
  const ISSUES_URL = GITHUB_REPO + '/issues';
6
6
 
7
7
  export function helpCommand(): void {
@@ -33,9 +33,9 @@ export function historyCommand(): void {
33
33
 
34
34
  } catch (error) {
35
35
  if (error instanceof Error) {
36
- console.error(chalk.red('' + error.message));
36
+ console.error(chalk.red('' + error.message));
37
37
  } else {
38
- console.error(chalk.red('Failed to load history'));
38
+ console.error(chalk.red('Failed to load history'));
39
39
  }
40
40
  process.exit(1);
41
41
  }
package/src/index.ts CHANGED
@@ -12,7 +12,7 @@ const program = new Command();
12
12
  program
13
13
  .name('commitect')
14
14
  .description('Zero-config Git Commit Assistant')
15
- .version('1.0.0');
15
+ .version('1.1.0');
16
16
 
17
17
  program
18
18
  .command('analyze')
@@ -1,4 +1,5 @@
1
1
  import axios, { AxiosError } from 'axios';
2
+ import crypto from 'crypto';
2
3
  import { commitCache } from '../utils/cache.js';
3
4
 
4
5
  export interface CommitSuggestion {
@@ -6,14 +7,45 @@ export interface CommitSuggestion {
6
7
  message: string;
7
8
  }
8
9
 
10
+ interface DiffAnalysis {
11
+ hasBugFix: boolean;
12
+ hasTestFix: boolean;
13
+ hasNewFunction: boolean;
14
+ hasNewClass: boolean;
15
+ hasNewEndpoint: boolean;
16
+ hasNewComponent: boolean;
17
+ hasRefactor: boolean;
18
+ hasRename: boolean;
19
+ hasMovedCode: boolean;
20
+ hasDocsChange: boolean;
21
+ hasCommentChange: boolean;
22
+ hasTestChange: boolean;
23
+ hasDeletions: boolean;
24
+ hasStyleChange: boolean;
25
+ hasWhitespaceOnly: boolean;
26
+ hasConfigChange: boolean;
27
+ hasDependencyChange: boolean;
28
+ additions: number;
29
+ deletions: number;
30
+ hasChanges: boolean;
31
+ }
32
+
33
+ interface ChangeSummary {
34
+ total?: number;
35
+ renamed?: number;
36
+ }
37
+
9
38
  const API_ENDPOINT = 'http://commitintentdetector.runasp.net/api/Commit/analyze';
10
39
 
11
- export async function generateCommitMessage(diff: string): Promise<CommitSuggestion> {
40
+ export async function generateCommitMessage(diff: string, summary?: ChangeSummary): Promise<CommitSuggestion> {
41
+ const diffHash = crypto.createHash('sha1').update(diff).digest('hex');
42
+
12
43
  // Check cache first
13
- const cached = commitCache.get(diff);
44
+ const cached = commitCache.get(diffHash);
14
45
  if (cached) {
15
46
  return cached;
16
47
  }
48
+
17
49
  const maxRetries = 3;
18
50
  let lastError: Error | null = null;
19
51
 
@@ -26,7 +58,7 @@ export async function generateCommitMessage(diff: string): Promise<CommitSuggest
26
58
  headers: {
27
59
  'Content-Type': 'application/json'
28
60
  },
29
- timeout: 30000 // 30 second timeout
61
+ timeout: 10000
30
62
  }
31
63
  );
32
64
 
@@ -40,7 +72,7 @@ export async function generateCommitMessage(diff: string): Promise<CommitSuggest
40
72
  const result = parseResponse(data.intent);
41
73
 
42
74
  // Cache the result
43
- commitCache.set(diff, result.intent, result.message);
75
+ commitCache.set(diffHash, result.intent, result.message);
44
76
 
45
77
  return result;
46
78
 
@@ -53,16 +85,16 @@ export async function generateCommitMessage(diff: string): Promise<CommitSuggest
53
85
  // Handle rate limiting (429)
54
86
  if (axiosError.response?.status === 429) {
55
87
  if (attempt < maxRetries) {
56
- await sleep(1000 * attempt); // Exponential backoff
88
+ await sleep(500 * Math.pow(2, attempt));
57
89
  continue;
58
90
  }
59
- throw new Error('API rate limit reached. Please try again later.');
91
+ break;
60
92
  }
61
93
 
62
94
  // Handle server errors (5xx) - retry
63
95
  if (axiosError.response?.status && axiosError.response.status >= 500) {
64
96
  if (attempt < maxRetries) {
65
- await sleep(1000 * attempt);
97
+ await sleep(500 * Math.pow(2, attempt));
66
98
  continue;
67
99
  }
68
100
  }
@@ -70,10 +102,9 @@ export async function generateCommitMessage(diff: string): Promise<CommitSuggest
70
102
  // Handle network errors - retry
71
103
  if (axiosError.code === 'ECONNREFUSED' || axiosError.code === 'ETIMEDOUT') {
72
104
  if (attempt < maxRetries) {
73
- await sleep(1000 * attempt);
105
+ await sleep(500 * Math.pow(2, attempt));
74
106
  continue;
75
107
  }
76
- throw new Error('Unable to connect to API. Please check your network connection.');
77
108
  }
78
109
  }
79
110
 
@@ -84,13 +115,14 @@ export async function generateCommitMessage(diff: string): Promise<CommitSuggest
84
115
 
85
116
  // Retry on other errors
86
117
  if (attempt < maxRetries) {
87
- await sleep(1000 * attempt);
118
+ await sleep(500 * Math.pow(2, attempt));
88
119
  continue;
89
120
  }
90
121
  }
91
122
  }
92
123
 
93
- throw new Error('Failed to generate commit message. Please check your API configuration.');
124
+ console.warn('⚠ AI service unavailable, using fallback commit message.');
125
+ return generateFallbackCommit(diff, summary);
94
126
  }
95
127
 
96
128
  function parseResponse(response: string): CommitSuggestion {
@@ -118,6 +150,245 @@ function parseResponse(response: string): CommitSuggestion {
118
150
  return { intent, message };
119
151
  }
120
152
 
153
+ function extractFilesFromDiff(diff: string): string[] {
154
+ const files = new Set<string>();
155
+ const regex = /^diff --git a\/(.+?) b\/(.+)$/gm;
156
+ let match;
157
+ while ((match = regex.exec(diff))) {
158
+ files.add(match[2]);
159
+ }
160
+ return [...files];
161
+ }
162
+
163
+ function isTrivialWhitespace(lines: string[]): boolean {
164
+ return lines.every(l =>
165
+ /^[+-]\s*$/.test(l) ||
166
+ /^[+-]\s*[{}();,]*\s*$/.test(l)
167
+ );
168
+ }
169
+
170
+ /**
171
+ * Analyze the diff content for patterns
172
+ * @param diff - The git diff string
173
+ * @param summary - Optional summary with file change counts
174
+ * @returns Analysis results with detected patterns
175
+ */
176
+ function analyzeDiff(diff: string, summary: ChangeSummary = {}): DiffAnalysis {
177
+ const lines = diff.split('\n');
178
+ const lowerDiff = diff.toLowerCase();
179
+ const files = extractFilesFromDiff(diff);
180
+
181
+ const addedLines = lines.filter(l => l.startsWith('+') && !l.startsWith('+++'));
182
+ const removedLines = lines.filter(l => l.startsWith('-') && !l.startsWith('---'));
183
+
184
+ const additions = addedLines.length;
185
+ const deletions = removedLines.length;
186
+
187
+ const matchesAny = (patterns: RegExp[], text: string): boolean =>
188
+ patterns.some(p => p.test(text));
189
+
190
+ const patterns = {
191
+ bugFix: [/\b(fix(e[ds])?|bug|error|issue|crash|incorrect|fault)\b/i],
192
+ testFix: [/\b(fix|repair|correct).*(test|spec)\b/i],
193
+ refactor: [/\b(refactor|cleanup|simplify|restructure|reorganize)\b/i],
194
+ style: [/\b(format|lint|prettier|indent)\b/i]
195
+ };
196
+
197
+ const hasDocsChange = files.some(f =>
198
+ /\.(md|rst|txt)$/i.test(f) || /readme/i.test(f)
199
+ );
200
+
201
+ const hasTestChange = files.some(f =>
202
+ /(__tests__|\.test\.|\.spec\.)/i.test(f)
203
+ );
204
+
205
+ const hasConfigChange = files.some(f =>
206
+ /\.(json|ya?ml|env|toml)$/i.test(f)
207
+ );
208
+
209
+ const hasDependencyChange = files.some(f =>
210
+ /(package(-lock)?\.json|requirements\.txt|go\.mod|pom\.xml)/i.test(f)
211
+ );
212
+
213
+ const hasNewFunction =
214
+ addedLines.some(l =>
215
+ /^\+\s*(export\s+)?(async\s+)?function\s+\w+/.test(l) ||
216
+ /^\+\s*(export\s+)?const\s+\w+\s*=\s*(async\s*)?\(/.test(l)
217
+ );
218
+
219
+ const hasNewClass =
220
+ addedLines.some(l =>
221
+ /^\+\s*(export\s+)?class\s+\w+/.test(l)
222
+ );
223
+
224
+ const hasNewEndpoint =
225
+ addedLines.some(l =>
226
+ /\b(app|router)\.(get|post|put|delete|patch)\b/i.test(l)
227
+ ) ||
228
+ /^\+\s*@(Get|Post|Put|Delete|Patch)\b/m.test(diff);
229
+
230
+ const hasNewComponent =
231
+ files.some(f => /\.(jsx|tsx)$/i.test(f)) &&
232
+ addedLines.some(l =>
233
+ /^\+\s*(export\s+)?(function|const)\s+[A-Z]\w*/.test(l)
234
+ );
235
+
236
+ const hasWhitespaceOnly =
237
+ additions + deletions > 0 &&
238
+ isTrivialWhitespace([...addedLines, ...removedLines]);
239
+
240
+ return {
241
+ hasBugFix: matchesAny(patterns.bugFix, diff),
242
+ hasTestFix: hasTestChange && matchesAny(patterns.testFix, diff),
243
+
244
+ hasNewFunction,
245
+ hasNewClass,
246
+ hasNewEndpoint,
247
+ hasNewComponent,
248
+
249
+ hasRefactor: matchesAny(patterns.refactor, diff),
250
+
251
+ hasRename: (summary.renamed ?? 0) > 0,
252
+ hasMovedCode: (summary.renamed ?? 0) > 0 && additions > 0 && deletions > 0,
253
+
254
+ hasDocsChange,
255
+ hasCommentChange: addedLines.some(l => /^\+\s*(\/\/|\/\*|\*)/.test(l)),
256
+ hasTestChange,
257
+
258
+ hasDeletions: deletions > 0,
259
+ hasStyleChange: matchesAny(patterns.style, diff),
260
+
261
+ hasWhitespaceOnly,
262
+ hasConfigChange,
263
+ hasDependencyChange,
264
+
265
+ additions,
266
+ deletions,
267
+ hasChanges: additions + deletions > 0
268
+ };
269
+ }
270
+
271
+ /**
272
+ * Determine the commit intent type based on analysis
273
+ * @param analysis - Analysis results from analyzeDiff
274
+ * @param summary - Changes summary
275
+ * @returns The intent type string
276
+ */
277
+ function determineIntent(analysis: DiffAnalysis, summary: ChangeSummary = {}): string {
278
+ if (!analysis.hasChanges) return 'Chore';
279
+
280
+ if (analysis.hasBugFix || analysis.hasTestFix) return 'Bug Fix';
281
+ if (analysis.hasTestChange && !analysis.hasBugFix) return 'Test';
282
+ if (analysis.hasDocsChange) return 'Documentation';
283
+
284
+ if (
285
+ analysis.hasRefactor ||
286
+ analysis.hasMovedCode ||
287
+ (analysis.deletions > analysis.additions * 2)
288
+ )
289
+ return 'Refactor';
290
+
291
+ if (
292
+ analysis.hasNewFunction ||
293
+ analysis.hasNewClass ||
294
+ analysis.hasNewComponent ||
295
+ analysis.hasNewEndpoint
296
+ )
297
+ return 'Feature';
298
+
299
+ if (analysis.hasDependencyChange || analysis.hasConfigChange) return 'Chore';
300
+ if (analysis.hasStyleChange || analysis.hasWhitespaceOnly) return 'Style';
301
+
302
+ return 'Update';
303
+ }
304
+
305
+ /**
306
+ * Generate a descriptive commit message based on analysis
307
+ * @param analysis - Analysis results from analyzeDiff
308
+ * @param intent - The determined intent type
309
+ * @returns A commit message string
310
+ */
311
+ function generateMessage(analysis: DiffAnalysis, intent: string, summary: ChangeSummary = {}): string {
312
+ const fileCount = summary.total;
313
+ const hasFileCount = typeof fileCount === 'number' && fileCount > 0;
314
+ const fileWord = fileCount === 1 ? 'file' : 'files';
315
+
316
+ switch (intent) {
317
+ case 'Bug Fix':
318
+ return analysis.hasTestFix
319
+ ? hasFileCount
320
+ ? `fix failing tests in ${fileCount} ${fileWord}`
321
+ : 'fix failing tests'
322
+ : hasFileCount
323
+ ? `fix issues in ${fileCount} ${fileWord}`
324
+ : 'fix issues';
325
+
326
+ case 'Feature':
327
+ if (analysis.hasNewEndpoint) return 'add new API endpoints';
328
+ if (analysis.hasNewComponent) return 'add new components';
329
+ if (analysis.hasNewClass || analysis.hasNewFunction)
330
+ return hasFileCount
331
+ ? `add new functionality to ${fileCount} ${fileWord}`
332
+ : 'add new functionality';
333
+ return hasFileCount
334
+ ? `implement new features in ${fileCount} ${fileWord}`
335
+ : 'implement new features';
336
+
337
+ case 'Refactor':
338
+ if (analysis.hasMovedCode)
339
+ return hasFileCount
340
+ ? `restructure code in ${fileCount} ${fileWord}`
341
+ : 'restructure code';
342
+ if (analysis.deletions > analysis.additions * 2)
343
+ return hasFileCount
344
+ ? `remove unused code from ${fileCount} ${fileWord}`
345
+ : 'remove unused code';
346
+ return hasFileCount
347
+ ? `refactor code in ${fileCount} ${fileWord}`
348
+ : 'refactor code';
349
+
350
+ case 'Test':
351
+ return hasFileCount
352
+ ? `add/update tests in ${fileCount} ${fileWord}`
353
+ : 'add/update tests';
354
+
355
+ case 'Chore':
356
+ if (analysis.hasDependencyChange) return 'update dependencies';
357
+ if (analysis.hasConfigChange) return 'update configuration files';
358
+ return 'update project configuration';
359
+
360
+ case 'Style':
361
+ return hasFileCount
362
+ ? `format and style ${fileCount} ${fileWord}`
363
+ : 'format and style code';
364
+
365
+ case 'Documentation':
366
+ return hasFileCount
367
+ ? fileCount === 1
368
+ ? 'update documentation'
369
+ : `update documentation in ${fileCount} ${fileWord}`
370
+ : 'update documentation';
371
+
372
+ default:
373
+ return hasFileCount
374
+ ? `update ${fileCount} ${fileWord}`
375
+ : 'update code';
376
+ }
377
+ }
378
+
379
+ function generateFallbackCommit(diff: string, summary?: ChangeSummary): CommitSuggestion {
380
+ const diffHash = crypto.createHash('sha1').update(diff).digest('hex');
381
+
382
+ const analysis = analyzeDiff(diff, summary);
383
+ const intent = determineIntent(analysis, summary);
384
+ const message = generateMessage(analysis, intent, summary);
385
+
386
+ const result = { intent, message };
387
+ commitCache.set(diffHash, intent, message);
388
+
389
+ return result;
390
+ }
391
+
121
392
  function sleep(ms: number): Promise<void> {
122
393
  return new Promise(resolve => setTimeout(resolve, ms));
123
394
  }