@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.
- package/dist/config.d.ts +7 -239
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -221
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +11 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -16
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +1 -69
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +150 -711
- package/dist/server.js.map +1 -1
- package/dist/tools/git-analytics.d.ts +1 -0
- package/dist/tools/git-analytics.d.ts.map +1 -1
- package/dist/tools/git-analytics.js +18 -7
- package/dist/tools/git-analytics.js.map +1 -1
- package/dist/tools/git-archive.d.ts +2 -149
- package/dist/tools/git-archive.d.ts.map +1 -1
- package/dist/tools/git-archive.js +5 -222
- package/dist/tools/git-archive.js.map +1 -1
- package/dist/tools/git-backup.d.ts +1 -198
- package/dist/tools/git-backup.d.ts.map +1 -1
- package/dist/tools/git-backup.js +4 -805
- package/dist/tools/git-backup.js.map +1 -1
- package/dist/tools/git-branches.d.ts +1 -158
- package/dist/tools/git-branches.d.ts.map +1 -1
- package/dist/tools/git-branches.js +4 -539
- package/dist/tools/git-branches.js.map +1 -1
- package/dist/tools/git-config.d.ts +2 -124
- package/dist/tools/git-config.d.ts.map +1 -1
- package/dist/tools/git-config.js +5 -263
- package/dist/tools/git-config.js.map +1 -1
- package/dist/tools/git-files.d.ts +2 -115
- package/dist/tools/git-files.d.ts.map +1 -1
- package/dist/tools/git-files.js +161 -407
- package/dist/tools/git-files.js.map +1 -1
- package/dist/tools/git-issues.d.ts +1 -214
- package/dist/tools/git-issues.d.ts.map +1 -1
- package/dist/tools/git-issues.js +4 -678
- package/dist/tools/git-issues.js.map +1 -1
- package/dist/tools/git-monitor.d.ts +1 -143
- package/dist/tools/git-monitor.d.ts.map +1 -1
- package/dist/tools/git-monitor.js +4 -738
- package/dist/tools/git-monitor.js.map +1 -1
- package/dist/tools/git-packages.d.ts +2 -91
- package/dist/tools/git-packages.d.ts.map +1 -1
- package/dist/tools/git-packages.js +5 -258
- package/dist/tools/git-packages.js.map +1 -1
- package/dist/tools/git-pulls.d.ts +1 -63
- package/dist/tools/git-pulls.d.ts.map +1 -1
- package/dist/tools/git-pulls.js +4 -77
- package/dist/tools/git-pulls.js.map +1 -1
- package/dist/tools/git-release.d.ts +1 -169
- package/dist/tools/git-release.d.ts.map +1 -1
- package/dist/tools/git-release.js +4 -611
- package/dist/tools/git-release.js.map +1 -1
- package/dist/tools/git-remote.d.ts +1 -153
- package/dist/tools/git-remote.d.ts.map +1 -1
- package/dist/tools/git-remote.js +4 -555
- package/dist/tools/git-remote.js.map +1 -1
- package/dist/tools/git-reset.d.ts +1 -157
- package/dist/tools/git-reset.d.ts.map +1 -1
- package/dist/tools/git-reset.js +4 -597
- package/dist/tools/git-reset.js.map +1 -1
- package/dist/tools/git-stash.d.ts +1 -161
- package/dist/tools/git-stash.d.ts.map +1 -1
- package/dist/tools/git-stash.js +4 -640
- package/dist/tools/git-stash.js.map +1 -1
- package/dist/tools/git-sync.d.ts +1 -0
- package/dist/tools/git-sync.d.ts.map +1 -1
- package/dist/tools/git-sync.js +13 -7
- package/dist/tools/git-sync.js.map +1 -1
- package/dist/tools/git-tags.d.ts +1 -162
- package/dist/tools/git-tags.d.ts.map +1 -1
- package/dist/tools/git-tags.js +4 -549
- package/dist/tools/git-tags.js.map +1 -1
- package/dist/tools/git-workflow.d.ts +3 -96
- package/dist/tools/git-workflow.d.ts.map +1 -1
- package/dist/tools/git-workflow.js +287 -314
- package/dist/tools/git-workflow.js.map +1 -1
- package/package.json +3 -3
- package/dist/server-minimal.d.ts +0 -8
- package/dist/server-minimal.d.ts.map +0 -1
- package/dist/server-minimal.js +0 -218
- 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
|
|
5
|
+
const terminal_controller_js_1 = require("../utils/terminal-controller.js");
|
|
9
6
|
/**
|
|
10
|
-
* Tool
|
|
7
|
+
* Git Workflow Tool - Ferramenta Principal
|
|
11
8
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
17
|
-
* -
|
|
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
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
action:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
message:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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 já é 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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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:
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
331
|
-
|
|
292
|
+
const detection = (0, auto_detection_js_1.autoDetect)(projectPath);
|
|
293
|
+
let result;
|
|
294
|
+
switch (action) {
|
|
332
295
|
case 'init':
|
|
333
|
-
|
|
296
|
+
result = await handleInit(projectPath, detection);
|
|
297
|
+
break;
|
|
334
298
|
case 'commit':
|
|
335
|
-
|
|
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
|
-
|
|
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
|
-
|
|
311
|
+
result = await handleStatus(projectPath, detection);
|
|
312
|
+
break;
|
|
340
313
|
case 'backup':
|
|
341
|
-
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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
|
};
|