@entro314labs/ai-changelog-generator 3.3.0 → 3.6.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 +42 -2
- package/README.md +21 -1
- package/bin/ai-changelog-dxt.js +6 -3
- package/manifest.json +177 -0
- package/package.json +29 -26
- package/src/application/orchestrators/changelog.orchestrator.js +7 -1
- package/src/cli.js +12 -0
- package/src/domains/changelog/changelog.service.js +8 -2
- package/src/domains/changelog/workspace-changelog.service.js +44 -12
- package/src/infrastructure/config/configuration.manager.js +1 -9
- package/src/infrastructure/mcp/mcp-server.service.js +72 -23
- package/src/shared/utils/cli-ui.js +7 -9
- package/src/shared/utils/utils.js +19 -4
- package/types/index.d.ts +61 -68
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
10
10
|
### Next Release
|
|
11
11
|
- TBD
|
|
12
12
|
|
|
13
|
+
## [3.6.0] - 2025-11-27
|
|
14
|
+
|
|
15
|
+
### Feat
|
|
16
|
+
- **MCPB Support**: Added full support for Model Context Protocol Bundle (MCPB) extension format.
|
|
17
|
+
- **Packaging**: Updated manifest and packaging for seamless MCP server integration.
|
|
18
|
+
|
|
19
|
+
### Fix
|
|
20
|
+
- **Dry Run**: Fixed `dry-run` mode to correctly skip file writing while preserving output preview.
|
|
21
|
+
- **CLI**: Fixed interactive mode timeouts in non-TTY/CI environments.
|
|
22
|
+
- **MCP Server**: Fixed `ReferenceError` by using dynamic imports for `child_process` in ESM environment.
|
|
23
|
+
- **Validation**: Fixed `WorkspaceChangelogService` validation to correctly detect git repositories.
|
|
24
|
+
- **UI**: Fixed `EnhancedConsole.metrics` method shadowing in CLI UI utilities.
|
|
25
|
+
- **Tests**: Fixed integration test failures in styling and workspace services.
|
|
26
|
+
|
|
27
|
+
### Test
|
|
28
|
+
- **Coverage**: Validated full test suite with 696 passing tests.
|
|
29
|
+
- **Mocking**: Fixed mocking strategies in styling integration tests.
|
|
30
|
+
|
|
31
|
+
### Chore
|
|
32
|
+
- **Dependencies**: Updated project dependencies and type definitions.
|
|
33
|
+
- **Audit**: Verified project robustness and MCP tool integration.
|
|
34
|
+
|
|
35
|
+
## [3.3.0] - 2025-10-19
|
|
36
|
+
|
|
37
|
+
### Refactor
|
|
38
|
+
- **Architecture**: Major refactor of git management with new `GitManager` and `CommitTagger` domains.
|
|
39
|
+
- **Services**: Re-architected `AnalysisEngine`, `ChangelogService`, and `WorkspaceChangelogService` for better separation of concerns.
|
|
40
|
+
- **Config**: Modernized `biome.json` and `package.json` configurations.
|
|
41
|
+
|
|
42
|
+
### Feat
|
|
43
|
+
- **Git Analysis**: Enhanced merge commit analysis and processing.
|
|
44
|
+
- **Configuration**: Added support for `merge` commit type in configuration.
|
|
45
|
+
|
|
46
|
+
### Fix
|
|
47
|
+
- **Reliability**: Resolved intermittent test failures and improved test suite reliability.
|
|
48
|
+
- **Error Handling**: Added comprehensive error classes and improved exception handling.
|
|
49
|
+
|
|
50
|
+
### Test
|
|
51
|
+
- **New Tests**: Added `missing-functionality.test.js` covering edge cases and new architectural components.
|
|
52
|
+
|
|
13
53
|
## [3.2.1] - 2025-08-10
|
|
14
54
|
|
|
15
55
|
### feat
|
|
@@ -22,7 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
22
62
|
- add professional documentation and provider setup guides
|
|
23
63
|
|
|
24
64
|
### fix
|
|
25
|
-
- fix AI provider initialization and isAvailable method calls
|
|
65
|
+
- fix AI provider initialization and isAvailable method calls
|
|
26
66
|
- fix configuration manager null safety with proper error handling
|
|
27
67
|
- fix CLI test timeouts and hanging commands
|
|
28
68
|
- fix missing boolean getters (hasAI, gitExists) in main facade
|
|
@@ -31,7 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
31
71
|
- fix Node.js version consistency across all configurations
|
|
32
72
|
- fix Vitest reporter deprecation warnings
|
|
33
73
|
|
|
34
|
-
### test
|
|
74
|
+
### test
|
|
35
75
|
- add 658 comprehensive tests with 100% pass rate
|
|
36
76
|
- add missing service method implementations for test compatibility
|
|
37
77
|
- add resilient CLI end-to-end testing with proper timeouts
|
package/README.md
CHANGED
|
@@ -133,7 +133,7 @@ ai-changelog --help
|
|
|
133
133
|
# Generate changelog from recent commits
|
|
134
134
|
./ai-changelog.sh
|
|
135
135
|
|
|
136
|
-
# Interactive mode with guided setup
|
|
136
|
+
# Interactive mode with guided setup
|
|
137
137
|
./ai-changelog.sh --interactive
|
|
138
138
|
|
|
139
139
|
# Analyze working directory changes
|
|
@@ -351,9 +351,29 @@ ai-changelog health --detailed
|
|
|
351
351
|
- **[AI Provider Setup](./docs/providers.md)** - Configure OpenAI, Claude, and other providers
|
|
352
352
|
- **[Configuration Reference](./docs/configuration.md)** - All YAML and environment options
|
|
353
353
|
- **[MCP Integration](./docs/mcp-integration.md)** - Claude Desktop and MCP server setup
|
|
354
|
+
- **[Desktop Extension (MCPB)](./MCPB_BUILD.md)** - Build and package as Claude Desktop Extension
|
|
354
355
|
- **[API Reference](./docs/api-reference.md)** - All commands, options, and programmatic usage
|
|
355
356
|
- **[Demo Media](./docs/media/)** - Interactive demos, GIFs, and video walkthroughs
|
|
356
357
|
|
|
358
|
+
### Claude Desktop Extension
|
|
359
|
+
|
|
360
|
+
Install AI Changelog Generator in Claude Desktop with **one click** using the MCPB (MCP Bundle) format:
|
|
361
|
+
|
|
362
|
+
1. Download the latest `.mcpb` file from [Releases](https://github.com/entro314-labs/AI-changelog-generator/releases)
|
|
363
|
+
2. Open Claude Desktop → Settings → Extensions
|
|
364
|
+
3. Drag and drop the `.mcpb` file
|
|
365
|
+
4. Click "Install"
|
|
366
|
+
|
|
367
|
+
No configuration files, no terminal commands - just drag, drop, and start generating changelogs!
|
|
368
|
+
|
|
369
|
+
**For developers:** Learn how to build and package the extension in [MCPB_BUILD.md](./MCPB_BUILD.md)
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
# Build Desktop Extension
|
|
373
|
+
pnpm mcpb:validate # Validate manifest
|
|
374
|
+
pnpm mcpb:pack # Create .mcpb file
|
|
375
|
+
```
|
|
376
|
+
|
|
357
377
|
## Contributing
|
|
358
378
|
|
|
359
379
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
package/bin/ai-changelog-dxt.js
CHANGED
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* AI Changelog Generator - Claude Desktop Extension Entry Point
|
|
5
|
-
* Optimized for
|
|
5
|
+
* Optimized for MCPB (MCP Bundle) packaging and Claude Desktop integration
|
|
6
|
+
*
|
|
7
|
+
* Note: This file is maintained for backward compatibility.
|
|
8
|
+
* The main MCP server entry point is bin/ai-changelog-mcp.js
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
11
|
import AIChangelogMCPServer from '../src/infrastructure/mcp/mcp-server.service.js'
|
|
9
12
|
import { runMCPServer, setupProcessErrorHandlers } from '../src/shared/utils/cli-entry-utils.js'
|
|
10
13
|
|
|
11
|
-
// Setup error handlers for
|
|
14
|
+
// Setup error handlers for MCPB environment
|
|
12
15
|
setupProcessErrorHandlers('AI Changelog Generator - Claude Desktop Extension')
|
|
13
16
|
|
|
14
|
-
//
|
|
17
|
+
// MCPB-specific initialization (legacy DXT compatibility)
|
|
15
18
|
async function initializeDXTServer() {
|
|
16
19
|
await runMCPServer(
|
|
17
20
|
'AI Changelog Generator - Claude Desktop Extension',
|
package/manifest.json
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest_version": "0.3",
|
|
3
|
+
"name": "ai-changelog-generator",
|
|
4
|
+
"display_name": "AI Changelog Generator",
|
|
5
|
+
"version": "3.6.0",
|
|
6
|
+
"description": "AI-powered changelog generator with MCP server support - works with most providers, online and local models",
|
|
7
|
+
"long_description": "Generate intelligent changelogs from git commits using AI. Supports multiple providers including OpenAI, Claude, Gemini, Ollama, and LM Studio. Perfect for automating release documentation with smart commit analysis and categorization.\n\nFeatures:\n- Automatic changelog generation from git commits\n- Working directory change analysis\n- Multiple AI provider support (OpenAI, Azure, Claude, Gemini, Ollama, LM Studio)\n- Interactive and batch modes\n- Repository health analysis\n- Branch analysis and recommendations\n- Commit categorization and impact assessment",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "entro314-labs",
|
|
10
|
+
"email": "hey@entro314.com",
|
|
11
|
+
"url": "https://github.com/entro314-labs"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/entro314-labs/AI-changelog-generator.git"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/entro314-labs/AI-changelog-generator",
|
|
18
|
+
"documentation": "https://github.com/entro314-labs/AI-changelog-generator#readme",
|
|
19
|
+
"support": "https://github.com/entro314-labs/AI-changelog-generator/issues",
|
|
20
|
+
"icon": "icon.png",
|
|
21
|
+
"server": {
|
|
22
|
+
"type": "node",
|
|
23
|
+
"entry_point": "bin/ai-changelog-mcp.js",
|
|
24
|
+
"mcp_config": {
|
|
25
|
+
"command": "node",
|
|
26
|
+
"args": ["${__dirname}/bin/ai-changelog-mcp.js"],
|
|
27
|
+
"env": {
|
|
28
|
+
"AI_PROVIDER": "${user_config.AI_PROVIDER}",
|
|
29
|
+
"OPENAI_API_KEY": "${user_config.OPENAI_API_KEY}",
|
|
30
|
+
"AZURE_OPENAI_KEY": "${user_config.AZURE_OPENAI_KEY}",
|
|
31
|
+
"AZURE_OPENAI_ENDPOINT": "${user_config.AZURE_OPENAI_ENDPOINT}",
|
|
32
|
+
"AZURE_OPENAI_DEPLOYMENT_NAME": "${user_config.AZURE_OPENAI_DEPLOYMENT_NAME}",
|
|
33
|
+
"ANTHROPIC_API_KEY": "${user_config.ANTHROPIC_API_KEY}",
|
|
34
|
+
"GOOGLE_API_KEY": "${user_config.GOOGLE_API_KEY}",
|
|
35
|
+
"HUGGINGFACE_API_KEY": "${user_config.HUGGINGFACE_API_KEY}",
|
|
36
|
+
"VERTEX_PROJECT_ID": "${user_config.VERTEX_PROJECT_ID}",
|
|
37
|
+
"OLLAMA_HOST": "${user_config.OLLAMA_HOST}",
|
|
38
|
+
"LMSTUDIO_API_BASE": "${user_config.LMSTUDIO_API_BASE}",
|
|
39
|
+
"DEFAULT_ANALYSIS_MODE": "${user_config.DEFAULT_ANALYSIS_MODE}"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"tools": [
|
|
44
|
+
{
|
|
45
|
+
"name": "generate_changelog",
|
|
46
|
+
"description": "Generate AI-powered changelog from git commits or working directory changes"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "analyze_repository",
|
|
50
|
+
"description": "Comprehensive repository analysis including health, commits, and branches"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "analyze_current_changes",
|
|
54
|
+
"description": "Analyze staged and unstaged changes in working directory with AI-powered insights"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "configure_providers",
|
|
58
|
+
"description": "Manage AI providers - list, switch, test, and configure"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"tools_generated": false,
|
|
62
|
+
"user_config": {
|
|
63
|
+
"AI_PROVIDER": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"title": "AI Provider",
|
|
66
|
+
"description": "Choose your preferred AI provider, choose from: azure, openai, google, huggingface, ollama, lmstudio",
|
|
67
|
+
"required": false,
|
|
68
|
+
"sensitive": false,
|
|
69
|
+
"default": "openai"
|
|
70
|
+
},
|
|
71
|
+
"OPENAI_API_KEY": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"title": "OpenAI API Key",
|
|
74
|
+
"description": "Your OpenAI API key for GPT models",
|
|
75
|
+
"required": false,
|
|
76
|
+
"sensitive": true
|
|
77
|
+
},
|
|
78
|
+
"AZURE_OPENAI_KEY": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"title": "Azure OpenAI API Key",
|
|
81
|
+
"description": "Your Azure OpenAI API key",
|
|
82
|
+
"required": false,
|
|
83
|
+
"sensitive": true
|
|
84
|
+
},
|
|
85
|
+
"ANTHROPIC_API_KEY": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"title": "Anthropic API Key",
|
|
88
|
+
"description": "Your Anthropic API key for Claude models",
|
|
89
|
+
"required": false,
|
|
90
|
+
"sensitive": true
|
|
91
|
+
},
|
|
92
|
+
"GOOGLE_API_KEY": {
|
|
93
|
+
"type": "string",
|
|
94
|
+
"title": "Google AI API Key",
|
|
95
|
+
"description": "Your Google AI API key for Gemini models",
|
|
96
|
+
"required": false,
|
|
97
|
+
"sensitive": true
|
|
98
|
+
},
|
|
99
|
+
"HUGGINGFACE_API_KEY": {
|
|
100
|
+
"type": "string",
|
|
101
|
+
"title": "Hugging Face API Key",
|
|
102
|
+
"description": "Your Hugging Face API key",
|
|
103
|
+
"required": false,
|
|
104
|
+
"sensitive": true
|
|
105
|
+
},
|
|
106
|
+
"DEFAULT_ANALYSIS_MODE": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"title": "Default Analysis Mode",
|
|
109
|
+
"description": "Default mode for changelog generation (standard, detailed, or enterprise)",
|
|
110
|
+
"required": false,
|
|
111
|
+
"sensitive": false,
|
|
112
|
+
"default": "standard"
|
|
113
|
+
},
|
|
114
|
+
"AZURE_OPENAI_ENDPOINT": {
|
|
115
|
+
"type": "string",
|
|
116
|
+
"title": "Azure OpenAI Endpoint",
|
|
117
|
+
"description": "Your Azure OpenAI endpoint URL (e.g., https://your-resource.openai.azure.com)",
|
|
118
|
+
"required": false,
|
|
119
|
+
"sensitive": false
|
|
120
|
+
},
|
|
121
|
+
"AZURE_OPENAI_DEPLOYMENT_NAME": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"title": "Azure Deployment Name",
|
|
124
|
+
"description": "Your Azure OpenAI deployment name (e.g., gpt-4o)",
|
|
125
|
+
"required": false,
|
|
126
|
+
"sensitive": false
|
|
127
|
+
},
|
|
128
|
+
"VERTEX_PROJECT_ID": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"title": "Google Cloud Project ID",
|
|
131
|
+
"description": "Your Google Cloud Project ID for Vertex AI",
|
|
132
|
+
"required": false,
|
|
133
|
+
"sensitive": false
|
|
134
|
+
},
|
|
135
|
+
"OLLAMA_HOST": {
|
|
136
|
+
"type": "string",
|
|
137
|
+
"title": "Ollama Host",
|
|
138
|
+
"description": "Your Ollama server URL",
|
|
139
|
+
"required": false,
|
|
140
|
+
"sensitive": false,
|
|
141
|
+
"default": "http://localhost:11434"
|
|
142
|
+
},
|
|
143
|
+
"LMSTUDIO_API_BASE": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"title": "LM Studio API Base",
|
|
146
|
+
"description": "Your LM Studio server URL",
|
|
147
|
+
"required": false,
|
|
148
|
+
"sensitive": false,
|
|
149
|
+
"default": "http://localhost:1234/v1"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"keywords": [
|
|
153
|
+
"changelog",
|
|
154
|
+
"git",
|
|
155
|
+
"ai",
|
|
156
|
+
"automation",
|
|
157
|
+
"mcp",
|
|
158
|
+
"openai",
|
|
159
|
+
"claude",
|
|
160
|
+
"anthropic",
|
|
161
|
+
"gemini",
|
|
162
|
+
"azure",
|
|
163
|
+
"ollama",
|
|
164
|
+
"lmstudio",
|
|
165
|
+
"devops",
|
|
166
|
+
"release-notes",
|
|
167
|
+
"commit-analysis"
|
|
168
|
+
],
|
|
169
|
+
"license": "MIT",
|
|
170
|
+
"compatibility": {
|
|
171
|
+
"claude_desktop": ">=1.0.0",
|
|
172
|
+
"platforms": ["darwin", "win32", "linux"],
|
|
173
|
+
"runtimes": {
|
|
174
|
+
"node": ">=22.x"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
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.6.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",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"bin/",
|
|
15
15
|
"src/",
|
|
16
16
|
"types/",
|
|
17
|
+
"manifest.json",
|
|
17
18
|
"ai-changelog.sh",
|
|
18
19
|
"ai-changelog-mcp.sh",
|
|
19
20
|
"README.md",
|
|
@@ -21,38 +22,38 @@
|
|
|
21
22
|
"CHANGELOG.md"
|
|
22
23
|
],
|
|
23
24
|
"dependencies": {
|
|
24
|
-
"@anthropic-ai/sdk": "^0.
|
|
25
|
-
"@aws-sdk/client-bedrock-runtime": "^3.
|
|
25
|
+
"@anthropic-ai/sdk": "^0.71.0",
|
|
26
|
+
"@aws-sdk/client-bedrock-runtime": "^3.941.0",
|
|
26
27
|
"@azure/identity": "^4.13.0",
|
|
27
28
|
"@clack/prompts": "^0.11.0",
|
|
28
|
-
"@google/genai": "^1.
|
|
29
|
+
"@google/genai": "^1.30.0",
|
|
29
30
|
"@google/generative-ai": "^0.24.1",
|
|
30
|
-
"@huggingface/hub": "^2.
|
|
31
|
-
"@huggingface/inference": "^4.
|
|
31
|
+
"@huggingface/hub": "^2.7.1",
|
|
32
|
+
"@huggingface/inference": "^4.13.4",
|
|
32
33
|
"@lmstudio/sdk": "^1.5.0",
|
|
33
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
34
|
-
"@modelcontextprotocol/server-filesystem": "2025.
|
|
34
|
+
"@modelcontextprotocol/sdk": "^1.23.0",
|
|
35
|
+
"@modelcontextprotocol/server-filesystem": "2025.11.25",
|
|
35
36
|
"boxen": "^8.0.1",
|
|
36
37
|
"chalk": "^5.6.2",
|
|
37
38
|
"cli-table3": "^0.6.5",
|
|
38
39
|
"dotenv": "^17.2.3",
|
|
39
40
|
"figures": "^6.1.0",
|
|
40
|
-
"google-auth-library": "^10.
|
|
41
|
+
"google-auth-library": "^10.5.0",
|
|
41
42
|
"gradient-string": "^3.0.0",
|
|
42
|
-
"js-yaml": "^4.1.
|
|
43
|
-
"ollama": "^0.6.
|
|
44
|
-
"openai": "^6.
|
|
43
|
+
"js-yaml": "^4.1.1",
|
|
44
|
+
"ollama": "^0.6.3",
|
|
45
|
+
"openai": "^6.9.1",
|
|
45
46
|
"ora": "^9.0.0",
|
|
46
47
|
"yargs": "^18.0.0"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
|
-
"@anthropic-ai/mcpb": "^
|
|
50
|
-
"@types/node": "24.
|
|
51
|
-
"@vitest/browser": "
|
|
52
|
-
"@vitest/coverage-v8": "
|
|
53
|
-
"@vitest/ui": "
|
|
50
|
+
"@anthropic-ai/mcpb": "^2.0.1",
|
|
51
|
+
"@types/node": "24.10.1",
|
|
52
|
+
"@vitest/browser": "latest",
|
|
53
|
+
"@vitest/coverage-v8": "latest",
|
|
54
|
+
"@vitest/ui": "latest",
|
|
54
55
|
"tempy": "^3.1.0",
|
|
55
|
-
"vitest": "
|
|
56
|
+
"vitest": "latest"
|
|
56
57
|
},
|
|
57
58
|
"keywords": [
|
|
58
59
|
"changelog",
|
|
@@ -94,8 +95,8 @@
|
|
|
94
95
|
"access": "public"
|
|
95
96
|
},
|
|
96
97
|
"engines": {
|
|
97
|
-
"node": ">=22.
|
|
98
|
-
"pnpm": ">=10.
|
|
98
|
+
"node": ">=22.21.1",
|
|
99
|
+
"pnpm": ">=10.23.0"
|
|
99
100
|
},
|
|
100
101
|
"funding": {
|
|
101
102
|
"type": "github",
|
|
@@ -107,8 +108,8 @@
|
|
|
107
108
|
}
|
|
108
109
|
},
|
|
109
110
|
"volta": {
|
|
110
|
-
"node": "22.
|
|
111
|
-
"pnpm": "10.
|
|
111
|
+
"node": "22.22.1",
|
|
112
|
+
"pnpm": "10.23.0"
|
|
112
113
|
},
|
|
113
114
|
"scripts": {
|
|
114
115
|
"start": "node bin/ai-changelog.js",
|
|
@@ -146,14 +147,16 @@
|
|
|
146
147
|
"test:legacy": "node test/test-runner.js comprehensive",
|
|
147
148
|
"test:git": "node src/domains/git/git.service.js info",
|
|
148
149
|
"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
150
|
"providers:test": "node test/test-providers.js",
|
|
153
151
|
"providers:validate": "node test/test-provider-switching.js",
|
|
154
152
|
"git:info": "node src/domains/git/git.service.js info",
|
|
155
153
|
"git:commits": "node src/domains/git/git.service.js commits 10",
|
|
156
154
|
"git:stats": "node src/domains/git/git.service.js stats 5",
|
|
157
|
-
"
|
|
155
|
+
"mcpb:init": "mcpb init .",
|
|
156
|
+
"mcpb:validate": "mcpb validate manifest.json",
|
|
157
|
+
"mcpb:pack": "mcpb pack . ai-changelog-generator.mcpb",
|
|
158
|
+
"mcpb:build": "pnpm mcpb:validate && pnpm mcpb:pack",
|
|
159
|
+
"mcpb:info": "mcpb info ai-changelog-generator.mcpb",
|
|
160
|
+
"postinstall": "node -e \"console.log('🎉 AI Changelog Generator installed!⚡ Quick Start: ai-changelog - Generate changelog ai-changelog --detailed - Detailed analysis ai-changelog --interactive - Interactive mode ai-changelog-mcp - Start MCP server🤖 AI Models Supported: • GPT-4.1 series (1M context, 75% cost reduction) • o3/o4 reasoning models (Azure-only) • Automatic model selection📖 Docs: https://github.com/entro314-labs/AI-changelog-generator© All trademarks belong to their respective owners.')\""
|
|
158
161
|
}
|
|
159
162
|
}
|
|
@@ -168,7 +168,7 @@ export class ChangelogOrchestrator {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// Generate changelog using the service
|
|
171
|
-
const result = await this.changelogService.generateChangelog(version, since)
|
|
171
|
+
const result = await this.changelogService.generateChangelog(version, since, this.options)
|
|
172
172
|
|
|
173
173
|
if (!result) {
|
|
174
174
|
console.log(colors.warningMessage('No changelog generated'))
|
|
@@ -211,6 +211,12 @@ export class ChangelogOrchestrator {
|
|
|
211
211
|
async runInteractive() {
|
|
212
212
|
await this.ensureInitialized()
|
|
213
213
|
|
|
214
|
+
// Check for interactive environment
|
|
215
|
+
if (!process.stdin.isTTY && !process.env.CI) {
|
|
216
|
+
console.log(colors.warningMessage('Interactive mode requires a TTY terminal.'))
|
|
217
|
+
return { interactive: false, status: 'skipped' }
|
|
218
|
+
}
|
|
219
|
+
|
|
214
220
|
const { runInteractiveMode } = await import('../../shared/utils/utils.js')
|
|
215
221
|
const { confirm } = await this._getCachedImport('@clack/prompts')
|
|
216
222
|
|
package/src/cli.js
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* DEPRECATED: Legacy CLI Entry Point
|
|
5
|
+
*
|
|
6
|
+
* This file is deprecated and maintained only for backward compatibility.
|
|
7
|
+
* Please use bin/ai-changelog.js which delegates to CLIController instead.
|
|
8
|
+
*
|
|
9
|
+
* @deprecated Use bin/ai-changelog.js with CLIController
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
console.warn('\n⚠️ WARNING: This CLI entry point is deprecated.')
|
|
13
|
+
console.warn('Please use the main CLI: ai-changelog (or bin/ai-changelog.js)\n')
|
|
14
|
+
|
|
3
15
|
/**
|
|
4
16
|
* CLI Entry Point for AI Changelog Generator
|
|
5
17
|
* Provides command-line interface for changelog generation functionality
|
|
@@ -31,9 +31,10 @@ export class ChangelogService {
|
|
|
31
31
|
* Generates a changelog from committed changes (git history)
|
|
32
32
|
* @param {string} version - Version number for the release
|
|
33
33
|
* @param {string} since - Generate changelog since this date/commit
|
|
34
|
+
* @param {Object} options - Additional options (dryRun, etc.)
|
|
34
35
|
* @returns {Promise<string>} Complete changelog content
|
|
35
36
|
*/
|
|
36
|
-
async generateChangelog(version = null, since = null) {
|
|
37
|
+
async generateChangelog(version = null, since = null, options = {}) {
|
|
37
38
|
console.log(colors.processingMessage('🤖 Analyzing changes with AI...'))
|
|
38
39
|
|
|
39
40
|
// Get committed changes
|
|
@@ -95,7 +96,12 @@ export class ChangelogService {
|
|
|
95
96
|
// Write changelog to file using existing utility
|
|
96
97
|
const filename = version && version !== 'latest' ? `CHANGELOG-${version}.md` : 'AI_CHANGELOG.md'
|
|
97
98
|
const outputFile = path.join(process.cwd(), filename)
|
|
98
|
-
handleUnifiedOutput(changelog, {
|
|
99
|
+
handleUnifiedOutput(changelog, {
|
|
100
|
+
format: 'markdown',
|
|
101
|
+
outputFile,
|
|
102
|
+
silent: false,
|
|
103
|
+
dryRun: options.dryRun,
|
|
104
|
+
})
|
|
99
105
|
|
|
100
106
|
return {
|
|
101
107
|
changelog,
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import colors from '../../shared/constants/colors.js'
|
|
2
|
+
import { getWorkingDirectoryChanges } from '../../shared/utils/utils.js'
|
|
2
3
|
import { ChangelogService } from './changelog.service.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* WorkspaceChangelogService extends ChangelogService with workspace-specific functionality
|
|
6
7
|
* for analyzing uncommitted changes and workspace state
|
|
8
|
+
*
|
|
9
|
+
* @deprecated This class is being phased out. The workspace changelog logic has been
|
|
10
|
+
* consolidated into ChangelogService. This class is maintained for backward compatibility
|
|
11
|
+
* with existing tests but should not be used in new code.
|
|
7
12
|
*/
|
|
8
13
|
export class WorkspaceChangelogService extends ChangelogService {
|
|
9
14
|
constructor(gitService, aiAnalysisService, analysisEngine = null, configManager = null) {
|
|
@@ -24,16 +29,34 @@ export class WorkspaceChangelogService extends ChangelogService {
|
|
|
24
29
|
console.log(colors.processingMessage('🔍 Analyzing workspace changes...'))
|
|
25
30
|
|
|
26
31
|
try {
|
|
27
|
-
// Get git status information
|
|
28
|
-
const
|
|
32
|
+
// Get git status information using utility function
|
|
33
|
+
const changes = getWorkingDirectoryChanges()
|
|
34
|
+
|
|
35
|
+
// Categorize changes
|
|
36
|
+
const status = {
|
|
37
|
+
staged: [],
|
|
38
|
+
unstaged: [],
|
|
39
|
+
untracked: []
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
changes.forEach(change => {
|
|
43
|
+
const statusCode = change.status || '??'
|
|
44
|
+
if (statusCode.startsWith('??')) {
|
|
45
|
+
status.untracked.push(change.filePath)
|
|
46
|
+
} else if (statusCode[0] !== ' ' && statusCode[0] !== '?') {
|
|
47
|
+
status.staged.push(change.filePath)
|
|
48
|
+
} else {
|
|
49
|
+
status.unstaged.push(change.filePath)
|
|
50
|
+
}
|
|
51
|
+
})
|
|
29
52
|
|
|
30
53
|
// Update workspace metrics
|
|
31
54
|
this.workspaceMetrics.unstagedFiles = status.unstaged?.length || 0
|
|
32
55
|
this.workspaceMetrics.stagedFiles = status.staged?.length || 0
|
|
33
56
|
this.workspaceMetrics.untrackedFiles = status.untracked?.length || 0
|
|
34
57
|
|
|
35
|
-
// Get detailed diff for staged/unstaged changes
|
|
36
|
-
const diff =
|
|
58
|
+
// Get detailed diff for staged/unstaged changes (empty for now)
|
|
59
|
+
const diff = ''
|
|
37
60
|
|
|
38
61
|
// Use analysis engine if available
|
|
39
62
|
let analysis = null
|
|
@@ -124,14 +147,24 @@ export class WorkspaceChangelogService extends ChangelogService {
|
|
|
124
147
|
async validateWorkspace() {
|
|
125
148
|
try {
|
|
126
149
|
// Check if we're in a git repository
|
|
127
|
-
|
|
150
|
+
let isGitRepo = false
|
|
151
|
+
try {
|
|
152
|
+
const { execSync } = await import('node:child_process')
|
|
153
|
+
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' })
|
|
154
|
+
isGitRepo = true
|
|
155
|
+
} catch {
|
|
156
|
+
isGitRepo = false
|
|
157
|
+
}
|
|
158
|
+
|
|
128
159
|
if (!isGitRepo) {
|
|
129
160
|
console.error(colors.errorMessage('Not in a git repository'))
|
|
130
161
|
return false
|
|
131
162
|
}
|
|
132
163
|
|
|
164
|
+
const changes = getWorkingDirectoryChanges()
|
|
165
|
+
|
|
133
166
|
// Check if workspace has changes
|
|
134
|
-
if (!this.hasWorkspaceChanges()) {
|
|
167
|
+
if (!this.hasWorkspaceChanges() && changes.length === 0) {
|
|
135
168
|
console.log(colors.infoMessage('No workspace changes detected'))
|
|
136
169
|
return false
|
|
137
170
|
}
|
|
@@ -201,14 +234,13 @@ export class WorkspaceChangelogService extends ChangelogService {
|
|
|
201
234
|
|
|
202
235
|
for (const change of changes) {
|
|
203
236
|
try {
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
237
|
+
// For workspace changelog service, we don't have detailed diffs
|
|
238
|
+
// Just add basic enhancement
|
|
207
239
|
enhancedChanges.push({
|
|
208
240
|
...change,
|
|
209
|
-
diff,
|
|
210
|
-
complexity: this.assessChangeComplexity(
|
|
211
|
-
impact: this.assessChangeImpact(change.file,
|
|
241
|
+
diff: '',
|
|
242
|
+
complexity: this.assessChangeComplexity(''),
|
|
243
|
+
impact: this.assessChangeImpact(change.file, ''),
|
|
212
244
|
})
|
|
213
245
|
} catch (error) {
|
|
214
246
|
console.warn(
|
|
@@ -5,15 +5,7 @@ import process from 'node:process'
|
|
|
5
5
|
import yaml from 'js-yaml'
|
|
6
6
|
|
|
7
7
|
import colors from '../../shared/constants/colors.js'
|
|
8
|
-
|
|
9
|
-
// Model configurations - moved from lib/utils/model-config.js
|
|
10
|
-
const MODEL_CONFIGS = {
|
|
11
|
-
'gpt-4': { maxTokens: 8192, cost: 0.03 },
|
|
12
|
-
'gpt-3.5-turbo': { maxTokens: 4096, cost: 0.002 },
|
|
13
|
-
'claude-3-opus': { maxTokens: 200000, cost: 0.015 },
|
|
14
|
-
'claude-3-sonnet': { maxTokens: 200000, cost: 0.003 },
|
|
15
|
-
'claude-3-haiku': { maxTokens: 200000, cost: 0.00025 },
|
|
16
|
-
}
|
|
8
|
+
import { MODEL_CONFIGS } from '../providers/utils/model-config.js'
|
|
17
9
|
|
|
18
10
|
/**
|
|
19
11
|
* Unified Configuration Manager
|
|
@@ -9,6 +9,7 @@ import fs from 'node:fs'
|
|
|
9
9
|
import path, { dirname } from 'node:path'
|
|
10
10
|
import process from 'node:process'
|
|
11
11
|
import { fileURLToPath } from 'node:url'
|
|
12
|
+
import { execSync } from 'node:child_process'
|
|
12
13
|
|
|
13
14
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
|
|
14
15
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
@@ -61,12 +62,17 @@ class AIChangelogMCPServer {
|
|
|
61
62
|
// Set MCP server mode to suppress verbose logging
|
|
62
63
|
process.env.MCP_SERVER_MODE = 'true'
|
|
63
64
|
|
|
65
|
+
// Initialize configuration
|
|
64
66
|
this.configManager = new ConfigurationManager()
|
|
67
|
+
|
|
68
|
+
// Initialize application service
|
|
65
69
|
this.applicationService = new ApplicationService()
|
|
70
|
+
|
|
71
|
+
// Initialize orchestrator with proper dependencies (it will create its own services)
|
|
66
72
|
this.changelogOrchestrator = new ChangelogOrchestrator(this.configManager)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.providerService = new ProviderManagerService(this.configManager.
|
|
73
|
+
|
|
74
|
+
// Initialize provider service
|
|
75
|
+
this.providerService = new ProviderManagerService(this.configManager.getAll())
|
|
70
76
|
|
|
71
77
|
// Log available configuration
|
|
72
78
|
const hasProvider = process.env.AI_PROVIDER
|
|
@@ -80,6 +86,9 @@ class AIChangelogMCPServer {
|
|
|
80
86
|
} else {
|
|
81
87
|
console.error(`[MCP] Configured with provider: ${process.env.AI_PROVIDER}`)
|
|
82
88
|
}
|
|
89
|
+
|
|
90
|
+
// Wait for orchestrator to initialize its services
|
|
91
|
+
this.initPromise = this.changelogOrchestrator.ensureInitialized()
|
|
83
92
|
} catch (error) {
|
|
84
93
|
console.error('[MCP] Failed to initialize services:', error.message)
|
|
85
94
|
console.error('[MCP] Server will start but tools may require configuration')
|
|
@@ -296,27 +305,55 @@ class AIChangelogMCPServer {
|
|
|
296
305
|
} = args
|
|
297
306
|
|
|
298
307
|
try {
|
|
308
|
+
// Ensure services are initialized
|
|
309
|
+
if (this.initPromise) {
|
|
310
|
+
await this.initPromise
|
|
311
|
+
}
|
|
312
|
+
|
|
299
313
|
let result
|
|
300
314
|
|
|
301
315
|
if (source === 'working-dir' || (source === 'auto' && this.hasWorkingDirectoryChanges())) {
|
|
302
|
-
// Generate from working directory changes
|
|
303
|
-
|
|
304
|
-
|
|
316
|
+
// Generate from working directory changes using ChangelogService
|
|
317
|
+
// Access the changelogService through the orchestrator
|
|
318
|
+
await this.changelogOrchestrator.ensureInitialized()
|
|
319
|
+
const changelogService = this.changelogOrchestrator.changelogService
|
|
320
|
+
|
|
321
|
+
result = await changelogService.generateWorkspaceChangelog(version, {
|
|
305
322
|
analysisMode,
|
|
306
323
|
includeAttribution,
|
|
307
324
|
})
|
|
325
|
+
|
|
326
|
+
// Format result to match expected structure
|
|
327
|
+
if (result && result.changelog) {
|
|
328
|
+
result = {
|
|
329
|
+
content: result.changelog,
|
|
330
|
+
metadata: {
|
|
331
|
+
version,
|
|
332
|
+
source: 'working-directory',
|
|
333
|
+
filesProcessed: result.filesProcessed,
|
|
334
|
+
filesSkipped: result.filesSkipped,
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
308
338
|
} else {
|
|
309
|
-
// Generate from commits
|
|
310
|
-
result = await this.changelogOrchestrator.generateChangelog(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
339
|
+
// Generate from commits - use orchestrator's generateChangelog(version, since)
|
|
340
|
+
result = await this.changelogOrchestrator.generateChangelog(version, since)
|
|
341
|
+
|
|
342
|
+
// Wrap result if needed
|
|
343
|
+
if (result && typeof result === 'string') {
|
|
344
|
+
result = {
|
|
345
|
+
content: result,
|
|
346
|
+
metadata: {
|
|
347
|
+
version,
|
|
348
|
+
since,
|
|
349
|
+
source: 'commits'
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
316
353
|
}
|
|
317
354
|
|
|
318
355
|
// Write file if requested
|
|
319
|
-
if (writeFile && result.content) {
|
|
356
|
+
if (writeFile && result && result.content) {
|
|
320
357
|
const changelogPath = path.join(process.cwd(), 'AI_CHANGELOG.md')
|
|
321
358
|
try {
|
|
322
359
|
fs.writeFileSync(changelogPath, result.content, 'utf8')
|
|
@@ -330,10 +367,10 @@ class AIChangelogMCPServer {
|
|
|
330
367
|
content: [
|
|
331
368
|
{
|
|
332
369
|
type: 'text',
|
|
333
|
-
text: result
|
|
370
|
+
text: result?.content || 'No changelog content generated',
|
|
334
371
|
},
|
|
335
372
|
],
|
|
336
|
-
metadata: result
|
|
373
|
+
metadata: result?.metadata,
|
|
337
374
|
}
|
|
338
375
|
} catch (error) {
|
|
339
376
|
throw new Error(`Changelog generation failed: ${error.message}`)
|
|
@@ -344,23 +381,30 @@ class AIChangelogMCPServer {
|
|
|
344
381
|
const { analysisType = 'comprehensive', includeRecommendations = true, commitLimit = 50 } = args
|
|
345
382
|
|
|
346
383
|
try {
|
|
384
|
+
// Ensure services are initialized
|
|
385
|
+
if (this.initPromise) {
|
|
386
|
+
await this.initPromise
|
|
387
|
+
}
|
|
388
|
+
await this.changelogOrchestrator.ensureInitialized()
|
|
389
|
+
|
|
347
390
|
let result
|
|
348
391
|
|
|
349
392
|
switch (analysisType) {
|
|
350
393
|
case 'health':
|
|
351
|
-
result = await this.
|
|
394
|
+
result = await this.changelogOrchestrator.gitService.assessRepositoryHealth(includeRecommendations)
|
|
352
395
|
break
|
|
353
396
|
case 'commits':
|
|
354
|
-
result = await this.analysisEngine.analyzeRecentCommits(commitLimit)
|
|
397
|
+
result = await this.changelogOrchestrator.analysisEngine.analyzeRecentCommits(commitLimit)
|
|
355
398
|
break
|
|
356
399
|
case 'branches':
|
|
357
|
-
result = await this.
|
|
400
|
+
result = await this.changelogOrchestrator.gitService.analyzeBranches()
|
|
358
401
|
break
|
|
359
402
|
case 'working-dir':
|
|
360
|
-
result = await this.analysisEngine.analyzeCurrentChanges()
|
|
403
|
+
result = await this.changelogOrchestrator.analysisEngine.analyzeCurrentChanges()
|
|
361
404
|
break
|
|
362
405
|
default:
|
|
363
|
-
|
|
406
|
+
// Comprehensive analysis
|
|
407
|
+
result = await this.changelogOrchestrator.analyzeRepository({ type: analysisType })
|
|
364
408
|
break
|
|
365
409
|
}
|
|
366
410
|
|
|
@@ -381,7 +425,13 @@ class AIChangelogMCPServer {
|
|
|
381
425
|
const { includeAIAnalysis = true, includeAttribution = true } = args
|
|
382
426
|
|
|
383
427
|
try {
|
|
384
|
-
|
|
428
|
+
// Ensure services are initialized
|
|
429
|
+
if (this.initPromise) {
|
|
430
|
+
await this.initPromise
|
|
431
|
+
}
|
|
432
|
+
await this.changelogOrchestrator.ensureInitialized()
|
|
433
|
+
|
|
434
|
+
const result = await this.changelogOrchestrator.analysisEngine.analyzeCurrentChanges({
|
|
385
435
|
includeAIAnalysis,
|
|
386
436
|
includeAttribution,
|
|
387
437
|
})
|
|
@@ -472,7 +522,6 @@ class AIChangelogMCPServer {
|
|
|
472
522
|
hasWorkingDirectoryChanges() {
|
|
473
523
|
try {
|
|
474
524
|
// Simple check for working directory changes
|
|
475
|
-
const { execSync } = require('node:child_process')
|
|
476
525
|
const result = execSync('git status --porcelain', { encoding: 'utf8' })
|
|
477
526
|
return result.trim().length > 0
|
|
478
527
|
} catch (_error) {
|
|
@@ -223,8 +223,13 @@ export class EnhancedConsole {
|
|
|
223
223
|
EnhancedConsole.log(message, 'ai')
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
static metrics(
|
|
227
|
-
|
|
226
|
+
static metrics(data, title = 'Metrics') {
|
|
227
|
+
if (typeof data === 'string') {
|
|
228
|
+
EnhancedConsole.log(data, 'metrics')
|
|
229
|
+
} else if (data && Object.keys(data).length > 0) {
|
|
230
|
+
EnhancedConsole.section(title)
|
|
231
|
+
console.log(colors.formatMetrics(data))
|
|
232
|
+
}
|
|
228
233
|
}
|
|
229
234
|
|
|
230
235
|
static section(title, content = '') {
|
|
@@ -252,13 +257,6 @@ export class EnhancedConsole {
|
|
|
252
257
|
}
|
|
253
258
|
}
|
|
254
259
|
|
|
255
|
-
static metrics(metrics, title = 'Metrics') {
|
|
256
|
-
if (metrics && Object.keys(metrics).length > 0) {
|
|
257
|
-
EnhancedConsole.section(title)
|
|
258
|
-
console.log(colors.formatMetrics(metrics))
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
260
|
static divider(char = '─', length = 60) {
|
|
263
261
|
console.log(colors.separator(char, length))
|
|
264
262
|
}
|
|
@@ -1144,7 +1144,7 @@ ${enhancedMergeSummary}
|
|
|
1144
1144
|
'ENHANCED MERGE SUMMARY:\n' + (enhancedMergeSummary || 'None') + '\n\n' +
|
|
1145
1145
|
'FILES SECTION (first 3000 chars):\n' + filesSection.substring(0, 3000) + '\n\n' +
|
|
1146
1146
|
'FULL PROMPT PREVIEW:\n' + prompt.substring(0, 2000) + '\n=== END DEBUG ==='
|
|
1147
|
-
|
|
1147
|
+
|
|
1148
1148
|
fs.writeFileSync('AI_INPUT_DEBUG.txt', debugContent)
|
|
1149
1149
|
console.log('*** AI INPUT SAVED TO AI_INPUT_DEBUG.txt ***')
|
|
1150
1150
|
} catch (error) {
|
|
@@ -1439,6 +1439,15 @@ function extractCategoryFromText(content) {
|
|
|
1439
1439
|
*/
|
|
1440
1440
|
/**
|
|
1441
1441
|
* Get raw working directory changes from git status
|
|
1442
|
+
*
|
|
1443
|
+
* Note: This is a lightweight utility function that shells out to git directly
|
|
1444
|
+
* for simple status checks. For comprehensive git operations, services should
|
|
1445
|
+
* use GitService/GitManager, but this utility is kept for:
|
|
1446
|
+
* - Performance (avoids service initialization overhead)
|
|
1447
|
+
* - Simplicity (standalone function for basic status checks)
|
|
1448
|
+
* - Backward compatibility (widely used across codebase)
|
|
1449
|
+
*
|
|
1450
|
+
* @returns {Array} Array of change objects with status and filePath
|
|
1442
1451
|
*/
|
|
1443
1452
|
export function getWorkingDirectoryChanges() {
|
|
1444
1453
|
try {
|
|
@@ -1826,11 +1835,11 @@ function assessWorkspaceComplexity(categorizedChanges, totalFiles) {
|
|
|
1826
1835
|
* Handle unified output for analysis commands
|
|
1827
1836
|
*/
|
|
1828
1837
|
export function handleUnifiedOutput(data, config) {
|
|
1829
|
-
const { format = 'markdown', outputFile, silent } = config
|
|
1838
|
+
const { format = 'markdown', outputFile, silent, dryRun } = config
|
|
1830
1839
|
if (format === 'json') {
|
|
1831
1840
|
const jsonOutput = safeJsonStringify(data)
|
|
1832
1841
|
|
|
1833
|
-
if (outputFile) {
|
|
1842
|
+
if (outputFile && !dryRun) {
|
|
1834
1843
|
// Write to file
|
|
1835
1844
|
try {
|
|
1836
1845
|
fs.writeFileSync(outputFile, jsonOutput, 'utf8')
|
|
@@ -1844,13 +1853,16 @@ export function handleUnifiedOutput(data, config) {
|
|
|
1844
1853
|
}
|
|
1845
1854
|
}
|
|
1846
1855
|
} else if (!silent) {
|
|
1856
|
+
if (dryRun && outputFile) {
|
|
1857
|
+
console.log(colors.infoMessage(`[DRY RUN] Would save changelog to: ${colors.file(outputFile)}`))
|
|
1858
|
+
}
|
|
1847
1859
|
console.log(jsonOutput)
|
|
1848
1860
|
}
|
|
1849
1861
|
} else {
|
|
1850
1862
|
// Markdown format (default)
|
|
1851
1863
|
const markdownOutput = typeof data === 'string' ? data : safeJsonStringify(data)
|
|
1852
1864
|
|
|
1853
|
-
if (outputFile) {
|
|
1865
|
+
if (outputFile && !dryRun) {
|
|
1854
1866
|
try {
|
|
1855
1867
|
fs.writeFileSync(outputFile, markdownOutput, 'utf8')
|
|
1856
1868
|
if (!silent) {
|
|
@@ -1863,6 +1875,9 @@ export function handleUnifiedOutput(data, config) {
|
|
|
1863
1875
|
}
|
|
1864
1876
|
}
|
|
1865
1877
|
} else if (!silent) {
|
|
1878
|
+
if (dryRun && outputFile) {
|
|
1879
|
+
console.log(colors.infoMessage(`[DRY RUN] Would save changelog to: ${colors.file(outputFile)}`))
|
|
1880
|
+
}
|
|
1866
1881
|
console.log(markdownOutput)
|
|
1867
1882
|
}
|
|
1868
1883
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -310,51 +310,42 @@ export class AIChangelogGenerator {
|
|
|
310
310
|
constructor(constructorOptions?: {
|
|
311
311
|
repositoryPath?: string
|
|
312
312
|
configPath?: string
|
|
313
|
+
analysisMode?: AnalysisMode
|
|
314
|
+
modelOverride?: AIModel
|
|
315
|
+
dryRun?: boolean
|
|
316
|
+
silent?: boolean
|
|
313
317
|
})
|
|
314
318
|
|
|
315
|
-
// Core methods
|
|
316
|
-
|
|
317
|
-
generateChangelog(changelogOptions?: ChangelogOptions): Promise<string>
|
|
318
|
-
analyzeCommits(commitOptions?: {
|
|
319
|
-
since?: string
|
|
320
|
-
limit?: number
|
|
321
|
-
repositoryPath?: string
|
|
322
|
-
}): Promise<CommitAnalysis>
|
|
319
|
+
// Core methods (these actually exist in the implementation)
|
|
320
|
+
generateChangelog(version?: string | null, since?: string | null): Promise<string>
|
|
323
321
|
|
|
324
|
-
//
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
322
|
+
// Analysis methods
|
|
323
|
+
analyzeRepository(config?: { type?: string }): Promise<any>
|
|
324
|
+
analyzeCurrentChanges(): Promise<CurrentChangesAnalysis>
|
|
325
|
+
analyzeRecentCommits(limit?: number): Promise<CommitAnalysis>
|
|
326
|
+
analyzeBranches(config?: any): Promise<BranchAnalysis>
|
|
327
|
+
analyzeComprehensive(config?: any): Promise<RepositoryHealthCheck>
|
|
329
328
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
repositoryPath?: string
|
|
333
|
-
}): Promise<BranchAnalysis>
|
|
329
|
+
// Repository health
|
|
330
|
+
assessRepositoryHealth(includeRecommendations?: boolean): Promise<any>
|
|
334
331
|
|
|
335
|
-
|
|
332
|
+
// Interactive mode
|
|
333
|
+
runInteractive(): Promise<void>
|
|
336
334
|
|
|
337
|
-
// Configuration
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
provider?: AIProvider
|
|
341
|
-
model?: AIModel
|
|
342
|
-
capabilities?: ModelCapabilities
|
|
343
|
-
error?: string
|
|
344
|
-
}>
|
|
335
|
+
// Configuration
|
|
336
|
+
setAnalysisMode(mode: AnalysisMode): void
|
|
337
|
+
setModelOverride(model: AIModel): void
|
|
345
338
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
models?: Array<{
|
|
349
|
-
name: AIModel
|
|
350
|
-
available: boolean
|
|
351
|
-
capabilities?: ModelCapabilities
|
|
352
|
-
}>
|
|
353
|
-
error?: string
|
|
354
|
-
}>
|
|
339
|
+
// Validation
|
|
340
|
+
validateConfiguration(): Promise<void>
|
|
355
341
|
|
|
356
|
-
//
|
|
357
|
-
|
|
342
|
+
// Metrics
|
|
343
|
+
getMetrics(): {
|
|
344
|
+
startTime: number
|
|
345
|
+
commitsProcessed: number
|
|
346
|
+
apiCalls: number
|
|
347
|
+
errors: number
|
|
348
|
+
}
|
|
358
349
|
}
|
|
359
350
|
|
|
360
351
|
export class AIChangelogMCPServer {
|
|
@@ -362,53 +353,55 @@ export class AIChangelogMCPServer {
|
|
|
362
353
|
|
|
363
354
|
run(): Promise<void>
|
|
364
355
|
|
|
365
|
-
// MCP Tools
|
|
356
|
+
// MCP Tools (these match the actual implementation)
|
|
366
357
|
generateChangelog(params: {
|
|
367
358
|
repositoryPath?: string
|
|
359
|
+
source?: 'commits' | 'working-dir' | 'auto'
|
|
368
360
|
analysisMode?: AnalysisMode
|
|
369
|
-
outputFormat?: OutputFormat
|
|
370
361
|
since?: string
|
|
371
362
|
version?: string
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}): Promise<
|
|
363
|
+
includeAttribution?: boolean
|
|
364
|
+
writeFile?: boolean
|
|
365
|
+
}): Promise<{
|
|
366
|
+
content: Array<{
|
|
367
|
+
type: 'text'
|
|
368
|
+
text: string
|
|
369
|
+
}>
|
|
370
|
+
metadata?: any
|
|
371
|
+
}>
|
|
375
372
|
|
|
376
|
-
|
|
373
|
+
analyzeRepository(params: {
|
|
377
374
|
repositoryPath?: string
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
375
|
+
analysisType?: 'health' | 'commits' | 'branches' | 'working-dir' | 'comprehensive'
|
|
376
|
+
includeRecommendations?: boolean
|
|
377
|
+
commitLimit?: number
|
|
378
|
+
}): Promise<{
|
|
379
|
+
content: Array<{
|
|
380
|
+
type: 'text'
|
|
381
|
+
text: string
|
|
382
|
+
}>
|
|
383
|
+
}>
|
|
381
384
|
|
|
382
385
|
analyzeCurrentChanges(params: {
|
|
383
386
|
repositoryPath?: string
|
|
384
387
|
includeAIAnalysis?: boolean
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
getGitInfo(params: { repositoryPath?: string; includeStats?: boolean }): Promise<GitInfo>
|
|
388
|
-
|
|
389
|
-
configureAIProvider(params: {
|
|
390
|
-
provider?: AIProvider
|
|
391
|
-
showModels?: boolean
|
|
392
|
-
testConnection?: boolean
|
|
388
|
+
includeAttribution?: boolean
|
|
393
389
|
}): Promise<{
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
390
|
+
content: Array<{
|
|
391
|
+
type: 'text'
|
|
392
|
+
text: string
|
|
393
|
+
}>
|
|
398
394
|
}>
|
|
399
395
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
396
|
+
configureProviders(params: {
|
|
397
|
+
action?: 'list' | 'switch' | 'test' | 'configure' | 'validate'
|
|
398
|
+
provider?: string
|
|
399
|
+
testConnection?: boolean
|
|
404
400
|
}): Promise<{
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
available: boolean
|
|
409
|
-
capabilities?: ModelCapabilities
|
|
401
|
+
content: Array<{
|
|
402
|
+
type: 'text'
|
|
403
|
+
text: string
|
|
410
404
|
}>
|
|
411
|
-
error?: string
|
|
412
405
|
}>
|
|
413
406
|
}
|
|
414
407
|
|