@andrebuzeli/git-mcp 3.3.0 → 4.0.2

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 (139) hide show
  1. package/README.md +63 -283
  2. package/dist/providers/base-provider.d.ts.map +1 -1
  3. package/dist/providers/base-provider.js +3 -26
  4. package/dist/providers/base-provider.js.map +1 -1
  5. package/dist/providers/gitea-provider.d.ts +0 -2
  6. package/dist/providers/gitea-provider.d.ts.map +1 -1
  7. package/dist/providers/gitea-provider.js +0 -62
  8. package/dist/providers/gitea-provider.js.map +1 -1
  9. package/dist/providers/github-provider.d.ts +0 -2
  10. package/dist/providers/github-provider.d.ts.map +1 -1
  11. package/dist/providers/github-provider.js +48 -105
  12. package/dist/providers/github-provider.js.map +1 -1
  13. package/dist/server.d.ts +0 -27
  14. package/dist/server.d.ts.map +1 -1
  15. package/dist/server.js +130 -1215
  16. package/dist/server.js.map +1 -1
  17. package/dist/tools/{git-commits.d.ts → git-analytics.d.ts} +4 -10
  18. package/dist/tools/git-analytics.d.ts.map +1 -0
  19. package/dist/tools/git-analytics.js +18 -0
  20. package/dist/tools/git-analytics.js.map +1 -0
  21. package/dist/tools/git-archive.d.ts +3 -0
  22. package/dist/tools/git-archive.d.ts.map +1 -1
  23. package/dist/tools/git-archive.js +2 -2
  24. package/dist/tools/git-archive.js.map +1 -1
  25. package/dist/tools/git-backup.d.ts +216 -0
  26. package/dist/tools/git-backup.d.ts.map +1 -0
  27. package/dist/tools/git-backup.js +813 -0
  28. package/dist/tools/git-backup.js.map +1 -0
  29. package/dist/tools/git-branches.d.ts +159 -8
  30. package/dist/tools/git-branches.d.ts.map +1 -1
  31. package/dist/tools/git-branches.js +554 -2
  32. package/dist/tools/git-branches.js.map +1 -1
  33. package/dist/tools/git-config.d.ts +3 -0
  34. package/dist/tools/git-config.d.ts.map +1 -1
  35. package/dist/tools/git-config.js +2 -2
  36. package/dist/tools/git-config.js.map +1 -1
  37. package/dist/tools/git-files.d.ts +130 -8
  38. package/dist/tools/git-files.d.ts.map +1 -1
  39. package/dist/tools/git-files.js +426 -2
  40. package/dist/tools/git-files.js.map +1 -1
  41. package/dist/tools/git-issues.d.ts +137 -471
  42. package/dist/tools/git-issues.d.ts.map +1 -1
  43. package/dist/tools/git-issues.js +605 -613
  44. package/dist/tools/git-issues.js.map +1 -1
  45. package/dist/tools/git-monitor.d.ts +161 -0
  46. package/dist/tools/git-monitor.d.ts.map +1 -0
  47. package/dist/tools/git-monitor.js +746 -0
  48. package/dist/tools/git-monitor.js.map +1 -0
  49. package/dist/tools/git-packages.d.ts +5 -2
  50. package/dist/tools/git-packages.d.ts.map +1 -1
  51. package/dist/tools/git-packages.js +3 -3
  52. package/dist/tools/git-packages.js.map +1 -1
  53. package/dist/tools/git-pulls.d.ts +38 -646
  54. package/dist/tools/git-pulls.d.ts.map +1 -1
  55. package/dist/tools/git-pulls.js +64 -716
  56. package/dist/tools/git-pulls.js.map +1 -1
  57. package/dist/tools/git-release.d.ts +187 -0
  58. package/dist/tools/git-release.d.ts.map +1 -0
  59. package/dist/tools/git-release.js +619 -0
  60. package/dist/tools/git-release.js.map +1 -0
  61. package/dist/tools/git-remote.d.ts +112 -77
  62. package/dist/tools/git-remote.d.ts.map +1 -1
  63. package/dist/tools/git-remote.js +481 -183
  64. package/dist/tools/git-remote.js.map +1 -1
  65. package/dist/tools/git-repos.d.ts +19 -0
  66. package/dist/tools/git-repos.d.ts.map +1 -0
  67. package/dist/tools/git-repos.js +18 -0
  68. package/dist/tools/git-repos.js.map +1 -0
  69. package/dist/tools/git-reset.d.ts +121 -74
  70. package/dist/tools/git-reset.d.ts.map +1 -1
  71. package/dist/tools/git-reset.js +540 -159
  72. package/dist/tools/git-reset.js.map +1 -1
  73. package/dist/tools/git-stash.d.ts +119 -78
  74. package/dist/tools/git-stash.d.ts.map +1 -1
  75. package/dist/tools/git-stash.js +560 -209
  76. package/dist/tools/git-stash.js.map +1 -1
  77. package/dist/tools/git-sync.d.ts +3 -163
  78. package/dist/tools/git-sync.d.ts.map +1 -1
  79. package/dist/tools/git-sync.js +9 -326
  80. package/dist/tools/git-sync.js.map +1 -1
  81. package/dist/tools/git-tags.d.ts +105 -331
  82. package/dist/tools/git-tags.d.ts.map +1 -1
  83. package/dist/tools/git-tags.js +545 -416
  84. package/dist/tools/git-tags.js.map +1 -1
  85. package/dist/tools/git-workflow.d.ts +127 -0
  86. package/dist/tools/git-workflow.d.ts.map +1 -0
  87. package/dist/tools/git-workflow.js +359 -0
  88. package/dist/tools/git-workflow.js.map +1 -0
  89. package/dist/utils/auto-detection.d.ts +113 -0
  90. package/dist/utils/auto-detection.d.ts.map +1 -0
  91. package/dist/utils/auto-detection.js +235 -0
  92. package/dist/utils/auto-detection.js.map +1 -0
  93. package/dist/utils/error-handler.d.ts +107 -0
  94. package/dist/utils/error-handler.d.ts.map +1 -0
  95. package/dist/utils/error-handler.js +331 -0
  96. package/dist/utils/error-handler.js.map +1 -0
  97. package/dist/utils/git-operations.d.ts.map +1 -1
  98. package/dist/utils/git-operations.js +6 -51
  99. package/dist/utils/git-operations.js.map +1 -1
  100. package/dist/utils/user-detection.d.ts +1 -13
  101. package/dist/utils/user-detection.d.ts.map +1 -1
  102. package/dist/utils/user-detection.js +1 -26
  103. package/dist/utils/user-detection.js.map +1 -1
  104. package/package.json +60 -60
  105. package/dist/client.d.ts +0 -307
  106. package/dist/client.d.ts.map +0 -1
  107. package/dist/client.js +0 -299
  108. package/dist/client.js.map +0 -1
  109. package/dist/tools/git-branch-protection.d.ts +0 -97
  110. package/dist/tools/git-branch-protection.d.ts.map +0 -1
  111. package/dist/tools/git-branch-protection.js +0 -182
  112. package/dist/tools/git-branch-protection.js.map +0 -1
  113. package/dist/tools/git-commits.d.ts.map +0 -1
  114. package/dist/tools/git-commits.js +0 -5
  115. package/dist/tools/git-commits.js.map +0 -1
  116. package/dist/tools/git-initialize.d.ts +0 -208
  117. package/dist/tools/git-initialize.d.ts.map +0 -1
  118. package/dist/tools/git-initialize.js +0 -470
  119. package/dist/tools/git-initialize.js.map +0 -1
  120. package/dist/tools/git-projects.d.ts +0 -112
  121. package/dist/tools/git-projects.d.ts.map +0 -1
  122. package/dist/tools/git-projects.js +0 -319
  123. package/dist/tools/git-projects.js.map +0 -1
  124. package/dist/tools/git-releases.d.ts +0 -486
  125. package/dist/tools/git-releases.d.ts.map +0 -1
  126. package/dist/tools/git-releases.js +0 -561
  127. package/dist/tools/git-releases.js.map +0 -1
  128. package/dist/tools/git-repositories.d.ts +0 -469
  129. package/dist/tools/git-repositories.d.ts.map +0 -1
  130. package/dist/tools/git-repositories.js +0 -637
  131. package/dist/tools/git-repositories.js.map +0 -1
  132. package/dist/tools/git-revert.d.ts +0 -147
  133. package/dist/tools/git-revert.d.ts.map +0 -1
  134. package/dist/tools/git-revert.js +0 -199
  135. package/dist/tools/git-revert.js.map +0 -1
  136. package/dist/tools/git-update-project.d.ts +0 -309
  137. package/dist/tools/git-update-project.d.ts.map +0 -1
  138. package/dist/tools/git-update-project.js +0 -878
  139. package/dist/tools/git-update-project.js.map +0 -1
@@ -1,878 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gitUpdateProjectTool = void 0;
4
- const zod_1 = require("zod");
5
- const index_js_1 = require("../providers/index.js");
6
- const user_detection_js_1 = require("../utils/user-detection.js");
7
- const git_operations_js_1 = require("../utils/git-operations.js");
8
- const GitUpdateProjectInputSchema = zod_1.z.discriminatedUnion('action', [
9
- // Action: init - upload inicial completo (substitui upload-project)
10
- zod_1.z.object({
11
- action: zod_1.z.literal('init'),
12
- // repo: extraído automaticamente do projectPath
13
- projectPath: zod_1.z.string(),
14
- provider: zod_1.z.enum(['gitea', 'github']),
15
- message: zod_1.z.string().min(1, 'Commit message is required'),
16
- branch: zod_1.z.string().optional(),
17
- createRepo: zod_1.z.boolean().optional(),
18
- forcePush: zod_1.z.boolean().optional(),
19
- granular: zod_1.z.boolean().optional() // commits granulares por tipo de arquivo
20
- }),
21
- // Action: update - commit incremental
22
- zod_1.z.object({
23
- action: zod_1.z.literal('update'),
24
- // repo: extraído automaticamente do projectPath
25
- projectPath: zod_1.z.string(),
26
- provider: zod_1.z.enum(['gitea', 'github']),
27
- message: zod_1.z.string().min(1, 'Commit message is required'),
28
- branch: zod_1.z.string().optional(),
29
- forcePush: zod_1.z.boolean().optional()
30
- }),
31
- // Action: status - verificar status do repositório
32
- zod_1.z.object({
33
- action: zod_1.z.literal('status'),
34
- projectPath: zod_1.z.string(),
35
- detailed: zod_1.z.boolean().optional()
36
- }),
37
- // Action: diff - mostrar diferenças
38
- zod_1.z.object({
39
- action: zod_1.z.literal('diff'),
40
- projectPath: zod_1.z.string(),
41
- staged: zod_1.z.boolean().optional(),
42
- nameOnly: zod_1.z.boolean().optional(),
43
- commit: zod_1.z.string().optional()
44
- }),
45
- // Action: log - histórico de commits
46
- zod_1.z.object({
47
- action: zod_1.z.literal('log'),
48
- projectPath: zod_1.z.string(),
49
- maxCount: zod_1.z.number().optional(),
50
- oneline: zod_1.z.boolean().optional(),
51
- branch: zod_1.z.string().optional()
52
- }),
53
- // Action: reset - desfazer mudanças
54
- zod_1.z.object({
55
- action: zod_1.z.literal('reset'),
56
- projectPath: zod_1.z.string(),
57
- mode: zod_1.z.enum(['soft', 'mixed', 'hard']).optional(),
58
- commit: zod_1.z.string().optional()
59
- }),
60
- // Action: stash - gerenciar mudanças temporárias
61
- zod_1.z.object({
62
- action: zod_1.z.literal('stash'),
63
- projectPath: zod_1.z.string(),
64
- operation: zod_1.z.enum(['save', 'pop', 'apply', 'list', 'drop', 'clear']).optional(),
65
- message: zod_1.z.string().optional()
66
- }),
67
- // Action: pull - atualizar do remoto
68
- zod_1.z.object({
69
- action: zod_1.z.literal('pull'),
70
- projectPath: zod_1.z.string(),
71
- branch: zod_1.z.string().optional()
72
- }),
73
- // Action: sync - sincronização completa (pull + commit + push)
74
- zod_1.z.object({
75
- action: zod_1.z.literal('sync'),
76
- // repo: extraído automaticamente do projectPath
77
- projectPath: zod_1.z.string(),
78
- provider: zod_1.z.enum(['gitea', 'github']),
79
- message: zod_1.z.string().min(1, 'Commit message is required'),
80
- branch: zod_1.z.string().optional(),
81
- forcePush: zod_1.z.boolean().optional()
82
- })
83
- ]);
84
- const GitUpdateProjectResultSchema = zod_1.z.object({
85
- success: zod_1.z.boolean(),
86
- action: zod_1.z.string(),
87
- message: zod_1.z.string(),
88
- data: zod_1.z.any().optional(),
89
- error: zod_1.z.string().optional()
90
- });
91
- exports.gitUpdateProjectTool = {
92
- name: 'git-update-project',
93
- description: 'tool: Gerenciamento COMPLETO de projetos Git (local + remoto)\\n──────────────\\n9 ACTIONS DISPONÍVEIS:\\n• init: UPLOAD INICIAL completo (substitui upload-project)\\n• update: Commit incremental automático\\n• status: Verificar status do repositório\\n• diff: Mostrar diferenças entre versões\\n• log: Histórico de commits\\n• reset: Desfazer mudanças\\n• stash: Gerenciar mudanças temporárias\\n• pull: Atualizar do repositório remoto\\n• sync: Sincronização completa (pull+commit+push)\\n───────────────\\nCOMMITS REAIS + RASTREABILIDADE TOTAL\\nFunciona com GitHub, Gitea e qualquer repositório Git',
94
- inputSchema: {
95
- type: 'object',
96
- properties: {
97
- action: {
98
- type: 'string',
99
- enum: ['init', 'update', 'status', 'diff', 'log', 'reset', 'stash', 'pull', 'sync'],
100
- description: 'Action to perform'
101
- },
102
- // Parâmetros comuns
103
- repo: { type: 'string', description: 'Repository name (required for init/update/sync)' },
104
- projectPath: { type: 'string', description: 'Local project path (OBRIGATÓRIO para TODAS as operações)' },
105
- provider: { type: 'string', enum: ['gitea', 'github'], description: 'Provider (required for init/update/sync)' },
106
- // Parâmetros específicos
107
- message: { type: 'string', description: 'Commit message (required for init/update/sync)' },
108
- branch: { type: 'string', description: 'Branch name', default: 'main' },
109
- forcePush: { type: 'boolean', description: 'Force push', default: false },
110
- createRepo: { type: 'boolean', description: 'Create remote repository if not exists', default: false },
111
- granular: { type: 'boolean', description: 'Create granular commits by file type for init', default: false },
112
- detailed: { type: 'boolean', description: 'Detailed output for status', default: false },
113
- staged: { type: 'boolean', description: 'Show staged changes for diff', default: false },
114
- nameOnly: { type: 'boolean', description: 'Show only filenames for diff', default: false },
115
- commit: { type: 'string', description: 'Target commit for reset/diff' },
116
- maxCount: { type: 'number', description: 'Max commits for log', default: 10 },
117
- oneline: { type: 'boolean', description: 'One line format for log', default: true },
118
- mode: { type: 'string', enum: ['soft', 'mixed', 'hard'], description: 'Reset mode', default: 'mixed' },
119
- operation: { type: 'string', enum: ['save', 'pop', 'apply', 'list', 'drop', 'clear'], description: 'Stash operation', default: 'save' }
120
- },
121
- required: ['action', 'projectPath']
122
- },
123
- async handler(input) {
124
- try {
125
- const validatedInput = GitUpdateProjectInputSchema.parse(input);
126
- // Aplicar extração automática do nome do repositório
127
- const processedInput = (0, user_detection_js_1.applyAutoRepoExtraction)(validatedInput);
128
- // Roteamento baseado na action
129
- switch (processedInput.action) {
130
- case 'init':
131
- return await this.handleInit(processedInput);
132
- case 'update':
133
- return await this.handleUpdate(processedInput);
134
- case 'status':
135
- return await this.handleStatus(processedInput);
136
- case 'diff':
137
- return await this.handleDiff(processedInput);
138
- case 'log':
139
- return await this.handleLog(processedInput);
140
- case 'reset':
141
- return await this.handleReset(processedInput);
142
- case 'stash':
143
- return await this.handleStash(processedInput);
144
- case 'pull':
145
- return await this.handlePull(processedInput);
146
- case 'sync':
147
- return await this.handleSync(processedInput);
148
- default:
149
- throw new Error(`Action '${processedInput.action}' não suportada`);
150
- }
151
- }
152
- catch (error) {
153
- return {
154
- success: false,
155
- action: input.action,
156
- message: `Erro na operação ${input.action}`,
157
- error: error instanceof Error ? error.message : String(error)
158
- };
159
- }
160
- },
161
- async handleUpdate(params) {
162
- try {
163
- const repo = params.repo || (0, user_detection_js_1.extractRepoName)(params.projectPath);
164
- const { projectPath, message, branch = 'main', forcePush = false, provider: providerName } = params;
165
- // Inicializar operações Git locais
166
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
167
- // Verificar se é um repositório Git
168
- const isGitRepo = await gitOps.isGitRepository();
169
- if (!isGitRepo) {
170
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
171
- }
172
- // Verificar status para ver se há mudanças
173
- const statusResult = await gitOps.status({ porcelain: true });
174
- if (!statusResult.success) {
175
- throw new Error(`Falha ao verificar status do Git: ${statusResult.error}`);
176
- }
177
- // Verificar se há mudanças para commitar
178
- const hasChanges = statusResult.output.trim().length > 0;
179
- if (!hasChanges) {
180
- return {
181
- success: true,
182
- action: 'update',
183
- message: `Nenhuma mudança detectada no projeto '${repo}'`,
184
- data: {
185
- repo,
186
- branch,
187
- provider: providerName,
188
- message,
189
- changesDetected: false,
190
- filesChanged: 0,
191
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0',
192
- note: 'Nenhuma mudança para commitar'
193
- }
194
- };
195
- }
196
- // Contar arquivos modificados
197
- const changedFiles = statusResult.output.trim().split('\n').filter(line => line.trim().length > 0);
198
- const filesCount = changedFiles.length;
199
- // Adicionar arquivos ao staging
200
- const addResult = await gitOps.addFiles(['.']);
201
- if (!addResult.success) {
202
- throw new Error(`Falha ao adicionar arquivos: ${addResult.error}`);
203
- }
204
- // Verificar se há algo no staging após add
205
- const statusAfterAdd = await gitOps.status({ porcelain: true });
206
- if (!statusAfterAdd.success) {
207
- throw new Error(`Falha ao verificar status após add: ${statusAfterAdd.error}`);
208
- }
209
- const hasStagedChanges = statusAfterAdd.output.includes('A') || statusAfterAdd.output.includes('M') || statusAfterAdd.output.includes('D');
210
- if (!hasStagedChanges) {
211
- return {
212
- success: true,
213
- action: 'update',
214
- message: `Arquivos adicionados mas nenhuma mudança válida para commit no projeto '${repo}'`,
215
- data: {
216
- repo,
217
- branch,
218
- provider: providerName,
219
- message,
220
- changesDetected: true,
221
- filesChanged: filesCount,
222
- stagedChanges: false,
223
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0',
224
- note: 'Arquivos adicionados mas não há mudanças válidas para commit'
225
- }
226
- };
227
- }
228
- // Fazer commit
229
- const commitResult = await gitOps.commit(message);
230
- if (!commitResult.success) {
231
- throw new Error(`Falha no commit: ${commitResult.error}`);
232
- }
233
- // Resolver provider explicitamente quando informado e alinhar remote ao provider
234
- let providerRemoteAligned = false;
235
- if (providerName) {
236
- // Aplicar auto-detecção (mantém params) e obter provider solicitado; NÃO fazer fallback
237
- const processedInput = await (0, user_detection_js_1.applyAutoUserDetection)(params, providerName);
238
- const requestedProvider = index_js_1.globalProviderFactory.getProvider(processedInput.provider);
239
- if (!requestedProvider) {
240
- throw new Error(`Provider '${providerName}' não encontrado. Configure o provider corretamente ou omita o campo para usar o padrão.`);
241
- }
242
- // Obter owner para compor a URL correta do remoto
243
- const currentUser = await requestedProvider.getCurrentUser();
244
- const owner = currentUser.login;
245
- const desiredRemoteUrl = requestedProvider.getRepositoryUrl(owner, repo);
246
- // Garantir que o remote 'origin' existe e aponta para o provider correto
247
- const showRemote = await gitOps.remote('get-url', 'origin');
248
- if (!showRemote.success) {
249
- // Não existe 'origin' → adicionar
250
- const addOrigin = await gitOps.remote('add', 'origin', desiredRemoteUrl);
251
- providerRemoteAligned = addOrigin.success;
252
- if (!addOrigin.success && !(addOrigin.error || '').includes('already exists')) {
253
- throw new Error(`Falha ao adicionar remote origin: ${addOrigin.error}`);
254
- }
255
- }
256
- else {
257
- const currentUrl = showRemote.output.trim();
258
- if (currentUrl !== desiredRemoteUrl) {
259
- const setUrl = await gitOps.remote('set-url', 'origin', desiredRemoteUrl);
260
- providerRemoteAligned = setUrl.success;
261
- if (!setUrl.success) {
262
- throw new Error(`Falha ao atualizar URL do remote origin: ${setUrl.error}`);
263
- }
264
- }
265
- else {
266
- providerRemoteAligned = true;
267
- }
268
- }
269
- }
270
- // Tentar fazer push para o remote
271
- let pushSuccessful = false;
272
- let pushError = '';
273
- try {
274
- // Verificar se há remote configurado
275
- const remoteResult = await gitOps.remote('get-url', 'origin');
276
- if (remoteResult.success) {
277
- // Tentar push
278
- const pushOptions = {};
279
- if (forcePush) {
280
- pushOptions.force = true;
281
- }
282
- const pushResult = await gitOps.push('origin', branch, pushOptions);
283
- pushSuccessful = pushResult.success;
284
- if (!pushSuccessful) {
285
- pushError = pushResult.error || 'Erro desconhecido no push';
286
- }
287
- }
288
- else {
289
- pushError = 'Nenhum remote configurado (origin)';
290
- }
291
- }
292
- catch (pushErr) {
293
- pushError = pushErr instanceof Error ? pushErr.message : String(pushErr);
294
- }
295
- // Obter informações do commit criado
296
- const logResult = await gitOps.log({ maxCount: 1, oneline: true });
297
- const commitInfo = logResult.success ? logResult.output : 'Commit criado mas não foi possível obter informações';
298
- return {
299
- success: true,
300
- action: 'update',
301
- message: `Projeto '${repo}' atualizado com sucesso${pushSuccessful ? ' e enviado para remote' : ''}`,
302
- data: {
303
- repo,
304
- branch,
305
- provider: providerName,
306
- message,
307
- changesDetected: true,
308
- filesChanged: filesCount,
309
- stagedChanges: true,
310
- commitCreated: true,
311
- commitInfo,
312
- pushSuccessful,
313
- providerRemoteAligned,
314
- pushError: pushSuccessful ? undefined : pushError,
315
- note: pushSuccessful ?
316
- 'Commit criado e enviado para remote com sucesso' :
317
- `Commit criado localmente. Push falhou: ${pushError}. Use git push manualmente.`
318
- }
319
- };
320
- }
321
- catch (error) {
322
- return {
323
- success: false,
324
- action: 'update',
325
- message: 'Erro na atualização incremental do projeto',
326
- error: error instanceof Error ? error.message : String(error)
327
- };
328
- }
329
- },
330
- // Action: init - upload inicial completo (substitui upload-project)
331
- async handleInit(params) {
332
- try {
333
- const repo = params.repo || (0, user_detection_js_1.extractRepoName)(params.projectPath);
334
- const { projectPath, message, branch = 'main', forcePush = false, createRepo = false, granular = false, provider: providerName } = params;
335
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
336
- // Aplicar auto-detecção de usuário
337
- const processedInput = await (0, user_detection_js_1.applyAutoUserDetection)(params, providerName);
338
- const provider = index_js_1.globalProviderFactory.getProvider(processedInput.provider);
339
- if (!provider) {
340
- throw new Error(`Provider '${providerName}' não encontrado`);
341
- }
342
- const currentUser = await provider.getCurrentUser();
343
- const owner = currentUser.login;
344
- // 1. Inicializar repositório Git local se necessário
345
- const isGitRepo = await gitOps.isGitRepository();
346
- if (!isGitRepo) {
347
- const initResult = await gitOps.initRepository();
348
- if (!initResult.success) {
349
- throw new Error(`Falha ao inicializar repositório Git: ${initResult.error}`);
350
- }
351
- }
352
- // 2. Verificar/criar repositório remoto
353
- let repoExists = true;
354
- try {
355
- await provider.getRepository(owner, repo);
356
- }
357
- catch (error) {
358
- repoExists = false;
359
- if (createRepo) {
360
- try {
361
- await provider.createRepository(repo, `Projeto ${repo}`, false);
362
- repoExists = true;
363
- }
364
- catch (createError) {
365
- console.warn(`Aviso: Não foi possível criar repositório: ${createError instanceof Error ? createError.message : String(createError)}`);
366
- }
367
- }
368
- else {
369
- throw new Error(`Repositório '${repo}' não existe. Use createRepo: true para criar automaticamente.`);
370
- }
371
- }
372
- // 3. Preparar arquivos para commit
373
- let filesCommitted = 0;
374
- let commitsCreated = 0;
375
- if (granular) {
376
- // Commits granulares por tipo de arquivo (melhor rastreabilidade)
377
- const fileGroups = await this.groupFilesByType(projectPath);
378
- for (const [fileType, files] of Object.entries(fileGroups)) {
379
- if (files.length > 0) {
380
- // Adicionar arquivos do tipo específico
381
- const addResult = await gitOps.addFiles(files);
382
- if (addResult.success) {
383
- // Verificar se há mudanças para commitar
384
- const statusResult = await gitOps.status({ porcelain: true });
385
- if (statusResult.success && statusResult.output.trim()) {
386
- const commitResult = await gitOps.commit(`${message} - ${fileType} files`);
387
- if (commitResult.success) {
388
- commitsCreated++;
389
- filesCommitted += files.length;
390
- }
391
- }
392
- }
393
- }
394
- }
395
- }
396
- else {
397
- // Commit único de todos os arquivos (como upload-project)
398
- const addResult = await gitOps.addFiles(['.']);
399
- if (addResult.success) {
400
- const statusResult = await gitOps.status({ porcelain: true });
401
- if (statusResult.success && statusResult.output.trim()) {
402
- const commitResult = await gitOps.commit(message);
403
- if (commitResult.success) {
404
- commitsCreated++;
405
- filesCommitted = statusResult.output.trim().split('\n').length;
406
- }
407
- }
408
- }
409
- }
410
- // 4. Configurar e fazer push para remote
411
- let pushSuccessful = false;
412
- const remoteUrl = provider.getRepositoryUrl(owner, repo);
413
- // Configurar remote origin
414
- const remoteResult = await gitOps.remote('show', 'origin');
415
- if (!remoteResult.success) {
416
- const addRemoteResult = await gitOps.remote('add', 'origin', remoteUrl);
417
- if (!addRemoteResult.success && !addRemoteResult.error?.includes('already exists')) {
418
- console.warn(`Aviso: Falha ao adicionar remote: ${addRemoteResult.error}`);
419
- }
420
- }
421
- else {
422
- // Atualizar URL se necessário
423
- const setUrlResult = await gitOps.remote('set-url', 'origin', remoteUrl);
424
- if (!setUrlResult.success) {
425
- console.warn(`Aviso: Falha ao atualizar remote URL: ${setUrlResult.error}`);
426
- }
427
- }
428
- // Fazer push
429
- if (commitsCreated > 0) {
430
- try {
431
- const pushOptions = { setUpstream: true };
432
- if (forcePush)
433
- pushOptions.force = true;
434
- const pushResult = await gitOps.push('origin', branch, pushOptions);
435
- pushSuccessful = pushResult.success;
436
- if (!pushSuccessful) {
437
- console.warn(`Aviso: Push falhou: ${pushResult.error}`);
438
- }
439
- }
440
- catch (pushErr) {
441
- console.warn(`Aviso: Erro no push: ${pushErr instanceof Error ? pushErr.message : String(pushErr)}`);
442
- }
443
- }
444
- return {
445
- success: true,
446
- action: 'init',
447
- message: `Upload inicial concluído com ${commitsCreated} commit(s) e ${filesCommitted} arquivo(s)`,
448
- data: {
449
- repo,
450
- branch,
451
- provider: providerName,
452
- owner,
453
- remoteUrl,
454
- repositoryCreated: !repoExists && createRepo,
455
- gitInit: !isGitRepo,
456
- commitsCreated,
457
- filesCommitted,
458
- pushSuccessful,
459
- granular,
460
- implementation: 'REAL_GIT_OPERATIONS_v2.40.0',
461
- note: granular ?
462
- 'Commits granulares criados por tipo de arquivo para melhor rastreabilidade' :
463
- 'Commit único criado (como upload-project original)'
464
- }
465
- };
466
- }
467
- catch (error) {
468
- return {
469
- success: false,
470
- action: 'init',
471
- message: 'Erro no upload inicial do projeto',
472
- error: error instanceof Error ? error.message : String(error)
473
- };
474
- }
475
- },
476
- // Action: status - verificar status do repositório
477
- async handleStatus(params) {
478
- try {
479
- const { projectPath, detailed = false } = params;
480
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
481
- // Verificar se é um repositório Git
482
- const isGitRepo = await gitOps.isGitRepository();
483
- if (!isGitRepo) {
484
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
485
- }
486
- // Obter status detalhado
487
- const statusResult = await gitOps.status({ porcelain: false });
488
- if (!statusResult.success) {
489
- throw new Error(`Falha ao obter status: ${statusResult.error}`);
490
- }
491
- // Obter branch atual
492
- const branchResult = await gitOps.getCurrentBranch();
493
- const currentBranch = branchResult.success ? branchResult.output.trim() : 'unknown';
494
- // Contar mudanças
495
- const porcelainResult = await gitOps.status({ porcelain: true });
496
- const changes = porcelainResult.success ? porcelainResult.output.trim() : '';
497
- const filesChanged = changes ? changes.split('\n').filter(line => line.trim().length > 0).length : 0;
498
- return {
499
- success: true,
500
- action: 'status',
501
- message: `Status do repositório obtido com sucesso`,
502
- data: {
503
- currentBranch,
504
- filesChanged,
505
- hasChanges: filesChanged > 0,
506
- statusOutput: detailed ? statusResult.output : statusResult.output.split('\n').slice(0, 10).join('\n'),
507
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0',
508
- detailed
509
- }
510
- };
511
- }
512
- catch (error) {
513
- return {
514
- success: false,
515
- action: 'status',
516
- message: 'Erro ao verificar status do repositório',
517
- error: error instanceof Error ? error.message : String(error)
518
- };
519
- }
520
- },
521
- // Action: diff - mostrar diferenças
522
- async handleDiff(params) {
523
- try {
524
- const { projectPath, staged = false, nameOnly = false, commit } = params;
525
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
526
- // Verificar se é um repositório Git
527
- const isGitRepo = await gitOps.isGitRepository();
528
- if (!isGitRepo) {
529
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
530
- }
531
- const diffOptions = {};
532
- if (staged)
533
- diffOptions.cached = true;
534
- if (nameOnly)
535
- diffOptions.nameOnly = true;
536
- if (commit)
537
- diffOptions.commit = commit;
538
- const diffResult = await gitOps.diff(diffOptions);
539
- if (!diffResult.success && diffResult.error) {
540
- throw new Error(`Falha ao obter diferenças: ${diffResult.error}`);
541
- }
542
- const hasDifferences = diffResult.output.trim().length > 0;
543
- return {
544
- success: true,
545
- action: 'diff',
546
- message: hasDifferences ? 'Diferenças encontradas' : 'Nenhuma diferença encontrada',
547
- data: {
548
- hasDifferences,
549
- diffOutput: diffResult.output,
550
- staged,
551
- nameOnly,
552
- commit: commit || 'HEAD',
553
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
554
- }
555
- };
556
- }
557
- catch (error) {
558
- return {
559
- success: false,
560
- action: 'diff',
561
- message: 'Erro ao obter diferenças',
562
- error: error instanceof Error ? error.message : String(error)
563
- };
564
- }
565
- },
566
- // Action: log - histórico de commits
567
- async handleLog(params) {
568
- try {
569
- const { projectPath, maxCount = 10, oneline = true, branch } = params;
570
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
571
- // Verificar se é um repositório Git
572
- const isGitRepo = await gitOps.isGitRepository();
573
- if (!isGitRepo) {
574
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
575
- }
576
- // Obter histórico de commits
577
- const logOptions = {};
578
- if (maxCount)
579
- logOptions.maxCount = maxCount;
580
- if (oneline)
581
- logOptions.oneline = true;
582
- if (branch)
583
- logOptions.branches = [branch];
584
- const logResult = await gitOps.log(logOptions);
585
- if (!logResult.success) {
586
- throw new Error(`Falha ao obter histórico: ${logResult.error}`);
587
- }
588
- const commits = logResult.output.trim();
589
- const commitCount = commits ? commits.split('\n').filter(line => line.trim().length > 0).length : 0;
590
- return {
591
- success: true,
592
- action: 'log',
593
- message: `${commitCount} commits encontrados no histórico`,
594
- data: {
595
- commits: commits || 'Nenhum commit encontrado',
596
- commitCount,
597
- maxCount,
598
- oneline,
599
- branch: branch || 'all',
600
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
601
- }
602
- };
603
- }
604
- catch (error) {
605
- return {
606
- success: false,
607
- action: 'log',
608
- message: 'Erro ao obter histórico de commits',
609
- error: error instanceof Error ? error.message : String(error)
610
- };
611
- }
612
- },
613
- // Action: reset - desfazer mudanças
614
- async handleReset(params) {
615
- try {
616
- const { projectPath, mode = 'mixed', commit } = params;
617
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
618
- // Verificar se é um repositório Git
619
- const isGitRepo = await gitOps.isGitRepository();
620
- if (!isGitRepo) {
621
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
622
- }
623
- // Executar reset
624
- const target = commit || 'HEAD';
625
- const resetOptions = { mode };
626
- const resetResult = await gitOps.reset(target, resetOptions);
627
- if (!resetResult.success) {
628
- throw new Error(`Falha no reset: ${resetResult.error}`);
629
- }
630
- return {
631
- success: true,
632
- action: 'reset',
633
- message: `Reset ${mode} executado com sucesso`,
634
- data: {
635
- mode,
636
- targetCommit: target,
637
- resetOutput: resetResult.output,
638
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
639
- }
640
- };
641
- }
642
- catch (error) {
643
- return {
644
- success: false,
645
- action: 'reset',
646
- message: 'Erro ao executar reset',
647
- error: error instanceof Error ? error.message : String(error)
648
- };
649
- }
650
- },
651
- // Action: stash - gerenciar mudanças temporárias
652
- async handleStash(params) {
653
- try {
654
- const { projectPath, operation = 'save', message } = params;
655
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
656
- // Verificar se é um repositório Git
657
- const isGitRepo = await gitOps.isGitRepository();
658
- if (!isGitRepo) {
659
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
660
- }
661
- let stashResult;
662
- switch (operation) {
663
- case 'save':
664
- stashResult = await gitOps.stash('push', { message });
665
- break;
666
- case 'pop':
667
- stashResult = await gitOps.stash('pop');
668
- break;
669
- case 'apply':
670
- stashResult = await gitOps.stash('apply');
671
- break;
672
- case 'list':
673
- stashResult = await gitOps.stash('list');
674
- break;
675
- case 'drop':
676
- stashResult = await gitOps.stash('drop');
677
- break;
678
- case 'clear':
679
- stashResult = await gitOps.stash('clear');
680
- break;
681
- default:
682
- throw new Error(`Operação de stash '${operation}' não suportada`);
683
- }
684
- if (!stashResult.success) {
685
- throw new Error(`Falha na operação stash ${operation}: ${stashResult.error}`);
686
- }
687
- return {
688
- success: true,
689
- action: 'stash',
690
- message: `Operação stash '${operation}' executada com sucesso`,
691
- data: {
692
- operation,
693
- message: message || undefined,
694
- stashOutput: stashResult.output,
695
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
696
- }
697
- };
698
- }
699
- catch (error) {
700
- return {
701
- success: false,
702
- action: 'stash',
703
- message: 'Erro na operação de stash',
704
- error: error instanceof Error ? error.message : String(error)
705
- };
706
- }
707
- },
708
- // Action: pull - atualizar do remoto
709
- async handlePull(params) {
710
- try {
711
- const { projectPath, branch } = params;
712
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
713
- // Verificar se é um repositório Git
714
- const isGitRepo = await gitOps.isGitRepository();
715
- if (!isGitRepo) {
716
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
717
- }
718
- // Executar pull
719
- const pullResult = await gitOps.pull('origin', branch);
720
- if (!pullResult.success) {
721
- throw new Error(`Falha no pull: ${pullResult.error}`);
722
- }
723
- return {
724
- success: true,
725
- action: 'pull',
726
- message: `Pull do remoto executado com sucesso`,
727
- data: {
728
- remote: 'origin',
729
- branch: branch || 'current',
730
- pullOutput: pullResult.output,
731
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0'
732
- }
733
- };
734
- }
735
- catch (error) {
736
- return {
737
- success: false,
738
- action: 'pull',
739
- message: 'Erro ao executar pull',
740
- error: error instanceof Error ? error.message : String(error)
741
- };
742
- }
743
- },
744
- // Action: sync - sincronização completa (pull + commit + push)
745
- async handleSync(params) {
746
- try {
747
- const repo = params.repo || (0, user_detection_js_1.extractRepoName)(params.projectPath);
748
- const { projectPath, message, branch = 'main', forcePush = false, provider: providerName } = params;
749
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
750
- // Verificar se é um repositório Git
751
- const isGitRepo = await gitOps.isGitRepository();
752
- if (!isGitRepo) {
753
- throw new Error(`Diretório '${projectPath}' não é um repositório Git válido`);
754
- }
755
- const syncResults = {
756
- pull: { success: false, output: '', error: '' },
757
- commit: { success: false, output: '', error: '', created: false },
758
- push: { success: false, output: '', error: '' }
759
- };
760
- // 1. Pull do remoto
761
- try {
762
- const pullResult = await gitOps.pull('origin', branch);
763
- syncResults.pull = {
764
- success: pullResult.success,
765
- output: pullResult.output,
766
- error: pullResult.error || ''
767
- };
768
- }
769
- catch (pullErr) {
770
- syncResults.pull.error = pullErr instanceof Error ? pullErr.message : String(pullErr);
771
- }
772
- // 2. Verificar se há mudanças após pull
773
- const statusResult = await gitOps.status({ porcelain: true });
774
- const hasChanges = statusResult.success && statusResult.output.trim().length > 0;
775
- if (hasChanges) {
776
- // Fazer commit das mudanças
777
- const addResult = await gitOps.addFiles(['.']);
778
- if (addResult.success) {
779
- const commitResult = await gitOps.commit(message);
780
- syncResults.commit = {
781
- success: commitResult.success,
782
- output: commitResult.output,
783
- error: commitResult.error || '',
784
- created: commitResult.success
785
- };
786
- }
787
- else {
788
- syncResults.commit.error = `Falha ao adicionar arquivos: ${addResult.error}`;
789
- }
790
- }
791
- // 3. Push se commit foi criado
792
- if (syncResults.commit.created) {
793
- try {
794
- const pushOptions = {};
795
- if (forcePush)
796
- pushOptions.force = true;
797
- const pushResult = await gitOps.push('origin', branch, pushOptions);
798
- syncResults.push = {
799
- success: pushResult.success,
800
- output: pushResult.output,
801
- error: pushResult.error || ''
802
- };
803
- }
804
- catch (pushErr) {
805
- syncResults.push.error = pushErr instanceof Error ? pushErr.message : String(pushErr);
806
- }
807
- }
808
- const overallSuccess = syncResults.pull.success && (!hasChanges || syncResults.commit.success);
809
- return {
810
- success: overallSuccess,
811
- action: 'sync',
812
- message: `Sincronização ${overallSuccess ? 'concluída' : 'com problemas'}`,
813
- data: {
814
- repo,
815
- branch,
816
- provider: providerName,
817
- syncResults,
818
- hasChanges,
819
- implementation: 'REAL_GIT_OPERATIONS_v2.38.0',
820
- summary: {
821
- pullSuccessful: syncResults.pull.success,
822
- commitCreated: syncResults.commit.created,
823
- pushSuccessful: syncResults.push.success
824
- }
825
- }
826
- };
827
- }
828
- catch (error) {
829
- return {
830
- success: false,
831
- action: 'sync',
832
- message: 'Erro na sincronização completa',
833
- error: error instanceof Error ? error.message : String(error)
834
- };
835
- }
836
- },
837
- // Helper method para agrupar arquivos por tipo
838
- async groupFilesByType(projectPath) {
839
- const gitOps = new git_operations_js_1.GitOperations(projectPath);
840
- const statusResult = await gitOps.status({ porcelain: true });
841
- if (!statusResult.success) {
842
- return {};
843
- }
844
- const lines = statusResult.output.trim().split('\n').filter(line => line.trim());
845
- const fileGroups = {
846
- 'config': [],
847
- 'source': [],
848
- 'documentation': [],
849
- 'assets': [],
850
- 'other': []
851
- };
852
- for (const line of lines) {
853
- // Extrair nome do arquivo (remover status indicators)
854
- const fileName = line.substring(3).trim();
855
- if (fileName.includes('package.json') || fileName.includes('.config.') ||
856
- fileName.includes('tsconfig') || fileName.includes('.env')) {
857
- fileGroups.config.push(fileName);
858
- }
859
- else if (fileName.endsWith('.ts') || fileName.endsWith('.js') ||
860
- fileName.endsWith('.py') || fileName.endsWith('.java')) {
861
- fileGroups.source.push(fileName);
862
- }
863
- else if (fileName.endsWith('.md') || fileName.endsWith('.txt') ||
864
- fileName.includes('README') || fileName.includes('LICENSE')) {
865
- fileGroups.documentation.push(fileName);
866
- }
867
- else if (fileName.endsWith('.png') || fileName.endsWith('.jpg') ||
868
- fileName.endsWith('.svg') || fileName.endsWith('.css')) {
869
- fileGroups.assets.push(fileName);
870
- }
871
- else {
872
- fileGroups.other.push(fileName);
873
- }
874
- }
875
- return fileGroups;
876
- }
877
- };
878
- //# sourceMappingURL=git-update-project.js.map