@andrebuzeli/git-mcp 5.0.4 → 5.0.6

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 (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +143 -89
  3. package/dist/config.d.ts +72 -71
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +226 -139
  6. package/dist/config.js.map +1 -1
  7. package/dist/index.d.ts +15 -17
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +133 -128
  10. package/dist/index.js.map +1 -1
  11. package/dist/providers/base-provider.d.ts +42 -153
  12. package/dist/providers/base-provider.d.ts.map +1 -1
  13. package/dist/providers/base-provider.js +42 -302
  14. package/dist/providers/base-provider.js.map +1 -1
  15. package/dist/providers/gitea-provider.d.ts +67 -118
  16. package/dist/providers/gitea-provider.d.ts.map +1 -1
  17. package/dist/providers/gitea-provider.js +487 -1161
  18. package/dist/providers/gitea-provider.js.map +1 -1
  19. package/dist/providers/github-provider.d.ts +70 -81
  20. package/dist/providers/github-provider.d.ts.map +1 -1
  21. package/dist/providers/github-provider.js +641 -278
  22. package/dist/providers/github-provider.js.map +1 -1
  23. package/dist/providers/index.d.ts +9 -9
  24. package/dist/providers/index.d.ts.map +1 -1
  25. package/dist/providers/index.js +13 -19
  26. package/dist/providers/index.js.map +1 -1
  27. package/dist/providers/provider-factory.d.ts +29 -59
  28. package/dist/providers/provider-factory.d.ts.map +1 -1
  29. package/dist/providers/provider-factory.js +134 -265
  30. package/dist/providers/provider-factory.js.map +1 -1
  31. package/dist/providers/provider-operation-handler.d.ts +93 -0
  32. package/dist/providers/provider-operation-handler.d.ts.map +1 -0
  33. package/dist/providers/provider-operation-handler.js +280 -0
  34. package/dist/providers/provider-operation-handler.js.map +1 -0
  35. package/dist/providers/types.d.ts +201 -355
  36. package/dist/providers/types.d.ts.map +1 -1
  37. package/dist/providers/types.js +3 -2
  38. package/dist/providers/types.js.map +1 -1
  39. package/dist/server.d.ts +34 -4
  40. package/dist/server.d.ts.map +1 -1
  41. package/dist/server.js +439 -262
  42. package/dist/server.js.map +1 -1
  43. package/dist/tools/git-analytics.d.ts +239 -16
  44. package/dist/tools/git-analytics.d.ts.map +1 -1
  45. package/dist/tools/git-analytics.js +737 -25
  46. package/dist/tools/git-analytics.js.map +1 -1
  47. package/dist/tools/git-archive.d.ts +109 -15
  48. package/dist/tools/git-archive.d.ts.map +1 -1
  49. package/dist/tools/git-archive.js +462 -10
  50. package/dist/tools/git-archive.js.map +1 -1
  51. package/dist/tools/git-backup.d.ts +101 -15
  52. package/dist/tools/git-backup.d.ts.map +1 -1
  53. package/dist/tools/git-backup.js +410 -10
  54. package/dist/tools/git-backup.js.map +1 -1
  55. package/dist/tools/git-branches.d.ts +141 -15
  56. package/dist/tools/git-branches.d.ts.map +1 -1
  57. package/dist/tools/git-branches.js +466 -11
  58. package/dist/tools/git-branches.js.map +1 -1
  59. package/dist/tools/git-config.d.ts +115 -15
  60. package/dist/tools/git-config.d.ts.map +1 -1
  61. package/dist/tools/git-config.js +446 -11
  62. package/dist/tools/git-config.js.map +1 -1
  63. package/dist/tools/git-files.d.ts +179 -59
  64. package/dist/tools/git-files.d.ts.map +1 -1
  65. package/dist/tools/git-files.js +682 -222
  66. package/dist/tools/git-files.js.map +1 -1
  67. package/dist/tools/git-issues.d.ts +158 -15
  68. package/dist/tools/git-issues.d.ts.map +1 -1
  69. package/dist/tools/git-issues.js +323 -11
  70. package/dist/tools/git-issues.js.map +1 -1
  71. package/dist/tools/git-monitor.d.ts +149 -14
  72. package/dist/tools/git-monitor.d.ts.map +1 -1
  73. package/dist/tools/git-monitor.js +528 -11
  74. package/dist/tools/git-monitor.js.map +1 -1
  75. package/dist/tools/git-packages.d.ts +163 -15
  76. package/dist/tools/git-packages.d.ts.map +1 -1
  77. package/dist/tools/git-packages.js +526 -11
  78. package/dist/tools/git-packages.js.map +1 -1
  79. package/dist/tools/git-pulls.d.ts +174 -15
  80. package/dist/tools/git-pulls.d.ts.map +1 -1
  81. package/dist/tools/git-pulls.js +352 -11
  82. package/dist/tools/git-pulls.js.map +1 -1
  83. package/dist/tools/git-release.d.ts +167 -15
  84. package/dist/tools/git-release.d.ts.map +1 -1
  85. package/dist/tools/git-release.js +465 -11
  86. package/dist/tools/git-release.js.map +1 -1
  87. package/dist/tools/git-remote.d.ts +124 -15
  88. package/dist/tools/git-remote.d.ts.map +1 -1
  89. package/dist/tools/git-remote.js +539 -11
  90. package/dist/tools/git-remote.js.map +1 -1
  91. package/dist/tools/git-reset.d.ts +100 -15
  92. package/dist/tools/git-reset.d.ts.map +1 -1
  93. package/dist/tools/git-reset.js +409 -11
  94. package/dist/tools/git-reset.js.map +1 -1
  95. package/dist/tools/git-stash.d.ts +120 -15
  96. package/dist/tools/git-stash.d.ts.map +1 -1
  97. package/dist/tools/git-stash.js +503 -11
  98. package/dist/tools/git-stash.js.map +1 -1
  99. package/dist/tools/git-sync.d.ts +160 -16
  100. package/dist/tools/git-sync.d.ts.map +1 -1
  101. package/dist/tools/git-sync.js +462 -113
  102. package/dist/tools/git-sync.js.map +1 -1
  103. package/dist/tools/git-tags.d.ts +142 -15
  104. package/dist/tools/git-tags.d.ts.map +1 -1
  105. package/dist/tools/git-tags.js +471 -11
  106. package/dist/tools/git-tags.js.map +1 -1
  107. package/dist/tools/git-workflow.d.ts +151 -80
  108. package/dist/tools/git-workflow.d.ts.map +1 -1
  109. package/dist/tools/git-workflow.js +407 -912
  110. package/dist/tools/git-workflow.js.map +1 -1
  111. package/dist/utils/credential-manager.d.ts +119 -0
  112. package/dist/utils/credential-manager.d.ts.map +1 -0
  113. package/dist/utils/credential-manager.js +450 -0
  114. package/dist/utils/credential-manager.js.map +1 -0
  115. package/dist/utils/git-command-executor.d.ts +326 -0
  116. package/dist/utils/git-command-executor.d.ts.map +1 -0
  117. package/dist/utils/git-command-executor.js +877 -0
  118. package/dist/utils/git-command-executor.js.map +1 -0
  119. package/dist/utils/logger.d.ts +143 -0
  120. package/dist/utils/logger.d.ts.map +1 -0
  121. package/dist/utils/logger.js +473 -0
  122. package/dist/utils/logger.js.map +1 -0
  123. package/dist/utils/operation-error-handler.d.ts +54 -41
  124. package/dist/utils/operation-error-handler.d.ts.map +1 -1
  125. package/dist/utils/operation-error-handler.js +211 -227
  126. package/dist/utils/operation-error-handler.js.map +1 -1
  127. package/dist/utils/parameter-validator.d.ts +41 -0
  128. package/dist/utils/parameter-validator.d.ts.map +1 -0
  129. package/dist/utils/parameter-validator.js +464 -0
  130. package/dist/utils/parameter-validator.js.map +1 -0
  131. package/dist/utils/repository-detector.d.ts +128 -0
  132. package/dist/utils/repository-detector.d.ts.map +1 -0
  133. package/dist/utils/repository-detector.js +422 -0
  134. package/dist/utils/repository-detector.js.map +1 -0
  135. package/dist/utils/response-formatter.d.ts +146 -0
  136. package/dist/utils/response-formatter.d.ts.map +1 -0
  137. package/dist/utils/response-formatter.js +378 -0
  138. package/dist/utils/response-formatter.js.map +1 -0
  139. package/dist/utils/retry.d.ts +12 -0
  140. package/dist/utils/retry.d.ts.map +1 -0
  141. package/dist/utils/retry.js +28 -0
  142. package/dist/utils/retry.js.map +1 -0
  143. package/dist/utils/terminal-controller.d.ts +73 -139
  144. package/dist/utils/terminal-controller.d.ts.map +1 -1
  145. package/dist/utils/terminal-controller.js +234 -459
  146. package/dist/utils/terminal-controller.js.map +1 -1
  147. package/package.json +79 -60
  148. package/dist/providers/error-handler.d.ts +0 -51
  149. package/dist/providers/error-handler.d.ts.map +0 -1
  150. package/dist/providers/error-handler.js +0 -176
  151. package/dist/providers/error-handler.js.map +0 -1
  152. package/dist/providers/github-provider-backup.d.ts +0 -81
  153. package/dist/providers/github-provider-backup.d.ts.map +0 -1
  154. package/dist/providers/github-provider-backup.js +0 -1179
  155. package/dist/providers/github-provider-backup.js.map +0 -1
  156. package/dist/providers/github-provider-complete.d.ts +0 -1
  157. package/dist/providers/github-provider-complete.d.ts.map +0 -1
  158. package/dist/providers/github-provider-complete.js +0 -2
  159. package/dist/providers/github-provider-complete.js.map +0 -1
  160. package/dist/tools/git-init.d.ts +0 -50
  161. package/dist/tools/git-init.d.ts.map +0 -1
  162. package/dist/tools/git-init.js +0 -258
  163. package/dist/tools/git-init.js.map +0 -1
  164. package/dist/tools/git-log.d.ts +0 -67
  165. package/dist/tools/git-log.d.ts.map +0 -1
  166. package/dist/tools/git-log.js +0 -320
  167. package/dist/tools/git-log.js.map +0 -1
  168. package/dist/tools/git-status.d.ts +0 -29
  169. package/dist/tools/git-status.d.ts.map +0 -1
  170. package/dist/tools/git-status.js +0 -182
  171. package/dist/tools/git-status.js.map +0 -1
  172. package/dist/tools/git-update.d.ts +0 -34
  173. package/dist/tools/git-update.d.ts.map +0 -1
  174. package/dist/tools/git-update.js +0 -191
  175. package/dist/tools/git-update.js.map +0 -1
  176. package/dist/utils/auto-detection.d.ts +0 -120
  177. package/dist/utils/auto-detection.d.ts.map +0 -1
  178. package/dist/utils/auto-detection.js +0 -259
  179. package/dist/utils/auto-detection.js.map +0 -1
  180. package/dist/utils/configuration-error-generator.d.ts +0 -41
  181. package/dist/utils/configuration-error-generator.d.ts.map +0 -1
  182. package/dist/utils/configuration-error-generator.js +0 -168
  183. package/dist/utils/configuration-error-generator.js.map +0 -1
  184. package/dist/utils/configuration-validator.d.ts +0 -67
  185. package/dist/utils/configuration-validator.d.ts.map +0 -1
  186. package/dist/utils/configuration-validator.js +0 -257
  187. package/dist/utils/configuration-validator.js.map +0 -1
  188. package/dist/utils/error-handler.d.ts +0 -107
  189. package/dist/utils/error-handler.d.ts.map +0 -1
  190. package/dist/utils/error-handler.js +0 -331
  191. package/dist/utils/error-handler.js.map +0 -1
  192. package/dist/utils/git-operations.d.ts +0 -200
  193. package/dist/utils/git-operations.d.ts.map +0 -1
  194. package/dist/utils/git-operations.js +0 -836
  195. package/dist/utils/git-operations.js.map +0 -1
  196. package/dist/utils/multi-provider-error-handler.d.ts +0 -75
  197. package/dist/utils/multi-provider-error-handler.d.ts.map +0 -1
  198. package/dist/utils/multi-provider-error-handler.js +0 -276
  199. package/dist/utils/multi-provider-error-handler.js.map +0 -1
  200. package/dist/utils/multi-provider-operation-handler.d.ts +0 -113
  201. package/dist/utils/multi-provider-operation-handler.d.ts.map +0 -1
  202. package/dist/utils/multi-provider-operation-handler.js +0 -303
  203. package/dist/utils/multi-provider-operation-handler.js.map +0 -1
  204. package/dist/utils/provider-operation-handler.d.ts +0 -80
  205. package/dist/utils/provider-operation-handler.d.ts.map +0 -1
  206. package/dist/utils/provider-operation-handler.js +0 -201
  207. package/dist/utils/provider-operation-handler.js.map +0 -1
  208. package/dist/utils/response-helper.d.ts +0 -57
  209. package/dist/utils/response-helper.d.ts.map +0 -1
  210. package/dist/utils/response-helper.js +0 -54
  211. package/dist/utils/response-helper.js.map +0 -1
  212. package/dist/utils/user-detection.d.ts +0 -25
  213. package/dist/utils/user-detection.d.ts.map +0 -1
  214. package/dist/utils/user-detection.js +0 -54
  215. package/dist/utils/user-detection.js.map +0 -1
@@ -1,985 +1,480 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gitWorkflowTool = void 0;
4
- const auto_detection_js_1 = require("../utils/auto-detection.js");
5
- const configuration_validator_js_1 = require("../utils/configuration-validator.js");
6
- const provider_operation_handler_js_1 = require("../utils/provider-operation-handler.js");
7
- const operation_error_handler_js_1 = require("../utils/operation-error-handler.js");
8
- const terminal_controller_js_1 = require("../utils/terminal-controller.js");
9
2
  /**
10
- * Git Workflow Tool - Ferramenta Principal
3
+ * Git Workflow Tool
11
4
  *
12
- * Implementa o workflow completo de Git com operações integradas:
13
- * - init: Inicializar projeto completo
14
- * - commit: Commit + push automático
15
- * - sync: Pull + commit + push completo
16
- * - status: Status detalhado do projeto
17
- * - backup: Backup completo do projeto
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
18
10
  */
19
- const inputSchema = {
20
- type: 'object',
21
- properties: {
22
- action: {
23
- type: 'string',
24
- enum: ['init', 'commit', 'sync', 'status', 'backup', 'create', 'list', 'get', 'update', 'delete', 'fork', 'search'],
25
- description: 'Ação do workflow a executar'
26
- },
27
- projectPath: {
28
- type: 'string',
29
- description: 'Caminho do projeto (obrigatório)'
30
- },
31
- provider: {
32
- type: 'string',
33
- enum: ['github', 'gitea', 'both'],
34
- description: 'Provider para operações remotas (obrigatório para create, list, get, update, delete, fork, search)'
35
- },
36
- message: {
37
- type: 'string',
38
- description: 'Mensagem de commit (para commit/sync)'
39
- },
40
- branch: {
41
- type: 'string',
42
- description: 'Branch para operações (padrão: main)'
43
- },
44
- remote: {
45
- type: 'string',
46
- description: 'Remote para operações (padrão: origin)'
47
- },
48
- // Parâmetros para gerenciamento de repositórios
49
- repoName: {
50
- type: 'string',
51
- description: 'Nome do repositório (para create/get/update/delete/fork)'
52
- },
53
- description: {
54
- type: 'string',
55
- description: 'Descrição do repositório (para create/update)'
56
- },
57
- private: {
58
- type: 'boolean',
59
- description: 'Repositório privado (para create/update)'
60
- },
61
- sourceRepo: {
62
- type: 'string',
63
- description: 'Repositório de origem (para fork)'
64
- },
65
- searchQuery: {
66
- type: 'string',
67
- description: 'Termo de busca (para search)'
68
- },
69
- language: {
70
- type: 'string',
71
- description: 'Filtrar por linguagem (para search)'
72
- },
73
- sort: {
74
- type: 'string',
75
- description: 'Ordenar por: stars, updated, created (padrão: stars)'
76
- },
77
- order: {
78
- type: 'string',
79
- description: 'Ordem: asc, desc (padrão: desc)'
80
- },
81
- page: {
82
- type: 'number',
83
- description: 'Página para paginação (padrão: 1)'
84
- },
85
- perPage: {
86
- type: 'number',
87
- description: 'Itens por página (padrão: 30)'
88
- }
89
- },
90
- required: ['action', 'projectPath'],
91
- // Provider é obrigatório para operações remotas
92
- if: {
93
- properties: {
94
- action: {
95
- enum: ['create', 'list', 'get', 'update', 'delete', 'fork', 'search']
96
- }
97
- }
98
- },
99
- then: {
100
- required: ['action', 'projectPath', 'provider']
101
- }
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
102
13
  };
103
- async function handleInit(projectPath, detection) {
104
- try {
105
- const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
106
- if (isRepo) {
107
- return {
108
- success: true,
109
- action: 'init',
110
- message: 'Projeto já é um repositório Git',
111
- data: {
112
- alreadyInitialized: true,
113
- projectPath,
114
- repoName: detection.repoName
115
- }
116
- };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.GitWorkflowTool = void 0;
16
+ const git_command_executor_js_1 = require("../utils/git-command-executor.js");
17
+ const parameter_validator_js_1 = require("../utils/parameter-validator.js");
18
+ const operation_error_handler_js_1 = require("../utils/operation-error-handler.js");
19
+ const provider_operation_handler_js_1 = require("../providers/provider-operation-handler.js");
20
+ const path_1 = __importDefault(require("path"));
21
+ class GitWorkflowTool {
22
+ gitExecutor;
23
+ providerHandler;
24
+ constructor(providerConfig) {
25
+ this.gitExecutor = new git_command_executor_js_1.GitCommandExecutor();
26
+ if (providerConfig) {
27
+ this.providerHandler = new provider_operation_handler_js_1.ProviderOperationHandler(providerConfig);
117
28
  }
118
- // Inicializar repositório Git
119
- const { execSync } = require('child_process');
120
- execSync('git init', { cwd: projectPath });
121
- execSync('git add .', { cwd: projectPath });
122
- execSync('git commit -m "Initial commit"', { cwd: projectPath });
123
- return {
124
- success: true,
125
- action: 'init',
126
- message: 'Projeto inicializado com sucesso',
127
- data: {
128
- initialized: true,
129
- projectPath,
130
- repoName: detection.repoName,
131
- initialCommit: true
132
- }
133
- };
134
29
  }
135
- catch (error) {
136
- throw new Error(`Falha ao inicializar projeto: ${error instanceof Error ? error.message : String(error)}`);
137
- }
138
- }
139
- async function handleCommit(projectPath, message, branch = 'main', remote = 'origin') {
140
- try {
141
- const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
142
- if (!isRepo) {
143
- throw new Error('Diretório não é um repositório Git');
144
- }
145
- // Status antes do commit
146
- const statusResult = await (0, terminal_controller_js_1.getGitStatus)(projectPath);
147
- // Add all changes
148
- const addResult = await (0, terminal_controller_js_1.gitAdd)(projectPath, '.');
149
- if (addResult.exitCode !== 0) {
150
- throw new Error(`Falha ao adicionar arquivos: ${addResult.error}`);
151
- }
152
- // Commit
153
- const commitResult = await (0, terminal_controller_js_1.gitCommit)(projectPath, message);
154
- if (commitResult.exitCode !== 0) {
155
- throw new Error(`Falha ao fazer commit: ${commitResult.error}`);
156
- }
157
- // Push
158
- const pushResult = await (0, terminal_controller_js_1.gitPush)(projectPath, branch, remote);
159
- return {
160
- success: true,
161
- action: 'commit',
162
- message: 'Commit realizado com sucesso',
163
- data: {
164
- committed: true,
165
- message,
166
- branch,
167
- remote,
168
- pushed: pushResult.exitCode === 0,
169
- statusBefore: statusResult.output,
170
- commitOutput: commitResult.output,
171
- pushOutput: pushResult.output
30
+ /**
31
+ * Execute git-workflow operation
32
+ */
33
+ async execute(params) {
34
+ const startTime = Date.now();
35
+ try {
36
+ // Validate basic parameters
37
+ const validation = parameter_validator_js_1.ParameterValidator.validateToolParams('git-workflow', params);
38
+ if (!validation.isValid) {
39
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('VALIDATION_ERROR', `Parameter validation failed: ${validation.errors.join(', ')}`, params.action, { validationErrors: validation.errors }, validation.suggestions);
172
40
  }
173
- };
174
- }
175
- catch (error) {
176
- throw new Error(`Falha no commit: ${error instanceof Error ? error.message : String(error)}`);
177
- }
178
- }
179
- async function handleSync(projectPath, message, branch = 'main', remote = 'origin') {
180
- try {
181
- const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
182
- if (!isRepo) {
183
- throw new Error('Diretório não é um repositório Git');
184
- }
185
- // Pull primeiro
186
- const pullResult = await (0, terminal_controller_js_1.gitPull)(projectPath, branch, remote);
187
- // Status após pull
188
- const statusResult = await (0, terminal_controller_js_1.getGitStatus)(projectPath);
189
- // Se há mudanças, fazer commit
190
- if (statusResult.output.includes('Changes') || statusResult.output.includes('modified')) {
191
- // Add all changes
192
- const addResult = await (0, terminal_controller_js_1.gitAdd)(projectPath, '.');
193
- if (addResult.exitCode !== 0) {
194
- throw new Error(`Falha ao adicionar arquivos: ${addResult.error}`);
41
+ // Validate operation-specific parameters
42
+ const operationValidation = parameter_validator_js_1.ParameterValidator.validateOperationParams('git-workflow', params.action, params);
43
+ if (!operationValidation.isValid) {
44
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('VALIDATION_ERROR', `Operation validation failed: ${operationValidation.errors.join(', ')}`, params.action, { validationErrors: operationValidation.errors }, operationValidation.suggestions);
195
45
  }
196
- // Commit
197
- const commitResult = await (0, terminal_controller_js_1.gitCommit)(projectPath, message);
198
- if (commitResult.exitCode !== 0) {
199
- throw new Error(`Falha ao fazer commit: ${commitResult.error}`);
46
+ // Route to appropriate handler
47
+ const isRemoteOperation = this.isRemoteOperation(params.action);
48
+ if (isRemoteOperation) {
49
+ return await this.executeRemoteOperation(params, startTime);
50
+ }
51
+ else {
52
+ return await this.executeLocalOperation(params, startTime);
200
53
  }
201
- // Push
202
- const pushResult = await (0, terminal_controller_js_1.gitPush)(projectPath, branch, remote);
203
- return {
204
- success: true,
205
- action: 'sync',
206
- message: 'Sincronização completa realizada',
207
- data: {
208
- pulled: pullResult.exitCode === 0,
209
- committed: true,
210
- pushed: pushResult.exitCode === 0,
211
- message,
212
- branch,
213
- remote,
214
- pullOutput: pullResult.output,
215
- commitOutput: commitResult.output,
216
- pushOutput: pushResult.output
217
- }
218
- };
219
- }
220
- else {
221
- return {
222
- success: true,
223
- action: 'sync',
224
- message: 'Sincronização realizada - nenhuma mudança local',
225
- data: {
226
- pulled: pullResult.exitCode === 0,
227
- committed: false,
228
- pushed: false,
229
- message: 'No local changes to commit',
230
- branch,
231
- remote,
232
- pullOutput: pullResult.output
233
- }
234
- };
235
- }
236
- }
237
- catch (error) {
238
- throw new Error(`Falha na sincronização: ${error instanceof Error ? error.message : String(error)}`);
239
- }
240
- }
241
- async function handleStatus(projectPath, detection) {
242
- try {
243
- const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
244
- if (!isRepo) {
245
- return {
246
- success: true,
247
- action: 'status',
248
- message: 'Diretório não é um repositório Git',
249
- data: {
250
- isGitRepo: false,
251
- projectPath,
252
- repoName: detection.repoName,
253
- suggestion: 'Use a ação "init" para inicializar o repositório'
254
- }
255
- };
256
- }
257
- // Status detalhado
258
- const statusResult = await (0, terminal_controller_js_1.getGitStatus)(projectPath);
259
- // Informações adicionais via execSync
260
- const { execSync } = require('child_process');
261
- let branchInfo = '';
262
- let remoteInfo = '';
263
- let lastCommit = '';
264
- try {
265
- branchInfo = execSync('git branch --show-current', { cwd: projectPath, encoding: 'utf8' }).trim();
266
- remoteInfo = execSync('git remote -v', { cwd: projectPath, encoding: 'utf8' }).trim();
267
- lastCommit = execSync('git log -1 --oneline', { cwd: projectPath, encoding: 'utf8' }).trim();
268
54
  }
269
55
  catch (error) {
270
- // Ignorar erros de comandos git adicionais
56
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
57
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('EXECUTION_ERROR', `Failed to execute ${params.action}: ${errorMessage}`, params.action, { error: errorMessage }, ['Check the error details and try again']);
271
58
  }
272
- return {
273
- success: true,
274
- action: 'status',
275
- message: 'Status do repositório obtido com sucesso',
276
- data: {
277
- isGitRepo: true,
278
- projectPath,
279
- repoName: detection.repoName,
280
- owner: detection.owner,
281
- providers: detection.providers,
282
- currentBranch: branchInfo,
283
- remotes: remoteInfo,
284
- lastCommit,
285
- status: statusResult.output,
286
- statusClean: statusResult.exitCode === 0
287
- }
288
- };
289
59
  }
290
- catch (error) {
291
- throw new Error(`Falha ao obter status: ${error instanceof Error ? error.message : String(error)}`);
292
- }
293
- }
294
- async function handleBackup(projectPath, detection) {
295
- try {
296
- const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
297
- if (!isRepo) {
298
- throw new Error('Diretório não é um repositório Git');
299
- }
300
- // Criar backup simples via tar/zip
301
- const fs = require('fs');
302
- const path = require('path');
303
- const { execSync } = require('child_process');
304
- const backupDir = path.join(projectPath, '..', 'backups');
305
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
306
- const backupName = `${detection.repoName}-backup-${timestamp}`;
307
- // Criar diretório de backup se não existir
308
- if (!fs.existsSync(backupDir)) {
309
- fs.mkdirSync(backupDir, { recursive: true });
310
- }
311
- // Criar backup (tar no Linux/Mac, zip no Windows)
312
- const isWindows = process.platform === 'win32';
313
- let backupFile = '';
314
- if (isWindows) {
315
- backupFile = path.join(backupDir, `${backupName}.zip`);
316
- execSync(`powershell Compress-Archive -Path "${projectPath}\\*" -DestinationPath "${backupFile}"`, { cwd: backupDir });
60
+ /**
61
+ * Execute local Git operations
62
+ */
63
+ async executeLocalOperation(params, startTime) {
64
+ switch (params.action) {
65
+ case 'init':
66
+ return await this.handleInit(params, startTime);
67
+ case 'status':
68
+ return await this.handleStatus(params, startTime);
69
+ case 'commit':
70
+ return await this.handleCommit(params, startTime);
71
+ case 'sync':
72
+ return await this.handleSync(params, startTime);
73
+ case 'backup':
74
+ return await this.handleBackup(params, startTime);
75
+ default:
76
+ 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']);
317
77
  }
318
- else {
319
- backupFile = path.join(backupDir, `${backupName}.tar.gz`);
320
- execSync(`tar -czf "${backupFile}" -C "${path.dirname(projectPath)}" "${path.basename(projectPath)}"`, { cwd: backupDir });
321
- }
322
- const stats = fs.statSync(backupFile);
323
- return {
324
- success: true,
325
- action: 'backup',
326
- message: 'Backup criado com sucesso',
327
- data: {
328
- backupCreated: true,
329
- backupFile,
330
- backupSize: stats.size,
331
- backupSizeHuman: `${(stats.size / 1024 / 1024).toFixed(2)} MB`,
332
- timestamp,
333
- projectPath,
334
- repoName: detection.repoName
335
- }
336
- };
337
- }
338
- catch (error) {
339
- throw new Error(`Falha ao criar backup: ${error instanceof Error ? error.message : String(error)}`);
340
78
  }
341
- }
342
- // Funções para gerenciamento de repositórios remotos
343
- async function handleCreateRepo(repoName, description, isPrivate, detection, projectPath, provider) {
344
- try {
345
- // Execute both local and remote operations simultaneously
346
- const results = await Promise.allSettled([
347
- // Local operation: initialize Git repository
348
- handleInit(projectPath, detection),
349
- // Remote operation: create repository on specified provider(s)
350
- provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.createRepository(repoName, description || `Repositório ${repoName}`, isPrivate || false))
351
- ]);
352
- const localResult = results[0];
353
- const remoteResult = results[1];
354
- // Format results
355
- const localData = localResult.status === 'fulfilled' ? localResult.value : null;
356
- const localError = localResult.status === 'rejected' ? localResult.reason.message : null;
357
- const remoteData = remoteResult.status === 'fulfilled' ? remoteResult.value : null;
358
- const remoteError = remoteResult.status === 'rejected' ? remoteResult.reason.message : null;
359
- // Determine overall success and message
360
- const localSuccess = localResult.status === 'fulfilled';
361
- const remoteSuccess = remoteResult.status === 'fulfilled' && remoteData?.success;
362
- let message;
363
- if (localSuccess && remoteSuccess) {
364
- message = `Repositório '${repoName}' criado com sucesso (local e remoto)`;
365
- }
366
- else if (localSuccess && !remoteSuccess) {
367
- message = `Repositório '${repoName}' criado localmente, falha na criação remota`;
368
- }
369
- else if (!localSuccess && remoteSuccess) {
370
- message = `Repositório '${repoName}' criado remotamente, falha na inicialização local`;
371
- }
372
- else {
373
- message = `Falha ao criar repositório '${repoName}' (local e remoto)`;
374
- }
375
- return {
376
- success: localSuccess || remoteSuccess, // Success if at least one operation succeeded
377
- action: 'create',
378
- message,
379
- data: {
380
- repoName,
381
- description: description || `Repositório ${repoName}`,
382
- private: isPrivate || false,
383
- local: {
384
- success: localSuccess,
385
- data: localData,
386
- error: localError
387
- },
388
- remote: remoteData || {
389
- success: false,
390
- error: remoteError || 'Unknown remote operation error'
391
- }
392
- }
79
+ /**
80
+ * Execute remote provider operations
81
+ */
82
+ async executeRemoteOperation(params, startTime) {
83
+ if (!this.providerHandler) {
84
+ 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']);
85
+ }
86
+ if (!params.provider) {
87
+ 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']);
88
+ }
89
+ const operation = {
90
+ provider: params.provider,
91
+ operation: this.mapActionToProviderOperation(params.action),
92
+ parameters: this.extractRemoteParameters(params),
93
+ requiresAuth: true,
94
+ isRemoteOperation: true
393
95
  };
394
- }
395
- catch (error) {
396
- throw new Error(`Falha ao criar repositório: ${error instanceof Error ? error.message : String(error)}`);
397
- }
398
- }
399
- async function handleListRepos(detection, page = 1, perPage = 30, sort = 'updated', provider) {
400
- try {
401
- // Execute operation on specified provider(s)
402
- const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.listRepositories(detection.owner, page, perPage));
403
- if (!result.success) {
404
- const errorMessage = 'message' in result
405
- ? result.message
406
- : ('error' in result ? result.error || 'Failed to list repositories' : 'Unknown error');
407
- throw new Error(errorMessage);
408
- }
409
- // Handle single provider result
410
- if ('provider' in result && result.data) {
411
- const repositories = result.data;
96
+ try {
97
+ const result = await this.providerHandler.executeOperation(operation);
412
98
  return {
413
- success: true,
414
- action: 'list',
415
- message: `${repositories.length} repositórios encontrados no ${result.provider}`,
416
- data: {
417
- repositories,
418
- total: repositories.length,
419
- page,
420
- perPage,
421
- sort,
422
- owner: detection.owner,
423
- provider: result.provider
99
+ success: result.success,
100
+ data: result.partialFailure ? result : result.results[0]?.data,
101
+ error: result.success ? undefined : {
102
+ code: result.errors[0]?.error?.code || 'REMOTE_OPERATION_ERROR',
103
+ message: result.errors[0]?.error?.message || 'Remote operation failed',
104
+ details: result.errors,
105
+ suggestions: ['Check provider configuration and credentials']
106
+ },
107
+ metadata: {
108
+ provider: params.provider,
109
+ operation: params.action,
110
+ timestamp: new Date().toISOString(),
111
+ executionTime: Date.now() - startTime
424
112
  }
425
113
  };
426
114
  }
427
- // Handle multi-provider result
428
- if ('message' in result && typeof result.data === 'object') {
429
- const multiData = result.data;
430
- const allRepositories = [];
431
- const providerResults = {};
432
- // Collect repositories from all successful providers
433
- if (multiData.github?.success && multiData.github.data) {
434
- allRepositories.push(...multiData.github.data);
435
- providerResults.github = {
436
- success: true,
437
- count: multiData.github.data.length,
438
- repositories: multiData.github.data
439
- };
440
- }
441
- else if (multiData.github) {
442
- providerResults.github = {
443
- success: false,
444
- error: multiData.github.error
445
- };
446
- }
447
- if (multiData.gitea?.success && multiData.gitea.data) {
448
- allRepositories.push(...multiData.gitea.data);
449
- providerResults.gitea = {
115
+ catch (error) {
116
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
117
+ 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']);
118
+ }
119
+ }
120
+ /**
121
+ * Handle git init operation
122
+ */
123
+ async handleInit(params, startTime) {
124
+ try {
125
+ // Check if already a git repository
126
+ const isRepo = await this.gitExecutor.isGitRepository(params.projectPath);
127
+ if (isRepo) {
128
+ return {
450
129
  success: true,
451
- count: multiData.gitea.data.length,
452
- repositories: multiData.gitea.data
130
+ data: {
131
+ message: 'Repository already initialized',
132
+ path: params.projectPath,
133
+ alreadyExists: true
134
+ },
135
+ metadata: {
136
+ operation: 'init',
137
+ timestamp: new Date().toISOString(),
138
+ executionTime: Date.now() - startTime
139
+ }
453
140
  };
454
141
  }
455
- else if (multiData.gitea) {
456
- providerResults.gitea = {
457
- success: false,
458
- error: multiData.gitea.error
459
- };
142
+ const result = await this.gitExecutor.initRepository(params.projectPath, params.bare || false);
143
+ if (!result.success) {
144
+ return operation_error_handler_js_1.OperationErrorHandler.handleGitError(result.stderr, 'init', params.projectPath);
460
145
  }
461
146
  return {
462
147
  success: true,
463
- action: 'list',
464
- message: result.message,
465
148
  data: {
466
- repositories: allRepositories,
467
- total: allRepositories.length,
468
- page,
469
- perPage,
470
- sort,
471
- owner: detection.owner,
472
- provider: 'both',
473
- providerResults,
474
- warnings: result.warnings
149
+ message: 'Git repository initialized successfully',
150
+ path: params.projectPath,
151
+ bare: params.bare || false,
152
+ output: result.stdout
153
+ },
154
+ metadata: {
155
+ operation: 'init',
156
+ timestamp: new Date().toISOString(),
157
+ executionTime: Date.now() - startTime
475
158
  }
476
159
  };
477
160
  }
478
- throw new Error('Unexpected result format from provider operation');
479
- }
480
- catch (error) {
481
- throw new Error(`Falha ao listar repositórios: ${error instanceof Error ? error.message : String(error)}`);
482
- }
483
- }
484
- async function handleGetRepo(repoName, detection, provider) {
485
- try {
486
- // Execute operation on specified provider(s)
487
- const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.getRepository(detection.owner, repoName));
488
- if (!result.success) {
489
- const errorMessage = 'message' in result
490
- ? result.message
491
- : ('error' in result ? result.error || 'Failed to get repository' : 'Unknown error');
492
- throw new Error(errorMessage);
493
- }
494
- // Handle single provider result
495
- if ('provider' in result && result.data) {
496
- return {
497
- success: true,
498
- action: 'get',
499
- message: `Detalhes do repositório '${repoName}' obtidos do ${result.provider}`,
500
- data: {
501
- repository: result.data,
502
- provider: result.provider
503
- }
504
- };
161
+ catch (error) {
162
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
163
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('INIT_ERROR', `Failed to initialize repository: ${errorMessage}`, 'init', { error: errorMessage, projectPath: params.projectPath });
505
164
  }
506
- // Handle multi-provider result
507
- if ('message' in result && typeof result.data === 'object') {
508
- const multiData = result.data;
509
- const repositories = {};
510
- if (multiData.github?.success && multiData.github.data) {
511
- repositories.github = multiData.github.data;
512
- }
513
- if (multiData.gitea?.success && multiData.gitea.data) {
514
- repositories.gitea = multiData.gitea.data;
165
+ }
166
+ /**
167
+ * Handle git status operation
168
+ */
169
+ async handleStatus(params, startTime) {
170
+ try {
171
+ const result = await this.gitExecutor.getStatus(params.projectPath);
172
+ if (!result.success) {
173
+ return operation_error_handler_js_1.OperationErrorHandler.handleGitError(result.stderr, 'status', params.projectPath);
515
174
  }
516
175
  return {
517
176
  success: true,
518
- action: 'get',
519
- message: result.message,
520
177
  data: {
521
- repositories,
522
- provider: 'both',
523
- providerResults: {
524
- github: multiData.github ? {
525
- success: multiData.github.success,
526
- error: multiData.github.error
527
- } : undefined,
528
- gitea: multiData.gitea ? {
529
- success: multiData.gitea.success,
530
- error: multiData.gitea.error
531
- } : undefined
532
- },
533
- warnings: 'warnings' in result ? result.warnings : undefined
178
+ status: result.parsedStatus,
179
+ raw: result.stdout,
180
+ repository: {
181
+ path: params.projectPath,
182
+ isGitRepository: result.isGitRepository
183
+ }
184
+ },
185
+ metadata: {
186
+ operation: 'status',
187
+ timestamp: new Date().toISOString(),
188
+ executionTime: Date.now() - startTime
534
189
  }
535
190
  };
536
191
  }
537
- throw new Error('Unexpected result format from provider operation');
538
- }
539
- catch (error) {
540
- throw new Error(`Falha ao obter repositório: ${error instanceof Error ? error.message : String(error)}`);
541
- }
542
- }
543
- async function handleSearchRepos(searchQuery, detection, provider, language, sort = 'stars', order = 'desc') {
544
- try {
545
- // Execute operation on specified provider(s)
546
- const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.searchRepositories(searchQuery));
547
- if (!result.success) {
548
- const errorMessage = 'message' in result
549
- ? result.message
550
- : ('error' in result ? result.error || 'Failed to search repositories' : 'Unknown error');
551
- throw new Error(errorMessage);
552
- }
553
- // Handle single provider result
554
- if ('provider' in result && result.data) {
555
- const searchResults = result.data;
556
- return {
557
- success: true,
558
- action: 'search',
559
- message: `${searchResults.length} repositórios encontrados para '${searchQuery}' no ${result.provider}`,
560
- data: {
561
- query: searchQuery,
562
- language,
563
- sort,
564
- order,
565
- results: searchResults,
566
- total: searchResults.length,
567
- provider: result.provider
568
- }
569
- };
192
+ catch (error) {
193
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
194
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('STATUS_ERROR', `Failed to get repository status: ${errorMessage}`, 'status', { error: errorMessage, projectPath: params.projectPath });
570
195
  }
571
- // Handle multi-provider result
572
- if ('message' in result && typeof result.data === 'object') {
573
- const multiData = result.data;
574
- const allResults = [];
575
- const providerResults = {};
576
- // Collect results from all successful providers
577
- if (multiData.github?.success && multiData.github.data) {
578
- const githubResults = multiData.github.data.map((repo) => ({
579
- ...repo,
580
- source: 'github'
581
- }));
582
- allResults.push(...githubResults);
583
- providerResults.github = {
584
- success: true,
585
- count: multiData.github.data.length,
586
- results: multiData.github.data
587
- };
588
- }
589
- else if (multiData.github) {
590
- providerResults.github = {
591
- success: false,
592
- error: multiData.github.error
593
- };
196
+ }
197
+ /**
198
+ * Handle git commit operation
199
+ */
200
+ async handleCommit(params, startTime) {
201
+ try {
202
+ if (!params.message) {
203
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('MISSING_PARAMETER', 'Commit message is required', 'commit', {}, ['Provide a commit message using the message parameter']);
594
204
  }
595
- if (multiData.gitea?.success && multiData.gitea.data) {
596
- const giteaResults = multiData.gitea.data.map((repo) => ({
597
- ...repo,
598
- source: 'gitea'
599
- }));
600
- allResults.push(...giteaResults);
601
- providerResults.gitea = {
602
- success: true,
603
- count: multiData.gitea.data.length,
604
- results: multiData.gitea.data
605
- };
205
+ // Add files to staging area
206
+ const filesToAdd = params.files || ['.'];
207
+ const addResult = await this.gitExecutor.addFiles(params.projectPath, filesToAdd);
208
+ if (!addResult.success) {
209
+ return operation_error_handler_js_1.OperationErrorHandler.handleGitError(addResult.stderr, 'commit (add)', params.projectPath);
606
210
  }
607
- else if (multiData.gitea) {
608
- providerResults.gitea = {
609
- success: false,
610
- error: multiData.gitea.error
611
- };
211
+ // Commit changes
212
+ const commitResult = await this.gitExecutor.commit(params.projectPath, params.message);
213
+ if (!commitResult.success) {
214
+ return operation_error_handler_js_1.OperationErrorHandler.handleGitError(commitResult.stderr, 'commit', params.projectPath);
612
215
  }
613
216
  return {
614
217
  success: true,
615
- action: 'search',
616
- message: result.message,
617
218
  data: {
618
- query: searchQuery,
619
- language,
620
- sort,
621
- order,
622
- results: allResults,
623
- total: allResults.length,
624
- provider: 'both',
625
- providerResults,
626
- warnings: 'warnings' in result ? result.warnings : undefined
219
+ message: 'Changes committed successfully',
220
+ commitMessage: params.message,
221
+ files: filesToAdd,
222
+ output: commitResult.stdout,
223
+ addOutput: addResult.stdout
224
+ },
225
+ metadata: {
226
+ operation: 'commit',
227
+ timestamp: new Date().toISOString(),
228
+ executionTime: Date.now() - startTime
627
229
  }
628
230
  };
629
231
  }
630
- throw new Error('Unexpected result format from provider operation');
631
- }
632
- catch (error) {
633
- throw new Error(`Falha na busca: ${error instanceof Error ? error.message : String(error)}`);
634
- }
635
- }
636
- async function handleUpdateRepo(repoName, detection, provider, description, isPrivate) {
637
- try {
638
- // Prepare update data
639
- const updateData = {};
640
- if (description !== undefined)
641
- updateData.description = description;
642
- if (isPrivate !== undefined)
643
- updateData.private = isPrivate;
644
- // Execute operation on specified provider(s)
645
- const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.updateRepository(detection.owner, repoName, updateData));
646
- if (!result.success) {
647
- const errorMessage = 'message' in result
648
- ? result.message
649
- : ('error' in result ? result.error || 'Failed to update repository' : 'Unknown error');
650
- throw new Error(errorMessage);
651
- }
652
- // Handle single provider result
653
- if ('provider' in result && result.data) {
654
- return {
655
- success: true,
656
- action: 'update',
657
- message: `Repositório '${repoName}' atualizado com sucesso no ${result.provider}`,
658
- data: {
659
- repoUpdated: true,
660
- repository: result.data,
661
- provider: result.provider
662
- }
663
- };
232
+ catch (error) {
233
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
234
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('COMMIT_ERROR', `Failed to commit changes: ${errorMessage}`, 'commit', { error: errorMessage, projectPath: params.projectPath });
664
235
  }
665
- // Handle multi-provider result
666
- if ('message' in result && typeof result.data === 'object') {
667
- const multiData = result.data;
668
- const updatedRepositories = {};
669
- if (multiData.github?.success && multiData.github.data) {
670
- updatedRepositories.github = multiData.github.data;
671
- }
672
- if (multiData.gitea?.success && multiData.gitea.data) {
673
- updatedRepositories.gitea = multiData.gitea.data;
236
+ }
237
+ /**
238
+ * Handle git sync operation (fetch + pull + push)
239
+ */
240
+ async handleSync(params, startTime) {
241
+ try {
242
+ const remote = params.remote || 'origin';
243
+ const results = [];
244
+ // Fetch from remote
245
+ const fetchResult = await this.gitExecutor.fetch(params.projectPath, remote, { all: true, prune: true });
246
+ results.push({ operation: 'fetch', success: fetchResult.success, output: fetchResult.stdout, error: fetchResult.stderr });
247
+ // Pull changes
248
+ const pullResult = await this.gitExecutor.pull(params.projectPath, remote, params.branch, { force: params.force });
249
+ results.push({ operation: 'pull', success: pullResult.success, output: pullResult.stdout, error: pullResult.stderr });
250
+ // Push changes (only if pull was successful)
251
+ let pushResult = null;
252
+ if (pullResult.success) {
253
+ pushResult = await this.gitExecutor.push(params.projectPath, remote, params.branch, { force: params.force });
254
+ results.push({ operation: 'push', success: pushResult.success, output: pushResult.stdout, error: pushResult.stderr });
674
255
  }
256
+ const allSuccessful = results.every(r => r.success);
257
+ const hasErrors = results.some(r => !r.success);
675
258
  return {
676
- success: true,
677
- action: 'update',
678
- message: result.message,
259
+ success: allSuccessful,
679
260
  data: {
680
- repoUpdated: true,
681
- repositories: updatedRepositories,
682
- provider: 'both',
683
- providerResults: {
684
- github: multiData.github ? {
685
- success: multiData.github.success,
686
- error: multiData.github.error
687
- } : undefined,
688
- gitea: multiData.gitea ? {
689
- success: multiData.gitea.success,
690
- error: multiData.gitea.error
691
- } : undefined
692
- },
693
- warnings: 'warnings' in result ? result.warnings : undefined
261
+ message: allSuccessful ? 'Repository synchronized successfully' : 'Synchronization completed with some errors',
262
+ remote,
263
+ branch: params.branch,
264
+ operations: results,
265
+ summary: {
266
+ fetch: fetchResult.success,
267
+ pull: pullResult.success,
268
+ push: pushResult?.success || false
269
+ }
270
+ },
271
+ error: hasErrors ? {
272
+ code: 'SYNC_PARTIAL_ERROR',
273
+ message: 'Some synchronization operations failed',
274
+ details: results.filter(r => !r.success),
275
+ suggestions: ['Check the individual operation errors and resolve them']
276
+ } : undefined,
277
+ metadata: {
278
+ operation: 'sync',
279
+ timestamp: new Date().toISOString(),
280
+ executionTime: Date.now() - startTime
694
281
  }
695
282
  };
696
283
  }
697
- throw new Error('Unexpected result format from provider operation');
698
- }
699
- catch (error) {
700
- throw new Error(`Falha ao atualizar repositório: ${error instanceof Error ? error.message : String(error)}`);
701
- }
702
- }
703
- async function handleDeleteRepo(repoName, detection, provider) {
704
- try {
705
- // Execute operation on specified provider(s)
706
- const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.deleteRepository(detection.owner, repoName));
707
- if (!result.success) {
708
- const errorMessage = 'message' in result
709
- ? result.message
710
- : ('error' in result ? result.error || 'Failed to delete repository' : 'Unknown error');
711
- throw new Error(errorMessage);
712
- }
713
- const deletedAt = new Date().toISOString();
714
- // Handle single provider result
715
- if ('provider' in result) {
716
- return {
717
- success: true,
718
- action: 'delete',
719
- message: `Repositório '${repoName}' removido com sucesso do ${result.provider}`,
720
- data: {
721
- repoDeleted: true,
722
- repoName,
723
- owner: detection.owner,
724
- provider: result.provider,
725
- deletedAt,
726
- warning: 'Esta ação é irreversível'
727
- }
728
- };
284
+ catch (error) {
285
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
286
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('SYNC_ERROR', `Failed to synchronize repository: ${errorMessage}`, 'sync', { error: errorMessage, projectPath: params.projectPath });
729
287
  }
730
- // Handle multi-provider result
731
- if ('data' in result && typeof result.data === 'object') {
732
- const multiData = result.data;
733
- const deletionResults = {};
734
- if (multiData.github) {
735
- deletionResults.github = {
736
- success: multiData.github.success,
737
- error: multiData.github.error
738
- };
288
+ }
289
+ /**
290
+ * Handle git backup operation
291
+ */
292
+ async handleBackup(params, startTime) {
293
+ try {
294
+ if (!params.backupPath) {
295
+ // Generate default backup path
296
+ const projectName = path_1.default.basename(params.projectPath);
297
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
298
+ params.backupPath = path_1.default.join(params.projectPath, '..', `${projectName}-backup-${timestamp}`);
739
299
  }
740
- if (multiData.gitea) {
741
- deletionResults.gitea = {
742
- success: multiData.gitea.success,
743
- error: multiData.gitea.error
744
- };
300
+ const result = await this.gitExecutor.createBackup(params.projectPath, params.backupPath, 'tar');
301
+ if (!result.success) {
302
+ return operation_error_handler_js_1.OperationErrorHandler.handleGitError(result.stderr, 'backup', params.projectPath);
745
303
  }
746
304
  return {
747
305
  success: true,
748
- action: 'delete',
749
- message: result.message,
750
306
  data: {
751
- repoDeleted: true,
752
- repoName,
753
- owner: detection.owner,
754
- provider: 'both',
755
- deletionResults,
756
- deletedAt,
757
- warning: 'Esta ação é irreversível',
758
- warnings: 'warnings' in result ? result.warnings : undefined
307
+ message: 'Repository backup created successfully',
308
+ backupPath: `${params.backupPath}.tar.gz`,
309
+ originalPath: params.projectPath,
310
+ format: 'tar.gz',
311
+ output: result.stdout
312
+ },
313
+ metadata: {
314
+ operation: 'backup',
315
+ timestamp: new Date().toISOString(),
316
+ executionTime: Date.now() - startTime
759
317
  }
760
318
  };
761
319
  }
762
- throw new Error('Unexpected result format from provider operation');
320
+ catch (error) {
321
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
322
+ return operation_error_handler_js_1.OperationErrorHandler.createToolError('BACKUP_ERROR', `Failed to create repository backup: ${errorMessage}`, 'backup', { error: errorMessage, projectPath: params.projectPath });
323
+ }
763
324
  }
764
- catch (error) {
765
- throw new Error(`Falha ao remover repositório: ${error instanceof Error ? error.message : String(error)}`);
325
+ /**
326
+ * Check if operation is a remote operation
327
+ */
328
+ isRemoteOperation(action) {
329
+ const remoteOperations = ['create', 'list', 'get', 'update', 'delete', 'fork', 'search'];
330
+ return remoteOperations.includes(action);
766
331
  }
767
- }
768
- async function handleForkRepo(sourceRepo, newRepoName, detection, provider) {
769
- try {
770
- // Parse sourceRepo (format: owner/repo)
771
- const [sourceOwner, sourceRepoName] = sourceRepo.split('/');
772
- if (!sourceOwner || !sourceRepoName) {
773
- throw new Error('sourceRepo deve estar no formato "owner/repo"');
774
- }
775
- const forkName = newRepoName || sourceRepoName;
776
- // Execute operation on specified provider(s)
777
- const result = await provider_operation_handler_js_1.ProviderOperationHandler.executeOperation(provider, (providerInstance) => providerInstance.forkRepository(sourceOwner, sourceRepoName));
778
- if (!result.success) {
779
- const errorMessage = 'message' in result
780
- ? result.message
781
- : ('error' in result ? result.error || 'Failed to fork repository' : 'Unknown error');
782
- throw new Error(errorMessage);
783
- }
784
- // Handle single provider result
785
- if ('provider' in result && result.data) {
786
- return {
787
- success: true,
788
- action: 'fork',
789
- message: `Fork '${forkName}' criado com sucesso de '${sourceRepo}' no ${result.provider}`,
790
- data: {
791
- repoForked: true,
792
- originalRepo: sourceRepo,
793
- forkName,
794
- repository: result.data,
795
- provider: result.provider
796
- }
797
- };
798
- }
799
- // Handle multi-provider result
800
- if ('message' in result && typeof result.data === 'object') {
801
- const multiData = result.data;
802
- const forkedRepositories = {};
803
- if (multiData.github?.success && multiData.github.data) {
804
- forkedRepositories.github = multiData.github.data;
805
- }
806
- if (multiData.gitea?.success && multiData.gitea.data) {
807
- forkedRepositories.gitea = multiData.gitea.data;
808
- }
809
- return {
810
- success: true,
811
- action: 'fork',
812
- message: result.message,
813
- data: {
814
- repoForked: true,
815
- originalRepo: sourceRepo,
816
- forkName,
817
- repositories: forkedRepositories,
818
- provider: 'both',
819
- providerResults: {
820
- github: multiData.github ? {
821
- success: multiData.github.success,
822
- error: multiData.github.error
823
- } : undefined,
824
- gitea: multiData.gitea ? {
825
- success: multiData.gitea.success,
826
- error: multiData.gitea.error
827
- } : undefined
828
- },
829
- warnings: 'warnings' in result ? result.warnings : undefined
830
- }
831
- };
832
- }
833
- throw new Error('Unexpected result format from provider operation');
332
+ /**
333
+ * Extract parameters for remote operations
334
+ */
335
+ extractRemoteParameters(params) {
336
+ const remoteParams = {
337
+ projectPath: params.projectPath
338
+ };
339
+ // Common parameters
340
+ if (params.owner)
341
+ remoteParams.owner = params.owner;
342
+ if (params.repo)
343
+ remoteParams.repo = params.repo;
344
+ // Operation-specific parameters
345
+ switch (params.action) {
346
+ case 'create':
347
+ if (params.name)
348
+ remoteParams.name = params.name;
349
+ if (params.description)
350
+ remoteParams.description = params.description;
351
+ if (params.private !== undefined)
352
+ remoteParams.private = params.private;
353
+ break;
354
+ case 'list':
355
+ // List operations may have type, sort, order parameters
356
+ break;
357
+ case 'get':
358
+ // Get operations need owner and repo (already handled above)
359
+ break;
360
+ case 'update':
361
+ if (params.name)
362
+ remoteParams.name = params.name;
363
+ if (params.description)
364
+ remoteParams.description = params.description;
365
+ if (params.private !== undefined)
366
+ remoteParams.private = params.private;
367
+ break;
368
+ case 'delete':
369
+ // Delete operations need owner and repo (already handled above)
370
+ break;
371
+ case 'fork':
372
+ // Fork operations may have organization parameter
373
+ break;
374
+ case 'search':
375
+ if (params.query)
376
+ remoteParams.query = params.query;
377
+ break;
378
+ }
379
+ return remoteParams;
834
380
  }
835
- catch (error) {
836
- throw new Error(`Falha ao criar fork: ${error instanceof Error ? error.message : String(error)}`);
381
+ /**
382
+ * Map git-workflow actions to provider operations
383
+ */
384
+ mapActionToProviderOperation(action) {
385
+ const actionMap = {
386
+ 'create': 'repo-create',
387
+ 'list': 'repo-list',
388
+ 'get': 'repo-get',
389
+ 'update': 'repo-update',
390
+ 'delete': 'repo-delete',
391
+ 'fork': 'repo-fork',
392
+ 'search': 'repo-search'
393
+ };
394
+ return actionMap[action] || action;
837
395
  }
838
- }
839
- exports.gitWorkflowTool = {
840
- name: 'git-workflow',
841
- description: '🔄 WORKFLOW COMPLETO - Operações Git locais + gerenciamento completo de repositórios remotos: init, commit, sync, status, backup, create, list, get, update, delete, fork, search',
842
- inputSchema,
843
- async handler(input) {
844
- try {
845
- const { action, projectPath, provider, message, branch, remote, repoName, description, private: isPrivate, sourceRepo, searchQuery, language, sort, order, page, perPage } = input;
846
- if (!projectPath) {
847
- throw new Error('projectPath é obrigatório');
848
- }
849
- // Define remote operations that require provider parameter
850
- const remoteOperations = ['create', 'list', 'get', 'update', 'delete', 'fork', 'search'];
851
- // Validate provider parameter for remote operations
852
- if (remoteOperations.includes(action)) {
853
- if (!provider) {
854
- const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
855
- return (0, auto_detection_js_1.createUniversalResponse)(false, action, 'Provider parameter is required for remote operations', detection, 'git-workflow', undefined, {
856
- code: 'MISSING_PROVIDER_PARAMETER',
857
- message: 'Provider parameter is required for remote operations',
858
- cause: 'Provider parameter not provided for remote operation',
859
- suggestion: 'Add provider parameter with one of: github, gitea, both'
860
- });
861
- }
862
- // Validate provider parameter value
863
- const providerValidation = configuration_validator_js_1.ConfigurationValidator.validateProvider(provider);
864
- if (!providerValidation.valid) {
865
- const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
866
- return (0, auto_detection_js_1.createUniversalResponse)(false, action, providerValidation.error.message, detection, 'git-workflow', undefined, {
867
- code: providerValidation.error.code,
868
- message: providerValidation.error.message,
869
- cause: 'Invalid provider parameter value',
870
- suggestion: providerValidation.error.suggestion
871
- });
872
- }
873
- // Validate provider configuration
874
- const configValidation = configuration_validator_js_1.ConfigurationValidator.validateProviderConfiguration(provider);
875
- if (!configValidation.valid) {
876
- const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
877
- const errorMessage = configuration_validator_js_1.ConfigurationValidator.formatValidationError(configValidation);
878
- // Create comprehensive error response for configuration issues
879
- const configError = configValidation.error.configuration;
880
- const enhancedMessage = configError
881
- ? `${configValidation.error.message}\n\n${configuration_validator_js_1.ConfigurationValidator.formatValidationError(configValidation)}`
882
- : configValidation.error.message;
883
- return (0, auto_detection_js_1.createUniversalResponse)(false, action, enhancedMessage, detection, 'git-workflow', undefined, {
884
- code: configValidation.error.code,
885
- message: errorMessage,
886
- cause: 'Provider configuration validation failed',
887
- suggestion: configValidation.error.suggestion
888
- });
889
- }
890
- }
891
- const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
892
- let result;
893
- switch (action) {
894
- // Operações Git locais
895
- case 'init':
896
- result = await handleInit(projectPath, detection);
897
- break;
898
- case 'commit':
899
- if (!message) {
900
- throw new Error('message é obrigatória para commit');
901
- }
902
- result = await handleCommit(projectPath, message, branch, remote);
903
- break;
904
- case 'sync':
905
- if (!message) {
906
- throw new Error('message é obrigatória para sync');
907
- }
908
- result = await handleSync(projectPath, message, branch, remote);
909
- break;
910
- case 'status':
911
- result = await handleStatus(projectPath, detection);
912
- break;
913
- case 'backup':
914
- result = await handleBackup(projectPath, detection);
915
- break;
916
- // Gerenciamento de repositórios remotos
917
- case 'create':
918
- if (!repoName) {
919
- throw new Error('repoName é obrigatório para create');
920
- }
921
- result = await handleCreateRepo(repoName, description || '', isPrivate || false, detection, projectPath, provider);
922
- break;
923
- case 'list':
924
- result = await handleListRepos(detection, page, perPage, sort, provider);
925
- break;
926
- case 'get':
927
- if (!repoName) {
928
- throw new Error('repoName é obrigatório para get');
929
- }
930
- result = await handleGetRepo(repoName, detection, provider);
931
- break;
932
- case 'search':
933
- if (!searchQuery) {
934
- throw new Error('searchQuery é obrigatório para search');
935
- }
936
- result = await handleSearchRepos(searchQuery, detection, provider, language, sort, order);
937
- break;
938
- case 'update':
939
- if (!repoName) {
940
- throw new Error('repoName é obrigatório para update');
941
- }
942
- result = await handleUpdateRepo(repoName, detection, provider, description, isPrivate);
943
- break;
944
- case 'delete':
945
- if (!repoName) {
946
- throw new Error('repoName é obrigatório para delete');
947
- }
948
- result = await handleDeleteRepo(repoName, detection, provider);
949
- break;
950
- case 'fork':
951
- if (!sourceRepo) {
952
- throw new Error('sourceRepo é obrigatório para fork');
396
+ /**
397
+ * Get tool schema for MCP registration
398
+ */
399
+ static getToolSchema() {
400
+ return {
401
+ name: 'git-workflow',
402
+ description: 'Core Git workflow tool for local and remote Git operations. Supports init, status, commit, sync, backup, create, list, get, update, delete, fork, and search operations.',
403
+ inputSchema: {
404
+ type: 'object',
405
+ properties: {
406
+ action: {
407
+ type: 'string',
408
+ enum: ['init', 'status', 'commit', 'sync', 'backup', 'create', 'list', 'get', 'update', 'delete', 'fork', 'search'],
409
+ description: 'The Git operation to perform'
410
+ },
411
+ projectPath: {
412
+ type: 'string',
413
+ description: 'Absolute path to the project directory'
414
+ },
415
+ provider: {
416
+ type: 'string',
417
+ enum: ['github', 'gitea', 'both'],
418
+ description: 'Provider for remote operations (required for remote operations)'
419
+ },
420
+ message: {
421
+ type: 'string',
422
+ description: 'Commit message (required for commit action)'
423
+ },
424
+ files: {
425
+ type: 'array',
426
+ items: { type: 'string' },
427
+ description: 'Specific files to commit (default: all changes)'
428
+ },
429
+ bare: {
430
+ type: 'boolean',
431
+ description: 'Initialize as bare repository (for init action)'
432
+ },
433
+ backupPath: {
434
+ type: 'string',
435
+ description: 'Path for backup file (for backup action)'
436
+ },
437
+ name: {
438
+ type: 'string',
439
+ description: 'Repository name (for create action)'
440
+ },
441
+ description: {
442
+ type: 'string',
443
+ description: 'Repository description (for create/update actions)'
444
+ },
445
+ private: {
446
+ type: 'boolean',
447
+ description: 'Create private repository (for create action)'
448
+ },
449
+ query: {
450
+ type: 'string',
451
+ description: 'Search query (for search action)'
452
+ },
453
+ owner: {
454
+ type: 'string',
455
+ description: 'Repository owner (for get/update/delete/fork actions)'
456
+ },
457
+ repo: {
458
+ type: 'string',
459
+ description: 'Repository name (for get/update/delete/fork actions)'
460
+ },
461
+ remote: {
462
+ type: 'string',
463
+ description: 'Remote name for sync (default: origin)'
464
+ },
465
+ branch: {
466
+ type: 'string',
467
+ description: 'Branch name for sync'
468
+ },
469
+ force: {
470
+ type: 'boolean',
471
+ description: 'Force operation (for sync action)'
953
472
  }
954
- result = await handleForkRepo(sourceRepo, repoName, detection, provider);
955
- break;
956
- default:
957
- throw new Error(`Ação '${action}' não suportada. Use: init, commit, sync, status, backup, create, list, get, update, delete, fork, search`);
958
- }
959
- return (0, auto_detection_js_1.createUniversalResponse)(result.success, action, result.message, detection, 'git-workflow', result.data);
960
- }
961
- catch (error) {
962
- const detection = (0, auto_detection_js_1.autoDetect)(input.projectPath || '');
963
- const errorInstance = error instanceof Error ? error : new Error(String(error));
964
- // For remote operations, provide comprehensive error handling
965
- const remoteOperations = ['create', 'list', 'get', 'update', 'delete', 'fork', 'search'];
966
- if (remoteOperations.includes(input.action) && input.provider) {
967
- const operationError = operation_error_handler_js_1.OperationErrorHandler.analyzeAndHandleError(errorInstance, input.provider, input.action);
968
- return (0, auto_detection_js_1.createUniversalResponse)(false, input.action || 'unknown', operationError.message, detection, 'git-workflow', undefined, {
969
- code: operationError.code,
970
- message: operation_error_handler_js_1.OperationErrorHandler.formatErrorMessage(operationError),
971
- cause: operationError.cause,
972
- suggestion: operationError.solution
973
- });
473
+ },
474
+ required: ['action', 'projectPath']
974
475
  }
975
- // For local operations, provide generic error handling
976
- return (0, auto_detection_js_1.createUniversalResponse)(false, input.action || 'unknown', errorInstance.message, detection, 'git-workflow', undefined, {
977
- code: 'WORKFLOW_ERROR',
978
- message: errorInstance.message,
979
- cause: 'Erro na execução do workflow Git',
980
- suggestion: 'Verifique os parâmetros e tente novamente'
981
- });
982
- }
476
+ };
983
477
  }
984
- };
478
+ }
479
+ exports.GitWorkflowTool = GitWorkflowTool;
985
480
  //# sourceMappingURL=git-workflow.js.map