ai-changelog-generator-extension 0.4.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.
@@ -0,0 +1,172 @@
1
+ import * as vscode from 'vscode'
2
+ import * as fs from 'fs'
3
+ import * as path from 'path'
4
+
5
+ export interface DetectedEnvVars {
6
+ [key: string]: string
7
+ }
8
+
9
+ export class EnvFileService {
10
+ /**
11
+ * Detect .env files in workspace and parse compatible API keys
12
+ */
13
+ static async detectEnvironmentVariables(): Promise<DetectedEnvVars> {
14
+ const workspaceFolders = vscode.workspace.workspaceFolders
15
+ if (!workspaceFolders || workspaceFolders.length === 0) {
16
+ return {}
17
+ }
18
+
19
+ const rootPath = workspaceFolders[0].uri.fsPath
20
+ const config = vscode.workspace.getConfiguration('aiChangelog')
21
+ const envFilePath = config.get<string>('envFilePath', '.env.local')
22
+
23
+ // Try multiple .env file locations
24
+ const envFiles = [
25
+ path.join(rootPath, envFilePath),
26
+ path.join(rootPath, '.env.local'),
27
+ path.join(rootPath, '.env'),
28
+ ]
29
+
30
+ let detectedVars: DetectedEnvVars = {}
31
+
32
+ for (const envFile of envFiles) {
33
+ if (fs.existsSync(envFile)) {
34
+ try {
35
+ const content = fs.readFileSync(envFile, 'utf8')
36
+ const vars = this.parseEnvFile(content)
37
+ detectedVars = { ...detectedVars, ...vars }
38
+ } catch (error) {
39
+ console.error(`Failed to read ${envFile}:`, error)
40
+ }
41
+ }
42
+ }
43
+
44
+ return detectedVars
45
+ }
46
+
47
+ /**
48
+ * Parse .env file content and extract AI provider keys
49
+ */
50
+ private static parseEnvFile(content: string): DetectedEnvVars {
51
+ const lines = content.split('\n')
52
+ const vars: DetectedEnvVars = {}
53
+
54
+ // Known API key and config patterns
55
+ const keyPatterns = [
56
+ 'AI_PROVIDER',
57
+ 'OPENAI_API_KEY',
58
+ 'ANTHROPIC_API_KEY',
59
+ 'GOOGLE_API_KEY',
60
+ 'AZURE_OPENAI_KEY',
61
+ 'AZURE_OPENAI_API_KEY',
62
+ 'AZURE_OPENAI_ENDPOINT',
63
+ 'AZURE_OPENAI_DEPLOYMENT_NAME',
64
+ 'AZURE_OPENAI_API_VERSION',
65
+ 'AZURE_OPENAI_USE_V1_API',
66
+ 'AZURE_USE_AD_AUTH',
67
+ 'AWS_ACCESS_KEY_ID',
68
+ 'AWS_SECRET_ACCESS_KEY',
69
+ 'HUGGINGFACE_API_KEY',
70
+ 'OLLAMA_HOST',
71
+ 'OLLAMA_MODEL',
72
+ 'LMSTUDIO_BASE_URL',
73
+ 'VERTEX_PROJECT_ID',
74
+ 'VERTEX_LOCATION',
75
+ 'GOOGLE_APPLICATION_CREDENTIALS',
76
+ ]
77
+
78
+ for (const line of lines) {
79
+ const trimmed = line.trim()
80
+
81
+ // Skip comments and empty lines
82
+ if (trimmed.startsWith('#') || !trimmed || !trimmed.includes('=')) {
83
+ continue
84
+ }
85
+
86
+ const [key, ...valueParts] = trimmed.split('=')
87
+ const value = valueParts.join('=').trim()
88
+
89
+ // Remove quotes
90
+ const cleanValue = value.replace(/^["']|["']$/g, '')
91
+
92
+ // Check if this is a known API key
93
+ if (keyPatterns.includes(key.trim())) {
94
+ vars[key.trim()] = cleanValue
95
+ }
96
+ }
97
+
98
+ return vars
99
+ }
100
+
101
+ /**
102
+ * Save API key to .env file
103
+ */
104
+ static async saveToEnvFile(key: string, value: string): Promise<void> {
105
+ const workspaceFolders = vscode.workspace.workspaceFolders
106
+ if (!workspaceFolders || workspaceFolders.length === 0) {
107
+ throw new Error('No workspace folder open')
108
+ }
109
+
110
+ const rootPath = workspaceFolders[0].uri.fsPath
111
+ const config = vscode.workspace.getConfiguration('aiChangelog')
112
+ const envFilePath = config.get<string>('envFilePath', '.env.local')
113
+ const envFile = path.join(rootPath, envFilePath)
114
+
115
+ let content = ''
116
+ let keyExists = false
117
+
118
+ // Read existing content
119
+ if (fs.existsSync(envFile)) {
120
+ content = fs.readFileSync(envFile, 'utf8')
121
+ const lines = content.split('\n')
122
+ const updatedLines: string[] = []
123
+
124
+ for (const line of lines) {
125
+ if (line.trim().startsWith(`${key}=`)) {
126
+ updatedLines.push(`${key}="${value}"`)
127
+ keyExists = true
128
+ } else {
129
+ updatedLines.push(line)
130
+ }
131
+ }
132
+
133
+ content = updatedLines.join('\n')
134
+ }
135
+
136
+ // Add key if it doesn't exist
137
+ if (!keyExists) {
138
+ if (content && !content.endsWith('\n')) {
139
+ content += '\n'
140
+ }
141
+ content += `${key}="${value}"\n`
142
+ }
143
+
144
+ // Write to file
145
+ fs.writeFileSync(envFile, content, 'utf8')
146
+ }
147
+
148
+ /**
149
+ * Check if any environment variables are detected
150
+ */
151
+ static async hasEnvVars(): Promise<boolean> {
152
+ const vars = await this.detectEnvironmentVariables()
153
+ return Object.keys(vars).length > 0
154
+ }
155
+
156
+ /**
157
+ * Get provider name from key name
158
+ */
159
+ static getProviderFromKey(key: string): string | null {
160
+ const keyMap: Record<string, string> = {
161
+ OPENAI_API_KEY: 'openai',
162
+ ANTHROPIC_API_KEY: 'anthropic',
163
+ GOOGLE_API_KEY: 'google',
164
+ AZURE_OPENAI_KEY: 'azure',
165
+ AZURE_OPENAI_API_KEY: 'azure',
166
+ AWS_ACCESS_KEY_ID: 'bedrock',
167
+ HUGGINGFACE_API_KEY: 'huggingface',
168
+ }
169
+
170
+ return keyMap[key] || null
171
+ }
172
+ }
@@ -0,0 +1,224 @@
1
+ import * as vscode from 'vscode'
2
+ import { EnvFileService } from './EnvFileService'
3
+
4
+ export class ExtensionConfigurationManager {
5
+ private secretStorage: vscode.SecretStorage
6
+ private initialized = false
7
+ private config: Record<string, any> = {}
8
+
9
+ constructor(secretStorage: vscode.SecretStorage) {
10
+ this.secretStorage = secretStorage
11
+ }
12
+
13
+ async initialize(): Promise<void> {
14
+ if (this.initialized) return
15
+
16
+ // Load base config
17
+ this.loadConfig()
18
+
19
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
20
+ const storageMode = wsConfig.get<string>('storageMode', 'secrets')
21
+
22
+ if (storageMode === 'env') {
23
+ await this.loadFromEnvFile()
24
+ } else if (storageMode === 'settings') {
25
+ this.loadFromSettings()
26
+ } else {
27
+ await this.loadFromSecrets()
28
+ }
29
+
30
+ this.initialized = true
31
+ }
32
+
33
+ private async loadFromSecrets(): Promise<void> {
34
+ const providers = ['openai', 'anthropic', 'google', 'azure', 'bedrock', 'huggingface']
35
+
36
+ for (const provider of providers) {
37
+ const apiKey = await this.getApiKey(provider)
38
+ if (apiKey) {
39
+ const keyName = this.getKeyNameForProvider(provider)
40
+ this.config[keyName] = apiKey
41
+ }
42
+ }
43
+ }
44
+
45
+ private async loadFromEnvFile(): Promise<void> {
46
+ const envVars = await EnvFileService.detectEnvironmentVariables()
47
+
48
+ // Load all env vars into config
49
+ for (const [key, value] of Object.entries(envVars)) {
50
+ this.config[key] = value
51
+ }
52
+
53
+ // Also set AI_PROVIDER from env
54
+ if (!this.config.AI_PROVIDER && envVars.AI_PROVIDER) {
55
+ this.config.AI_PROVIDER = envVars.AI_PROVIDER
56
+ }
57
+ }
58
+
59
+ private loadFromSettings(): void {
60
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
61
+ const providers = ['openai', 'anthropic', 'google', 'azure', 'bedrock', 'huggingface']
62
+
63
+ for (const provider of providers) {
64
+ const keyName = `${provider}ApiKey`
65
+ const apiKey = wsConfig.get<string>(keyName)
66
+ if (apiKey) {
67
+ const configKeyName = this.getKeyNameForProvider(provider)
68
+ this.config[configKeyName] = apiKey
69
+ }
70
+ }
71
+ }
72
+
73
+ private getKeyNameForProvider(provider: string): string {
74
+ const keyMap: Record<string, string> = {
75
+ openai: 'OPENAI_API_KEY',
76
+ anthropic: 'ANTHROPIC_API_KEY',
77
+ google: 'GOOGLE_API_KEY',
78
+ azure: 'AZURE_OPENAI_KEY',
79
+ bedrock: 'AWS_ACCESS_KEY_ID',
80
+ huggingface: 'HUGGINGFACE_API_KEY',
81
+ }
82
+ return keyMap[provider] || `${provider.toUpperCase()}_API_KEY`
83
+ }
84
+
85
+ loadConfig() {
86
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
87
+
88
+ // Base configuration with defaults
89
+ this.config = {
90
+ AI_PROVIDER: wsConfig.get<string>('provider', 'openai'),
91
+ DEFAULT_ANALYSIS_MODE: wsConfig.get<string>('analysisMode', 'standard'),
92
+ OUTPUT_FORMAT: wsConfig.get<string>('outputFormat', 'markdown'),
93
+ INCLUDE_ATTRIBUTION: wsConfig.get<boolean>('includeAttribution', true),
94
+ RATE_LIMIT_DELAY: wsConfig.get<number>('rateLimitDelay', 1000),
95
+ MAX_RETRIES: wsConfig.get<number>('maxRetries', 3),
96
+ }
97
+
98
+ // Model override
99
+ const model = wsConfig.get<string>('model')
100
+ if (model) {
101
+ this.config.OPENAI_MODEL = model
102
+ }
103
+
104
+ // Ollama config
105
+ this.config.OLLAMA_HOST = wsConfig.get<string>('ollamaHost', 'http://localhost:11434')
106
+ this.config.OLLAMA_MODEL = wsConfig.get<string>('ollamaModel', 'llama3')
107
+
108
+ // Azure config
109
+ const azureEndpoint = wsConfig.get<string>('azureEndpoint')
110
+ const azureDeployment = wsConfig.get<string>('azureDeploymentName')
111
+ const azureVersion = wsConfig.get<string>('azureApiVersion')
112
+
113
+ if (azureEndpoint) this.config.AZURE_OPENAI_ENDPOINT = azureEndpoint
114
+ if (azureDeployment) this.config.AZURE_OPENAI_DEPLOYMENT_NAME = azureDeployment
115
+ if (azureVersion) this.config.AZURE_OPENAI_API_VERSION = azureVersion
116
+
117
+ // Vertex AI config
118
+ const vertexProject = wsConfig.get<string>('vertexProjectId')
119
+ const vertexLocation = wsConfig.get<string>('vertexLocation')
120
+
121
+ if (vertexProject) this.config.VERTEX_PROJECT_ID = vertexProject
122
+ if (vertexLocation) this.config.VERTEX_LOCATION = vertexLocation
123
+
124
+ // LM Studio config
125
+ const lmstudioUrl = wsConfig.get<string>('lmstudioBaseUrl')
126
+ if (lmstudioUrl) this.config.LMSTUDIO_BASE_URL = lmstudioUrl
127
+ }
128
+
129
+ async getApiKey(provider: string): Promise<string | undefined> {
130
+ const keyMap: Record<string, string> = {
131
+ openai: 'OPENAI_API_KEY',
132
+ anthropic: 'ANTHROPIC_API_KEY',
133
+ google: 'GOOGLE_API_KEY',
134
+ azure: 'AZURE_OPENAI_KEY',
135
+ bedrock: 'AWS_ACCESS_KEY_ID',
136
+ huggingface: 'HUGGINGFACE_API_KEY',
137
+ }
138
+
139
+ const secretKey = keyMap[provider]
140
+ if (secretKey) {
141
+ return await this.secretStorage.get(secretKey)
142
+ }
143
+ return undefined
144
+ }
145
+
146
+ async storeApiKey(provider: string, key: string): Promise<void> {
147
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
148
+ const storageMode = wsConfig.get<string>('storageMode', 'secrets')
149
+ const secretKey = this.getKeyNameForProvider(provider)
150
+
151
+ if (storageMode === 'env') {
152
+ await EnvFileService.saveToEnvFile(secretKey, key)
153
+ } else if (storageMode === 'settings') {
154
+ const keyName = `${provider}ApiKey`
155
+ await wsConfig.update(keyName, key, vscode.ConfigurationTarget.Workspace)
156
+ } else {
157
+ await this.secretStorage.store(secretKey, key)
158
+ }
159
+
160
+ this.config[secretKey] = key
161
+ }
162
+
163
+ get(key: string): any {
164
+ return this.config[key]
165
+ }
166
+
167
+ set(key: string, value: any) {
168
+ this.config[key] = value
169
+ }
170
+
171
+ getAll(): Record<string, any> {
172
+ return { ...this.config }
173
+ }
174
+
175
+ isSetupComplete(): boolean {
176
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
177
+ return wsConfig.get<boolean>('setupCompleted', false)
178
+ }
179
+
180
+ isInitialized(): boolean {
181
+ return this.initialized
182
+ }
183
+
184
+ getCurrentProvider(): string {
185
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
186
+ return wsConfig.get<string>('provider') || this.config.AI_PROVIDER || 'openai'
187
+ }
188
+
189
+ getStorageMode(): string {
190
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
191
+ return wsConfig.get<string>('storageMode', 'secrets')
192
+ }
193
+
194
+ async hasApiKey(provider: string): Promise<boolean> {
195
+ const keyName = this.getKeyNameForProvider(provider)
196
+
197
+ // Check in memory first
198
+ if (this.config[keyName]) {
199
+ return true
200
+ }
201
+
202
+ // Check based on storage mode
203
+ const storageMode = this.getStorageMode()
204
+
205
+ if (storageMode === 'secrets') {
206
+ const key = await this.secretStorage.get(keyName)
207
+ return !!key
208
+ } else if (storageMode === 'env') {
209
+ const envVars = await EnvFileService.detectEnvironmentVariables()
210
+ return !!envVars[keyName]
211
+ } else if (storageMode === 'settings') {
212
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
213
+ const settingsKey = `${provider}ApiKey`
214
+ const key = wsConfig.get<string>(settingsKey)
215
+ return !!key
216
+ }
217
+
218
+ return false
219
+ }
220
+
221
+ get context() {
222
+ return { secrets: this.secretStorage }
223
+ }
224
+ }
@@ -0,0 +1,211 @@
1
+ import * as vscode from 'vscode'
2
+ import { ExtensionConfigurationManager } from '../services/ExtensionConfigurationManager'
3
+ import { EnvFileService } from '../services/EnvFileService'
4
+
5
+ export interface SetupStatus {
6
+ isComplete: boolean
7
+ provider?: string
8
+ storageMode?: string
9
+ hasApiKey: boolean
10
+ errors: string[]
11
+ }
12
+
13
+ export class StatusService {
14
+ private static statusBarItem: vscode.StatusBarItem | null = null
15
+ private static outputChannel: vscode.OutputChannel | null = null
16
+
17
+ static initialize(context: vscode.ExtensionContext) {
18
+ this.statusBarItem = vscode.window.createStatusBarItem(
19
+ vscode.StatusBarAlignment.Right,
20
+ 100
21
+ )
22
+ this.statusBarItem.command = 'ai-changelog.showStatus'
23
+ context.subscriptions.push(this.statusBarItem)
24
+
25
+ this.outputChannel = vscode.window.createOutputChannel('AI Changelog')
26
+ context.subscriptions.push(this.outputChannel)
27
+ }
28
+
29
+ static async updateStatus(configManager: ExtensionConfigurationManager) {
30
+ if (!this.statusBarItem) return
31
+
32
+ const status = await this.getStatus(configManager)
33
+
34
+ if (!status.isComplete) {
35
+ this.statusBarItem.text = '$(warning) AI Changelog: Setup Required'
36
+ this.statusBarItem.tooltip = 'Click to run setup wizard'
37
+ this.statusBarItem.backgroundColor = new vscode.ThemeColor(
38
+ 'statusBarItem.warningBackground'
39
+ )
40
+ } else if (!status.hasApiKey) {
41
+ this.statusBarItem.text = `$(error) AI Changelog: No API Key`
42
+ this.statusBarItem.tooltip = `Provider: ${status.provider}\nNo API key configured`
43
+ this.statusBarItem.backgroundColor = new vscode.ThemeColor(
44
+ 'statusBarItem.errorBackground'
45
+ )
46
+ } else if (status.errors.length > 0) {
47
+ this.statusBarItem.text = `$(alert) AI Changelog: ${status.provider}`
48
+ this.statusBarItem.tooltip = `Issues:\n${status.errors.join('\n')}`
49
+ this.statusBarItem.backgroundColor = new vscode.ThemeColor(
50
+ 'statusBarItem.warningBackground'
51
+ )
52
+ } else {
53
+ this.statusBarItem.text = `$(check) AI Changelog: ${status.provider}`
54
+ this.statusBarItem.tooltip = `Ready to generate\nProvider: ${status.provider}\nStorage: ${status.storageMode}`
55
+ this.statusBarItem.backgroundColor = undefined
56
+ }
57
+
58
+ this.statusBarItem.show()
59
+ }
60
+
61
+ static async getStatus(
62
+ configManager: ExtensionConfigurationManager
63
+ ): Promise<SetupStatus> {
64
+ const status: SetupStatus = {
65
+ isComplete: configManager.isSetupComplete(),
66
+ provider: configManager.getCurrentProvider(),
67
+ storageMode: configManager.getStorageMode(),
68
+ hasApiKey: false,
69
+ errors: [],
70
+ }
71
+
72
+ if (status.isComplete) {
73
+ // Check if API key exists
74
+ const provider = status.provider || 'openai'
75
+
76
+ if (provider === 'ollama' || provider === 'lmstudio') {
77
+ status.hasApiKey = true // Local models don't need API keys
78
+ } else {
79
+ // Ensure config is initialized to load env vars
80
+ if (!configManager.isInitialized()) {
81
+ await configManager.initialize()
82
+ }
83
+
84
+ // Check for API key in loaded config (includes env vars)
85
+ const keyName = configManager['getKeyNameForProvider'](provider)
86
+ const apiKey = configManager.get(keyName)
87
+
88
+ status.hasApiKey = !!apiKey && apiKey.length > 0
89
+
90
+ if (!status.hasApiKey) {
91
+ status.errors.push(`No API key found for ${provider}`)
92
+ }
93
+ }
94
+
95
+ // Check environment file if using env storage
96
+ if (status.storageMode === 'env') {
97
+ const hasEnv = await EnvFileService.hasEnvVars()
98
+ if (!hasEnv) {
99
+ status.errors.push('Storage mode is "env" but no .env file found')
100
+ }
101
+ }
102
+ }
103
+
104
+ return status
105
+ }
106
+
107
+ static log(message: string, show: boolean = false) {
108
+ if (this.outputChannel) {
109
+ const timestamp = new Date().toLocaleTimeString()
110
+ this.outputChannel.appendLine(`[${timestamp}] ${message}`)
111
+ if (show) {
112
+ this.outputChannel.show()
113
+ }
114
+ }
115
+ }
116
+
117
+ static async showStatusReport(configManager: ExtensionConfigurationManager) {
118
+ const status = await this.getStatus(configManager)
119
+
120
+ const lines: string[] = [
121
+ '# AI Changelog Generator - Configuration Status',
122
+ '',
123
+ '## Setup Status',
124
+ `- Setup Complete: ${status.isComplete ? '✅ Yes' : '❌ No'}`,
125
+ `- AI Provider: ${status.provider || 'Not configured'}`,
126
+ `- Storage Mode: ${status.storageMode || 'Not configured'}`,
127
+ `- Has API Key: ${status.hasApiKey ? '✅ Yes' : '❌ No'}`,
128
+ '',
129
+ ]
130
+
131
+ if (status.errors.length > 0) {
132
+ lines.push('## ⚠️ Issues Found')
133
+ status.errors.forEach((error) => lines.push(`- ${error}`))
134
+ lines.push('')
135
+ }
136
+
137
+ // Get detailed config
138
+ const wsConfig = vscode.workspace.getConfiguration('aiChangelog')
139
+ lines.push('## Current Settings')
140
+ lines.push(`- Provider: ${wsConfig.get('provider')}`)
141
+ lines.push(`- Model: ${wsConfig.get('model')}`)
142
+ lines.push(`- Temperature: ${wsConfig.get('temperature')}`)
143
+ lines.push(`- Storage Mode: ${wsConfig.get('storageMode')}`)
144
+ lines.push(`- Env File Path: ${wsConfig.get('envFilePath')}`)
145
+ lines.push(`- Auto Detect Env: ${wsConfig.get('autoDetectEnv')}`)
146
+ lines.push(`- Analysis Mode: ${wsConfig.get('analysisMode')}`)
147
+ lines.push('')
148
+
149
+ // Provider-specific settings
150
+ if (status.provider === 'ollama') {
151
+ lines.push('## Ollama Settings')
152
+ lines.push(`- Host: ${wsConfig.get('ollamaHost')}`)
153
+ lines.push(`- Model: ${wsConfig.get('ollamaModel')}`)
154
+ lines.push('')
155
+ } else if (status.provider === 'azure') {
156
+ lines.push('## Azure Settings')
157
+ lines.push(`- Endpoint: ${wsConfig.get('azureEndpoint') || 'Not set'}`)
158
+ lines.push(
159
+ `- Deployment: ${wsConfig.get('azureDeploymentName') || 'Not set'}`
160
+ )
161
+ lines.push(`- API Version: ${wsConfig.get('azureApiVersion')}`)
162
+ lines.push('')
163
+ } else if (status.provider === 'lmstudio') {
164
+ lines.push('## LM Studio Settings')
165
+ lines.push(`- Base URL: ${wsConfig.get('lmstudioBaseUrl')}`)
166
+ lines.push('')
167
+ }
168
+
169
+ // Environment file detection
170
+ if (wsConfig.get('autoDetectEnv')) {
171
+ const envVars = await EnvFileService.detectEnvironmentVariables()
172
+ if (Object.keys(envVars).length > 0) {
173
+ lines.push('## 🔍 Detected Environment Variables')
174
+ Object.keys(envVars).forEach((key) => {
175
+ lines.push(`- ${key}: ✅ Found`)
176
+ })
177
+ lines.push('')
178
+ }
179
+ }
180
+
181
+ // Recommendations
182
+ lines.push('## 💡 Recommendations')
183
+ if (!status.isComplete) {
184
+ lines.push('- Run the setup wizard: `AI Changelog: Setup Wizard`')
185
+ } else if (!status.hasApiKey) {
186
+ lines.push(
187
+ `- Configure API key for ${status.provider}: \`AI Changelog: Configure AI Provider\``
188
+ )
189
+ } else if (status.storageMode === 'settings') {
190
+ lines.push(
191
+ '- Consider using secure storage instead of settings.json for better security'
192
+ )
193
+ }
194
+
195
+ // Open in new document
196
+ const doc = await vscode.workspace.openTextDocument({
197
+ content: lines.join('\n'),
198
+ language: 'markdown',
199
+ })
200
+ await vscode.window.showTextDocument(doc)
201
+ }
202
+
203
+ static dispose() {
204
+ this.statusBarItem?.dispose()
205
+ this.outputChannel?.dispose()
206
+ }
207
+
208
+ static showOutputChannel() {
209
+ this.outputChannel?.show()
210
+ }
211
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Type definitions for core ai-changelog-generator modules
3
+ * These allow TypeScript to understand imports from the workspace dependency
4
+ */
5
+
6
+ declare module '@entro314labs/ai-changelog-generator/src/domains/git/git-manager.js' {
7
+ export class GitManager {
8
+ constructor(options: { cwd: string })
9
+ execGitSafe(command: string): string
10
+ execGit(command: string): string
11
+ getRepoRoot(): string
12
+ getCurrentBranch(): string
13
+ getTags(): string[]
14
+ getCommits(count?: number): any[]
15
+ }
16
+ }
17
+
18
+ declare module '@entro314labs/ai-changelog-generator/src/domains/git/git.service.js' {
19
+ export class GitService {
20
+ constructor(gitManager: any, tagger: any)
21
+ analyzeWorkingDirectoryFileChange(status: string, filePath: string): Promise<any>
22
+ getWorkingDirectoryChanges(): Promise<any[]>
23
+ getCommitsBetweenTags(fromTag: string, toTag?: string): Promise<any[]>
24
+ analyzeCommit(commitHash: string): Promise<any>
25
+ }
26
+ }
27
+
28
+ declare module '@entro314labs/ai-changelog-generator/src/domains/git/commit-tagger.js' {
29
+ export class CommitTagger {
30
+ constructor()
31
+ categorizeCommit(analysis: any): any
32
+ determineImportance(analysis: any): string
33
+ }
34
+ }
35
+
36
+ declare module '@entro314labs/ai-changelog-generator/src/application/services/application.service.js' {
37
+ export class ApplicationService {
38
+ constructor(options: { configManager: any; cwd: string })
39
+ generateCommitMessage(): Promise<{
40
+ success: boolean
41
+ suggestions?: string[]
42
+ error?: string
43
+ }>
44
+ generateChangelogFromChanges(version: string): Promise<{
45
+ success: boolean
46
+ changelog?: string
47
+ error?: string
48
+ }>
49
+ }
50
+ }
51
+
52
+ declare module '@entro314labs/ai-changelog-generator/src/infrastructure/config/configuration.manager.js' {
53
+ export class ConfigurationManager {
54
+ constructor()
55
+ config: Record<string, any>
56
+ loadConfig(): Record<string, any>
57
+ getAll(): Record<string, any>
58
+ get(key: string): any
59
+ set(key: string, value: any): void
60
+ }
61
+ }
62
+
63
+ declare module '@entro314labs/ai-changelog-generator/src/application/orchestrators/changelog.orchestrator.js' {
64
+ export class ChangelogOrchestrator {
65
+ constructor(options: any)
66
+ generateChangelog(options?: any): Promise<any>
67
+ analyzeChanges(): Promise<any>
68
+ }
69
+ }
70
+
71
+ declare module '@entro314labs/ai-changelog-generator/src/domains/ai/ai-analysis.service.js' {
72
+ export class AIAnalysisService {
73
+ constructor(aiProvider: any, promptEngine: any, tagger: any, analysisMode: string)
74
+ analyzeCommit(commit: any): Promise<any>
75
+ analyzeFileChange(analysis: any): Promise<any>
76
+ }
77
+ }
78
+
79
+ declare module '@entro314labs/ai-changelog-generator/src/infrastructure/providers/provider-manager.service.js' {
80
+ export class ProviderManagerService {
81
+ constructor(config: any)
82
+ getProvider(): any
83
+ isProviderAvailable(providerName: string): boolean
84
+ }
85
+ }