@entro314labs/ai-changelog-generator 3.2.0 → 3.3.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/CHANGELOG.md +41 -10
- package/ai-changelog-mcp.sh +0 -0
- package/ai-changelog.sh +0 -0
- package/bin/ai-changelog-dxt.js +0 -0
- package/package.json +72 -80
- package/src/ai-changelog-generator.js +11 -2
- package/src/application/orchestrators/changelog.orchestrator.js +12 -202
- package/src/cli.js +4 -5
- package/src/domains/ai/ai-analysis.service.js +2 -0
- package/src/domains/analysis/analysis.engine.js +758 -5
- package/src/domains/changelog/changelog.service.js +711 -13
- package/src/domains/changelog/workspace-changelog.service.js +429 -571
- package/src/domains/git/commit-tagger.js +552 -0
- package/src/domains/git/git-manager.js +357 -0
- package/src/domains/git/git.service.js +865 -16
- package/src/infrastructure/cli/cli.controller.js +14 -9
- package/src/infrastructure/config/configuration.manager.js +24 -2
- package/src/infrastructure/interactive/interactive-workflow.service.js +8 -1
- package/src/infrastructure/mcp/mcp-server.service.js +35 -11
- package/src/infrastructure/providers/core/base-provider.js +1 -1
- package/src/infrastructure/providers/implementations/anthropic.js +16 -173
- package/src/infrastructure/providers/implementations/azure.js +16 -63
- package/src/infrastructure/providers/implementations/dummy.js +13 -16
- package/src/infrastructure/providers/implementations/mock.js +13 -26
- package/src/infrastructure/providers/implementations/ollama.js +12 -4
- package/src/infrastructure/providers/implementations/openai.js +13 -165
- package/src/infrastructure/providers/provider-management.service.js +126 -412
- package/src/infrastructure/providers/utils/base-provider-helpers.js +11 -0
- package/src/shared/utils/cli-ui.js +1 -1
- package/src/shared/utils/diff-processor.js +21 -19
- package/src/shared/utils/error-classes.js +33 -0
- package/src/shared/utils/utils.js +65 -60
- package/src/domains/git/git-repository.analyzer.js +0 -678
package/CHANGELOG.md
CHANGED
|
@@ -5,22 +5,53 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [Unreleased]
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Next Release
|
|
11
|
+
- TBD
|
|
12
|
+
|
|
13
|
+
## [3.2.1] - 2025-08-10
|
|
9
14
|
|
|
10
15
|
### feat
|
|
11
|
-
- add
|
|
12
|
-
- add
|
|
13
|
-
- add
|
|
16
|
+
- add comprehensive test coverage with 100% test success rate
|
|
17
|
+
- add missing method implementations across all service classes
|
|
18
|
+
- add modern CI/CD pipeline with automated testing and publishing
|
|
19
|
+
- add Biome linting configuration for code quality
|
|
20
|
+
- add comprehensive error handling and validation
|
|
21
|
+
- add robust CLI timeout handling and graceful failures
|
|
22
|
+
- add professional documentation and provider setup guides
|
|
14
23
|
|
|
15
24
|
### fix
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
25
|
+
- fix AI provider initialization and isAvailable method calls
|
|
26
|
+
- fix configuration manager null safety with proper error handling
|
|
27
|
+
- fix CLI test timeouts and hanging commands
|
|
28
|
+
- fix missing boolean getters (hasAI, gitExists) in main facade
|
|
29
|
+
- fix homepage URL typo in package.json
|
|
30
|
+
- fix CI/CD workflow paths to match current project structure
|
|
31
|
+
- fix Node.js version consistency across all configurations
|
|
32
|
+
- fix Vitest reporter deprecation warnings
|
|
33
|
+
|
|
34
|
+
### test
|
|
35
|
+
- add 658 comprehensive tests with 100% pass rate
|
|
36
|
+
- add missing service method implementations for test compatibility
|
|
37
|
+
- add resilient CLI end-to-end testing with proper timeouts
|
|
38
|
+
- add comprehensive architecture and functionality testing
|
|
39
|
+
- add provider integration testing and validation
|
|
40
|
+
- add performance and memory usage testing
|
|
41
|
+
- add cross-platform compatibility testing
|
|
42
|
+
|
|
43
|
+
### build
|
|
44
|
+
- update to Node.js 22.x across all environments
|
|
45
|
+
- add pnpm workspace configuration for monorepo structure
|
|
46
|
+
- add Vitest testing framework with coverage reporting
|
|
47
|
+
- add modern GitHub Actions workflows for CI/CD
|
|
48
|
+
- standardize package management with pnpm
|
|
19
49
|
|
|
20
50
|
### docs
|
|
21
|
-
- update
|
|
22
|
-
-
|
|
23
|
-
-
|
|
51
|
+
- update comprehensive README with installation and usage
|
|
52
|
+
- add provider setup and troubleshooting documentation
|
|
53
|
+
- add environment variables and configuration guides
|
|
54
|
+
- update contributing guidelines and development setup
|
|
24
55
|
|
|
25
56
|
### chore
|
|
26
57
|
- update dependencies including version increments from 3.0.3 to 3.1.1
|
package/ai-changelog-mcp.sh
CHANGED
|
File without changes
|
package/ai-changelog.sh
CHANGED
|
File without changes
|
package/bin/ai-changelog-dxt.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entro314labs/ai-changelog-generator",
|
|
3
3
|
"displayName": "AI Changelog Generator",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.3.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "AI-powered changelog generator with MCP server support - works with most providers, online and local models",
|
|
7
7
|
"main": "src/ai-changelog-generator.js",
|
|
@@ -20,88 +20,39 @@
|
|
|
20
20
|
"LICENSE",
|
|
21
21
|
"CHANGELOG.md"
|
|
22
22
|
],
|
|
23
|
-
"scripts": {
|
|
24
|
-
"start": "node bin/ai-changelog.js",
|
|
25
|
-
"changelog": "node bin/ai-changelog.js",
|
|
26
|
-
"changelog:detailed": "node bin/ai-changelog.js --detailed",
|
|
27
|
-
"changelog:enterprise": "node bin/ai-changelog.js --enterprise",
|
|
28
|
-
"changelog:interactive": "node bin/ai-changelog.js --interactive",
|
|
29
|
-
"changelog:analyze": "node bin/ai-changelog.js --analyze",
|
|
30
|
-
"changelog:preview": "node bin/ai-changelog.js --dry-run",
|
|
31
|
-
"changelog:no-color": "node bin/ai-changelog.js --no-color",
|
|
32
|
-
"mcp": "node bin/ai-changelog-mcp.js",
|
|
33
|
-
"mcp:start": "node bin/ai-changelog-mcp.js",
|
|
34
|
-
"demo": "node test/test-end-to-end-full.js",
|
|
35
|
-
"lint": "exec biome lint src/",
|
|
36
|
-
"lint:fix": "exec biome lint --write src/",
|
|
37
|
-
"lint:fix-unsafe": "exec biome lint --unsafe --write src/",
|
|
38
|
-
"format": "exec biome format --write src/",
|
|
39
|
-
"format:unsafe": "exec biome format --write src/",
|
|
40
|
-
"format:check": "exec biome format src/",
|
|
41
|
-
"check": "exec biome check src/",
|
|
42
|
-
"check:fix": "exec biome check --write src/",
|
|
43
|
-
"test": "vitest run",
|
|
44
|
-
"test:watch": "vitest",
|
|
45
|
-
"test:ui": "vitest --ui",
|
|
46
|
-
"test:coverage": "vitest run --coverage",
|
|
47
|
-
"test:providers": "vitest run test/providers.test.js",
|
|
48
|
-
"test:cli": "vitest run test/cli.test.js",
|
|
49
|
-
"test:core": "vitest run test/core.test.js",
|
|
50
|
-
"test:services": "vitest run test/services.test.js",
|
|
51
|
-
"test:utils": "vitest run test/utils.test.js",
|
|
52
|
-
"test:integration": "vitest run test/integration.test.js",
|
|
53
|
-
"test:mcp": "vitest run test/mcp.test.js",
|
|
54
|
-
"test:styling": "vitest run test/cli-ui.test.js test/colors.test.js test/styling-integration.test.js",
|
|
55
|
-
"test:styling-e2e": "vitest run test/cli-styling-e2e.test.js --testTimeout=60000",
|
|
56
|
-
"test:legacy": "node test/test-runner.js comprehensive",
|
|
57
|
-
"test:git": "node src/domains/git/git.service.js info",
|
|
58
|
-
"setup": "node scripts/setup-azure-openai.js",
|
|
59
|
-
"config:create": "node src/infrastructure/config/configuration.manager.js create-sample",
|
|
60
|
-
"config:validate": "node src/infrastructure/config/configuration.manager.js validate",
|
|
61
|
-
"config:test-models": "node src/infrastructure/config/configuration.manager.js model-test",
|
|
62
|
-
"providers:test": "node test/test-providers.js",
|
|
63
|
-
"providers:validate": "node test/test-provider-switching.js",
|
|
64
|
-
"git:info": "node src/domains/git/git.service.js info",
|
|
65
|
-
"git:commits": "node src/domains/git/git.service.js commits 10",
|
|
66
|
-
"git:stats": "node src/domains/git/git.service.js stats 5",
|
|
67
|
-
"dxt:init": "npx @anthropic-ai/dxt init",
|
|
68
|
-
"dxt:pack": "npm run dxt:prepack && npx @anthropic-ai/dxt pack",
|
|
69
|
-
"dxt:prepack": "node -e \"const fs=require('fs'),path=require('path'); const src='node_modules/@modelcontextprotocol/sdk/dist', dest='node_modules/@modelcontextprotocol/sdk/dist'; if(fs.existsSync(src)) console.log('MCP SDK dist exists'); else console.error('MCP SDK dist missing');\"",
|
|
70
|
-
"dxt:validate": "npx @anthropic-ai/dxt validate",
|
|
71
|
-
"postinstall": "node -e \"console.log('\\n🎉 AI Changelog Generator installed!\\n\\n⚡ Quick Start:\\n ai-changelog - Generate changelog\\n ai-changelog --detailed - Detailed analysis\\n ai-changelog --interactive - Interactive mode\\n ai-changelog-mcp - Start MCP server\\n\\n🤖 AI Models Supported:\\n • GPT-4.1 series (1M context, 75% cost reduction)\\n • o3/o4 reasoning models (Azure-only)\\n • Automatic model selection\\n\\n📖 Docs: https://github.com/entro314-labs/AI-changelog-generator\\n\\n© All trademarks belong to their respective owners.\\n')\""
|
|
72
|
-
},
|
|
73
23
|
"dependencies": {
|
|
74
|
-
"@anthropic-ai/sdk": "^0.
|
|
75
|
-
"@aws-sdk/client-bedrock-runtime": "^3.
|
|
76
|
-
"@azure/identity": "^4.
|
|
24
|
+
"@anthropic-ai/sdk": "^0.67.0",
|
|
25
|
+
"@aws-sdk/client-bedrock-runtime": "^3.913.0",
|
|
26
|
+
"@azure/identity": "^4.13.0",
|
|
77
27
|
"@clack/prompts": "^0.11.0",
|
|
78
|
-
"@google/genai": "^1.
|
|
28
|
+
"@google/genai": "^1.25.0",
|
|
79
29
|
"@google/generative-ai": "^0.24.1",
|
|
80
|
-
"@huggingface/hub": "^2.
|
|
81
|
-
"@huggingface/inference": "^4.
|
|
82
|
-
"@lmstudio/sdk": "^1.
|
|
83
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
84
|
-
"@modelcontextprotocol/server-filesystem": "2025.
|
|
30
|
+
"@huggingface/hub": "^2.6.12",
|
|
31
|
+
"@huggingface/inference": "^4.11.3",
|
|
32
|
+
"@lmstudio/sdk": "^1.5.0",
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
34
|
+
"@modelcontextprotocol/server-filesystem": "2025.8.21",
|
|
85
35
|
"boxen": "^8.0.1",
|
|
86
|
-
"chalk": "^5.
|
|
36
|
+
"chalk": "^5.6.2",
|
|
87
37
|
"cli-table3": "^0.6.5",
|
|
88
|
-
"dotenv": "^17.2.
|
|
38
|
+
"dotenv": "^17.2.3",
|
|
89
39
|
"figures": "^6.1.0",
|
|
90
|
-
"google-auth-library": "^10.
|
|
40
|
+
"google-auth-library": "^10.4.1",
|
|
91
41
|
"gradient-string": "^3.0.0",
|
|
92
42
|
"js-yaml": "^4.1.0",
|
|
93
|
-
"ollama": "^0.
|
|
94
|
-
"openai": "^5.
|
|
95
|
-
"ora": "^
|
|
43
|
+
"ollama": "^0.6.0",
|
|
44
|
+
"openai": "^6.5.0",
|
|
45
|
+
"ora": "^9.0.0",
|
|
96
46
|
"yargs": "^18.0.0"
|
|
97
47
|
},
|
|
98
48
|
"devDependencies": {
|
|
99
|
-
"@anthropic-ai/
|
|
100
|
-
"@types/node": "24.
|
|
101
|
-
"@vitest/
|
|
102
|
-
"@vitest/
|
|
49
|
+
"@anthropic-ai/mcpb": "^1.1.1",
|
|
50
|
+
"@types/node": "24.8.1",
|
|
51
|
+
"@vitest/browser": "beta",
|
|
52
|
+
"@vitest/coverage-v8": "beta",
|
|
53
|
+
"@vitest/ui": "beta",
|
|
103
54
|
"tempy": "^3.1.0",
|
|
104
|
-
"vitest": "
|
|
55
|
+
"vitest": "beta"
|
|
105
56
|
},
|
|
106
57
|
"keywords": [
|
|
107
58
|
"changelog",
|
|
@@ -143,8 +94,8 @@
|
|
|
143
94
|
"access": "public"
|
|
144
95
|
},
|
|
145
96
|
"engines": {
|
|
146
|
-
"node": ">=22.
|
|
147
|
-
"pnpm": ">=
|
|
97
|
+
"node": ">=22.20.0",
|
|
98
|
+
"pnpm": ">=10.18.3"
|
|
148
99
|
},
|
|
149
100
|
"funding": {
|
|
150
101
|
"type": "github",
|
|
@@ -156,12 +107,53 @@
|
|
|
156
107
|
}
|
|
157
108
|
},
|
|
158
109
|
"volta": {
|
|
159
|
-
"node": "22.
|
|
160
|
-
"pnpm": "
|
|
110
|
+
"node": "22.20.0",
|
|
111
|
+
"pnpm": "10.18.3"
|
|
161
112
|
},
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
|
|
165
|
-
|
|
113
|
+
"scripts": {
|
|
114
|
+
"start": "node bin/ai-changelog.js",
|
|
115
|
+
"changelog": "node bin/ai-changelog.js",
|
|
116
|
+
"changelog:detailed": "node bin/ai-changelog.js --detailed",
|
|
117
|
+
"changelog:enterprise": "node bin/ai-changelog.js --enterprise",
|
|
118
|
+
"changelog:interactive": "node bin/ai-changelog.js --interactive",
|
|
119
|
+
"changelog:analyze": "node bin/ai-changelog.js --analyze",
|
|
120
|
+
"changelog:preview": "node bin/ai-changelog.js --dry-run",
|
|
121
|
+
"changelog:no-color": "node bin/ai-changelog.js --no-color",
|
|
122
|
+
"mcp": "node bin/ai-changelog-mcp.js",
|
|
123
|
+
"mcp:start": "node bin/ai-changelog-mcp.js",
|
|
124
|
+
"demo": "node test/test-end-to-end-full.js",
|
|
125
|
+
"lint": "exec biome lint src/",
|
|
126
|
+
"lint:fix": "exec biome lint --write src/",
|
|
127
|
+
"lint:fix-unsafe": "exec biome lint --unsafe --write src/",
|
|
128
|
+
"format": "exec biome format --write src/",
|
|
129
|
+
"format:unsafe": "exec biome format --write src/",
|
|
130
|
+
"format:check": "exec biome format src/",
|
|
131
|
+
"check": "exec biome check src/",
|
|
132
|
+
"check:fix": "exec biome check --write src/",
|
|
133
|
+
"test": "vitest run",
|
|
134
|
+
"test:watch": "vitest",
|
|
135
|
+
"test:ui": "vitest --ui",
|
|
136
|
+
"test:coverage": "vitest run --coverage",
|
|
137
|
+
"test:providers": "vitest run test/providers.test.js",
|
|
138
|
+
"test:cli": "vitest run test/cli.test.js",
|
|
139
|
+
"test:core": "vitest run test/core.test.js",
|
|
140
|
+
"test:services": "vitest run test/services.test.js",
|
|
141
|
+
"test:utils": "vitest run test/utils.test.js",
|
|
142
|
+
"test:integration": "vitest run test/integration.test.js",
|
|
143
|
+
"test:mcp": "vitest run test/mcp.test.js",
|
|
144
|
+
"test:styling": "vitest run test/cli-ui.test.js test/colors.test.js test/styling-integration.test.js",
|
|
145
|
+
"test:styling-e2e": "vitest run test/cli-styling-e2e.test.js --testTimeout=60000",
|
|
146
|
+
"test:legacy": "node test/test-runner.js comprehensive",
|
|
147
|
+
"test:git": "node src/domains/git/git.service.js info",
|
|
148
|
+
"setup": "node scripts/setup-azure-openai.js",
|
|
149
|
+
"config:create": "node src/infrastructure/config/configuration.manager.js create-sample",
|
|
150
|
+
"config:validate": "node src/infrastructure/config/configuration.manager.js validate",
|
|
151
|
+
"config:test-models": "node src/infrastructure/config/configuration.manager.js model-test",
|
|
152
|
+
"providers:test": "node test/test-providers.js",
|
|
153
|
+
"providers:validate": "node test/test-provider-switching.js",
|
|
154
|
+
"git:info": "node src/domains/git/git.service.js info",
|
|
155
|
+
"git:commits": "node src/domains/git/git.service.js commits 10",
|
|
156
|
+
"git:stats": "node src/domains/git/git.service.js stats 5",
|
|
157
|
+
"postinstall": "node -e \"console.log('\\n🎉 AI Changelog Generator installed!\\n\\n⚡ Quick Start:\\n ai-changelog - Generate changelog\\n ai-changelog --detailed - Detailed analysis\\n ai-changelog --interactive - Interactive mode\\n ai-changelog-mcp - Start MCP server\\n\\n🤖 AI Models Supported:\\n • GPT-4.1 series (1M context, 75% cost reduction)\\n • o3/o4 reasoning models (Azure-only)\\n • Automatic model selection\\n\\n📖 Docs: https://github.com/entro314-labs/AI-changelog-generator\\n\\n© All trademarks belong to their respective owners.\\n')\""
|
|
166
158
|
}
|
|
167
|
-
}
|
|
159
|
+
}
|
|
@@ -203,11 +203,20 @@ export class AIChangelogGenerator {
|
|
|
203
203
|
|
|
204
204
|
// Utility methods for backward compatibility
|
|
205
205
|
get hasAI() {
|
|
206
|
-
|
|
206
|
+
try {
|
|
207
|
+
return this.appService?.orchestrator?.aiProvider?.isAvailable()
|
|
208
|
+
} catch (_error) {
|
|
209
|
+
return false
|
|
210
|
+
}
|
|
207
211
|
}
|
|
208
212
|
|
|
209
213
|
get gitExists() {
|
|
210
|
-
|
|
214
|
+
try {
|
|
215
|
+
const isGitRepo = this.appService?.orchestrator?.gitManager?.isGitRepo
|
|
216
|
+
return Boolean(isGitRepo)
|
|
217
|
+
} catch (_error) {
|
|
218
|
+
return false
|
|
219
|
+
}
|
|
211
220
|
}
|
|
212
221
|
|
|
213
222
|
// Simple logging method
|
|
@@ -3,7 +3,9 @@ import process from 'node:process'
|
|
|
3
3
|
import { AIAnalysisService } from '../../domains/ai/ai-analysis.service.js'
|
|
4
4
|
import { AnalysisEngine } from '../../domains/analysis/analysis.engine.js'
|
|
5
5
|
import { ChangelogService } from '../../domains/changelog/changelog.service.js'
|
|
6
|
+
import { CommitTagger } from '../../domains/git/commit-tagger.js'
|
|
6
7
|
import { GitService } from '../../domains/git/git.service.js'
|
|
8
|
+
import { GitManager } from '../../domains/git/git-manager.js'
|
|
7
9
|
import { InteractiveStagingService } from '../../infrastructure/interactive/interactive-staging.service.js'
|
|
8
10
|
import { InteractiveWorkflowService } from '../../infrastructure/interactive/interactive-workflow.service.js'
|
|
9
11
|
import { ProviderManagerService } from '../../infrastructure/providers/provider-manager.service.js'
|
|
@@ -58,9 +60,9 @@ export class ChangelogOrchestrator {
|
|
|
58
60
|
})
|
|
59
61
|
this.aiProvider = this.providerManager.getActiveProvider()
|
|
60
62
|
|
|
61
|
-
// Create
|
|
62
|
-
this.gitManager =
|
|
63
|
-
this.tagger =
|
|
63
|
+
// Create proper implementations using the new classes
|
|
64
|
+
this.gitManager = new GitManager()
|
|
65
|
+
this.tagger = new CommitTagger()
|
|
64
66
|
this.promptEngine = await this.createPromptEngine()
|
|
65
67
|
|
|
66
68
|
// Initialize domain services with proper dependencies
|
|
@@ -121,207 +123,17 @@ export class ChangelogOrchestrator {
|
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
125
|
|
|
124
|
-
async createGitManager() {
|
|
125
|
-
const { execSync } = await this._getCachedImport('child_process')
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
isGitRepo: (() => {
|
|
129
|
-
try {
|
|
130
|
-
execSync('git rev-parse --git-dir', { stdio: 'ignore' })
|
|
131
|
-
return true
|
|
132
|
-
} catch {
|
|
133
|
-
return false
|
|
134
|
-
}
|
|
135
|
-
})(),
|
|
136
|
-
|
|
137
|
-
execGit(command) {
|
|
138
|
-
try {
|
|
139
|
-
return execSync(command, { encoding: 'utf8', stdio: 'pipe' })
|
|
140
|
-
} catch (error) {
|
|
141
|
-
// Enhanced error handling with more specific messages
|
|
142
|
-
if (error.code === 128) {
|
|
143
|
-
throw new Error(
|
|
144
|
-
`Git repository error: ${error.message.includes('not a git repository') ? 'Not in a git repository' : error.message}`
|
|
145
|
-
)
|
|
146
|
-
}
|
|
147
|
-
if (error.code === 129) {
|
|
148
|
-
throw new Error(`Git command syntax error: ${command}`)
|
|
149
|
-
}
|
|
150
|
-
throw new Error(`Git command failed (${command}): ${error.message}`)
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
|
|
154
|
-
execGitSafe(command) {
|
|
155
|
-
try {
|
|
156
|
-
return execSync(command, { encoding: 'utf8', stdio: 'pipe' })
|
|
157
|
-
} catch {
|
|
158
|
-
return ''
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
|
|
162
|
-
execGitShow(command) {
|
|
163
|
-
try {
|
|
164
|
-
return execSync(command, { encoding: 'utf8', stdio: 'pipe' })
|
|
165
|
-
} catch (_error) {
|
|
166
|
-
// console.warn(`Git command failed: ${command}`);
|
|
167
|
-
// console.warn(`Error: ${error.message}`);
|
|
168
|
-
return null
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
validateCommitHash(hash) {
|
|
173
|
-
try {
|
|
174
|
-
execSync(`git cat-file -e ${hash}`, { stdio: 'ignore' })
|
|
175
|
-
return true
|
|
176
|
-
} catch {
|
|
177
|
-
return false
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
|
|
181
|
-
getAllBranches() {
|
|
182
|
-
try {
|
|
183
|
-
const output = execSync('git branch -a', { encoding: 'utf8' })
|
|
184
|
-
return output
|
|
185
|
-
.split('\n')
|
|
186
|
-
.filter(Boolean)
|
|
187
|
-
.map((branch) => branch.trim().replace(/^\*\s*/, ''))
|
|
188
|
-
} catch {
|
|
189
|
-
return []
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
|
|
193
|
-
getUnmergedCommits() {
|
|
194
|
-
try {
|
|
195
|
-
const output = execSync('git log --oneline --no-merges HEAD ^origin/main', {
|
|
196
|
-
encoding: 'utf8',
|
|
197
|
-
})
|
|
198
|
-
return output.split('\n').filter(Boolean)
|
|
199
|
-
} catch {
|
|
200
|
-
return []
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
|
|
204
|
-
getDanglingCommits() {
|
|
205
|
-
try {
|
|
206
|
-
const output = execSync('git fsck --no-reflog | grep "dangling commit"', {
|
|
207
|
-
encoding: 'utf8',
|
|
208
|
-
})
|
|
209
|
-
return output.split('\n').filter(Boolean)
|
|
210
|
-
} catch {
|
|
211
|
-
return []
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
getUntrackedFiles() {
|
|
216
|
-
try {
|
|
217
|
-
const output = execSync('git ls-files --others --exclude-standard', { encoding: 'utf8' })
|
|
218
|
-
return output.split('\n').filter(Boolean)
|
|
219
|
-
} catch {
|
|
220
|
-
return []
|
|
221
|
-
}
|
|
222
|
-
},
|
|
223
|
-
|
|
224
|
-
getRecentCommits(limit = 10) {
|
|
225
|
-
try {
|
|
226
|
-
const output = execSync(`git log --oneline -${limit}`, { encoding: 'utf8' })
|
|
227
|
-
return output.split('\n').filter(Boolean)
|
|
228
|
-
} catch {
|
|
229
|
-
return []
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
|
|
233
|
-
getComprehensiveAnalysis() {
|
|
234
|
-
return {
|
|
235
|
-
totalCommits: this.getRecentCommits(1000).length,
|
|
236
|
-
branches: this.getAllBranches(),
|
|
237
|
-
untrackedFiles: this.getUntrackedFiles(),
|
|
238
|
-
}
|
|
239
|
-
},
|
|
240
|
-
|
|
241
|
-
hasFile(filename) {
|
|
242
|
-
try {
|
|
243
|
-
execSync(`test -f ${filename}`, { stdio: 'ignore' })
|
|
244
|
-
return true
|
|
245
|
-
} catch {
|
|
246
|
-
return false
|
|
247
|
-
}
|
|
248
|
-
},
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
async createTagger() {
|
|
253
|
-
const { analyzeSemanticChanges, analyzeFunctionalImpact } = await import(
|
|
254
|
-
'../../shared/utils/utils.js'
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
return {
|
|
258
|
-
analyzeCommit(commit) {
|
|
259
|
-
const semanticChanges = []
|
|
260
|
-
const breakingChanges = []
|
|
261
|
-
const categories = []
|
|
262
|
-
const tags = []
|
|
263
|
-
|
|
264
|
-
// Basic analysis based on commit message
|
|
265
|
-
const message = commit.message.toLowerCase()
|
|
266
|
-
|
|
267
|
-
if (message.includes('breaking') || message.includes('!:')) {
|
|
268
|
-
breakingChanges.push('Breaking change detected in commit message')
|
|
269
|
-
categories.push('breaking')
|
|
270
|
-
tags.push('breaking')
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (message.startsWith('feat')) {
|
|
274
|
-
categories.push('feature')
|
|
275
|
-
tags.push('feature')
|
|
276
|
-
} else if (message.startsWith('fix')) {
|
|
277
|
-
categories.push('fix')
|
|
278
|
-
tags.push('bugfix')
|
|
279
|
-
} else if (message.startsWith('docs')) {
|
|
280
|
-
categories.push('docs')
|
|
281
|
-
tags.push('documentation')
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Analyze files if available
|
|
285
|
-
if (commit.files && commit.files.length > 0) {
|
|
286
|
-
commit.files.forEach((file) => {
|
|
287
|
-
const semantic = analyzeSemanticChanges('', file.path)
|
|
288
|
-
if (semantic.frameworks) {
|
|
289
|
-
semanticChanges.push(...semantic.frameworks)
|
|
290
|
-
}
|
|
291
|
-
})
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Determine importance
|
|
295
|
-
let importance = 'medium'
|
|
296
|
-
if (breakingChanges.length > 0 || commit.files?.length > 10) {
|
|
297
|
-
importance = 'high'
|
|
298
|
-
} else if (categories.includes('docs') || commit.files?.length < 3) {
|
|
299
|
-
importance = 'low'
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
return {
|
|
303
|
-
semanticChanges,
|
|
304
|
-
breakingChanges,
|
|
305
|
-
categories,
|
|
306
|
-
importance,
|
|
307
|
-
tags,
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
126
|
async createPromptEngine() {
|
|
314
|
-
const { buildEnhancedPrompt } = await import('../../shared/utils/utils.js')
|
|
315
|
-
|
|
316
127
|
return {
|
|
317
128
|
systemPrompts: {
|
|
318
129
|
master:
|
|
319
|
-
'You are an expert software analyst specializing in code change analysis and changelog generation.',
|
|
320
|
-
standard:
|
|
130
|
+
'You are an expert software analyst specializing in code change analysis and changelog generation. Analyze code changes with precision and provide definitive, factual assessments. Never use uncertain language like "likely", "probably", "appears to", "seems to", or "possibly". Base your analysis solely on the actual changes shown in the code diffs.',
|
|
131
|
+
standard:
|
|
132
|
+
'Provide clear, concise analysis focusing on the practical impact of changes. Be definitive and factual in your descriptions.',
|
|
321
133
|
detailed:
|
|
322
|
-
'Provide comprehensive technical analysis with detailed explanations and implications.',
|
|
134
|
+
'Provide comprehensive technical analysis with detailed explanations and implications. Use precise, confident language backed by evidence from the code changes.',
|
|
323
135
|
enterprise:
|
|
324
|
-
'Provide enterprise-grade analysis suitable for stakeholder communication and decision-making.',
|
|
136
|
+
'Provide enterprise-grade analysis suitable for stakeholder communication and decision-making. Use authoritative, factual language that conveys confidence and accuracy.',
|
|
325
137
|
changesAnalysis: 'You are an expert at analyzing code changes and their business impact.',
|
|
326
138
|
},
|
|
327
139
|
|
|
@@ -399,9 +211,7 @@ export class ChangelogOrchestrator {
|
|
|
399
211
|
async runInteractive() {
|
|
400
212
|
await this.ensureInitialized()
|
|
401
213
|
|
|
402
|
-
const { runInteractiveMode
|
|
403
|
-
'../../shared/utils/utils.js'
|
|
404
|
-
)
|
|
214
|
+
const { runInteractiveMode } = await import('../../shared/utils/utils.js')
|
|
405
215
|
const { confirm } = await this._getCachedImport('@clack/prompts')
|
|
406
216
|
|
|
407
217
|
console.log(colors.processingMessage('🎮 Starting interactive mode...'))
|
|
@@ -1276,7 +1086,7 @@ Generate only the commit message, no explanation.`
|
|
|
1276
1086
|
if (!this.aiAnalysisService?.aiProvider?.isAvailable()) {
|
|
1277
1087
|
throw new Error('AI provider not available for suggestions')
|
|
1278
1088
|
}
|
|
1279
|
-
|
|
1089
|
+
|
|
1280
1090
|
const { select } = await this._getCachedImport('@clack/prompts')
|
|
1281
1091
|
|
|
1282
1092
|
console.log(colors.processingMessage('🤖 Generating AI suggestions...'))
|
package/src/cli.js
CHANGED
|
@@ -11,7 +11,6 @@ import { hideBin } from 'yargs/helpers'
|
|
|
11
11
|
import yargs from 'yargs/yargs'
|
|
12
12
|
|
|
13
13
|
import { AIChangelogGenerator } from './ai-changelog-generator.js'
|
|
14
|
-
import colors from './shared/constants/colors.js'
|
|
15
14
|
import { EnhancedConsole, SimpleSpinner } from './shared/utils/cli-ui.js'
|
|
16
15
|
|
|
17
16
|
async function runCLI() {
|
|
@@ -91,14 +90,14 @@ async function runCLI() {
|
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
if (argv.validate) {
|
|
94
|
-
|
|
93
|
+
EnhancedConsole.info('🔧 Validating configuration...')
|
|
95
94
|
await generator.validateConfiguration()
|
|
96
|
-
|
|
95
|
+
EnhancedConsole.success('✅ Configuration is valid')
|
|
97
96
|
return
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
if (argv.interactive) {
|
|
101
|
-
|
|
100
|
+
EnhancedConsole.info('🎮 Starting interactive mode...')
|
|
102
101
|
await generator.runInteractive()
|
|
103
102
|
return
|
|
104
103
|
}
|
|
@@ -170,7 +169,7 @@ export { runCLI }
|
|
|
170
169
|
// If this file is run directly, execute CLI
|
|
171
170
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
172
171
|
runCLI().catch((error) => {
|
|
173
|
-
|
|
172
|
+
EnhancedConsole.error('CLI Error:', error.message)
|
|
174
173
|
process.exit(1)
|
|
175
174
|
})
|
|
176
175
|
}
|