@andrebuzeli/git-mcp 5.4.4 → 5.4.5

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 (52) hide show
  1. package/dist/providers/provider-operation-handler.d.ts.map +1 -1
  2. package/dist/providers/provider-operation-handler.js +4 -7
  3. package/dist/providers/provider-operation-handler.js.map +1 -1
  4. package/dist/providers/types.d.ts +0 -18
  5. package/dist/providers/types.d.ts.map +1 -1
  6. package/dist/tools/git-analytics.d.ts +24 -29
  7. package/dist/tools/git-analytics.d.ts.map +1 -1
  8. package/dist/tools/git-analytics.js +26 -31
  9. package/dist/tools/git-analytics.js.map +1 -1
  10. package/dist/tools/git-branches.d.ts +1 -113
  11. package/dist/tools/git-branches.d.ts.map +1 -1
  12. package/dist/tools/git-branches.js +56 -51
  13. package/dist/tools/git-branches.js.map +1 -1
  14. package/dist/tools/git-files.d.ts +5 -10
  15. package/dist/tools/git-files.d.ts.map +1 -1
  16. package/dist/tools/git-files.js +7 -12
  17. package/dist/tools/git-files.js.map +1 -1
  18. package/dist/tools/git-issues.d.ts +73 -78
  19. package/dist/tools/git-issues.d.ts.map +1 -1
  20. package/dist/tools/git-issues.js +76 -81
  21. package/dist/tools/git-issues.js.map +1 -1
  22. package/dist/tools/git-packages.d.ts +13 -18
  23. package/dist/tools/git-packages.d.ts.map +1 -1
  24. package/dist/tools/git-packages.js +15 -20
  25. package/dist/tools/git-packages.js.map +1 -1
  26. package/dist/tools/git-pulls.d.ts +89 -94
  27. package/dist/tools/git-pulls.d.ts.map +1 -1
  28. package/dist/tools/git-pulls.js +92 -97
  29. package/dist/tools/git-pulls.js.map +1 -1
  30. package/dist/tools/git-release.d.ts +17 -22
  31. package/dist/tools/git-release.d.ts.map +1 -1
  32. package/dist/tools/git-release.js +19 -24
  33. package/dist/tools/git-release.js.map +1 -1
  34. package/dist/tools/git-sync.d.ts +5 -14
  35. package/dist/tools/git-sync.d.ts.map +1 -1
  36. package/dist/tools/git-sync.js +23 -27
  37. package/dist/tools/git-sync.js.map +1 -1
  38. package/dist/tools/git-tags.d.ts +9 -14
  39. package/dist/tools/git-tags.d.ts.map +1 -1
  40. package/dist/tools/git-tags.js +11 -16
  41. package/dist/tools/git-tags.js.map +1 -1
  42. package/dist/tools/git-workflow.d.ts +53 -85
  43. package/dist/tools/git-workflow.d.ts.map +1 -1
  44. package/dist/tools/git-workflow.js +231 -357
  45. package/dist/tools/git-workflow.js.map +1 -1
  46. package/dist/utils/parameter-validator.js +8 -8
  47. package/dist/utils/parameter-validator.js.map +1 -1
  48. package/dist/utils/repository-sync.d.ts +5 -3
  49. package/dist/utils/repository-sync.d.ts.map +1 -1
  50. package/dist/utils/repository-sync.js +37 -15
  51. package/dist/utils/repository-sync.js.map +1 -1
  52. package/package.json +2 -2
@@ -2,23 +2,18 @@
2
2
  /**
3
3
  * Git Workflow Tool
4
4
  *
5
- * Core Git workflow tool providing comprehensive Git operations.
6
- * Supports both local Git operations and remote provider operations.
7
- *
8
- * Local operations: init, status, commit, sync, backup
9
- * Remote operations: create, list, get, update, delete, fork, search
5
+ * Core Git workflow tool for local and remote Git operations.
6
+ * Supports init, status, commit, sync, backup, create, list, get, update, delete, fork, and search operations.
7
+ * Provides comprehensive Git repository management with both local and remote provider support (GitHub/Gitea).
8
+ * In universal mode (GIT_MCP_MODE=universal), automatically executes on both GitHub and Gitea providers.
10
9
  */
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
10
  Object.defineProperty(exports, "__esModule", { value: true });
15
11
  exports.GitWorkflowTool = void 0;
16
- const git_command_executor_js_1 = require("../utils/git-command-executor.js");
17
12
  const parameter_validator_js_1 = require("../utils/parameter-validator.js");
18
13
  const operation_error_handler_js_1 = require("../utils/operation-error-handler.js");
19
14
  const provider_operation_handler_js_1 = require("../providers/provider-operation-handler.js");
20
15
  const config_js_1 = require("../config.js");
21
- const path_1 = __importDefault(require("path"));
16
+ const git_command_executor_js_1 = require("../utils/git-command-executor.js");
22
17
  class GitWorkflowTool {
23
18
  gitExecutor;
24
19
  providerHandler;
@@ -59,32 +54,18 @@ class GitWorkflowTool {
59
54
  }
60
55
  }
61
56
  /**
62
- * Execute local Git operations
57
+ * Check if operation is remote
63
58
  */
64
- async executeLocalOperation(params, startTime) {
65
- switch (params.action) {
66
- case 'init':
67
- return await this.handleInit(params, startTime);
68
- case 'status':
69
- return await this.handleStatus(params, startTime);
70
- case 'commit':
71
- return await this.handleCommit(params, startTime);
72
- case 'sync':
73
- return await this.handleSync(params, startTime);
74
- case 'backup':
75
- return await this.handleBackup(params, startTime);
76
- case 'push':
77
- return await this.handlePush(params, startTime);
78
- case 'pull':
79
- return await this.handlePull(params, startTime);
80
- default:
81
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('UNSUPPORTED_OPERATION', `Local operation '${params.action}' is not supported`, params.action, {}, ['Use one of: init, status, commit, sync, backup, push, pull']);
82
- }
59
+ isRemoteOperation(action) {
60
+ // Remote operations require provider
61
+ const remoteOperations = ['create', 'list', 'get', 'update', 'delete', 'fork', 'search'];
62
+ return remoteOperations.includes(action);
83
63
  }
84
64
  /**
85
- * Execute remote provider operations
65
+ * Execute remote repository operations
86
66
  */
87
67
  async executeRemoteOperation(params, startTime) {
68
+ // Check provider configuration
88
69
  if (!this.providerHandler) {
89
70
  return operation_error_handler_js_1.OperationErrorHandler.createToolError('PROVIDER_NOT_CONFIGURED', 'Provider handler is not configured for remote operations', params.action, {}, ['Configure GitHub or Gitea provider to use remote operations']);
90
71
  }
@@ -97,10 +78,45 @@ class GitWorkflowTool {
97
78
  return operation_error_handler_js_1.OperationErrorHandler.createToolError('PROVIDER_REQUIRED', 'Provider parameter is required for remote operations', params.action, {}, ['Specify provider as: github, gitea, or both']);
98
79
  }
99
80
  }
81
+ return await this.executeRepositoryOperation(params, startTime);
82
+ }
83
+ /**
84
+ * Execute local Git operations
85
+ */
86
+ async executeLocalOperation(params, startTime) {
87
+ try {
88
+ switch (params.action) {
89
+ case 'init':
90
+ return await this.executeInit(params, startTime);
91
+ case 'status':
92
+ return await this.executeStatus(params, startTime);
93
+ case 'commit':
94
+ return await this.executeCommit(params, startTime);
95
+ case 'sync':
96
+ return await this.executeSync(params, startTime);
97
+ case 'backup':
98
+ return await this.executeBackup(params, startTime);
99
+ case 'push':
100
+ return await this.executePush(params, startTime);
101
+ case 'pull':
102
+ return await this.executePull(params, startTime);
103
+ default:
104
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('UNSUPPORTED_OPERATION', `Local operation '${params.action}' is not supported`, params.action, {}, ['Use supported local operations: init, status, commit, sync, backup, push, pull']);
105
+ }
106
+ }
107
+ catch (error) {
108
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
109
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('LOCAL_OPERATION_ERROR', `Local operation failed: ${errorMessage}`, params.action, { error: errorMessage }, ['Check Git installation and repository state']);
110
+ }
111
+ }
112
+ /**
113
+ * Execute repository operation through provider
114
+ */
115
+ async executeRepositoryOperation(params, startTime) {
100
116
  const operation = {
101
117
  provider: params.provider,
102
118
  operation: this.mapActionToProviderOperation(params.action),
103
- parameters: this.extractRemoteParameters(params),
119
+ parameters: this.extractRepositoryParameters(params),
104
120
  requiresAuth: true,
105
121
  isRemoteOperation: true
106
122
  };
@@ -110,10 +126,10 @@ class GitWorkflowTool {
110
126
  success: result.success,
111
127
  data: result.partialFailure ? result : result.results[0]?.data,
112
128
  error: result.success ? undefined : {
113
- code: result.errors[0]?.error?.code || 'REMOTE_OPERATION_ERROR',
114
- message: result.errors[0]?.error?.message || 'Remote operation failed',
129
+ code: result.errors[0]?.error?.code || 'REPO_OPERATION_ERROR',
130
+ message: result.errors[0]?.error?.message || 'Repository operation failed',
115
131
  details: result.errors,
116
- suggestions: ['Check provider configuration and credentials']
132
+ suggestions: this.getOperationSuggestions(params.action)
117
133
  },
118
134
  metadata: {
119
135
  provider: params.provider,
@@ -125,43 +141,19 @@ class GitWorkflowTool {
125
141
  }
126
142
  catch (error) {
127
143
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
128
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('REMOTE_OPERATION_ERROR', `Remote operation failed: ${errorMessage}`, params.action, { error: errorMessage }, ['Check provider configuration and network connectivity']);
144
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('REPO_OPERATION_ERROR', `Repository operation failed: ${errorMessage}`, params.action, { error: errorMessage }, ['Check provider configuration and network connectivity']);
129
145
  }
130
146
  }
131
147
  /**
132
- * Handle git init operation
148
+ * Execute Git init
133
149
  */
134
- async handleInit(params, startTime) {
135
- try {
136
- // Check if already a git repository
137
- const isRepo = await this.gitExecutor.isGitRepository(params.projectPath);
138
- if (isRepo) {
139
- return {
140
- success: true,
141
- data: {
142
- message: 'Repository already initialized',
143
- path: params.projectPath,
144
- alreadyExists: true
145
- },
146
- metadata: {
147
- operation: 'init',
148
- timestamp: new Date().toISOString(),
149
- executionTime: Date.now() - startTime
150
- }
151
- };
152
- }
153
- const result = await this.gitExecutor.initRepository(params.projectPath, params.bare || false);
154
- if (!result.success) {
155
- return operation_error_handler_js_1.OperationErrorHandler.handleGitError(result.stderr, 'init', params.projectPath);
156
- }
150
+ async executeInit(params, startTime) {
151
+ const initCommand = params.bare ? ['init', '--bare'] : ['init'];
152
+ const result = await this.gitExecutor.executeGitCommand('init', initCommand, params.projectPath);
153
+ if (result.success) {
157
154
  return {
158
155
  success: true,
159
- data: {
160
- message: 'Git repository initialized successfully',
161
- path: params.projectPath,
162
- bare: params.bare || false,
163
- output: result.stdout
164
- },
156
+ data: { message: 'Git repository initialized successfully' },
165
157
  metadata: {
166
158
  operation: 'init',
167
159
  timestamp: new Date().toISOString(),
@@ -169,29 +161,23 @@ class GitWorkflowTool {
169
161
  }
170
162
  };
171
163
  }
172
- catch (error) {
173
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
174
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('INIT_ERROR', `Failed to initialize repository: ${errorMessage}`, 'init', { error: errorMessage, projectPath: params.projectPath });
164
+ else {
165
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('INIT_FAILED', `Git init failed: ${result.stderr}`, 'init', { stderr: result.stderr }, ['Check if directory exists and is writable', 'Verify Git installation']);
175
166
  }
176
167
  }
177
168
  /**
178
- * Handle git status operation
169
+ * Execute Git status
179
170
  */
180
- async handleStatus(params, startTime) {
181
- try {
182
- const result = await this.gitExecutor.getStatus(params.projectPath);
183
- if (!result.success) {
184
- return operation_error_handler_js_1.OperationErrorHandler.handleGitError(result.stderr, 'status', params.projectPath);
185
- }
171
+ async executeStatus(params, startTime) {
172
+ const result = await this.gitExecutor.executeGitCommand('status', ['--porcelain'], params.projectPath);
173
+ if (result.success) {
174
+ const hasChanges = result.stdout.trim().length > 0;
186
175
  return {
187
176
  success: true,
188
177
  data: {
189
- status: result.parsedStatus,
190
- raw: result.stdout,
191
- repository: {
192
- path: params.projectPath,
193
- isGitRepository: result.isGitRepository
194
- }
178
+ hasChanges,
179
+ changes: hasChanges ? result.stdout.trim().split('\n') : [],
180
+ message: hasChanges ? 'Working directory has uncommitted changes' : 'Working directory is clean'
195
181
  },
196
182
  metadata: {
197
183
  operation: 'status',
@@ -200,39 +186,37 @@ class GitWorkflowTool {
200
186
  }
201
187
  };
202
188
  }
203
- catch (error) {
204
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
205
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('STATUS_ERROR', `Failed to get repository status: ${errorMessage}`, 'status', { error: errorMessage, projectPath: params.projectPath });
189
+ else {
190
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('STATUS_FAILED', `Git status failed: ${result.stderr}`, 'status', { stderr: result.stderr }, ['Ensure this is a Git repository', 'Check Git installation']);
206
191
  }
207
192
  }
208
193
  /**
209
- * Handle git commit operation
194
+ * Execute Git commit
210
195
  */
211
- async handleCommit(params, startTime) {
212
- try {
213
- if (!params.message) {
214
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('MISSING_PARAMETER', 'Commit message is required', 'commit', {}, ['Provide a commit message using the message parameter']);
215
- }
216
- // Add files to staging area
217
- const filesToAdd = params.files || ['.'];
218
- const addResult = await this.gitExecutor.addFiles(params.projectPath, filesToAdd);
196
+ async executeCommit(params, startTime) {
197
+ if (!params.message) {
198
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('COMMIT_MESSAGE_REQUIRED', 'Commit message is required', 'commit', {}, ['Provide a commit message with the message parameter']);
199
+ }
200
+ const commitArgs = ['-m', params.message];
201
+ if (params.files && params.files.length > 0) {
202
+ // Add specific files first
203
+ const addResult = await this.gitExecutor.executeGitCommand('add', params.files, params.projectPath);
219
204
  if (!addResult.success) {
220
- return operation_error_handler_js_1.OperationErrorHandler.handleGitError(addResult.stderr, 'commit (add)', params.projectPath);
205
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('ADD_FAILED', `Failed to add files: ${addResult.stderr}`, 'commit', { stderr: addResult.stderr }, ['Check if files exist', 'Verify file paths are correct']);
221
206
  }
222
- // Commit changes
223
- const commitResult = await this.gitExecutor.commit(params.projectPath, params.message);
224
- if (!commitResult.success) {
225
- return operation_error_handler_js_1.OperationErrorHandler.handleGitError(commitResult.stderr, 'commit', params.projectPath);
207
+ }
208
+ else {
209
+ // Add all changes
210
+ const addResult = await this.gitExecutor.executeGitCommand('add', ['.'], params.projectPath);
211
+ if (!addResult.success) {
212
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('ADD_FAILED', `Failed to add files: ${addResult.stderr}`, 'commit', { stderr: addResult.stderr }, ['Check working directory status']);
226
213
  }
214
+ }
215
+ const result = await this.gitExecutor.executeGitCommand('commit', commitArgs, params.projectPath);
216
+ if (result.success) {
227
217
  return {
228
218
  success: true,
229
- data: {
230
- message: 'Changes committed successfully',
231
- commitMessage: params.message,
232
- files: filesToAdd,
233
- output: commitResult.stdout,
234
- addOutput: addResult.stdout
235
- },
219
+ data: { message: 'Changes committed successfully' },
236
220
  metadata: {
237
221
  operation: 'commit',
238
222
  timestamp: new Date().toISOString(),
@@ -240,51 +224,29 @@ class GitWorkflowTool {
240
224
  }
241
225
  };
242
226
  }
243
- catch (error) {
244
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
245
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('COMMIT_ERROR', `Failed to commit changes: ${errorMessage}`, 'commit', { error: errorMessage, projectPath: params.projectPath });
227
+ else {
228
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('COMMIT_FAILED', `Git commit failed: ${result.stderr}`, 'commit', { stderr: result.stderr }, ['Check if there are changes to commit', 'Ensure commit message is provided']);
246
229
  }
247
230
  }
248
231
  /**
249
- * Handle git sync operation (fetch + pull + push)
232
+ * Execute Git sync (pull + push)
250
233
  */
251
- async handleSync(params, startTime) {
252
- try {
253
- const remote = params.remote || 'origin';
254
- const results = [];
255
- // Fetch from remote
256
- const fetchResult = await this.gitExecutor.fetch(params.projectPath, remote, { all: true, prune: true });
257
- results.push({ operation: 'fetch', success: fetchResult.success, output: fetchResult.stdout, error: fetchResult.stderr });
258
- // Pull changes
259
- const pullResult = await this.gitExecutor.pull(params.projectPath, remote, params.branch, { force: params.force });
260
- results.push({ operation: 'pull', success: pullResult.success, output: pullResult.stdout, error: pullResult.stderr });
261
- // Push changes (only if pull was successful)
262
- let pushResult = null;
263
- if (pullResult.success) {
264
- pushResult = await this.gitExecutor.push(params.projectPath, remote, params.branch, { force: params.force });
265
- results.push({ operation: 'push', success: pushResult.success, output: pushResult.stdout, error: pushResult.stderr });
266
- }
267
- const allSuccessful = results.every(r => r.success);
268
- const hasErrors = results.some(r => !r.success);
234
+ async executeSync(params, startTime) {
235
+ const remote = params.remote || 'origin';
236
+ const branch = params.branch || await this.getCurrentBranch(params.projectPath) || 'main';
237
+ // Pull first
238
+ const pullResult = await this.gitExecutor.executeGitCommand('pull', [remote, branch], params.projectPath);
239
+ if (!pullResult.success) {
240
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('PULL_FAILED', `Git pull failed: ${pullResult.stderr}`, 'sync', { stderr: pullResult.stderr }, ['Check remote configuration', 'Resolve merge conflicts if any']);
241
+ }
242
+ // Push
243
+ const pushArgs = params.force ? ['--force'] : [];
244
+ pushArgs.push(remote, branch);
245
+ const pushResult = await this.gitExecutor.executeGitCommand('push', pushArgs, params.projectPath);
246
+ if (pushResult.success) {
269
247
  return {
270
- success: allSuccessful,
271
- data: {
272
- message: allSuccessful ? 'Repository synchronized successfully' : 'Synchronization completed with some errors',
273
- remote,
274
- branch: params.branch,
275
- operations: results,
276
- summary: {
277
- fetch: fetchResult.success,
278
- pull: pullResult.success,
279
- push: pushResult?.success || false
280
- }
281
- },
282
- error: hasErrors ? {
283
- code: 'SYNC_PARTIAL_ERROR',
284
- message: 'Some synchronization operations failed',
285
- details: results.filter(r => !r.success),
286
- suggestions: ['Check the individual operation errors and resolve them']
287
- } : undefined,
248
+ success: true,
249
+ data: { message: 'Repository synchronized successfully' },
288
250
  metadata: {
289
251
  operation: 'sync',
290
252
  timestamp: new Date().toISOString(),
@@ -292,140 +254,65 @@ class GitWorkflowTool {
292
254
  }
293
255
  };
294
256
  }
295
- catch (error) {
296
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
297
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('SYNC_ERROR', `Failed to synchronize repository: ${errorMessage}`, 'sync', { error: errorMessage, projectPath: params.projectPath });
257
+ else {
258
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('PUSH_FAILED', `Git push failed: ${pushResult.stderr}`, 'sync', { stderr: pushResult.stderr }, ['Check remote configuration', 'Verify you have push permissions']);
298
259
  }
299
260
  }
300
261
  /**
301
- * Handle push operation
262
+ * Execute Git push
302
263
  */
303
- async handlePush(params, startTime) {
304
- try {
305
- const remote = params.pushRemote || 'origin';
306
- const branch = params.pushBranch || await this.getCurrentBranch(params.projectPath);
307
- if (!branch) {
308
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('NO_BRANCH', 'No branch found to push', params.action, {}, ['Ensure you are on a valid branch or specify pushBranch parameter']);
309
- }
310
- const pushArgs = [remote, branch];
311
- if (params.force) {
312
- pushArgs.push('--force');
313
- }
314
- const result = await this.gitExecutor.executeGitCommand('push', pushArgs, params.projectPath);
315
- if (!result.success) {
316
- // Check for common push errors
317
- if (result.stderr.includes('Push cannot contain secrets')) {
318
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('SECURITY_VIOLATION', 'Push blocked due to detected secrets in commit history', params.action, {
319
- gitError: result.stderr,
320
- suggestion: 'Remove sensitive data from commit history using git reset or git filter-branch'
321
- }, [
322
- 'Use git reset to remove commits with secrets',
323
- 'Use git filter-branch to clean history',
324
- 'Never commit tokens, passwords, or API keys'
325
- ]);
326
- }
327
- if (result.stderr.includes('rejected')) {
328
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('PUSH_REJECTED', `Push rejected: ${result.stderr}`, params.action, { gitError: result.stderr }, [
329
- 'Pull latest changes first with git pull',
330
- 'Resolve any conflicts before pushing',
331
- 'Check if you have push permissions'
332
- ]);
333
- }
334
- return operation_error_handler_js_1.OperationErrorHandler.handleGitError(result.stderr, 'push', params.projectPath);
335
- }
264
+ async executePush(params, startTime) {
265
+ const remote = params.pushRemote || 'origin';
266
+ const branch = params.pushBranch || await this.getCurrentBranch(params.projectPath) || 'main';
267
+ const pushArgs = [remote, branch];
268
+ const result = await this.gitExecutor.executeGitCommand('push', pushArgs, params.projectPath);
269
+ if (result.success) {
336
270
  return {
337
271
  success: true,
338
- data: {
339
- message: `Successfully pushed to ${remote}/${branch}`,
340
- remote,
341
- branch,
342
- output: result.stdout
343
- },
272
+ data: { message: 'Changes pushed successfully' },
344
273
  metadata: {
345
274
  operation: 'push',
346
- executionTime: Date.now() - startTime,
347
- timestamp: new Date().toISOString()
275
+ timestamp: new Date().toISOString(),
276
+ executionTime: Date.now() - startTime
348
277
  }
349
278
  };
350
279
  }
351
- catch (error) {
352
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
353
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('PUSH_ERROR', `Push operation failed: ${errorMessage}`, params.action, { error: errorMessage }, ['Check network connectivity and repository permissions']);
280
+ else {
281
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('PUSH_FAILED', `Git push failed: ${result.stderr}`, 'push', { stderr: result.stderr }, ['Check remote configuration', 'Verify you have push permissions']);
354
282
  }
355
283
  }
356
284
  /**
357
- * Handle pull operation
285
+ * Execute Git pull
358
286
  */
359
- async handlePull(params, startTime) {
360
- try {
361
- const remote = params.pullRemote || 'origin';
362
- const branch = params.pullBranch || await this.getCurrentBranch(params.projectPath);
363
- if (!branch) {
364
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('NO_BRANCH', 'No branch found to pull from', params.action, {}, ['Ensure you are on a valid branch or specify pullBranch parameter']);
365
- }
366
- const pullArgs = [remote, branch];
367
- if (params.strategy && params.strategy !== 'merge') {
368
- pullArgs.push(`--${params.strategy}`);
369
- }
370
- const result = await this.gitExecutor.executeGitCommand('pull', pullArgs, params.projectPath);
371
- if (!result.success) {
372
- if (result.stderr.includes('merge conflict')) {
373
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('MERGE_CONFLICT', 'Pull failed due to merge conflicts', params.action, {
374
- gitError: result.stderr,
375
- conflicts: this.extractConflictFiles(result.stderr)
376
- }, [
377
- 'Resolve conflicts in the listed files',
378
- 'Use git add to stage resolved files',
379
- 'Complete merge with git commit'
380
- ]);
381
- }
382
- return operation_error_handler_js_1.OperationErrorHandler.handleGitError(result.stderr, 'pull', params.projectPath);
383
- }
287
+ async executePull(params, startTime) {
288
+ const remote = params.pullRemote || 'origin';
289
+ const branch = params.pullBranch || await this.getCurrentBranch(params.projectPath) || 'main';
290
+ const result = await this.gitExecutor.executeGitCommand('pull', [remote, branch], params.projectPath);
291
+ if (result.success) {
384
292
  return {
385
293
  success: true,
386
- data: {
387
- message: `Successfully pulled from ${remote}/${branch}`,
388
- remote,
389
- branch,
390
- strategy: params.strategy || 'merge',
391
- output: result.stdout
392
- },
294
+ data: { message: 'Changes pulled successfully' },
393
295
  metadata: {
394
296
  operation: 'pull',
395
- executionTime: Date.now() - startTime,
396
- timestamp: new Date().toISOString()
297
+ timestamp: new Date().toISOString(),
298
+ executionTime: Date.now() - startTime
397
299
  }
398
300
  };
399
301
  }
400
- catch (error) {
401
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
402
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('PULL_ERROR', `Pull operation failed: ${errorMessage}`, params.action, { error: errorMessage }, ['Check network connectivity and repository access']);
302
+ else {
303
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('PULL_FAILED', `Git pull failed: ${result.stderr}`, 'pull', { stderr: result.stderr }, ['Check remote configuration', 'Resolve merge conflicts if any']);
403
304
  }
404
305
  }
405
306
  /**
406
- * Handle git backup operation
307
+ * Execute backup
407
308
  */
408
- async handleBackup(params, startTime) {
409
- try {
410
- if (!params.backupPath) {
411
- // Generate default backup path
412
- const projectName = path_1.default.basename(params.projectPath);
413
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
414
- params.backupPath = path_1.default.join(params.projectPath, '..', `${projectName}-backup-${timestamp}`);
415
- }
416
- const result = await this.gitExecutor.createBackup(params.projectPath, params.backupPath, 'tar');
417
- if (!result.success) {
418
- return operation_error_handler_js_1.OperationErrorHandler.handleGitError(result.stderr, 'backup', params.projectPath);
419
- }
309
+ async executeBackup(params, startTime) {
310
+ const backupPath = params.backupPath || `backup-${Date.now()}.tar.gz`;
311
+ const result = await this.gitExecutor.executeGitCommand('archive', ['--format=tar', '--output', backupPath, 'HEAD'], params.projectPath);
312
+ if (result.success) {
420
313
  return {
421
314
  success: true,
422
- data: {
423
- message: 'Repository backup created successfully',
424
- backupPath: `${params.backupPath}.tar.gz`,
425
- originalPath: params.projectPath,
426
- format: 'tar.gz',
427
- output: result.stdout
428
- },
315
+ data: { backupPath, message: 'Repository backed up successfully' },
429
316
  metadata: {
430
317
  operation: 'backup',
431
318
  timestamp: new Date().toISOString(),
@@ -433,66 +320,47 @@ class GitWorkflowTool {
433
320
  }
434
321
  };
435
322
  }
436
- catch (error) {
437
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
438
- return operation_error_handler_js_1.OperationErrorHandler.createToolError('BACKUP_ERROR', `Failed to create repository backup: ${errorMessage}`, 'backup', { error: errorMessage, projectPath: params.projectPath });
323
+ else {
324
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('BACKUP_FAILED', `Backup failed: ${result.stderr}`, 'backup', { stderr: result.stderr }, ['Check write permissions', 'Verify Git repository integrity']);
439
325
  }
440
326
  }
441
327
  /**
442
- * Check if operation is a remote operation
443
- */
444
- isRemoteOperation(action) {
445
- const remoteOperations = ['create', 'list', 'get', 'update', 'delete', 'fork', 'search'];
446
- return remoteOperations.includes(action);
447
- }
448
- /**
449
- * Extract parameters for remote operations
328
+ * Extract parameters for repository operations
450
329
  */
451
- extractRemoteParameters(params) {
452
- const remoteParams = {
330
+ extractRepositoryParameters(params) {
331
+ const repoParams = {
453
332
  projectPath: params.projectPath
454
333
  };
455
- // Common parameters
456
- if (params.owner)
457
- remoteParams.owner = params.owner;
334
+ // Auto-detect repo if not provided
458
335
  if (params.repo)
459
- remoteParams.repo = params.repo;
336
+ repoParams.repo = params.repo;
460
337
  // Operation-specific parameters
461
338
  switch (params.action) {
462
339
  case 'create':
463
340
  if (params.name)
464
- remoteParams.name = params.name;
341
+ repoParams.name = params.name;
465
342
  if (params.description)
466
- remoteParams.description = params.description;
343
+ repoParams.description = params.description;
467
344
  if (params.private !== undefined)
468
- remoteParams.private = params.private;
345
+ repoParams.private = params.private;
469
346
  break;
470
347
  case 'list':
471
- // List operations may have type, sort, order parameters
348
+ // No additional parameters needed
472
349
  break;
473
350
  case 'get':
474
- // Get operations need owner and repo (already handled above)
475
- break;
476
351
  case 'update':
477
- if (params.name)
478
- remoteParams.name = params.name;
479
- if (params.description)
480
- remoteParams.description = params.description;
481
- if (params.private !== undefined)
482
- remoteParams.private = params.private;
483
- break;
484
352
  case 'delete':
485
- // Delete operations need owner and repo (already handled above)
486
- break;
487
353
  case 'fork':
488
- // Fork operations may have organization parameter
354
+ // repo parameter already handled above
355
+ if (params.description)
356
+ repoParams.description = params.description;
489
357
  break;
490
358
  case 'search':
491
359
  if (params.query)
492
- remoteParams.query = params.query;
360
+ repoParams.query = params.query;
493
361
  break;
494
362
  }
495
- return remoteParams;
363
+ return repoParams;
496
364
  }
497
365
  /**
498
366
  * Map git-workflow actions to provider operations
@@ -509,6 +377,63 @@ class GitWorkflowTool {
509
377
  };
510
378
  return actionMap[action] || action;
511
379
  }
380
+ /**
381
+ * Get current branch name
382
+ */
383
+ async getCurrentBranch(projectPath) {
384
+ try {
385
+ const result = await this.gitExecutor.executeGitCommand('branch', ['--show-current'], projectPath);
386
+ if (result.success && result.stdout.trim()) {
387
+ return result.stdout.trim();
388
+ }
389
+ return null;
390
+ }
391
+ catch (error) {
392
+ return null;
393
+ }
394
+ }
395
+ /**
396
+ * Get operation-specific suggestions
397
+ */
398
+ getOperationSuggestions(action) {
399
+ const suggestions = {
400
+ 'create': [
401
+ 'Provide a unique repository name',
402
+ 'Check provider permissions for repository creation',
403
+ 'Verify repository name format'
404
+ ],
405
+ 'list': [
406
+ 'Check provider access permissions',
407
+ 'Verify provider configuration'
408
+ ],
409
+ 'get': [
410
+ 'Verify repository exists',
411
+ 'Check repository access permissions',
412
+ 'Ensure correct repository name'
413
+ ],
414
+ 'update': [
415
+ 'Verify repository exists and you have admin access',
416
+ 'Check what fields you can update',
417
+ 'Ensure repository name uniqueness if changing name'
418
+ ],
419
+ 'delete': [
420
+ 'Verify repository exists and you have delete permissions',
421
+ 'Ensure you really want to delete the repository',
422
+ 'Consider creating a backup first'
423
+ ],
424
+ 'fork': [
425
+ 'Verify source repository exists and is accessible',
426
+ 'Check fork permissions on the source repository',
427
+ 'Ensure you don\'t already have a fork'
428
+ ],
429
+ 'search': [
430
+ 'Provide a search query',
431
+ 'Check search syntax for the provider',
432
+ 'Try different search terms'
433
+ ]
434
+ };
435
+ return suggestions[action] || ['Check provider configuration and try again'];
436
+ }
512
437
  /**
513
438
  * Get tool schema for MCP registration
514
439
  */
@@ -521,7 +446,7 @@ class GitWorkflowTool {
521
446
  properties: {
522
447
  action: {
523
448
  type: 'string',
524
- enum: ['init', 'status', 'commit', 'sync', 'backup', 'create', 'list', 'get', 'update', 'delete', 'fork', 'search'],
449
+ enum: ['init', 'status', 'commit', 'sync', 'backup', 'push', 'pull', 'create', 'list', 'get', 'update', 'delete', 'fork', 'search'],
525
450
  description: 'The Git operation to perform. Local operations: init, status, commit, sync, backup. Remote operations: create, list, get, update, delete, fork, search (require provider parameter).'
526
451
  },
527
452
  projectPath: {
@@ -566,10 +491,6 @@ class GitWorkflowTool {
566
491
  type: 'string',
567
492
  description: 'Search query (for search action)'
568
493
  },
569
- owner: {
570
- type: 'string',
571
- description: 'Repository owner (for get/update/delete/fork actions)'
572
- },
573
494
  repo: {
574
495
  type: 'string',
575
496
  description: 'Repository name (for get/update/delete/fork actions)'
@@ -585,74 +506,27 @@ class GitWorkflowTool {
585
506
  force: {
586
507
  type: 'boolean',
587
508
  description: 'Force operation (for sync action)'
509
+ },
510
+ pushRemote: {
511
+ type: 'string',
512
+ description: 'Remote name for push (default: origin)'
513
+ },
514
+ pushBranch: {
515
+ type: 'string',
516
+ description: 'Branch name for push (default: current branch)'
517
+ },
518
+ pullRemote: {
519
+ type: 'string',
520
+ description: 'Remote name for pull (default: origin)'
521
+ },
522
+ pullBranch: {
523
+ type: 'string',
524
+ description: 'Branch name for pull (default: current branch)'
588
525
  }
589
526
  },
590
- required: ['action', 'projectPath'],
591
- additionalProperties: false
592
- },
593
- errorCodes: {
594
- 'VALIDATION_ERROR': 'Parameter validation failed - check required parameters and format',
595
- 'NOT_A_GIT_REPOSITORY': 'Directory is not a Git repository - use init action first',
596
- 'NOTHING_TO_COMMIT': 'No changes to commit - make changes first',
597
- 'MERGE_CONFLICT': 'Merge conflicts detected - resolve conflicts before proceeding',
598
- 'PERMISSION_DENIED': 'Permission denied - check credentials and access rights',
599
- 'PROVIDER_NOT_CONFIGURED': 'Provider not configured - set up GitHub or Gitea credentials',
600
- 'NETWORK_ERROR': 'Network connectivity issue - check internet connection',
601
- 'BACKUP_ERROR': 'Backup creation failed - check disk space and permissions'
602
- },
603
- examples: [
604
- {
605
- description: 'Initialize a new Git repository',
606
- input: {
607
- action: 'init',
608
- projectPath: '/path/to/project'
609
- }
610
- },
611
- {
612
- description: 'Commit all changes with message',
613
- input: {
614
- action: 'commit',
615
- projectPath: '/path/to/project',
616
- message: 'Add new feature implementation'
617
- }
618
- },
619
- {
620
- description: 'Create repository on GitHub',
621
- input: {
622
- action: 'create',
623
- projectPath: '/path/to/project',
624
- provider: 'github',
625
- name: 'my-new-repo',
626
- description: 'My new repository',
627
- private: true
628
- }
629
- }
630
- ]
631
- };
632
- }
633
- /**
634
- * Extract conflict files from git error output
635
- */
636
- extractConflictFiles(stderr) {
637
- const conflictMatches = stderr.match(/both modified:\s+(.+)/g);
638
- if (!conflictMatches)
639
- return [];
640
- return conflictMatches.map(match => match.replace('both modified:', '').trim());
641
- }
642
- /**
643
- * Get current branch name
644
- */
645
- async getCurrentBranch(projectPath) {
646
- try {
647
- const result = await this.gitExecutor.executeGitCommand('branch', ['--show-current'], projectPath);
648
- if (result.success && result.stdout.trim()) {
649
- return result.stdout.trim();
527
+ required: ['action', 'projectPath']
650
528
  }
651
- return null;
652
- }
653
- catch (error) {
654
- return null;
655
- }
529
+ };
656
530
  }
657
531
  }
658
532
  exports.GitWorkflowTool = GitWorkflowTool;