@andrebuzeli/git-mcp 4.0.20 → 4.0.21

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 (85) hide show
  1. package/dist/config.d.ts +7 -239
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +2 -221
  4. package/dist/config.js.map +1 -1
  5. package/dist/index.d.ts +11 -9
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +18 -16
  8. package/dist/index.js.map +1 -1
  9. package/dist/server.d.ts +1 -69
  10. package/dist/server.d.ts.map +1 -1
  11. package/dist/server.js +150 -711
  12. package/dist/server.js.map +1 -1
  13. package/dist/tools/git-analytics.d.ts +1 -0
  14. package/dist/tools/git-analytics.d.ts.map +1 -1
  15. package/dist/tools/git-analytics.js +18 -7
  16. package/dist/tools/git-analytics.js.map +1 -1
  17. package/dist/tools/git-archive.d.ts +2 -149
  18. package/dist/tools/git-archive.d.ts.map +1 -1
  19. package/dist/tools/git-archive.js +5 -222
  20. package/dist/tools/git-archive.js.map +1 -1
  21. package/dist/tools/git-backup.d.ts +1 -198
  22. package/dist/tools/git-backup.d.ts.map +1 -1
  23. package/dist/tools/git-backup.js +4 -805
  24. package/dist/tools/git-backup.js.map +1 -1
  25. package/dist/tools/git-branches.d.ts +1 -158
  26. package/dist/tools/git-branches.d.ts.map +1 -1
  27. package/dist/tools/git-branches.js +4 -539
  28. package/dist/tools/git-branches.js.map +1 -1
  29. package/dist/tools/git-config.d.ts +2 -124
  30. package/dist/tools/git-config.d.ts.map +1 -1
  31. package/dist/tools/git-config.js +5 -263
  32. package/dist/tools/git-config.js.map +1 -1
  33. package/dist/tools/git-files.d.ts +2 -115
  34. package/dist/tools/git-files.d.ts.map +1 -1
  35. package/dist/tools/git-files.js +161 -407
  36. package/dist/tools/git-files.js.map +1 -1
  37. package/dist/tools/git-issues.d.ts +1 -214
  38. package/dist/tools/git-issues.d.ts.map +1 -1
  39. package/dist/tools/git-issues.js +4 -678
  40. package/dist/tools/git-issues.js.map +1 -1
  41. package/dist/tools/git-monitor.d.ts +1 -143
  42. package/dist/tools/git-monitor.d.ts.map +1 -1
  43. package/dist/tools/git-monitor.js +4 -738
  44. package/dist/tools/git-monitor.js.map +1 -1
  45. package/dist/tools/git-packages.d.ts +2 -91
  46. package/dist/tools/git-packages.d.ts.map +1 -1
  47. package/dist/tools/git-packages.js +5 -258
  48. package/dist/tools/git-packages.js.map +1 -1
  49. package/dist/tools/git-pulls.d.ts +1 -63
  50. package/dist/tools/git-pulls.d.ts.map +1 -1
  51. package/dist/tools/git-pulls.js +4 -77
  52. package/dist/tools/git-pulls.js.map +1 -1
  53. package/dist/tools/git-release.d.ts +1 -169
  54. package/dist/tools/git-release.d.ts.map +1 -1
  55. package/dist/tools/git-release.js +4 -611
  56. package/dist/tools/git-release.js.map +1 -1
  57. package/dist/tools/git-remote.d.ts +1 -153
  58. package/dist/tools/git-remote.d.ts.map +1 -1
  59. package/dist/tools/git-remote.js +4 -555
  60. package/dist/tools/git-remote.js.map +1 -1
  61. package/dist/tools/git-reset.d.ts +1 -157
  62. package/dist/tools/git-reset.d.ts.map +1 -1
  63. package/dist/tools/git-reset.js +4 -597
  64. package/dist/tools/git-reset.js.map +1 -1
  65. package/dist/tools/git-stash.d.ts +1 -161
  66. package/dist/tools/git-stash.d.ts.map +1 -1
  67. package/dist/tools/git-stash.js +4 -640
  68. package/dist/tools/git-stash.js.map +1 -1
  69. package/dist/tools/git-sync.d.ts +1 -0
  70. package/dist/tools/git-sync.d.ts.map +1 -1
  71. package/dist/tools/git-sync.js +13 -7
  72. package/dist/tools/git-sync.js.map +1 -1
  73. package/dist/tools/git-tags.d.ts +1 -162
  74. package/dist/tools/git-tags.d.ts.map +1 -1
  75. package/dist/tools/git-tags.js +4 -549
  76. package/dist/tools/git-tags.js.map +1 -1
  77. package/dist/tools/git-workflow.d.ts +3 -96
  78. package/dist/tools/git-workflow.d.ts.map +1 -1
  79. package/dist/tools/git-workflow.js +287 -314
  80. package/dist/tools/git-workflow.js.map +1 -1
  81. package/package.json +3 -3
  82. package/dist/server-minimal.d.ts +0 -8
  83. package/dist/server-minimal.d.ts.map +0 -1
  84. package/dist/server-minimal.js +0 -218
  85. package/dist/server-minimal.js.map +0 -1
@@ -1,358 +1,331 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.gitWorkflowTool = void 0;
4
- const zod_1 = require("zod");
5
- const index_js_1 = require("../providers/index.js");
6
- const git_operations_js_1 = require("../utils/git-operations.js");
7
4
  const auto_detection_js_1 = require("../utils/auto-detection.js");
8
- const error_handler_js_1 = require("../utils/error-handler.js");
5
+ const terminal_controller_js_1 = require("../utils/terminal-controller.js");
9
6
  /**
10
- * Tool: git-workflow
7
+ * Git Workflow Tool - Ferramenta Principal
11
8
  *
12
- * FERRAMENTA UNIFICADA PARA WORKFLOW PRINCIPAL - v2.0 AI-First
13
- *
14
- * Conforme especificado no design.md, esta tool:
15
- * - Requer apenas action + projectPath como obrigatórios
16
- * - Auto-detecta repo name, owner e providers
17
- * - Fornece respostas universais para todos os AI agents
18
- * - Suporta apenas 5 ações principais otimizadas
19
- *
20
- * DESIGNED FOR: Programadores individuais usando AI agents (Cursor, VSCode, etc.)
21
- * PHILOSOPHY: Simplicidade máxima com automação total
9
+ * Implementa o workflow completo de Git com operações integradas:
10
+ * - init: Inicializar projeto completo
11
+ * - commit: Commit + push automático
12
+ * - sync: Pull + commit + push completo
13
+ * - status: Status detalhado do projeto
14
+ * - backup: Backup completo do projeto
22
15
  */
23
- const GitWorkflowInputSchema = zod_1.z.discriminatedUnion('action', [
24
- // INIT: Inicialização completa com auto-setup
25
- zod_1.z.object({
26
- action: zod_1.z.literal('init'),
27
- projectPath: zod_1.z.string(),
28
- message: zod_1.z.string().optional().default('Initial commit'),
29
- provider: zod_1.z.enum(['gitea', 'github']).optional() // Se omitido, usa todos disponíveis
30
- }),
31
- // COMMIT: Commit rápido com backup automático
32
- zod_1.z.object({
33
- action: zod_1.z.literal('commit'),
34
- projectPath: zod_1.z.string(),
35
- message: zod_1.z.string().min(1, 'Commit message is required'),
36
- provider: zod_1.z.enum(['gitea', 'github']).optional() // Se omitido, usa todos disponíveis
37
- }),
38
- // SYNC: Sincronização completa (pull+commit+push)
39
- zod_1.z.object({
40
- action: zod_1.z.literal('sync'),
41
- projectPath: zod_1.z.string(),
42
- message: zod_1.z.string().optional(),
43
- provider: zod_1.z.enum(['gitea', 'github']).optional() // Se omitido, usa todos disponíveis
44
- }),
45
- // STATUS: Status essencial com métricas
46
- zod_1.z.object({
47
- action: zod_1.z.literal('status'),
48
- projectPath: zod_1.z.string(),
49
- detailed: zod_1.z.boolean().optional().default(false)
50
- }),
51
- // BACKUP: Backup imediato do estado atual
52
- zod_1.z.object({
53
- action: zod_1.z.literal('backup'),
54
- projectPath: zod_1.z.string(),
55
- description: zod_1.z.string().optional()
56
- })
57
- ]);
58
- /**
59
- * Classe principal para executar operações Git workflow
60
- */
61
- class GitWorkflowExecutor {
62
- errorHandler = new error_handler_js_1.UniversalErrorHandler();
63
- /**
64
- * Executa operação init com auto-detecção completa
65
- */
66
- async executeInit(detection, input) {
67
- try {
68
- const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
69
- // Inicializa repositório Git se necessário
70
- if (!detection.isValidRepo) {
71
- await gitOps.initRepository();
72
- }
73
- // Cria commit inicial
74
- await gitOps.addFiles(['.']);
75
- await gitOps.commit(input.message || 'Initial commit');
76
- // Configura remotes para providers disponíveis
77
- const configuredProviders = [];
78
- for (const provider of detection.providers) {
79
- try {
80
- const providerInstance = index_js_1.globalProviderFactory.createProvider(provider);
81
- const remoteUrl = providerInstance.getRepositoryUrl(detection.owner, detection.repoName);
82
- await gitOps.remote('add', provider, remoteUrl);
83
- await gitOps.push('main', provider);
84
- configuredProviders.push(provider);
85
- }
86
- catch (error) {
87
- this.errorHandler.addError(error, provider, { action: 'init', projectPath: detection.projectPath });
88
- }
89
- }
90
- return (0, auto_detection_js_1.createUniversalResponse)(true, 'init', `Projeto inicializado com sucesso. ${configuredProviders.length} providers configurados.`, detection, 'git-workflow', {
91
- gitInitialized: true,
92
- initialCommit: true,
93
- providersConfigured: configuredProviders,
94
- remoteUrl: detection.providers.length > 0 ?
95
- `${detection.providers[0]}:${detection.owner}/${detection.repoName}` : null
96
- });
97
- }
98
- catch (error) {
99
- this.errorHandler.addError(error, undefined, { action: 'init', projectPath: detection.projectPath });
100
- return (0, auto_detection_js_1.createUniversalResponse)(false, 'init', 'Falha ao inicializar projeto', detection, 'git-workflow', undefined, this.errorHandler.toUniversalResponse());
16
+ const inputSchema = {
17
+ type: 'object',
18
+ properties: {
19
+ action: {
20
+ type: 'string',
21
+ enum: ['init', 'commit', 'sync', 'status', 'backup'],
22
+ description: 'Ação do workflow a executar'
23
+ },
24
+ projectPath: {
25
+ type: 'string',
26
+ description: 'Caminho do projeto (obrigatório)'
27
+ },
28
+ message: {
29
+ type: 'string',
30
+ description: 'Mensagem de commit (para commit/sync)'
31
+ },
32
+ branch: {
33
+ type: 'string',
34
+ description: 'Branch para operações (padrão: main)'
35
+ },
36
+ remote: {
37
+ type: 'string',
38
+ description: 'Remote para operações (padrão: origin)'
101
39
  }
102
- }
103
- /**
104
- * Executa operação commit com auto-detecção
105
- */
106
- async executeCommit(detection, input) {
107
- try {
108
- const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
109
- // Adiciona arquivos e commita
110
- await gitOps.addFiles(['.']);
111
- await gitOps.commit(input.message);
112
- // Push para providers disponíveis
113
- const pushedProviders = [];
114
- const providersToUse = input.provider ? [input.provider] : detection.providers;
115
- for (const provider of providersToUse) {
116
- try {
117
- await gitOps.push('main', provider);
118
- pushedProviders.push(provider);
119
- }
120
- catch (error) {
121
- this.errorHandler.addError(error, provider, { action: 'commit', projectPath: detection.projectPath });
40
+ },
41
+ required: ['action', 'projectPath']
42
+ };
43
+ async function handleInit(projectPath, detection) {
44
+ try {
45
+ const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
46
+ if (isRepo) {
47
+ return {
48
+ success: true,
49
+ action: 'init',
50
+ message: 'Projeto é um repositório Git',
51
+ data: {
52
+ alreadyInitialized: true,
53
+ projectPath,
54
+ repoName: detection.repoName
122
55
  }
56
+ };
57
+ }
58
+ // Inicializar repositório Git
59
+ const { execSync } = require('child_process');
60
+ execSync('git init', { cwd: projectPath });
61
+ execSync('git add .', { cwd: projectPath });
62
+ execSync('git commit -m "Initial commit"', { cwd: projectPath });
63
+ return {
64
+ success: true,
65
+ action: 'init',
66
+ message: 'Projeto inicializado com sucesso',
67
+ data: {
68
+ initialized: true,
69
+ projectPath,
70
+ repoName: detection.repoName,
71
+ initialCommit: true
123
72
  }
124
- return (0, auto_detection_js_1.createUniversalResponse)(true, 'commit', `Commit realizado com sucesso. Enviado para ${pushedProviders.length} providers.`, detection, 'git-workflow', {
125
- committed: true,
126
- pushedTo: pushedProviders,
127
- commitMessage: input.message
128
- });
73
+ };
74
+ }
75
+ catch (error) {
76
+ throw new Error(`Falha ao inicializar projeto: ${error instanceof Error ? error.message : String(error)}`);
77
+ }
78
+ }
79
+ async function handleCommit(projectPath, message, branch = 'main', remote = 'origin') {
80
+ try {
81
+ const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
82
+ if (!isRepo) {
83
+ throw new Error('Diretório não é um repositório Git');
129
84
  }
130
- catch (error) {
131
- this.errorHandler.addError(error, input.provider, { action: 'commit', projectPath: detection.projectPath });
132
- return (0, auto_detection_js_1.createUniversalResponse)(false, 'commit', 'Falha ao realizar commit', detection, 'git-workflow', undefined, this.errorHandler.toUniversalResponse());
85
+ // Status antes do commit
86
+ const statusResult = await (0, terminal_controller_js_1.getGitStatus)(projectPath);
87
+ // Add all changes
88
+ const addResult = await (0, terminal_controller_js_1.gitAdd)(projectPath, '.');
89
+ if (addResult.exitCode !== 0) {
90
+ throw new Error(`Falha ao adicionar arquivos: ${addResult.error}`);
133
91
  }
134
- }
135
- /**
136
- * Executa operação sync (pull + commit + push)
137
- */
138
- async executeSync(detection, input) {
139
- try {
140
- const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
141
- // Pull de todos os providers
142
- const pulledProviders = [];
143
- const providersToUse = input.provider ? [input.provider] : detection.providers;
144
- for (const provider of providersToUse) {
145
- try {
146
- await gitOps.pull('main', provider);
147
- pulledProviders.push(provider);
148
- }
149
- catch (error) {
150
- this.errorHandler.addError(error, provider, { action: 'sync', projectPath: detection.projectPath });
151
- }
92
+ // Commit
93
+ const commitResult = await (0, terminal_controller_js_1.gitCommit)(projectPath, message);
94
+ if (commitResult.exitCode !== 0) {
95
+ throw new Error(`Falha ao fazer commit: ${commitResult.error}`);
96
+ }
97
+ // Push
98
+ const pushResult = await (0, terminal_controller_js_1.gitPush)(projectPath, branch, remote);
99
+ return {
100
+ success: true,
101
+ action: 'commit',
102
+ message: 'Commit realizado com sucesso',
103
+ data: {
104
+ committed: true,
105
+ message,
106
+ branch,
107
+ remote,
108
+ pushed: pushResult.exitCode === 0,
109
+ statusBefore: statusResult.output,
110
+ commitOutput: commitResult.output,
111
+ pushOutput: pushResult.output
152
112
  }
153
- // Commit se houver mudanças
154
- let committed = false;
155
- try {
156
- await gitOps.addFiles(['.']);
157
- if (input.message) {
158
- await gitOps.commit(input.message);
159
- committed = true;
160
- }
113
+ };
114
+ }
115
+ catch (error) {
116
+ throw new Error(`Falha no commit: ${error instanceof Error ? error.message : String(error)}`);
117
+ }
118
+ }
119
+ async function handleSync(projectPath, message, branch = 'main', remote = 'origin') {
120
+ try {
121
+ const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
122
+ if (!isRepo) {
123
+ throw new Error('Diretório não é um repositório Git');
124
+ }
125
+ // Pull primeiro
126
+ const pullResult = await (0, terminal_controller_js_1.gitPull)(projectPath, branch, remote);
127
+ // Status após pull
128
+ const statusResult = await (0, terminal_controller_js_1.getGitStatus)(projectPath);
129
+ // Se há mudanças, fazer commit
130
+ if (statusResult.output.includes('Changes') || statusResult.output.includes('modified')) {
131
+ // Add all changes
132
+ const addResult = await (0, terminal_controller_js_1.gitAdd)(projectPath, '.');
133
+ if (addResult.exitCode !== 0) {
134
+ throw new Error(`Falha ao adicionar arquivos: ${addResult.error}`);
161
135
  }
162
- catch (error) {
163
- // Não é erro crítico se não houver mudanças para commitar
164
- if (!(error instanceof Error) || !error.message?.includes('nothing to commit')) {
165
- this.errorHandler.addError(error, undefined, { action: 'sync', projectPath: detection.projectPath });
166
- }
136
+ // Commit
137
+ const commitResult = await (0, terminal_controller_js_1.gitCommit)(projectPath, message);
138
+ if (commitResult.exitCode !== 0) {
139
+ throw new Error(`Falha ao fazer commit: ${commitResult.error}`);
167
140
  }
168
- // Push para todos os providers
169
- const pushedProviders = [];
170
- for (const provider of providersToUse) {
171
- try {
172
- await gitOps.push('main', provider);
173
- pushedProviders.push(provider);
174
- }
175
- catch (error) {
176
- this.errorHandler.addError(error, provider, { action: 'sync', projectPath: detection.projectPath });
141
+ // Push
142
+ const pushResult = await (0, terminal_controller_js_1.gitPush)(projectPath, branch, remote);
143
+ return {
144
+ success: true,
145
+ action: 'sync',
146
+ message: 'Sincronização completa realizada',
147
+ data: {
148
+ pulled: pullResult.exitCode === 0,
149
+ committed: true,
150
+ pushed: pushResult.exitCode === 0,
151
+ message,
152
+ branch,
153
+ remote,
154
+ pullOutput: pullResult.output,
155
+ commitOutput: commitResult.output,
156
+ pushOutput: pushResult.output
177
157
  }
178
- }
179
- return (0, auto_detection_js_1.createUniversalResponse)(true, 'sync', `Sincronização completa: ${pulledProviders.length} pulls, ${committed ? 1 : 0} commits, ${pushedProviders.length} pushes`, detection, 'git-workflow', {
180
- pulledFrom: pulledProviders,
181
- committed,
182
- pushedTo: pushedProviders,
183
- commitMessage: input.message
184
- });
158
+ };
185
159
  }
186
- catch (error) {
187
- this.errorHandler.addError(error, input.provider, { action: 'sync', projectPath: detection.projectPath });
188
- return (0, auto_detection_js_1.createUniversalResponse)(false, 'sync', 'Falha na sincronização', detection, 'git-workflow', undefined, this.errorHandler.toUniversalResponse());
160
+ else {
161
+ return {
162
+ success: true,
163
+ action: 'sync',
164
+ message: 'Sincronização realizada - nenhuma mudança local',
165
+ data: {
166
+ pulled: pullResult.exitCode === 0,
167
+ committed: false,
168
+ pushed: false,
169
+ message: 'No local changes to commit',
170
+ branch,
171
+ remote,
172
+ pullOutput: pullResult.output
173
+ }
174
+ };
189
175
  }
190
176
  }
191
- /**
192
- * Executa operação status
193
- */
194
- async executeStatus(detection, input) {
177
+ catch (error) {
178
+ throw new Error(`Falha na sincronização: ${error instanceof Error ? error.message : String(error)}`);
179
+ }
180
+ }
181
+ async function handleStatus(projectPath, detection) {
182
+ try {
183
+ const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
184
+ if (!isRepo) {
185
+ return {
186
+ success: true,
187
+ action: 'status',
188
+ message: 'Diretório não é um repositório Git',
189
+ data: {
190
+ isGitRepo: false,
191
+ projectPath,
192
+ repoName: detection.repoName,
193
+ suggestion: 'Use a ação "init" para inicializar o repositório'
194
+ }
195
+ };
196
+ }
197
+ // Status detalhado
198
+ const statusResult = await (0, terminal_controller_js_1.getGitStatus)(projectPath);
199
+ // Informações adicionais via execSync
200
+ const { execSync } = require('child_process');
201
+ let branchInfo = '';
202
+ let remoteInfo = '';
203
+ let lastCommit = '';
195
204
  try {
196
- const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
197
- const status = await gitOps.status(input.detailed ? {} : { short: true });
198
- return (0, auto_detection_js_1.createUniversalResponse)(true, 'status', 'Status obtido com sucesso', detection, 'git-workflow', {
199
- gitStatus: status,
200
- isValidRepo: detection.isValidRepo,
201
- providersConfigured: detection.providers.length,
202
- currentBranch: 'main' // Simplificado por enquanto
203
- });
205
+ branchInfo = execSync('git branch --show-current', { cwd: projectPath, encoding: 'utf8' }).trim();
206
+ remoteInfo = execSync('git remote -v', { cwd: projectPath, encoding: 'utf8' }).trim();
207
+ lastCommit = execSync('git log -1 --oneline', { cwd: projectPath, encoding: 'utf8' }).trim();
204
208
  }
205
209
  catch (error) {
206
- this.errorHandler.addError(error, undefined, { action: 'status', projectPath: detection.projectPath });
207
- return (0, auto_detection_js_1.createUniversalResponse)(false, 'status', 'Falha ao obter status', detection, 'git-workflow', undefined, this.errorHandler.toUniversalResponse());
210
+ // Ignorar erros de comandos git adicionais
208
211
  }
209
- }
210
- /**
211
- * Executa operação backup
212
- */
213
- async executeBackup(detection, input) {
214
- try {
215
- const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
216
- // Cria commit de backup
217
- const backupMessage = input.description ?
218
- `Backup: ${input.description}` :
219
- `Backup automático - ${new Date().toISOString()}`;
220
- await gitOps.addFiles(['.']);
221
- await gitOps.commit(backupMessage);
222
- // Push para todos os providers
223
- const backedUpTo = [];
224
- for (const provider of detection.providers) {
225
- try {
226
- await gitOps.push('main', provider);
227
- backedUpTo.push(provider);
228
- }
229
- catch (error) {
230
- this.errorHandler.addError(error, provider, { action: 'backup', projectPath: detection.projectPath });
231
- }
212
+ return {
213
+ success: true,
214
+ action: 'status',
215
+ message: 'Status do repositório obtido com sucesso',
216
+ data: {
217
+ isGitRepo: true,
218
+ projectPath,
219
+ repoName: detection.repoName,
220
+ owner: detection.owner,
221
+ providers: detection.providers,
222
+ currentBranch: branchInfo,
223
+ remotes: remoteInfo,
224
+ lastCommit,
225
+ status: statusResult.output,
226
+ statusClean: statusResult.exitCode === 0
232
227
  }
233
- return (0, auto_detection_js_1.createUniversalResponse)(true, 'backup', `Backup realizado com sucesso em ${backedUpTo.length} providers`, detection, 'git-workflow', {
234
- backupCreated: true,
235
- backedUpTo,
236
- backupMessage,
237
- timestamp: new Date().toISOString()
238
- });
228
+ };
229
+ }
230
+ catch (error) {
231
+ throw new Error(`Falha ao obter status: ${error instanceof Error ? error.message : String(error)}`);
232
+ }
233
+ }
234
+ async function handleBackup(projectPath, detection) {
235
+ try {
236
+ const isRepo = await (0, terminal_controller_js_1.isGitRepository)(projectPath);
237
+ if (!isRepo) {
238
+ throw new Error('Diretório não é um repositório Git');
239
239
  }
240
- catch (error) {
241
- this.errorHandler.addError(error, undefined, { action: 'backup', projectPath: detection.projectPath });
242
- return (0, auto_detection_js_1.createUniversalResponse)(false, 'backup', 'Falha ao criar backup', detection, 'git-workflow', undefined, this.errorHandler.toUniversalResponse());
240
+ // Criar backup simples via tar/zip
241
+ const fs = require('fs');
242
+ const path = require('path');
243
+ const { execSync } = require('child_process');
244
+ const backupDir = path.join(projectPath, '..', 'backups');
245
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
246
+ const backupName = `${detection.repoName}-backup-${timestamp}`;
247
+ // Criar diretório de backup se não existir
248
+ if (!fs.existsSync(backupDir)) {
249
+ fs.mkdirSync(backupDir, { recursive: true });
250
+ }
251
+ // Criar backup (tar no Linux/Mac, zip no Windows)
252
+ const isWindows = process.platform === 'win32';
253
+ let backupFile = '';
254
+ if (isWindows) {
255
+ backupFile = path.join(backupDir, `${backupName}.zip`);
256
+ execSync(`powershell Compress-Archive -Path "${projectPath}\\*" -DestinationPath "${backupFile}"`, { cwd: backupDir });
243
257
  }
258
+ else {
259
+ backupFile = path.join(backupDir, `${backupName}.tar.gz`);
260
+ execSync(`tar -czf "${backupFile}" -C "${path.dirname(projectPath)}" "${path.basename(projectPath)}"`, { cwd: backupDir });
261
+ }
262
+ const stats = fs.statSync(backupFile);
263
+ return {
264
+ success: true,
265
+ action: 'backup',
266
+ message: 'Backup criado com sucesso',
267
+ data: {
268
+ backupCreated: true,
269
+ backupFile,
270
+ backupSize: stats.size,
271
+ backupSizeHuman: `${(stats.size / 1024 / 1024).toFixed(2)} MB`,
272
+ timestamp,
273
+ projectPath,
274
+ repoName: detection.repoName
275
+ }
276
+ };
277
+ }
278
+ catch (error) {
279
+ throw new Error(`Falha ao criar backup: ${error instanceof Error ? error.message : String(error)}`);
244
280
  }
245
281
  }
246
- // Instância global do executor
247
- const workflowExecutor = new GitWorkflowExecutor();
248
282
  exports.gitWorkflowTool = {
249
283
  name: 'git-workflow',
250
- description: `🛠️ WORKFLOW PRINCIPAL v2.0 - AI-First Design
251
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
252
- 🎯 APENAS 5 AÇÕES OTIMIZADAS (conforme design.md):
253
-
254
- INIT: Inicialização completa com auto-detecção
255
- • Requer apenas: action + projectPath
256
- • Auto-detecta: repo name, owner, providers
257
- • Configura Git + remotes + commit inicial
258
-
259
- COMMIT: Commit inteligente com push automático
260
- • Requer apenas: action + projectPath + message
261
- • Auto-detecta providers e faz push para todos
262
-
263
- SYNC: Sincronização completa (pull+commit+push)
264
- • Requer apenas: action + projectPath
265
- • Pull de todos + commit opcional + push para todos
266
-
267
- STATUS: Status essencial com métricas
268
- • Requer apenas: action + projectPath
269
- • Informações críticas para desenvolvimento
270
-
271
- BACKUP: Backup imediato do estado atual
272
- • Requer apenas: action + projectPath
273
- • Commit + push para todos os providers
274
-
275
- ✨ DIFERENCIAIS v2.0:
276
- • Zero-config: Apenas action + projectPath obrigatórios
277
- • Auto-detecção universal: repo/owner/providers do projectPath
278
- • Respostas universais: Funciona com qualquer AI agent/IDE
279
- • Multi-provider automático: Usa todos os providers configurados
280
- • Error handling inteligente: Causas detalhadas + sugestões de recovery`,
281
- inputSchema: {
282
- type: 'object',
283
- properties: {
284
- action: {
285
- type: 'string',
286
- enum: ['init', 'commit', 'sync', 'status', 'backup'],
287
- description: 'Workflow action (apenas 5 ações otimizadas)'
288
- },
289
- projectPath: {
290
- type: 'string',
291
- description: 'Caminho absoluto do projeto (OBRIGATÓRIO - único parâmetro sempre necessário)'
292
- },
293
- message: {
294
- type: 'string',
295
- description: 'Mensagem para commit/init (obrigatório apenas para commit)'
296
- },
297
- provider: {
298
- type: 'string',
299
- enum: ['gitea', 'github'],
300
- description: 'Provider específico (opcional - se omitido, usa todos os configurados)'
301
- },
302
- detailed: {
303
- type: 'boolean',
304
- description: 'Output detalhado para status (opcional)',
305
- default: false
306
- },
307
- description: {
308
- type: 'string',
309
- description: 'Descrição para backup (opcional)'
310
- }
311
- },
312
- required: ['action', 'projectPath']
313
- },
284
+ description: '🔄 WORKFLOW PRINCIPAL - Operações Git integradas: init, commit, sync, status, backup',
285
+ inputSchema,
314
286
  async handler(input) {
315
287
  try {
316
- // Valida input
317
- const validatedInput = GitWorkflowInputSchema.parse(input);
318
- // Auto-detecta contexto do projeto
319
- const detection = (0, auto_detection_js_1.autoDetect)(validatedInput.projectPath);
320
- // Valida se a auto-detecção foi bem-sucedida
321
- const validation = (0, auto_detection_js_1.validateAutoDetection)(detection);
322
- if (!validation.isValid) {
323
- return (0, auto_detection_js_1.createUniversalResponse)(false, validatedInput.action, 'Falha na auto-detecção do projeto', detection, 'git-workflow', { validation }, {
324
- code: 'AUTO_DETECTION_FAILED',
325
- message: 'Não foi possível detectar automaticamente as configurações do projeto',
326
- cause: validation.errors.join('; '),
327
- suggestion: 'Verifique se as variáveis de ambiente estão configuradas: GITEA_USERNAME/GITEA_TOKEN/GITEA_URL ou GITHUB_USERNAME/GITHUB_TOKEN'
328
- });
288
+ const { action, projectPath, message, branch, remote } = input;
289
+ if (!projectPath) {
290
+ throw new Error('projectPath é obrigatório');
329
291
  }
330
- // Executa ação específica
331
- switch (validatedInput.action) {
292
+ const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
293
+ let result;
294
+ switch (action) {
332
295
  case 'init':
333
- return await workflowExecutor['executeInit'](detection, validatedInput);
296
+ result = await handleInit(projectPath, detection);
297
+ break;
334
298
  case 'commit':
335
- return await workflowExecutor['executeCommit'](detection, validatedInput);
299
+ if (!message) {
300
+ throw new Error('message é obrigatória para commit');
301
+ }
302
+ result = await handleCommit(projectPath, message, branch, remote);
303
+ break;
336
304
  case 'sync':
337
- return await workflowExecutor['executeSync'](detection, validatedInput);
305
+ if (!message) {
306
+ throw new Error('message é obrigatória para sync');
307
+ }
308
+ result = await handleSync(projectPath, message, branch, remote);
309
+ break;
338
310
  case 'status':
339
- return await workflowExecutor['executeStatus'](detection, validatedInput);
311
+ result = await handleStatus(projectPath, detection);
312
+ break;
340
313
  case 'backup':
341
- return await workflowExecutor['executeBackup'](detection, validatedInput);
314
+ result = await handleBackup(projectPath, detection);
315
+ break;
316
+ default:
317
+ throw new Error(`Ação '${action}' não suportada. Use: init, commit, sync, status, backup`);
342
318
  }
319
+ return (0, auto_detection_js_1.createUniversalResponse)(result.success, action, result.message, detection, 'git-workflow', result.data);
343
320
  }
344
321
  catch (error) {
345
- // Cria resposta de erro universal
346
- const detection = input.projectPath ? (0, auto_detection_js_1.autoDetect)(input.projectPath) : {
347
- projectPath: input.projectPath || 'unknown',
348
- repoName: 'unknown',
349
- owner: 'unknown',
350
- providers: [],
351
- isValidRepo: false
352
- };
353
- const errorHandler = new error_handler_js_1.UniversalErrorHandler();
354
- errorHandler.addError(error, undefined, { action: input.action, projectPath: input.projectPath });
355
- return (0, auto_detection_js_1.createUniversalResponse)(false, input.action, `Erro na operação ${input.action}`, detection, 'git-workflow', undefined, errorHandler.toUniversalResponse());
322
+ const detection = (0, auto_detection_js_1.autoDetect)(input.projectPath || '');
323
+ return (0, auto_detection_js_1.createUniversalResponse)(false, input.action || 'unknown', error instanceof Error ? error.message : String(error), detection, 'git-workflow', undefined, {
324
+ code: 'WORKFLOW_ERROR',
325
+ message: error instanceof Error ? error.message : String(error),
326
+ cause: 'Erro na execução do workflow Git',
327
+ suggestion: 'Verifique os parâmetros e tente novamente'
328
+ });
356
329
  }
357
330
  }
358
331
  };