@andrebuzeli/git-mcp 10.0.9 → 11.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 (137) hide show
  1. package/README.md +34 -428
  2. package/bin/git-mcp.js +21 -0
  3. package/docs/TOOLS.md +110 -0
  4. package/mcp.json.template +12 -0
  5. package/package.json +9 -76
  6. package/src/local/git.js +14 -0
  7. package/src/providers/gitea.js +13 -0
  8. package/src/providers/github.js +13 -0
  9. package/src/server.js +63 -0
  10. package/src/tools/git-actions.js +19 -0
  11. package/src/tools/git-activity.js +28 -0
  12. package/src/tools/git-admin.js +20 -0
  13. package/src/tools/git-checks.js +14 -0
  14. package/src/tools/git-commits.js +34 -0
  15. package/src/tools/git-contents.js +30 -0
  16. package/src/tools/git-deployments.js +21 -0
  17. package/src/tools/git-gists.js +15 -0
  18. package/src/tools/git-gitdata.js +19 -0
  19. package/src/tools/git-issues-prs.js +44 -0
  20. package/src/tools/git-issues.js +12 -0
  21. package/src/tools/git-local.js +66 -0
  22. package/src/tools/git-meta.js +19 -0
  23. package/src/tools/git-misc.js +21 -0
  24. package/src/tools/git-orgs.js +26 -0
  25. package/src/tools/git-packages.js +12 -0
  26. package/src/tools/git-raw.js +14 -0
  27. package/src/tools/git-releases.js +17 -0
  28. package/src/tools/git-remote.js +29 -0
  29. package/src/tools/git-repos.js +60 -0
  30. package/src/tools/git-search.js +18 -0
  31. package/src/tools/git-sync.js +40 -0
  32. package/src/tools/git-user.js +26 -0
  33. package/src/tools/schema.js +3 -0
  34. package/src/utils/fs.js +29 -0
  35. package/src/utils/project.js +7 -0
  36. package/tests/errors.js +26 -0
  37. package/tests/full_suite.js +98 -0
  38. package/tests/run.js +50 -0
  39. package/LICENSE +0 -21
  40. package/dist/index.d.ts +0 -2
  41. package/dist/index.js +0 -224
  42. package/dist/prompts/gitPrompts.d.ts +0 -93
  43. package/dist/prompts/gitPrompts.js +0 -177
  44. package/dist/providers/giteaProvider.d.ts +0 -3
  45. package/dist/providers/giteaProvider.js +0 -6
  46. package/dist/providers/githubProvider.d.ts +0 -2
  47. package/dist/providers/githubProvider.js +0 -4
  48. package/dist/providers/providerManager.d.ts +0 -11
  49. package/dist/providers/providerManager.js +0 -49
  50. package/dist/resources/toolsGuide.d.ts +0 -12
  51. package/dist/resources/toolsGuide.js +0 -1713
  52. package/dist/scripts/test_e2e.d.ts +0 -1
  53. package/dist/scripts/test_e2e.js +0 -199
  54. package/dist/scripts/test_exhaustive.d.ts +0 -1
  55. package/dist/scripts/test_exhaustive.js +0 -275
  56. package/dist/scripts/test_gitea_creation.d.ts +0 -1
  57. package/dist/scripts/test_gitea_creation.js +0 -116
  58. package/dist/scripts/verify_setup.d.ts +0 -1
  59. package/dist/scripts/verify_setup.js +0 -61
  60. package/dist/server.d.ts +0 -9
  61. package/dist/server.js +0 -73
  62. package/dist/tools/gitAnalytics.d.ts +0 -35
  63. package/dist/tools/gitAnalytics.js +0 -220
  64. package/dist/tools/gitArchive.d.ts +0 -119
  65. package/dist/tools/gitArchive.js +0 -150
  66. package/dist/tools/gitBackup.d.ts +0 -116
  67. package/dist/tools/gitBackup.js +0 -156
  68. package/dist/tools/gitBranches.d.ts +0 -54
  69. package/dist/tools/gitBranches.js +0 -282
  70. package/dist/tools/gitChangelog.d.ts +0 -37
  71. package/dist/tools/gitChangelog.js +0 -67
  72. package/dist/tools/gitConfig.d.ts +0 -97
  73. package/dist/tools/gitConfig.js +0 -125
  74. package/dist/tools/gitFiles.d.ts +0 -129
  75. package/dist/tools/gitFiles.js +0 -213
  76. package/dist/tools/gitFix.d.ts +0 -4
  77. package/dist/tools/gitFix.js +0 -159
  78. package/dist/tools/gitFix.tool.d.ts +0 -31
  79. package/dist/tools/gitFix.tool.js +0 -92
  80. package/dist/tools/gitHistory.d.ts +0 -41
  81. package/dist/tools/gitHistory.js +0 -349
  82. package/dist/tools/gitIgnore.d.ts +0 -214
  83. package/dist/tools/gitIgnore.js +0 -338
  84. package/dist/tools/gitIssues.d.ts +0 -80
  85. package/dist/tools/gitIssues.js +0 -363
  86. package/dist/tools/gitLog.d.ts +0 -30
  87. package/dist/tools/gitLog.js +0 -46
  88. package/dist/tools/gitMonitor.d.ts +0 -30
  89. package/dist/tools/gitMonitor.js +0 -284
  90. package/dist/tools/gitPackages.d.ts +0 -180
  91. package/dist/tools/gitPackages.js +0 -214
  92. package/dist/tools/gitPulls.d.ts +0 -66
  93. package/dist/tools/gitPulls.js +0 -347
  94. package/dist/tools/gitPush.d.ts +0 -40
  95. package/dist/tools/gitPush.js +0 -59
  96. package/dist/tools/gitRelease.d.ts +0 -49
  97. package/dist/tools/gitRelease.js +0 -359
  98. package/dist/tools/gitRemote.d.ts +0 -47
  99. package/dist/tools/gitRemote.js +0 -111
  100. package/dist/tools/gitReset.d.ts +0 -57
  101. package/dist/tools/gitReset.js +0 -79
  102. package/dist/tools/gitStash.d.ts +0 -61
  103. package/dist/tools/gitStash.js +0 -80
  104. package/dist/tools/gitSync.d.ts +0 -34
  105. package/dist/tools/gitSync.js +0 -182
  106. package/dist/tools/gitTags.d.ts +0 -45
  107. package/dist/tools/gitTags.js +0 -251
  108. package/dist/tools/gitUpdate.d.ts +0 -60
  109. package/dist/tools/gitUpdate.js +0 -474
  110. package/dist/tools/gitUpload.d.ts +0 -35
  111. package/dist/tools/gitUpload.js +0 -385
  112. package/dist/tools/gitWorkflow.d.ts +0 -117
  113. package/dist/tools/gitWorkflow.js +0 -472
  114. package/dist/types.d.ts +0 -20
  115. package/dist/types.js +0 -1
  116. package/dist/utils/agentHelpers.d.ts +0 -11
  117. package/dist/utils/agentHelpers.js +0 -41
  118. package/dist/utils/apiHelpers.d.ts +0 -29
  119. package/dist/utils/apiHelpers.js +0 -125
  120. package/dist/utils/cache.d.ts +0 -96
  121. package/dist/utils/cache.js +0 -208
  122. package/dist/utils/contextDetector.d.ts +0 -0
  123. package/dist/utils/contextDetector.js +0 -1
  124. package/dist/utils/errors.d.ts +0 -13
  125. package/dist/utils/errors.js +0 -17
  126. package/dist/utils/gitAdapter.d.ts +0 -224
  127. package/dist/utils/gitAdapter.js +0 -1162
  128. package/dist/utils/logger.d.ts +0 -45
  129. package/dist/utils/logger.js +0 -140
  130. package/dist/utils/rateLimiter.d.ts +0 -113
  131. package/dist/utils/rateLimiter.js +0 -257
  132. package/dist/utils/repoHelpers.d.ts +0 -44
  133. package/dist/utils/repoHelpers.js +0 -122
  134. package/dist/utils/safetyController.d.ts +0 -1
  135. package/dist/utils/safetyController.js +0 -12
  136. package/dist/utils/validation.d.ts +0 -115
  137. package/dist/utils/validation.js +0 -270
@@ -1,472 +0,0 @@
1
- import { MCPError } from '../utils/errors.js';
2
- import { normalizeToolParams } from '../utils/repoHelpers.js';
3
- import axios from 'axios';
4
- /**
5
- * Git Workflow Tool - Operações Git principais com segurança aprimorada
6
- * VERSÃO SEGURA: Remove exposição de tokens, validação robusta, sem --force por padrão
7
- */
8
- export class GitWorkflowTool {
9
- constructor() {
10
- this.name = 'git-workflow';
11
- this.description = 'Core Git operations including init, status, commit, sync, backup, and remote operations - automatic dual-provider for remote ops';
12
- this.inputSchema = {
13
- type: "object",
14
- properties: {
15
- projectPath: {
16
- type: "string",
17
- description: "Absolute path to the project/repository (REQUIRED)"
18
- },
19
- action: {
20
- type: "string",
21
- enum: ["init", "status", "commit", "sync", "backup", "create", "list", "get", "update", "delete", "fork", "search", "push"],
22
- description: "Action to perform: init (initialize repo), status (get repo status), commit (commit changes), sync (fetch/pull/push), backup (create backup), create (create repo on providers), list (list user repos), get (get repo details), update (update repo settings), delete (delete repo), fork (fork repo), search (search repos), push (push to remote)"
23
- },
24
- message: {
25
- type: "string",
26
- description: "Commit message (required for commit action)"
27
- },
28
- files: {
29
- type: "array",
30
- items: { type: "string" },
31
- description: "Files to add (optional for commit, default: ['.'])"
32
- },
33
- remote: {
34
- type: "string",
35
- description: "Remote name (optional for sync/push, default: 'origin')"
36
- },
37
- branch: {
38
- type: "string",
39
- description: "Branch name (optional for sync/push)"
40
- },
41
- backupPath: {
42
- type: "string",
43
- description: "Path for backup file (optional for backup)"
44
- },
45
- name: {
46
- type: "string",
47
- description: "Repository name (required for create)"
48
- },
49
- owner: {
50
- type: "string",
51
- description: "Repository owner (optional for create/get/update/delete/fork, uses env vars if not provided)"
52
- },
53
- repo: {
54
- type: "string",
55
- description: "Repository name (required for get/update/delete/fork)"
56
- },
57
- description: {
58
- type: "string",
59
- description: "Repository description (optional for create/update)"
60
- },
61
- private: {
62
- type: "boolean",
63
- description: "Make repository private (optional for create/update, default: true)"
64
- },
65
- has_issues: {
66
- type: "boolean",
67
- description: "Enable issues (optional for update)"
68
- },
69
- has_projects: {
70
- type: "boolean",
71
- description: "Enable projects (optional for update)"
72
- },
73
- has_wiki: {
74
- type: "boolean",
75
- description: "Enable wiki (optional for update)"
76
- },
77
- organization: {
78
- type: "string",
79
- description: "Organization for fork (optional for fork)"
80
- },
81
- query: {
82
- type: "string",
83
- description: "Search query (required for search)"
84
- },
85
- sort: {
86
- type: "string",
87
- description: "Sort field (optional for search)"
88
- },
89
- order: {
90
- type: "string",
91
- description: "Sort order (optional for search)"
92
- },
93
- limit: {
94
- type: "number",
95
- description: "Result limit (optional for search, default: 30)"
96
- },
97
- force: {
98
- type: "boolean",
99
- description: "Force push - REQUIRES confirmDestructive: true (optional for push, default: false)"
100
- },
101
- setUpstream: {
102
- type: "boolean",
103
- description: "Set upstream (optional for push, default: true)"
104
- },
105
- bare: {
106
- type: "boolean",
107
- description: "Initialize as bare repo (optional for init, default: false)"
108
- },
109
- confirmDestructive: {
110
- type: "boolean",
111
- description: "Required confirmation for destructive operations like force push (default: false)"
112
- }
113
- },
114
- required: ["projectPath", "action"],
115
- additionalProperties: true
116
- };
117
- }
118
- async handle(params, ctx) {
119
- // Normalize parameters to handle different IDE/agent formats
120
- params = normalizeToolParams(params);
121
- const action = params.action;
122
- if (!action)
123
- throw new MCPError('VALIDATION_ERROR', 'action is required. You can use either "action" or "command" parameter.');
124
- const projectPath = params.projectPath;
125
- // Validação de path para segurança
126
- if (projectPath) {
127
- const path = await import('path');
128
- const resolvedPath = path.resolve(projectPath);
129
- // Verificar se é um diretório válido e não está tentando escapar
130
- if (!resolvedPath || resolvedPath.includes('..')) {
131
- throw new MCPError('VALIDATION_ERROR', 'Invalid project path provided');
132
- }
133
- }
134
- if (!ctx.gitAdapter) {
135
- throw new MCPError('INTERNAL_ERROR', 'Git adapter not available');
136
- }
137
- switch (action) {
138
- case 'init': {
139
- if (!projectPath)
140
- throw new MCPError('VALIDATION_ERROR', 'projectPath is required for init');
141
- await ctx.gitAdapter.init(projectPath);
142
- return { success: true, path: projectPath };
143
- }
144
- case 'status': {
145
- if (!projectPath)
146
- throw new MCPError('VALIDATION_ERROR', 'projectPath is required for status');
147
- const status = await ctx.gitAdapter.status(projectPath);
148
- return { success: true, status };
149
- }
150
- case 'commit': {
151
- if (!projectPath)
152
- throw new MCPError('VALIDATION_ERROR', 'projectPath is required for commit');
153
- const message = params.message;
154
- if (!message)
155
- throw new MCPError('VALIDATION_ERROR', 'Commit message is required');
156
- let files = params.files || ['.'];
157
- // Handle case where files might be passed as a string (e.g., from some agents)
158
- if (typeof files === 'string') {
159
- files = files === '.' ? ['.'] : files.split(',').map(f => f.trim());
160
- }
161
- // Ensure files is an array
162
- if (!Array.isArray(files)) {
163
- files = [files];
164
- }
165
- try {
166
- await ctx.gitAdapter.add(projectPath, files);
167
- }
168
- catch (addErr) {
169
- console.warn(`Failed to add files: ${addErr.message}`);
170
- throw addErr;
171
- }
172
- const result = await ctx.gitAdapter.commit(projectPath, message);
173
- return { success: true, commit: result };
174
- }
175
- case 'sync': {
176
- if (!projectPath)
177
- throw new MCPError('VALIDATION_ERROR', 'projectPath is required for sync');
178
- const remote = params.remote || 'origin';
179
- let branch = params.branch;
180
- if (!branch) {
181
- branch = await ctx.gitAdapter.getCurrentBranch(projectPath);
182
- }
183
- await ctx.gitAdapter.fetch(projectPath, remote);
184
- await ctx.gitAdapter.pull(projectPath, remote, branch);
185
- await ctx.gitAdapter.push(projectPath, remote, branch);
186
- return { success: true, message: 'Repository synced' };
187
- }
188
- case 'backup': {
189
- const backupPath = params.backupPath || `${projectPath}-backup-${Date.now()}.tar.gz`;
190
- return { success: true, backupPath, message: 'Backup marked (simplified)' };
191
- }
192
- case 'create': {
193
- const name = params.name;
194
- if (!name)
195
- throw new MCPError('VALIDATION_ERROR', 'name is required');
196
- const githubOwner = params.owner || process.env.GITHUB_USERNAME;
197
- const giteaOwner = params.owner || process.env.GITEA_USERNAME;
198
- const results = { success: true, providers: {} };
199
- // GitHub
200
- if (ctx.providerManager.github && githubOwner) {
201
- try {
202
- const result = await ctx.providerManager.github.rest.repos.createForAuthenticatedUser({
203
- name,
204
- description: params.description,
205
- private: params.private || false,
206
- });
207
- results.providers.github = { success: true, repo: result.data };
208
- }
209
- catch (err) {
210
- results.providers.github = { success: false, error: err.message };
211
- }
212
- }
213
- // Gitea
214
- if (ctx.providerManager.giteaBaseUrl && giteaOwner) {
215
- try {
216
- const result = await axios.post(`${ctx.providerManager.giteaBaseUrl}/api/v1/user/repos`, {
217
- name,
218
- description: params.description,
219
- private: params.private || false,
220
- }, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
221
- results.providers.gitea = { success: true, repo: result.data };
222
- }
223
- catch (err) {
224
- results.providers.gitea = { success: false, error: err.message };
225
- }
226
- }
227
- return results;
228
- }
229
- case 'list': {
230
- const results = { success: true, providers: {} };
231
- // GitHub
232
- if (ctx.providerManager.github) {
233
- try {
234
- const result = await ctx.providerManager.github.rest.repos.listForAuthenticatedUser();
235
- results.providers.github = { success: true, repos: result.data };
236
- }
237
- catch (err) {
238
- results.providers.github = { success: false, error: err.message };
239
- }
240
- }
241
- // Gitea
242
- if (ctx.providerManager.giteaBaseUrl) {
243
- try {
244
- const result = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/user/repos`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
245
- results.providers.gitea = { success: true, repos: result.data };
246
- }
247
- catch (err) {
248
- results.providers.gitea = { success: false, error: err.message };
249
- }
250
- }
251
- return results;
252
- }
253
- case 'get': {
254
- const githubOwner = params.owner || process.env.GITHUB_USERNAME;
255
- const giteaOwner = params.owner || process.env.GITEA_USERNAME;
256
- const repo = params.repo;
257
- if (!githubOwner || !repo) {
258
- throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
259
- }
260
- const results = { success: true, providers: {} };
261
- // GitHub
262
- if (ctx.providerManager.github) {
263
- try {
264
- const result = await ctx.providerManager.github.rest.repos.get({ owner: githubOwner, repo });
265
- results.providers.github = { success: true, repo: result.data };
266
- }
267
- catch (err) {
268
- results.providers.github = { success: false, error: err.message };
269
- }
270
- }
271
- // Gitea
272
- if (ctx.providerManager.giteaBaseUrl) {
273
- try {
274
- const result = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
275
- results.providers.gitea = { success: true, repo: result.data };
276
- }
277
- catch (err) {
278
- results.providers.gitea = { success: false, error: err.message };
279
- }
280
- }
281
- return results;
282
- }
283
- case 'update': {
284
- const githubOwner = params.owner || process.env.GITHUB_USERNAME;
285
- const giteaOwner = params.owner || process.env.GITEA_USERNAME;
286
- const repo = params.repo;
287
- if (!githubOwner || !repo) {
288
- throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
289
- }
290
- const results = { success: true, providers: {} };
291
- // GitHub
292
- if (ctx.providerManager.github) {
293
- try {
294
- const result = await ctx.providerManager.github.rest.repos.update({
295
- owner: githubOwner,
296
- repo,
297
- description: params.description,
298
- private: params.private,
299
- has_issues: params.has_issues,
300
- has_projects: params.has_projects,
301
- has_wiki: params.has_wiki,
302
- });
303
- results.providers.github = { success: true, repo: result.data };
304
- }
305
- catch (err) {
306
- results.providers.github = { success: false, error: err.message };
307
- }
308
- }
309
- // Gitea
310
- if (ctx.providerManager.giteaBaseUrl) {
311
- try {
312
- const result = await axios.patch(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}`, {
313
- description: params.description,
314
- private: params.private,
315
- has_issues: params.has_issues,
316
- has_projects: params.has_projects,
317
- has_wiki: params.has_wiki,
318
- }, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
319
- results.providers.gitea = { success: true, repo: result.data };
320
- }
321
- catch (err) {
322
- results.providers.gitea = { success: false, error: err.message };
323
- }
324
- }
325
- return results;
326
- }
327
- case 'delete': {
328
- const githubOwner = params.owner || process.env.GITHUB_USERNAME;
329
- const giteaOwner = params.owner || process.env.GITEA_USERNAME;
330
- const repo = params.repo;
331
- if (!githubOwner || !repo) {
332
- throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
333
- }
334
- // Requer confirmação para deleção
335
- if (!params.confirmDestructive) {
336
- throw new MCPError('SAFETY_WARNING', 'Repository deletion is destructive. Set confirmDestructive: true to proceed.', [
337
- 'Repository deletion is permanent and cannot be undone.',
338
- 'Ensure you have backups before proceeding.',
339
- 'Consider archiving the repository instead.',
340
- ]);
341
- }
342
- const results = { success: true, providers: {} };
343
- // GitHub
344
- if (ctx.providerManager.github) {
345
- try {
346
- await ctx.providerManager.github.rest.repos.delete({ owner: githubOwner, repo });
347
- results.providers.github = { success: true, deleted: true };
348
- }
349
- catch (err) {
350
- results.providers.github = { success: false, error: err.message };
351
- }
352
- }
353
- // Gitea
354
- if (ctx.providerManager.giteaBaseUrl) {
355
- try {
356
- await axios.delete(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
357
- results.providers.gitea = { success: true, deleted: true };
358
- }
359
- catch (err) {
360
- results.providers.gitea = { success: false, error: err.message };
361
- }
362
- }
363
- return results;
364
- }
365
- case 'fork': {
366
- const githubOwner = params.owner || process.env.GITHUB_USERNAME;
367
- const giteaOwner = params.owner || process.env.GITEA_USERNAME;
368
- const repo = params.repo;
369
- if (!githubOwner || !repo) {
370
- throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
371
- }
372
- const results = { success: true, providers: {} };
373
- // GitHub
374
- if (ctx.providerManager.github) {
375
- try {
376
- const result = await ctx.providerManager.github.rest.repos.createFork({
377
- owner: githubOwner,
378
- repo,
379
- organization: params.organization,
380
- });
381
- results.providers.github = { success: true, fork: result.data };
382
- }
383
- catch (err) {
384
- results.providers.github = { success: false, error: err.message };
385
- }
386
- }
387
- // Gitea
388
- if (ctx.providerManager.giteaBaseUrl) {
389
- try {
390
- const result = await axios.post(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/forks`, { organization: params.organization }, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
391
- results.providers.gitea = { success: true, fork: result.data };
392
- }
393
- catch (err) {
394
- results.providers.gitea = { success: false, error: err.message };
395
- }
396
- }
397
- return results;
398
- }
399
- case 'search': {
400
- const query = params.query;
401
- if (!query)
402
- throw new MCPError('VALIDATION_ERROR', 'query is required');
403
- const results = { success: true, providers: {} };
404
- // GitHub
405
- if (ctx.providerManager.github) {
406
- try {
407
- const result = await ctx.providerManager.github.rest.search.repos({
408
- q: query,
409
- sort: params.sort,
410
- order: params.order,
411
- per_page: params.limit || 30,
412
- });
413
- results.providers.github = { success: true, repos: result.data.items, total: result.data.total_count };
414
- }
415
- catch (err) {
416
- results.providers.github = { success: false, error: err.message };
417
- }
418
- }
419
- // Gitea
420
- if (ctx.providerManager.giteaBaseUrl) {
421
- try {
422
- const result = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/search`, {
423
- params: { q: query, limit: params.limit || 30, sort: params.sort },
424
- headers: { Authorization: `token ${ctx.providerManager.giteaToken}` }
425
- });
426
- results.providers.gitea = { success: true, repos: result.data.data, total: result.data.ok ? result.data.data.length : 0 };
427
- }
428
- catch (err) {
429
- results.providers.gitea = { success: false, error: err.message };
430
- }
431
- }
432
- return results;
433
- }
434
- case 'push': {
435
- if (!projectPath)
436
- throw new MCPError('VALIDATION_ERROR', 'projectPath is required for push');
437
- const remote = params.remote || 'origin';
438
- let branch = params.branch;
439
- const force = params.force || false;
440
- const setUpstream = params.setUpstream !== undefined ? params.setUpstream : true;
441
- // Segurança: verificar confirmação para operações destrutivas
442
- if (force && !params.confirmDestructive) {
443
- throw new MCPError('SAFETY_WARNING', 'Force push is destructive and can overwrite remote history. Set confirmDestructive: true to confirm.', [
444
- 'Force push will overwrite remote branch history.',
445
- 'This operation is dangerous and can cause data loss for collaborators.',
446
- 'Consider using regular push without force parameter.',
447
- 'If you must force push, ensure you understand the consequences.',
448
- ]);
449
- }
450
- try {
451
- if (!branch) {
452
- branch = await ctx.gitAdapter.getCurrentBranch(projectPath);
453
- }
454
- await ctx.gitAdapter.push(projectPath, remote, branch, force, setUpstream);
455
- return {
456
- success: true,
457
- remote,
458
- branch,
459
- force,
460
- setUpstream,
461
- message: 'Push successful'
462
- };
463
- }
464
- catch (err) {
465
- throw new MCPError('PUSH_ERROR', `Failed to push: ${err.message}`);
466
- }
467
- }
468
- default:
469
- throw new MCPError('VALIDATION_ERROR', `Unsupported action: ${action}`);
470
- }
471
- }
472
- }
package/dist/types.d.ts DELETED
@@ -1,20 +0,0 @@
1
- import { ProviderManager } from './providers/providerManager.js';
2
- import { GitAdapter } from './utils/gitAdapter.js';
3
- export type MCPContext = {
4
- providerManager: ProviderManager;
5
- gitAdapter: GitAdapter;
6
- };
7
- export type ToolHandleResult = any;
8
- export interface Tool {
9
- name: string;
10
- description?: string;
11
- inputSchema?: any;
12
- handle(params: Record<string, any>, ctx: MCPContext): Promise<ToolHandleResult>;
13
- }
14
- export interface Resource {
15
- uri: string;
16
- name: string;
17
- description: string;
18
- mimeType: string;
19
- content: string;
20
- }
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,11 +0,0 @@
1
- export declare function ensureProjectPath(params: Record<string, any>): string;
2
- export declare function ensureActionAllowed(action: string | undefined, allowedActions?: string[]): string;
3
- /**
4
- * Convenience: validate common tool call shape.
5
- * @param params tool call params
6
- * @param allowedActions optional array of allowed action strings
7
- */
8
- export declare function validateToolCall(params: Record<string, any>, allowedActions?: string[]): {
9
- projectPath: string;
10
- action: any;
11
- };
@@ -1,41 +0,0 @@
1
- /**
2
- * Utilities to help AI agents build/validate tool calls.
3
- * Agents are responsible for detecting workspace and passing projectPath.
4
- * These helpers provide lightweight validation to avoid calling tools with
5
- * missing projectPath or invalid actions. Tools themselves will still
6
- * validate and throw MCPError if inputs are invalid.
7
- */
8
- import { MCPError } from './errors';
9
- export function ensureProjectPath(params) {
10
- if (!params || typeof params !== 'object') {
11
- throw new Error('params must be an object');
12
- }
13
- const projectPath = params.projectPath;
14
- if (!projectPath || typeof projectPath !== 'string' || projectPath.trim() === '') {
15
- throw new MCPError('VALIDATION_ERROR', 'projectPath is required for tool invocation');
16
- }
17
- return projectPath;
18
- }
19
- export function ensureActionAllowed(action, allowedActions) {
20
- if (!action || typeof action !== 'string') {
21
- throw new MCPError('VALIDATION_ERROR', 'action is required');
22
- }
23
- if (Array.isArray(allowedActions) && allowedActions.length > 0) {
24
- if (!allowedActions.includes(action)) {
25
- throw new MCPError('VALIDATION_ERROR', `Unsupported action: ${action}`);
26
- }
27
- }
28
- return action;
29
- }
30
- /**
31
- * Convenience: validate common tool call shape.
32
- * @param params tool call params
33
- * @param allowedActions optional array of allowed action strings
34
- */
35
- export function validateToolCall(params, allowedActions) {
36
- const projectPath = ensureProjectPath(params);
37
- if (allowedActions) {
38
- ensureActionAllowed(params.action, allowedActions);
39
- }
40
- return { projectPath, action: params.action };
41
- }
@@ -1,29 +0,0 @@
1
- interface RetryConfig {
2
- maxRetries: number;
3
- initialDelay: number;
4
- maxDelay: number;
5
- backoffFactor: number;
6
- }
7
- /**
8
- * Retry wrapper for operations that may have eventual consistency issues.
9
- * Used for GitHub API list operations after create/update.
10
- */
11
- export declare function retryUntilFound<T>(operation: () => Promise<T[]>, validateFn: (items: T[]) => boolean, config?: Partial<RetryConfig>): Promise<T[]>;
12
- /**
13
- * Retry a single operation with exponential backoff.
14
- */
15
- export declare function retryOperation<T>(operation: () => Promise<T>, shouldRetry: (error: any) => boolean, config?: Partial<RetryConfig>): Promise<T>;
16
- interface ValidationRule<T> {
17
- validate: (data: T) => boolean;
18
- errorMessage: string;
19
- }
20
- export declare function validateResponse<T>(data: T, rules: ValidationRule<T>[]): void;
21
- /**
22
- * Validate GitHub/Gitea stats response has required fields.
23
- */
24
- export declare function validateStatsResponse(response: any): any;
25
- /**
26
- * Validate contributors response.
27
- */
28
- export declare function validateContributorsResponse(response: any): any[];
29
- export {};