@commitsage/mcp-server 1.0.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.
Files changed (90) hide show
  1. package/README.md +434 -0
  2. package/dist/adapters/sse.d.ts +26 -0
  3. package/dist/adapters/sse.d.ts.map +1 -0
  4. package/dist/adapters/sse.js +45 -0
  5. package/dist/adapters/sse.js.map +1 -0
  6. package/dist/auth/jwt.d.ts +70 -0
  7. package/dist/auth/jwt.d.ts.map +1 -0
  8. package/dist/auth/jwt.js +171 -0
  9. package/dist/auth/jwt.js.map +1 -0
  10. package/dist/auth/oauth.d.ts +71 -0
  11. package/dist/auth/oauth.d.ts.map +1 -0
  12. package/dist/auth/oauth.js +213 -0
  13. package/dist/auth/oauth.js.map +1 -0
  14. package/dist/index.d.ts +7 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +19 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/models/errors.d.ts +34 -0
  19. package/dist/models/errors.d.ts.map +1 -0
  20. package/dist/models/errors.js +67 -0
  21. package/dist/models/errors.js.map +1 -0
  22. package/dist/models/types.d.ts +39 -0
  23. package/dist/models/types.d.ts.map +1 -0
  24. package/dist/models/types.js +9 -0
  25. package/dist/models/types.js.map +1 -0
  26. package/dist/server/mcpServer.d.ts +11 -0
  27. package/dist/server/mcpServer.d.ts.map +1 -0
  28. package/dist/server/mcpServer.js +216 -0
  29. package/dist/server/mcpServer.js.map +1 -0
  30. package/dist/server/tools.d.ts +93 -0
  31. package/dist/server/tools.d.ts.map +1 -0
  32. package/dist/server/tools.js +272 -0
  33. package/dist/server/tools.js.map +1 -0
  34. package/dist/services/aiService.d.ts +12 -0
  35. package/dist/services/aiService.d.ts.map +1 -0
  36. package/dist/services/aiService.js +86 -0
  37. package/dist/services/aiService.js.map +1 -0
  38. package/dist/services/baseAIService.d.ts +47 -0
  39. package/dist/services/baseAIService.d.ts.map +1 -0
  40. package/dist/services/baseAIService.js +153 -0
  41. package/dist/services/baseAIService.js.map +1 -0
  42. package/dist/services/codestralService.d.ts +7 -0
  43. package/dist/services/codestralService.d.ts.map +1 -0
  44. package/dist/services/codestralService.js +49 -0
  45. package/dist/services/codestralService.js.map +1 -0
  46. package/dist/services/geminiService.d.ts +18 -0
  47. package/dist/services/geminiService.d.ts.map +1 -0
  48. package/dist/services/geminiService.js +139 -0
  49. package/dist/services/geminiService.js.map +1 -0
  50. package/dist/services/gitBlameAnalyzer.d.ts +15 -0
  51. package/dist/services/gitBlameAnalyzer.d.ts.map +1 -0
  52. package/dist/services/gitBlameAnalyzer.js +135 -0
  53. package/dist/services/gitBlameAnalyzer.js.map +1 -0
  54. package/dist/services/gitService.d.ts +54 -0
  55. package/dist/services/gitService.d.ts.map +1 -0
  56. package/dist/services/gitService.js +394 -0
  57. package/dist/services/gitService.js.map +1 -0
  58. package/dist/services/ollamaService.d.ts +7 -0
  59. package/dist/services/ollamaService.d.ts.map +1 -0
  60. package/dist/services/ollamaService.js +43 -0
  61. package/dist/services/ollamaService.js.map +1 -0
  62. package/dist/services/openaiService.d.ts +9 -0
  63. package/dist/services/openaiService.d.ts.map +1 -0
  64. package/dist/services/openaiService.js +69 -0
  65. package/dist/services/openaiService.js.map +1 -0
  66. package/dist/services/promptService.d.ts +10 -0
  67. package/dist/services/promptService.d.ts.map +1 -0
  68. package/dist/services/promptService.js +136 -0
  69. package/dist/services/promptService.js.map +1 -0
  70. package/dist/utils/config.d.ts +27 -0
  71. package/dist/utils/config.d.ts.map +1 -0
  72. package/dist/utils/config.js +80 -0
  73. package/dist/utils/config.js.map +1 -0
  74. package/dist/utils/httpUtils.d.ts +33 -0
  75. package/dist/utils/httpUtils.d.ts.map +1 -0
  76. package/dist/utils/httpUtils.js +54 -0
  77. package/dist/utils/httpUtils.js.map +1 -0
  78. package/dist/utils/logger.d.ts +14 -0
  79. package/dist/utils/logger.d.ts.map +1 -0
  80. package/dist/utils/logger.js +59 -0
  81. package/dist/utils/logger.js.map +1 -0
  82. package/dist/utils/retryUtils.d.ts +29 -0
  83. package/dist/utils/retryUtils.d.ts.map +1 -0
  84. package/dist/utils/retryUtils.js +49 -0
  85. package/dist/utils/retryUtils.js.map +1 -0
  86. package/dist/utils/textProcessing.d.ts +8 -0
  87. package/dist/utils/textProcessing.d.ts.map +1 -0
  88. package/dist/utils/textProcessing.js +10 -0
  89. package/dist/utils/textProcessing.js.map +1 -0
  90. package/package.json +47 -0
@@ -0,0 +1,43 @@
1
+ import axios from 'axios';
2
+ import { Logger } from '../utils/logger.js';
3
+ import { ConfigService } from '../utils/config.js';
4
+ import { BaseAIService } from './baseAIService.js';
5
+ import { HttpUtils } from '../utils/httpUtils.js';
6
+ import { RetryUtils } from '../utils/retryUtils.js';
7
+ // AI сервис для работы с локальным Ollama API
8
+ // Реализует интерфейс IAIService со статическими методами
9
+ export class OllamaService {
10
+ static defaultModel = 'llama3.2';
11
+ static async generateCommitMessage(prompt, progress, attempt = 1) {
12
+ const baseUrl = ConfigService.getOllamaBaseUrl() || 'http://localhost:11434';
13
+ const model = ConfigService.getOllamaModel() || this.defaultModel;
14
+ const apiUrl = `${baseUrl}/api/chat`;
15
+ const payload = {
16
+ model: model,
17
+ messages: [
18
+ { role: "user", content: prompt }
19
+ ],
20
+ stream: false
21
+ };
22
+ try {
23
+ void Logger.log(`Attempt ${attempt}: Sending request to Ollama API`);
24
+ await RetryUtils.updateProgressForAttempt(progress, attempt);
25
+ const requestConfig = HttpUtils.createRequestConfig({ 'content-type': 'application/json' });
26
+ const response = await axios.post(apiUrl, payload, requestConfig);
27
+ void Logger.log('Ollama API response received successfully');
28
+ progress.report({ message: "Processing generated message...", increment: 100 });
29
+ const commitMessage = this.extractCommitMessage(response.data);
30
+ void Logger.log(`Commit message generated using ${model} model`);
31
+ return { message: commitMessage, model };
32
+ }
33
+ catch (error) {
34
+ // Используем retry utils для retry логики
35
+ return RetryUtils.handleGenerationError(error, prompt, progress, attempt, this.generateCommitMessage.bind(this), BaseAIService.handleOllamaError.bind(BaseAIService));
36
+ }
37
+ }
38
+ static extractCommitMessage(response) {
39
+ const content = response.message?.content;
40
+ return BaseAIService.extractAndValidateMessage(content, 'Ollama');
41
+ }
42
+ }
43
+ //# sourceMappingURL=ollamaService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollamaService.js","sourceRoot":"","sources":["../../src/services/ollamaService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAapD,8CAA8C;AAC9C,0DAA0D;AAC1D,MAAM,OAAO,aAAa;IACd,MAAM,CAAU,YAAY,GAAG,UAAU,CAAC;IAElD,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAC9B,MAAc,EACd,QAA0B,EAC1B,UAAkB,CAAC;QAEnB,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,EAAE,IAAI,wBAAwB,CAAC;QAC7E,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,YAAY,CAAC;QAClE,MAAM,MAAM,GAAG,GAAG,OAAO,WAAW,CAAC;QAErC,MAAM,OAAO,GAAG;YACZ,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE;gBACN,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;aACpC;YACD,MAAM,EAAE,KAAK;SAChB,CAAC;QAEF,IAAI,CAAC;YACD,KAAK,MAAM,CAAC,GAAG,CAAC,WAAW,OAAO,iCAAiC,CAAC,CAAC;YACrE,MAAM,UAAU,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAE7D,MAAM,aAAa,GAAG,SAAS,CAAC,mBAAmB,CAC/C,EAAE,cAAc,EAAE,kBAAkB,EAAE,CACzC,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAiB,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;YAElF,KAAK,MAAM,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;YAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YAEhF,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/D,KAAK,MAAM,CAAC,GAAG,CAAC,kCAAkC,KAAK,QAAQ,CAAC,CAAC;YACjE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,0CAA0C;YAC1C,OAAO,UAAU,CAAC,qBAAqB,CACnC,KAAc,EACd,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EACrC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CACtD,CAAC;QACN,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,oBAAoB,CAAC,QAAwB;QACxD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1C,OAAO,aAAa,CAAC,yBAAyB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACtE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { ProgressReporter, CommitMessage } from "../models/types.js";
2
+ export declare class OpenAIService {
3
+ private static readonly chatCompletionsPath;
4
+ private static readonly modelsPath;
5
+ static generateCommitMessage(prompt: string, progress: ProgressReporter, attempt?: number): Promise<CommitMessage>;
6
+ static fetchAvailableModels(baseUrl: string, apiKey: string): Promise<string[]>;
7
+ private static extractCommitMessage;
8
+ }
9
+ //# sourceMappingURL=openaiService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openaiService.d.ts","sourceRoot":"","sources":["../../src/services/openaiService.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAuBrE,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAa;WAElC,qBAAqB,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE,MAAU,GAClB,OAAO,CAAC,aAAa,CAAC;WAmDZ,oBAAoB,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC;IAwBpB,OAAO,CAAC,MAAM,CAAC,oBAAoB;CAIpC"}
@@ -0,0 +1,69 @@
1
+ import axios from "axios";
2
+ import { Logger } from "../utils/logger.js";
3
+ import { ConfigService } from "../utils/config.js";
4
+ import { ApiKeyInvalidError } from "../models/errors.js";
5
+ import { BaseAIService } from "./baseAIService.js";
6
+ import { HttpUtils } from "../utils/httpUtils.js";
7
+ import { RetryUtils } from "../utils/retryUtils.js";
8
+ // AI сервис для работы с OpenAI/совместимыми API
9
+ // Реализует интерфейс IModelService со статическими методами (включая fetchAvailableModels)
10
+ export class OpenAIService {
11
+ static chatCompletionsPath = "/chat/completions";
12
+ static modelsPath = "/models";
13
+ static async generateCommitMessage(prompt, progress, attempt = 1) {
14
+ try {
15
+ const apiKey = ConfigService.getApiKey("openai");
16
+ const model = ConfigService.getOpenAIModel();
17
+ const baseUrl = ConfigService.getOpenAIBaseUrl();
18
+ const payload = {
19
+ model,
20
+ messages: [{ role: "user", content: prompt }],
21
+ temperature: 0.7,
22
+ maxTokens: 1024,
23
+ };
24
+ await RetryUtils.updateProgressForAttempt(progress, attempt);
25
+ const headers = HttpUtils.createRequestHeaders(apiKey);
26
+ const requestConfig = HttpUtils.createRequestConfig(headers);
27
+ const response = await axios.post(`${baseUrl}/chat/completions`, payload, requestConfig);
28
+ progress.report({
29
+ message: "Processing generated message...",
30
+ increment: 90,
31
+ });
32
+ const message = this.extractCommitMessage(response.data);
33
+ void Logger.log(`Commit message generated using ${model} model`);
34
+ return { message, model };
35
+ }
36
+ catch (error) {
37
+ // Обработка специальных случаев для OpenAI
38
+ const axiosError = error;
39
+ if (axiosError.response?.status === 401) {
40
+ throw new ApiKeyInvalidError("OpenAI");
41
+ }
42
+ // Используем retry utils для retry логики
43
+ return RetryUtils.handleGenerationError(error, prompt, progress, attempt, this.generateCommitMessage.bind(this), BaseAIService.handleOpenAIError.bind(BaseAIService));
44
+ }
45
+ }
46
+ static async fetchAvailableModels(baseUrl, apiKey) {
47
+ try {
48
+ const headers = HttpUtils.createRequestHeaders(apiKey);
49
+ const requestConfig = HttpUtils.createRequestConfig(headers);
50
+ const response = await axios.get(`${baseUrl}${this.modelsPath}`, requestConfig);
51
+ if (!response.data?.data) {
52
+ return [];
53
+ }
54
+ const models = response.data.data.map((model) => model.id);
55
+ if (models.length > 0) {
56
+ void Logger.log(`Successfully fetched ${models.length} models`);
57
+ }
58
+ return models;
59
+ }
60
+ catch {
61
+ return [];
62
+ }
63
+ }
64
+ static extractCommitMessage(response) {
65
+ const content = response.choices?.[0]?.message?.content;
66
+ return BaseAIService.extractAndValidateMessage(content, "OpenAI");
67
+ }
68
+ }
69
+ //# sourceMappingURL=openaiService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openaiService.js","sourceRoot":"","sources":["../../src/services/openaiService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Prompt service for generating AI prompts
3
+ * Adapted from VSCode extension
4
+ */
5
+ import { CommitLanguage } from '../utils/config.js';
6
+ export declare class PromptService {
7
+ static generatePrompt(diff: string, blameAnalysis: string): string;
8
+ static getLanguagePrompt(language: CommitLanguage): string;
9
+ }
10
+ //# sourceMappingURL=promptService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptService.d.ts","sourceRoot":"","sources":["../../src/services/promptService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA+B,cAAc,EAAE,MAAM,oBAAoB,CAAC;AA8FjF,qBAAa,aAAa;IACxB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM;IAkClE,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM;CAe3D"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Prompt service for generating AI prompts
3
+ * Adapted from VSCode extension
4
+ */
5
+ import { ConfigService } from '../utils/config.js';
6
+ // Template imports will be added after copying templates
7
+ // For now, we'll use inline templates
8
+ const templates = {
9
+ conventional: `You are a Git commit message generator. Generate a commit message following the Conventional Commits format.
10
+
11
+ Format: <type>(<scope>): <description>
12
+
13
+ [optional body]
14
+
15
+ [optional footer]
16
+
17
+ Types: feat, fix, docs, style, refactor, test, chore
18
+ Scope: optional, describes the section of codebase
19
+ Description: short summary in imperative mood
20
+ Body: optional, detailed explanation
21
+ Footer: optional, references issues/breaking changes`,
22
+ angular: `You are a Git commit message generator. Generate a commit message following the Angular commit format.
23
+
24
+ Format: <type>(<scope>): <short summary>
25
+
26
+ <body>
27
+
28
+ <footer>
29
+
30
+ Types: build, ci, docs, feat, fix, perf, refactor, test
31
+ Scope: optional
32
+ Short summary: present tense, lowercase, no period at end
33
+ Body: optional, imperative mood
34
+ Footer: references issues, breaking changes`,
35
+ karma: `You are a Git commit message generator. Generate a commit message following the Karma format.
36
+
37
+ Format: <type>(<scope>): <message>
38
+
39
+ Types: feat, fix, docs, style, refactor, test, chore`,
40
+ semantic: `You are a Git commit message generator. Generate a commit message following the Semantic format.
41
+
42
+ Format: <type>: <message>
43
+
44
+ Types: feat, fix, docs, style, refactor, test, chore`,
45
+ emoji: `You are a Git commit message generator. Generate a commit message with emoji.
46
+
47
+ Format: :<emoji>: <message>
48
+
49
+ Common emojis:
50
+ :sparkles: - new feature
51
+ :bug: - bug fix
52
+ :memo: - documentation
53
+ :lipstick: - UI/style
54
+ :recycle: - refactor
55
+ :white_check_mark: - tests
56
+ :wrench: - configuration`,
57
+ emojiKarma: `You are a Git commit message generator. Generate a commit message with emoji and Karma format.
58
+
59
+ Format: :<emoji>: <type>(<scope>): <message>
60
+
61
+ Emojis:
62
+ :sparkles: feat
63
+ :bug: fix
64
+ :memo: docs
65
+ :lipstick: style
66
+ :recycle: refactor
67
+ :white_check_mark: test
68
+ :wrench: chore`,
69
+ google: `You are a Git commit message generator. Generate a commit message following the Google format.
70
+
71
+ Format:
72
+ Type: Description
73
+
74
+ Body
75
+
76
+ Footer
77
+
78
+ Types: Feature, Fix, Docs, Style, Refactor, Test, Chore`,
79
+ atom: `You are a Git commit message generator. Generate a commit message following the Atom format.
80
+
81
+ Format: <type>(<scope>): <subject>
82
+
83
+ <body>
84
+
85
+ <footer>
86
+
87
+ Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert`,
88
+ };
89
+ export class PromptService {
90
+ static generatePrompt(diff, blameAnalysis) {
91
+ const useCustomInstructions = ConfigService.useCustomInstructions();
92
+ const customInstructions = ConfigService.getCustomInstructions();
93
+ if (useCustomInstructions && customInstructions.trim()) {
94
+ return `${customInstructions}
95
+
96
+ Git diff to analyze:
97
+ ${diff}
98
+
99
+ Git blame analysis:
100
+ ${blameAnalysis}
101
+
102
+ Please provide ONLY the commit message, without any additional text or explanations.`;
103
+ }
104
+ const format = ConfigService.getCommitFormat();
105
+ const commitLanguage = ConfigService.getCommitLanguage();
106
+ const languagePrompt = this.getLanguagePrompt(commitLanguage);
107
+ const template = templates[format] || templates.conventional;
108
+ return `${template}
109
+
110
+ ${languagePrompt}
111
+
112
+ Git diff to analyze:
113
+ ${diff}
114
+
115
+ Git blame analysis:
116
+ ${blameAnalysis}
117
+
118
+ Please provide ONLY the commit message, without any additional text or explanations.`;
119
+ }
120
+ static getLanguagePrompt(language) {
121
+ switch (language) {
122
+ case 'russian':
123
+ return 'Пожалуйста, напиши сообщение коммита на русском языке.';
124
+ case 'chinese':
125
+ return '请用中文写提交信息。';
126
+ case 'japanese':
127
+ return 'コミットメッセージを日本語で書いてください。';
128
+ case 'spanish':
129
+ return 'Por favor, escribe el mensaje del commit en español.';
130
+ case 'english':
131
+ default:
132
+ return 'Please write the commit message in English.';
133
+ }
134
+ }
135
+ }
136
+ //# sourceMappingURL=promptService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptService.js","sourceRoot":"","sources":["../../src/services/promptService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAgC,MAAM,oBAAoB,CAAC;AAEjF,yDAAyD;AACzD,sCAAsC;AAEtC,MAAM,SAAS,GAAiC;IAC9C,YAAY,EAAE;;;;;;;;;;;;qDAYqC;IAEnD,OAAO,EAAE;;;;;;;;;;;;4CAYiC;IAE1C,KAAK,EAAE;;;;qDAI4C;IAEnD,QAAQ,EAAE;;;;qDAIyC;IAEnD,KAAK,EAAE;;;;;;;;;;;yBAWgB;IAEvB,UAAU,EAAE;;;;;;;;;;;eAWC;IAEb,MAAM,EAAE;;;;;;;;;wDAS8C;IAEtD,IAAI,EAAE;;;;;;;;8EAQsE;CAC7E,CAAC;AAEF,MAAM,OAAO,aAAa;IACxB,MAAM,CAAC,cAAc,CAAC,IAAY,EAAE,aAAqB;QACvD,MAAM,qBAAqB,GAAG,aAAa,CAAC,qBAAqB,EAAE,CAAC;QACpE,MAAM,kBAAkB,GAAG,aAAa,CAAC,qBAAqB,EAAE,CAAC;QAEjE,IAAI,qBAAqB,IAAI,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC;YACvD,OAAO,GAAG,kBAAkB;;;EAGhC,IAAI;;;EAGJ,aAAa;;qFAEsE,CAAC;QAClF,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,eAAe,EAAE,CAAC;QAC/C,MAAM,cAAc,GAAG,aAAa,CAAC,iBAAiB,EAAE,CAAC;QACzD,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,YAAY,CAAC;QAE7D,OAAO,GAAG,QAAQ;;EAEpB,cAAc;;;EAGd,IAAI;;;EAGJ,aAAa;;qFAEsE,CAAC;IACpF,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,QAAwB;QAC/C,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,SAAS;gBACZ,OAAO,wDAAwD,CAAC;YAClE,KAAK,SAAS;gBACZ,OAAO,YAAY,CAAC;YACtB,KAAK,UAAU;gBACb,OAAO,wBAAwB,CAAC;YAClC,KAAK,SAAS;gBACZ,OAAO,sDAAsD,CAAC;YAChE,KAAK,SAAS,CAAC;YACf;gBACE,OAAO,6CAA6C,CAAC;QACzD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Configuration service for MCP server
3
+ * Uses environment variables passed by the MCP client (e.g., Zed, Claude Desktop)
4
+ * No .env file dependency - all configuration must be provided via environment
5
+ */
6
+ export type CommitLanguage = "english" | "russian" | "chinese" | "japanese" | "spanish";
7
+ export type CommitFormat = "conventional" | "angular" | "karma" | "semantic" | "emoji" | "emojiKarma" | "google" | "atom";
8
+ export type ProviderType = "gemini" | "openai" | "codestral" | "ollama";
9
+ export declare class ConfigService {
10
+ private static apiKeys;
11
+ static initialize(): void;
12
+ static getProvider(): ProviderType;
13
+ static getCommitFormat(): CommitFormat;
14
+ static getCommitLanguage(): CommitLanguage;
15
+ static getApiKey(provider?: ProviderType): string;
16
+ static hasApiKey(provider: ProviderType): boolean;
17
+ static getGeminiModel(): string;
18
+ static getOpenAIModel(): string;
19
+ static getOpenAIBaseUrl(): string;
20
+ static getCodestralModel(): string;
21
+ static getOllamaBaseUrl(): string;
22
+ static getOllamaModel(): string;
23
+ static getApiRequestTimeout(): number;
24
+ static useCustomInstructions(): boolean;
25
+ static getCustomInstructions(): string;
26
+ }
27
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,SAAS,GACT,SAAS,GACT,UAAU,GACV,SAAS,CAAC;AACd,MAAM,MAAM,YAAY,GACpB,cAAc,GACd,SAAS,GACT,OAAO,GACP,UAAU,GACV,OAAO,GACP,YAAY,GACZ,QAAQ,GACR,MAAM,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;AAExE,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAkC;IAExD,MAAM,CAAC,UAAU,IAAI,IAAI;IAiBzB,MAAM,CAAC,WAAW,IAAI,YAAY;IASlC,MAAM,CAAC,eAAe,IAAI,YAAY;IAKtC,MAAM,CAAC,iBAAiB,IAAI,cAAc;IAK1C,MAAM,CAAC,SAAS,CAAC,QAAQ,GAAE,YAAiC,GAAG,MAAM;IAUrE,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO;IAIjD,MAAM,CAAC,cAAc,IAAI,MAAM;IAI/B,MAAM,CAAC,cAAc,IAAI,MAAM;IAI/B,MAAM,CAAC,gBAAgB,IAAI,MAAM;IAIjC,MAAM,CAAC,iBAAiB,IAAI,MAAM;IAIlC,MAAM,CAAC,gBAAgB,IAAI,MAAM;IAIjC,MAAM,CAAC,cAAc,IAAI,MAAM;IAI/B,MAAM,CAAC,oBAAoB,IAAI,MAAM;IAKrC,MAAM,CAAC,qBAAqB,IAAI,OAAO;IAIvC,MAAM,CAAC,qBAAqB,IAAI,MAAM;CAGvC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Configuration service for MCP server
3
+ * Uses environment variables passed by the MCP client (e.g., Zed, Claude Desktop)
4
+ * No .env file dependency - all configuration must be provided via environment
5
+ */
6
+ import { Logger } from "./logger.js";
7
+ export class ConfigService {
8
+ static apiKeys = new Map();
9
+ static initialize() {
10
+ // Load API keys from environment
11
+ const geminiKey = process.env.GEMINI_API_KEY;
12
+ const openaiKey = process.env.OPENAI_API_KEY;
13
+ const codestralKey = process.env.CODESTRAL_API_KEY;
14
+ if (geminiKey)
15
+ this.apiKeys.set("gemini", geminiKey);
16
+ if (openaiKey)
17
+ this.apiKeys.set("openai", openaiKey);
18
+ if (codestralKey)
19
+ this.apiKeys.set("codestral", codestralKey);
20
+ // Set log level
21
+ const logLevel = process.env.LOG_LEVEL || "info";
22
+ Logger.setLevel(logLevel);
23
+ Logger.log("ConfigService initialized");
24
+ }
25
+ static getProvider() {
26
+ const provider = process.env.DEFAULT_PROVIDER?.toLowerCase() || "gemini";
27
+ if (!["gemini", "openai", "codestral", "ollama"].includes(provider)) {
28
+ Logger.warn(`Invalid provider: ${provider}, defaulting to gemini`);
29
+ return "gemini";
30
+ }
31
+ return provider;
32
+ }
33
+ static getCommitFormat() {
34
+ const format = process.env.DEFAULT_COMMIT_FORMAT || "conventional";
35
+ return format;
36
+ }
37
+ static getCommitLanguage() {
38
+ const language = process.env.DEFAULT_COMMIT_LANGUAGE || "english";
39
+ return language;
40
+ }
41
+ static getApiKey(provider = this.getProvider()) {
42
+ const key = this.apiKeys.get(provider);
43
+ if (!key && provider !== "ollama") {
44
+ throw new Error(`API key not found for provider: ${provider}. Please set ${provider.toUpperCase()}_API_KEY environment variable.`);
45
+ }
46
+ return key || "";
47
+ }
48
+ static hasApiKey(provider) {
49
+ return this.apiKeys.has(provider);
50
+ }
51
+ static getGeminiModel() {
52
+ return process.env.GEMINI_MODEL || "auto";
53
+ }
54
+ static getOpenAIModel() {
55
+ return process.env.OPENAI_MODEL || "gpt-3.5-turbo";
56
+ }
57
+ static getOpenAIBaseUrl() {
58
+ return process.env.OPENAI_BASE_URL || "https://api.openai.com/v1";
59
+ }
60
+ static getCodestralModel() {
61
+ return process.env.CODESTRAL_MODEL || "codestral-latest";
62
+ }
63
+ static getOllamaBaseUrl() {
64
+ return process.env.OLLAMA_BASE_URL || "http://localhost:11434";
65
+ }
66
+ static getOllamaModel() {
67
+ return process.env.OLLAMA_MODEL || "llama3.2";
68
+ }
69
+ static getApiRequestTimeout() {
70
+ const timeout = parseInt(process.env.API_REQUEST_TIMEOUT || "30", 10);
71
+ return timeout === -1 ? 0 : timeout * 1000; // Convert to milliseconds
72
+ }
73
+ static useCustomInstructions() {
74
+ return process.env.USE_CUSTOM_INSTRUCTIONS === "true";
75
+ }
76
+ static getCustomInstructions() {
77
+ return process.env.CUSTOM_INSTRUCTIONS || "";
78
+ }
79
+ }
80
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * HTTP utilities for MCP server
3
+ * Adapted from VSCode extension
4
+ */
5
+ import { AxiosError } from 'axios';
6
+ export declare class HttpUtils {
7
+ static readonly DEFAULT_TIMEOUT = 30000;
8
+ /**
9
+ * Create request headers with API key
10
+ */
11
+ static createRequestHeaders(apiKey?: string, additionalHeaders?: Record<string, string>): Record<string, string>;
12
+ private static getConfiguredTimeout;
13
+ /**
14
+ * Create request configuration
15
+ */
16
+ static createRequestConfig(headers: Record<string, string>, timeout?: number): {
17
+ headers: Record<string, string>;
18
+ timeout: number | undefined;
19
+ };
20
+ /**
21
+ * Check if error is a network error
22
+ */
23
+ static isNetworkError(error: AxiosError): boolean;
24
+ /**
25
+ * Extract error message from API response
26
+ */
27
+ static extractErrorMessage(responseData: {
28
+ error?: {
29
+ message?: string;
30
+ };
31
+ }): string | undefined;
32
+ }
33
+ //# sourceMappingURL=httpUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpUtils.d.ts","sourceRoot":"","sources":["../../src/utils/httpUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGnC,qBAAa,SAAS;IACpB,MAAM,CAAC,QAAQ,CAAC,eAAe,SAAS;IAExC;;OAEG;IACH,MAAM,CAAC,oBAAoB,CACzB,MAAM,CAAC,EAAE,MAAM,EACf,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAazB,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAQnC;;OAEG;IACH,MAAM,CAAC,mBAAmB,CACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;IAOnE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;IAUjD;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE;QACvC,KAAK,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC9B,GAAG,MAAM,GAAG,SAAS;CAGvB"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * HTTP utilities for MCP server
3
+ * Adapted from VSCode extension
4
+ */
5
+ import { ConfigService } from './config.js';
6
+ export class HttpUtils {
7
+ static DEFAULT_TIMEOUT = 30000;
8
+ /**
9
+ * Create request headers with API key
10
+ */
11
+ static createRequestHeaders(apiKey, additionalHeaders) {
12
+ const headers = {
13
+ 'content-type': 'application/json',
14
+ ...additionalHeaders,
15
+ };
16
+ if (apiKey) {
17
+ headers['Authorization'] = `Bearer ${apiKey}`;
18
+ }
19
+ return headers;
20
+ }
21
+ static getConfiguredTimeout() {
22
+ const timeoutMs = ConfigService.getApiRequestTimeout();
23
+ if (timeoutMs === 0) {
24
+ return undefined; // No timeout
25
+ }
26
+ return timeoutMs;
27
+ }
28
+ /**
29
+ * Create request configuration
30
+ */
31
+ static createRequestConfig(headers, timeout) {
32
+ return {
33
+ headers,
34
+ timeout: timeout !== undefined ? timeout : this.getConfiguredTimeout(),
35
+ };
36
+ }
37
+ /**
38
+ * Check if error is a network error
39
+ */
40
+ static isNetworkError(error) {
41
+ return (error.code === 'ECONNREFUSED' ||
42
+ error.code === 'ETIMEDOUT' ||
43
+ error.message?.includes('ECONNREFUSED') ||
44
+ error.message?.includes('ETIMEDOUT') ||
45
+ false);
46
+ }
47
+ /**
48
+ * Extract error message from API response
49
+ */
50
+ static extractErrorMessage(responseData) {
51
+ return responseData?.error?.message;
52
+ }
53
+ }
54
+ //# sourceMappingURL=httpUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"httpUtils.js","sourceRoot":"","sources":["../../src/utils/httpUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,SAAS;IACpB,MAAM,CAAU,eAAe,GAAG,KAAK,CAAC;IAExC;;OAEG;IACH,MAAM,CAAC,oBAAoB,CACzB,MAAe,EACf,iBAA0C;QAE1C,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,GAAG,iBAAiB;SACrB,CAAC;QAEF,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;QAChD,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,MAAM,CAAC,oBAAoB;QACjC,MAAM,SAAS,GAAG,aAAa,CAAC,oBAAoB,EAAE,CAAC;QACvD,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,SAAS,CAAC,CAAC,aAAa;QACjC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,mBAAmB,CACxB,OAA+B,EAC/B,OAAgB;QAEhB,OAAO;YACL,OAAO;YACP,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,EAAE;SACvE,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,KAAiB;QACrC,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,cAAc;YAC7B,KAAK,CAAC,IAAI,KAAK,WAAW;YAC1B,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC;YACvC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC;YACpC,KAAK,CACN,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,YAE1B;QACC,OAAO,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC;IACtC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Simple logger for MCP server
3
+ * Adapted from VSCode extension logger to work with Node.js console
4
+ */
5
+ declare class Logger {
6
+ private static level;
7
+ static setLevel(level: string): void;
8
+ static log(message: string, ...args: unknown[]): void;
9
+ static error(message: string, error?: Error | unknown): void;
10
+ static warn(message: string, ...args: unknown[]): void;
11
+ static debug(message: string, ...args: unknown[]): void;
12
+ }
13
+ export { Logger };
14
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,cAAM,MAAM;IACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAA2B;IAE/C,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM;IAmB7B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAMrD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,IAAI;IAU5D,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAMtD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAKxD;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Simple logger for MCP server
3
+ * Adapted from VSCode extension logger to work with Node.js console
4
+ */
5
+ var LogLevel;
6
+ (function (LogLevel) {
7
+ LogLevel[LogLevel["ERROR"] = 0] = "ERROR";
8
+ LogLevel[LogLevel["WARN"] = 1] = "WARN";
9
+ LogLevel[LogLevel["INFO"] = 2] = "INFO";
10
+ LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG";
11
+ })(LogLevel || (LogLevel = {}));
12
+ class Logger {
13
+ static level = LogLevel.INFO;
14
+ static setLevel(level) {
15
+ switch (level.toLowerCase()) {
16
+ case 'error':
17
+ this.level = LogLevel.ERROR;
18
+ break;
19
+ case 'warn':
20
+ this.level = LogLevel.WARN;
21
+ break;
22
+ case 'info':
23
+ this.level = LogLevel.INFO;
24
+ break;
25
+ case 'debug':
26
+ this.level = LogLevel.DEBUG;
27
+ break;
28
+ default:
29
+ this.level = LogLevel.INFO;
30
+ }
31
+ }
32
+ static log(message, ...args) {
33
+ if (this.level >= LogLevel.INFO) {
34
+ console.log(`[INFO] ${message}`, ...args);
35
+ }
36
+ }
37
+ static error(message, error) {
38
+ if (this.level >= LogLevel.ERROR) {
39
+ if (error instanceof Error) {
40
+ console.error(`[ERROR] ${message}`, error.message, error.stack);
41
+ }
42
+ else {
43
+ console.error(`[ERROR] ${message}`, error);
44
+ }
45
+ }
46
+ }
47
+ static warn(message, ...args) {
48
+ if (this.level >= LogLevel.WARN) {
49
+ console.warn(`[WARN] ${message}`, ...args);
50
+ }
51
+ }
52
+ static debug(message, ...args) {
53
+ if (this.level >= LogLevel.DEBUG) {
54
+ console.debug(`[DEBUG] ${message}`, ...args);
55
+ }
56
+ }
57
+ }
58
+ export { Logger };
59
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,IAAK,QAKJ;AALD,WAAK,QAAQ;IACX,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;AACX,CAAC,EALI,QAAQ,KAAR,QAAQ,QAKZ;AAED,MAAM,MAAM;IACF,MAAM,CAAC,KAAK,GAAa,QAAQ,CAAC,IAAI,CAAC;IAE/C,MAAM,CAAC,QAAQ,CAAC,KAAa;QAC3B,QAAQ,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5B,KAAK,OAAO;gBACV,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;gBAC5B,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC;gBAC3B,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC;gBAC3B,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;gBAC5B,MAAM;YACR;gBACE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,OAAe,EAAE,GAAG,IAAe;QAC5C,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAe,EAAE,KAAuB;QACnD,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,OAAO,CAAC,KAAK,CAAC,WAAW,OAAO,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAClE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,WAAW,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QAC7C,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,UAAU,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QAC9C,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,WAAW,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;;AAGH,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Retry utilities for API calls
3
+ */
4
+ import { CommitMessage, ProgressReporter } from '../models/types.js';
5
+ export interface ApiErrorResult {
6
+ errorMessage: string;
7
+ shouldRetry: boolean;
8
+ }
9
+ export declare class RetryUtils {
10
+ static readonly DEFAULT_MAX_RETRIES = 3;
11
+ static readonly DEFAULT_MAX_RETRY_BACKOFF = 10000;
12
+ /**
13
+ * Update progress based on attempt number
14
+ */
15
+ static updateProgressForAttempt(progress: ProgressReporter, attempt: number): Promise<void>;
16
+ /**
17
+ * Calculate retry delay with exponential backoff
18
+ */
19
+ static calculateRetryDelay(attempt: number, maxBackoff?: number): number;
20
+ /**
21
+ * Create a delay
22
+ */
23
+ static delay(ms: number): Promise<void>;
24
+ /**
25
+ * Universal error handling with retry logic
26
+ */
27
+ static handleGenerationError(error: Error, prompt: string, progress: ProgressReporter, attempt: number, generateFn: (prompt: string, progress: ProgressReporter, attempt: number) => Promise<CommitMessage>, errorHandler: (error: Error) => ApiErrorResult): Promise<CommitMessage>;
28
+ }
29
+ //# sourceMappingURL=retryUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryUtils.d.ts","sourceRoot":"","sources":["../../src/utils/retryUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,UAAU;IACrB,MAAM,CAAC,QAAQ,CAAC,mBAAmB,KAAK;IACxC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,SAAS;IAElD;;OAEG;WACU,wBAAwB,CACnC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAQhB;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;IAKxE;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC;;OAEG;WACU,qBAAqB,CAChC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,CACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,aAAa,CAAC,EAC3B,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,cAAc,GAC7C,OAAO,CAAC,aAAa,CAAC;CAkB1B"}