@entro314labs/ai-changelog-generator 3.2.1 ā 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/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 +5 -4
- 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 +714 -37
- package/src/domains/changelog/changelog.service.js +615 -30
- package/src/domains/changelog/workspace-changelog.service.js +418 -627
- 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/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
|
+
}
|
|
@@ -204,16 +204,17 @@ export class AIChangelogGenerator {
|
|
|
204
204
|
// Utility methods for backward compatibility
|
|
205
205
|
get hasAI() {
|
|
206
206
|
try {
|
|
207
|
-
return this.appService?.orchestrator?.aiProvider?.isAvailable()
|
|
208
|
-
} catch (
|
|
207
|
+
return this.appService?.orchestrator?.aiProvider?.isAvailable()
|
|
208
|
+
} catch (_error) {
|
|
209
209
|
return false
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
get gitExists() {
|
|
214
214
|
try {
|
|
215
|
-
|
|
216
|
-
|
|
215
|
+
const isGitRepo = this.appService?.orchestrator?.gitManager?.isGitRepo
|
|
216
|
+
return Boolean(isGitRepo)
|
|
217
|
+
} catch (_error) {
|
|
217
218
|
return false
|
|
218
219
|
}
|
|
219
220
|
}
|
|
@@ -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
|
}
|