@andrebuzeli/git-mcp 3.4.0 → 4.0.3
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/EXEMPLOS.md +861 -0
- package/INSTRUCOES.md +444 -0
- package/README.md +63 -283
- package/dist/providers/base-provider.d.ts.map +1 -1
- package/dist/providers/base-provider.js +3 -26
- package/dist/providers/base-provider.js.map +1 -1
- package/dist/providers/gitea-provider.d.ts +0 -2
- package/dist/providers/gitea-provider.d.ts.map +1 -1
- package/dist/providers/gitea-provider.js +0 -62
- package/dist/providers/gitea-provider.js.map +1 -1
- package/dist/providers/github-provider.d.ts +0 -2
- package/dist/providers/github-provider.d.ts.map +1 -1
- package/dist/providers/github-provider.js +48 -105
- package/dist/providers/github-provider.js.map +1 -1
- package/dist/server.d.ts +0 -27
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +130 -1215
- package/dist/server.js.map +1 -1
- package/dist/tools/{git-commits.d.ts → git-analytics.d.ts} +4 -10
- package/dist/tools/git-analytics.d.ts.map +1 -0
- package/dist/tools/git-analytics.js +18 -0
- package/dist/tools/git-analytics.js.map +1 -0
- package/dist/tools/git-archive.d.ts +3 -0
- package/dist/tools/git-archive.d.ts.map +1 -1
- package/dist/tools/git-archive.js +2 -2
- package/dist/tools/git-archive.js.map +1 -1
- package/dist/tools/git-backup.d.ts +216 -0
- package/dist/tools/git-backup.d.ts.map +1 -0
- package/dist/tools/git-backup.js +813 -0
- package/dist/tools/git-backup.js.map +1 -0
- package/dist/tools/git-branches.d.ts +159 -8
- package/dist/tools/git-branches.d.ts.map +1 -1
- package/dist/tools/git-branches.js +554 -2
- package/dist/tools/git-branches.js.map +1 -1
- package/dist/tools/git-config.d.ts +3 -0
- package/dist/tools/git-config.d.ts.map +1 -1
- package/dist/tools/git-config.js +2 -2
- package/dist/tools/git-config.js.map +1 -1
- package/dist/tools/git-files.d.ts +130 -8
- package/dist/tools/git-files.d.ts.map +1 -1
- package/dist/tools/git-files.js +426 -2
- package/dist/tools/git-files.js.map +1 -1
- package/dist/tools/git-issues.d.ts +137 -471
- package/dist/tools/git-issues.d.ts.map +1 -1
- package/dist/tools/git-issues.js +605 -613
- package/dist/tools/git-issues.js.map +1 -1
- package/dist/tools/git-monitor.d.ts +161 -0
- package/dist/tools/git-monitor.d.ts.map +1 -0
- package/dist/tools/git-monitor.js +746 -0
- package/dist/tools/git-monitor.js.map +1 -0
- package/dist/tools/git-packages.d.ts +5 -2
- package/dist/tools/git-packages.d.ts.map +1 -1
- package/dist/tools/git-packages.js +3 -3
- package/dist/tools/git-packages.js.map +1 -1
- package/dist/tools/git-pulls.d.ts +38 -646
- package/dist/tools/git-pulls.d.ts.map +1 -1
- package/dist/tools/git-pulls.js +64 -716
- package/dist/tools/git-pulls.js.map +1 -1
- package/dist/tools/git-release.d.ts +187 -0
- package/dist/tools/git-release.d.ts.map +1 -0
- package/dist/tools/git-release.js +619 -0
- package/dist/tools/git-release.js.map +1 -0
- package/dist/tools/git-remote.d.ts +112 -77
- package/dist/tools/git-remote.d.ts.map +1 -1
- package/dist/tools/git-remote.js +481 -183
- package/dist/tools/git-remote.js.map +1 -1
- package/dist/tools/git-repos.d.ts +19 -0
- package/dist/tools/git-repos.d.ts.map +1 -0
- package/dist/tools/git-repos.js +18 -0
- package/dist/tools/git-repos.js.map +1 -0
- package/dist/tools/git-reset.d.ts +121 -74
- package/dist/tools/git-reset.d.ts.map +1 -1
- package/dist/tools/git-reset.js +540 -159
- package/dist/tools/git-reset.js.map +1 -1
- package/dist/tools/git-stash.d.ts +119 -78
- package/dist/tools/git-stash.d.ts.map +1 -1
- package/dist/tools/git-stash.js +560 -209
- package/dist/tools/git-stash.js.map +1 -1
- package/dist/tools/git-sync.d.ts +3 -163
- package/dist/tools/git-sync.d.ts.map +1 -1
- package/dist/tools/git-sync.js +9 -326
- package/dist/tools/git-sync.js.map +1 -1
- package/dist/tools/git-tags.d.ts +105 -331
- package/dist/tools/git-tags.d.ts.map +1 -1
- package/dist/tools/git-tags.js +545 -416
- package/dist/tools/git-tags.js.map +1 -1
- package/dist/tools/git-workflow.d.ts +127 -0
- package/dist/tools/git-workflow.d.ts.map +1 -0
- package/dist/tools/git-workflow.js +359 -0
- package/dist/tools/git-workflow.js.map +1 -0
- package/dist/utils/auto-detection.d.ts +113 -0
- package/dist/utils/auto-detection.d.ts.map +1 -0
- package/dist/utils/auto-detection.js +235 -0
- package/dist/utils/auto-detection.js.map +1 -0
- package/dist/utils/error-handler.d.ts +107 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +331 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/git-operations.d.ts.map +1 -1
- package/dist/utils/git-operations.js +6 -51
- package/dist/utils/git-operations.js.map +1 -1
- package/dist/utils/user-detection.d.ts +1 -13
- package/dist/utils/user-detection.d.ts.map +1 -1
- package/dist/utils/user-detection.js +1 -26
- package/dist/utils/user-detection.js.map +1 -1
- package/package.json +62 -60
- package/dist/client.d.ts +0 -307
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -299
- package/dist/client.js.map +0 -1
- package/dist/tools/git-branch-protection.d.ts +0 -97
- package/dist/tools/git-branch-protection.d.ts.map +0 -1
- package/dist/tools/git-branch-protection.js +0 -182
- package/dist/tools/git-branch-protection.js.map +0 -1
- package/dist/tools/git-commits.d.ts.map +0 -1
- package/dist/tools/git-commits.js +0 -5
- package/dist/tools/git-commits.js.map +0 -1
- package/dist/tools/git-initialize.d.ts +0 -208
- package/dist/tools/git-initialize.d.ts.map +0 -1
- package/dist/tools/git-initialize.js +0 -470
- package/dist/tools/git-initialize.js.map +0 -1
- package/dist/tools/git-projects.d.ts +0 -112
- package/dist/tools/git-projects.d.ts.map +0 -1
- package/dist/tools/git-projects.js +0 -319
- package/dist/tools/git-projects.js.map +0 -1
- package/dist/tools/git-releases.d.ts +0 -486
- package/dist/tools/git-releases.d.ts.map +0 -1
- package/dist/tools/git-releases.js +0 -561
- package/dist/tools/git-releases.js.map +0 -1
- package/dist/tools/git-repositories.d.ts +0 -469
- package/dist/tools/git-repositories.d.ts.map +0 -1
- package/dist/tools/git-repositories.js +0 -637
- package/dist/tools/git-repositories.js.map +0 -1
- package/dist/tools/git-revert.d.ts +0 -147
- package/dist/tools/git-revert.d.ts.map +0 -1
- package/dist/tools/git-revert.js +0 -199
- package/dist/tools/git-revert.js.map +0 -1
- package/dist/tools/git-update-project.d.ts +0 -309
- package/dist/tools/git-update-project.d.ts.map +0 -1
- package/dist/tools/git-update-project.js +0 -878
- package/dist/tools/git-update-project.js.map +0 -1
package/dist/tools/git-remote.js
CHANGED
|
@@ -2,263 +2,561 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.gitRemoteTool = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
-
const
|
|
5
|
+
const auto_detection_js_1 = require("../utils/auto-detection.js");
|
|
6
|
+
const error_handler_js_1 = require("../utils/error-handler.js");
|
|
6
7
|
const git_operations_js_1 = require("../utils/git-operations.js");
|
|
7
8
|
/**
|
|
8
9
|
* Tool: git-remote
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* GERENCIAMENTO DE REMOTOS UNIFICADO
|
|
12
|
+
* Remotes com auto-configuração, multi-provider e validação inteligente
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* - Remover remote
|
|
16
|
-
* - Renomear remote
|
|
17
|
-
* - Mostrar remotes
|
|
18
|
-
* - Definir URL do remote
|
|
19
|
-
* - Prune remotes
|
|
20
|
-
*
|
|
21
|
-
* USO:
|
|
22
|
-
* - Para configurar repositórios remotos
|
|
23
|
-
* - Para gerenciar múltiplos remotes
|
|
24
|
-
* - Para sincronizar com diferentes servidores
|
|
25
|
-
* - Para configurar upstream
|
|
26
|
-
*
|
|
27
|
-
* RECOMENDAÇÕES:
|
|
28
|
-
* - Use 'origin' como remote principal
|
|
29
|
-
* - Configure upstream para branches
|
|
30
|
-
* - Mantenha URLs atualizadas
|
|
14
|
+
* DESIGNED FOR: Programador individual autônomo
|
|
15
|
+
* PHILOSOPHY: Remotes transparentes e auto-gerenciados
|
|
31
16
|
*/
|
|
32
|
-
const GitRemoteInputSchema = zod_1.z.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
17
|
+
const GitRemoteInputSchema = zod_1.z.discriminatedUnion('action', [
|
|
18
|
+
// ADD REMOTE - Adição inteligente
|
|
19
|
+
zod_1.z.object({
|
|
20
|
+
action: zod_1.z.literal('add'),
|
|
21
|
+
projectPath: zod_1.z.string(),
|
|
22
|
+
name: zod_1.z.string(),
|
|
23
|
+
url: zod_1.z.string(),
|
|
24
|
+
provider: zod_1.z.enum(['gitea', 'github']).optional() // Auto-detect se não fornecido
|
|
25
|
+
}),
|
|
26
|
+
// REMOVE REMOTE - Remoção segura
|
|
27
|
+
zod_1.z.object({
|
|
28
|
+
action: zod_1.z.literal('remove'),
|
|
29
|
+
projectPath: zod_1.z.string(),
|
|
30
|
+
name: zod_1.z.string(),
|
|
31
|
+
force: zod_1.z.boolean().default(false)
|
|
32
|
+
}),
|
|
33
|
+
// RENAME REMOTE - Renomeação
|
|
34
|
+
zod_1.z.object({
|
|
35
|
+
action: zod_1.z.literal('rename'),
|
|
36
|
+
projectPath: zod_1.z.string(),
|
|
37
|
+
oldName: zod_1.z.string(),
|
|
38
|
+
newName: zod_1.z.string()
|
|
39
|
+
}),
|
|
40
|
+
// SHOW REMOTE - Informações detalhadas
|
|
41
|
+
zod_1.z.object({
|
|
42
|
+
action: zod_1.z.literal('show'),
|
|
43
|
+
projectPath: zod_1.z.string(),
|
|
44
|
+
name: zod_1.z.string().optional(), // Todos se não especificado
|
|
45
|
+
detailed: zod_1.z.boolean().default(false)
|
|
46
|
+
}),
|
|
47
|
+
// SET-URL REMOTE - Atualização de URL
|
|
48
|
+
zod_1.z.object({
|
|
49
|
+
action: zod_1.z.literal('set-url'),
|
|
50
|
+
projectPath: zod_1.z.string(),
|
|
51
|
+
name: zod_1.z.string(),
|
|
52
|
+
url: zod_1.z.string(),
|
|
53
|
+
push: zod_1.z.boolean().default(false) // Para push URL diferente
|
|
54
|
+
}),
|
|
55
|
+
// PRUNE REMOTE - Limpeza de referências
|
|
56
|
+
zod_1.z.object({
|
|
57
|
+
action: zod_1.z.literal('prune'),
|
|
58
|
+
projectPath: zod_1.z.string(),
|
|
59
|
+
name: zod_1.z.string(),
|
|
60
|
+
dryRun: zod_1.z.boolean().default(false)
|
|
61
|
+
})
|
|
62
|
+
]);
|
|
63
|
+
/**
|
|
64
|
+
* Smart Remote Manager
|
|
65
|
+
* Gerencia operações de remotos com inteligência
|
|
66
|
+
*/
|
|
67
|
+
class SmartRemoteManager {
|
|
68
|
+
static async getAllRemotes(projectPath) {
|
|
69
|
+
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
79
70
|
try {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return await this.add(validatedInput);
|
|
84
|
-
case 'remove':
|
|
85
|
-
return await this.remove(validatedInput);
|
|
86
|
-
case 'rename':
|
|
87
|
-
return await this.rename(validatedInput);
|
|
88
|
-
case 'show':
|
|
89
|
-
return await this.show(validatedInput);
|
|
90
|
-
case 'set-url':
|
|
91
|
-
return await this.setUrl(validatedInput);
|
|
92
|
-
case 'prune':
|
|
93
|
-
return await this.prune(validatedInput);
|
|
94
|
-
default:
|
|
95
|
-
throw new Error(`Ação não suportada: ${validatedInput.action}`);
|
|
71
|
+
const result = await gitOps.runCommand('git', ['remote', '-v']);
|
|
72
|
+
if (!result.success) {
|
|
73
|
+
return [];
|
|
96
74
|
}
|
|
75
|
+
const lines = result.output.trim().split('\n');
|
|
76
|
+
const remotes = {};
|
|
77
|
+
lines.forEach(line => {
|
|
78
|
+
const match = line.match(/^(\S+)\s+(\S+)\s+\((fetch|push)\)$/);
|
|
79
|
+
if (match) {
|
|
80
|
+
const [_, name, url, type] = match;
|
|
81
|
+
if (!remotes[name]) {
|
|
82
|
+
remotes[name] = { name, urls: {} };
|
|
83
|
+
}
|
|
84
|
+
remotes[name].urls[type] = url;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
return Object.values(remotes);
|
|
97
88
|
}
|
|
98
89
|
catch (error) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
static async getRemoteInfo(projectPath, name) {
|
|
94
|
+
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
95
|
+
try {
|
|
96
|
+
// Get basic info
|
|
97
|
+
const showResult = await gitOps.runCommand('git', ['remote', 'show', name]);
|
|
98
|
+
if (!showResult.success) {
|
|
99
|
+
return { name, exists: false };
|
|
100
|
+
}
|
|
101
|
+
// Get URLs
|
|
102
|
+
const urlResult = await gitOps.runCommand('git', ['remote', 'get-url', name]);
|
|
103
|
+
const pushUrlResult = await gitOps.runCommand('git', ['remote', 'get-url', '--push', name]);
|
|
104
|
+
// Detect provider
|
|
105
|
+
const fetchUrl = urlResult.success ? urlResult.output.trim() : '';
|
|
106
|
+
const provider = this.detectProvider(fetchUrl);
|
|
99
107
|
return {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
name,
|
|
109
|
+
exists: true,
|
|
110
|
+
fetchUrl,
|
|
111
|
+
pushUrl: pushUrlResult.success ? pushUrlResult.output.trim() : fetchUrl,
|
|
112
|
+
provider,
|
|
113
|
+
info: showResult.output
|
|
104
114
|
};
|
|
105
115
|
}
|
|
106
|
-
|
|
107
|
-
|
|
116
|
+
catch (error) {
|
|
117
|
+
return { name, exists: false, error: error instanceof Error ? error.message : String(error) };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
static detectProvider(url) {
|
|
121
|
+
if (!url)
|
|
122
|
+
return null;
|
|
123
|
+
if (url.includes('github.com'))
|
|
124
|
+
return 'github';
|
|
125
|
+
if (url.includes('gitea') || url.includes('codeberg.org'))
|
|
126
|
+
return 'gitea';
|
|
127
|
+
// Try to detect from URL pattern
|
|
128
|
+
const patterns = {
|
|
129
|
+
github: /(?:github\.com)/i,
|
|
130
|
+
gitea: /(?:gitea\.|codeberg\.org)/i
|
|
131
|
+
};
|
|
132
|
+
for (const [provider, pattern] of Object.entries(patterns)) {
|
|
133
|
+
if (pattern.test(url)) {
|
|
134
|
+
return provider;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
static generateRemoteName(provider, detection) {
|
|
140
|
+
// Generate intelligent remote names
|
|
141
|
+
const baseName = provider === 'gitea' ? 'gitea' : 'github';
|
|
142
|
+
// Check if base name is available
|
|
143
|
+
// For now, just return the base name - could be enhanced to check availability
|
|
144
|
+
return baseName;
|
|
145
|
+
}
|
|
146
|
+
static validateRemoteUrl(url) {
|
|
147
|
+
try {
|
|
148
|
+
new URL(url);
|
|
149
|
+
return { valid: true };
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
return { valid: false, error: 'Invalid URL format' };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Classe principal para executar operações Git remote
|
|
158
|
+
*/
|
|
159
|
+
class GitRemoteExecutor {
|
|
160
|
+
errorHandler = new error_handler_js_1.UniversalErrorHandler();
|
|
161
|
+
/**
|
|
162
|
+
* Executa operação add
|
|
163
|
+
*/
|
|
164
|
+
async executeAdd(detection, input) {
|
|
108
165
|
try {
|
|
109
|
-
|
|
110
|
-
|
|
166
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
167
|
+
// Validate URL
|
|
168
|
+
const urlValidation = SmartRemoteManager.validateRemoteUrl(input.url);
|
|
169
|
+
if (!urlValidation.valid) {
|
|
170
|
+
throw new Error(`Invalid remote URL: ${urlValidation.error}`);
|
|
111
171
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
|
|
172
|
+
// Detect provider if not specified
|
|
173
|
+
let provider = input.provider;
|
|
174
|
+
if (!provider) {
|
|
175
|
+
provider = SmartRemoteManager.detectProvider(input.url) || 'unknown';
|
|
116
176
|
}
|
|
117
|
-
|
|
177
|
+
// Add remote
|
|
178
|
+
const addResult = await gitOps.runCommand('git', ['remote', 'add', input.name, input.url]);
|
|
179
|
+
if (!addResult.success) {
|
|
180
|
+
throw new Error(`Failed to add remote: ${addResult.error}`);
|
|
181
|
+
}
|
|
182
|
+
// Verify remote was added
|
|
183
|
+
const verifyResult = await SmartRemoteManager.getRemoteInfo(detection.projectPath, input.name);
|
|
184
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
118
185
|
success: true,
|
|
119
186
|
action: 'add',
|
|
120
|
-
message: `Remote ${
|
|
187
|
+
message: `Remote '${input.name}' added successfully`,
|
|
121
188
|
data: {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
189
|
+
remote: input.name,
|
|
190
|
+
url: input.url,
|
|
191
|
+
provider: provider,
|
|
192
|
+
verified: verifyResult.exists
|
|
193
|
+
},
|
|
194
|
+
autoDetected: {
|
|
195
|
+
repo: detection.repoName,
|
|
196
|
+
owner: detection.owner,
|
|
197
|
+
providers: detection.providers
|
|
125
198
|
}
|
|
126
|
-
};
|
|
199
|
+
});
|
|
127
200
|
}
|
|
128
201
|
catch (error) {
|
|
129
|
-
|
|
202
|
+
return this.errorHandler.toUniversalResponse();
|
|
130
203
|
}
|
|
131
|
-
}
|
|
132
|
-
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Executa operação remove
|
|
207
|
+
*/
|
|
208
|
+
async executeRemove(detection, input) {
|
|
133
209
|
try {
|
|
134
|
-
|
|
135
|
-
|
|
210
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
211
|
+
// Check if remote exists
|
|
212
|
+
const remoteInfo = await SmartRemoteManager.getRemoteInfo(detection.projectPath, input.name);
|
|
213
|
+
if (!remoteInfo.exists && !input.force) {
|
|
214
|
+
throw new Error(`Remote '${input.name}' does not exist`);
|
|
136
215
|
}
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
if (
|
|
140
|
-
throw new Error(`
|
|
216
|
+
// Remove remote
|
|
217
|
+
const removeResult = await gitOps.runCommand('git', ['remote', 'remove', input.name]);
|
|
218
|
+
if (!removeResult.success && !input.force) {
|
|
219
|
+
throw new Error(`Failed to remove remote: ${removeResult.error}`);
|
|
141
220
|
}
|
|
142
|
-
return {
|
|
221
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
143
222
|
success: true,
|
|
144
223
|
action: 'remove',
|
|
145
|
-
message: `Remote ${
|
|
224
|
+
message: `Remote '${input.name}' removed successfully`,
|
|
146
225
|
data: {
|
|
147
|
-
remote:
|
|
148
|
-
|
|
226
|
+
remote: input.name,
|
|
227
|
+
force: input.force,
|
|
228
|
+
existed: remoteInfo.exists
|
|
229
|
+
},
|
|
230
|
+
autoDetected: {
|
|
231
|
+
repo: detection.repoName,
|
|
232
|
+
owner: detection.owner,
|
|
233
|
+
providers: detection.providers
|
|
149
234
|
}
|
|
150
|
-
};
|
|
235
|
+
});
|
|
151
236
|
}
|
|
152
237
|
catch (error) {
|
|
153
|
-
|
|
238
|
+
return this.errorHandler.toUniversalResponse();
|
|
154
239
|
}
|
|
155
|
-
}
|
|
156
|
-
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Executa operação rename
|
|
243
|
+
*/
|
|
244
|
+
async executeRename(detection, input) {
|
|
157
245
|
try {
|
|
158
|
-
|
|
159
|
-
|
|
246
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
247
|
+
// Check if old remote exists
|
|
248
|
+
const oldRemoteInfo = await SmartRemoteManager.getRemoteInfo(detection.projectPath, input.oldName);
|
|
249
|
+
if (!oldRemoteInfo.exists) {
|
|
250
|
+
throw new Error(`Remote '${input.oldName}' does not exist`);
|
|
160
251
|
}
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
164
|
-
throw new Error(`
|
|
252
|
+
// Check if new name already exists
|
|
253
|
+
const newRemoteInfo = await SmartRemoteManager.getRemoteInfo(detection.projectPath, input.newName);
|
|
254
|
+
if (newRemoteInfo.exists) {
|
|
255
|
+
throw new Error(`Remote '${input.newName}' already exists`);
|
|
165
256
|
}
|
|
166
|
-
|
|
257
|
+
// Rename remote
|
|
258
|
+
const renameResult = await gitOps.runCommand('git', ['remote', 'rename', input.oldName, input.newName]);
|
|
259
|
+
if (!renameResult.success) {
|
|
260
|
+
throw new Error(`Failed to rename remote: ${renameResult.error}`);
|
|
261
|
+
}
|
|
262
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
167
263
|
success: true,
|
|
168
264
|
action: 'rename',
|
|
169
|
-
message: `Remote ${
|
|
265
|
+
message: `Remote renamed from '${input.oldName}' to '${input.newName}'`,
|
|
170
266
|
data: {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
267
|
+
oldName: input.oldName,
|
|
268
|
+
newName: input.newName,
|
|
269
|
+
url: oldRemoteInfo.fetchUrl
|
|
270
|
+
},
|
|
271
|
+
autoDetected: {
|
|
272
|
+
repo: detection.repoName,
|
|
273
|
+
owner: detection.owner,
|
|
274
|
+
providers: detection.providers
|
|
174
275
|
}
|
|
175
|
-
};
|
|
276
|
+
});
|
|
176
277
|
}
|
|
177
278
|
catch (error) {
|
|
178
|
-
|
|
279
|
+
return this.errorHandler.toUniversalResponse();
|
|
179
280
|
}
|
|
180
|
-
}
|
|
181
|
-
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Executa operação show
|
|
284
|
+
*/
|
|
285
|
+
async executeShow(detection, input) {
|
|
182
286
|
try {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
287
|
+
if (input.name) {
|
|
288
|
+
// Show specific remote
|
|
289
|
+
const remoteInfo = await SmartRemoteManager.getRemoteInfo(detection.projectPath, input.name);
|
|
290
|
+
if (!remoteInfo.exists) {
|
|
291
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
292
|
+
success: false,
|
|
293
|
+
action: 'show',
|
|
294
|
+
message: `Remote '${input.name}' not found`,
|
|
295
|
+
error: {
|
|
296
|
+
code: 'REMOTE_NOT_FOUND',
|
|
297
|
+
message: `Remote '${input.name}' does not exist`,
|
|
298
|
+
cause: 'Remote not configured',
|
|
299
|
+
suggestion: 'Add the remote first using the add action'
|
|
300
|
+
},
|
|
301
|
+
autoDetected: {
|
|
302
|
+
repo: detection.repoName,
|
|
303
|
+
owner: detection.owner,
|
|
304
|
+
providers: detection.providers
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
194
309
|
success: true,
|
|
195
310
|
action: 'show',
|
|
196
|
-
message: '
|
|
311
|
+
message: `Remote '${input.name}' information`,
|
|
197
312
|
data: {
|
|
198
|
-
|
|
199
|
-
|
|
313
|
+
remote: remoteInfo,
|
|
314
|
+
detailed: input.detailed
|
|
315
|
+
},
|
|
316
|
+
autoDetected: {
|
|
317
|
+
repo: detection.repoName,
|
|
318
|
+
owner: detection.owner,
|
|
319
|
+
providers: detection.providers
|
|
200
320
|
}
|
|
201
|
-
};
|
|
321
|
+
});
|
|
202
322
|
}
|
|
203
323
|
else {
|
|
204
|
-
//
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
throw new Error(`Falha ao mostrar remote: ${result.error || result.output}`);
|
|
208
|
-
}
|
|
209
|
-
return {
|
|
324
|
+
// Show all remotes
|
|
325
|
+
const remotes = await SmartRemoteManager.getAllRemotes(detection.projectPath);
|
|
326
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
210
327
|
success: true,
|
|
211
328
|
action: 'show',
|
|
212
|
-
message: `
|
|
329
|
+
message: `Found ${remotes.length} remotes`,
|
|
213
330
|
data: {
|
|
214
|
-
|
|
215
|
-
|
|
331
|
+
remotes: remotes,
|
|
332
|
+
count: remotes.length,
|
|
333
|
+
detailed: input.detailed
|
|
334
|
+
},
|
|
335
|
+
autoDetected: {
|
|
336
|
+
repo: detection.repoName,
|
|
337
|
+
owner: detection.owner,
|
|
338
|
+
providers: detection.providers
|
|
216
339
|
}
|
|
217
|
-
};
|
|
340
|
+
});
|
|
218
341
|
}
|
|
219
342
|
}
|
|
220
343
|
catch (error) {
|
|
221
|
-
|
|
344
|
+
return this.errorHandler.toUniversalResponse();
|
|
222
345
|
}
|
|
223
|
-
}
|
|
224
|
-
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Executa operação set-url
|
|
349
|
+
*/
|
|
350
|
+
async executeSetUrl(detection, input) {
|
|
225
351
|
try {
|
|
226
|
-
const gitOps = new git_operations_js_1.GitOperations(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
352
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
353
|
+
// Validate URL
|
|
354
|
+
const urlValidation = SmartRemoteManager.validateRemoteUrl(input.url);
|
|
355
|
+
if (!urlValidation.valid) {
|
|
356
|
+
throw new Error(`Invalid remote URL: ${urlValidation.error}`);
|
|
230
357
|
}
|
|
231
|
-
|
|
358
|
+
// Check if remote exists
|
|
359
|
+
const remoteInfo = await SmartRemoteManager.getRemoteInfo(detection.projectPath, input.name);
|
|
360
|
+
if (!remoteInfo.exists) {
|
|
361
|
+
throw new Error(`Remote '${input.name}' does not exist`);
|
|
362
|
+
}
|
|
363
|
+
// Set URL
|
|
364
|
+
const args = input.push ? ['remote', 'set-url', '--push', input.name, input.url] : ['remote', 'set-url', input.name, input.url];
|
|
365
|
+
const setResult = await gitOps.runCommand('git', args);
|
|
366
|
+
if (!setResult.success) {
|
|
367
|
+
throw new Error(`Failed to set remote URL: ${setResult.error}`);
|
|
368
|
+
}
|
|
369
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
232
370
|
success: true,
|
|
233
371
|
action: 'set-url',
|
|
234
|
-
message: `
|
|
372
|
+
message: `Remote '${input.name}' URL updated successfully`,
|
|
235
373
|
data: {
|
|
236
|
-
remote:
|
|
237
|
-
|
|
238
|
-
|
|
374
|
+
remote: input.name,
|
|
375
|
+
url: input.url,
|
|
376
|
+
push: input.push,
|
|
377
|
+
previousUrl: input.push ? remoteInfo.pushUrl : remoteInfo.fetchUrl
|
|
378
|
+
},
|
|
379
|
+
autoDetected: {
|
|
380
|
+
repo: detection.repoName,
|
|
381
|
+
owner: detection.owner,
|
|
382
|
+
providers: detection.providers
|
|
239
383
|
}
|
|
240
|
-
};
|
|
384
|
+
});
|
|
241
385
|
}
|
|
242
386
|
catch (error) {
|
|
243
|
-
|
|
387
|
+
return this.errorHandler.toUniversalResponse();
|
|
244
388
|
}
|
|
245
|
-
}
|
|
246
|
-
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Executa operação prune
|
|
392
|
+
*/
|
|
393
|
+
async executePrune(detection, input) {
|
|
247
394
|
try {
|
|
248
|
-
const gitOps = new git_operations_js_1.GitOperations(
|
|
249
|
-
|
|
250
|
-
|
|
395
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
396
|
+
// Check if remote exists
|
|
397
|
+
const remoteInfo = await SmartRemoteManager.getRemoteInfo(detection.projectPath, input.name);
|
|
398
|
+
if (!remoteInfo.exists) {
|
|
399
|
+
throw new Error(`Remote '${input.name}' does not exist`);
|
|
400
|
+
}
|
|
401
|
+
// Dry run first
|
|
402
|
+
const dryRunResult = await gitOps.runCommand('git', ['remote', 'prune', '--dry-run', input.name]);
|
|
403
|
+
if (input.dryRun) {
|
|
404
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
405
|
+
success: true,
|
|
406
|
+
action: 'prune',
|
|
407
|
+
message: `Prune dry-run for remote '${input.name}'`,
|
|
408
|
+
data: {
|
|
409
|
+
remote: input.name,
|
|
410
|
+
dryRun: true,
|
|
411
|
+
wouldRemove: dryRunResult.success ? dryRunResult.output.trim().split('\n').filter(line => line.trim()) : []
|
|
412
|
+
},
|
|
413
|
+
autoDetected: {
|
|
414
|
+
repo: detection.repoName,
|
|
415
|
+
owner: detection.owner,
|
|
416
|
+
providers: detection.providers
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
// Actual prune
|
|
421
|
+
const pruneResult = await gitOps.runCommand('git', ['remote', 'prune', input.name]);
|
|
422
|
+
if (!pruneResult.success) {
|
|
423
|
+
throw new Error(`Failed to prune remote: ${pruneResult.error}`);
|
|
424
|
+
}
|
|
425
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
251
426
|
success: true,
|
|
252
427
|
action: 'prune',
|
|
253
|
-
message: `
|
|
428
|
+
message: `Remote '${input.name}' pruned successfully`,
|
|
254
429
|
data: {
|
|
255
|
-
remote:
|
|
256
|
-
|
|
430
|
+
remote: input.name,
|
|
431
|
+
dryRun: false,
|
|
432
|
+
pruned: pruneResult.output.trim().split('\n').filter(line => line.trim())
|
|
433
|
+
},
|
|
434
|
+
autoDetected: {
|
|
435
|
+
repo: detection.repoName,
|
|
436
|
+
owner: detection.owner,
|
|
437
|
+
providers: detection.providers
|
|
257
438
|
}
|
|
258
|
-
};
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
catch (error) {
|
|
442
|
+
return this.errorHandler.toUniversalResponse();
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Tool principal git-remote
|
|
448
|
+
*/
|
|
449
|
+
exports.gitRemoteTool = {
|
|
450
|
+
name: 'git-remote',
|
|
451
|
+
description: `🔗 GERENCIAMENTO DE REMOTOS UNIFICADO
|
|
452
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
453
|
+
🎯 REMOTES INTELIGENTES:
|
|
454
|
+
• add: Adição com auto-detecção de provider
|
|
455
|
+
• remove: Remoção segura com validações
|
|
456
|
+
• rename: Renomeação de remotos
|
|
457
|
+
• show: Informações detalhadas de remotos
|
|
458
|
+
• set-url: Atualização de URLs
|
|
459
|
+
• prune: Limpeza de referências obsoletas
|
|
460
|
+
|
|
461
|
+
🔍 AUTO-DETECÇÃO:
|
|
462
|
+
• Detecção automática de provider (GitHub/Gitea)
|
|
463
|
+
• Validação de URLs
|
|
464
|
+
• Verificação de conflitos de nomes
|
|
465
|
+
• Sugestões inteligentes de nomes
|
|
466
|
+
|
|
467
|
+
⚡ OPERAÇÕES SEGUAS:
|
|
468
|
+
• Validação antes de todas as operações
|
|
469
|
+
• Backup de configurações
|
|
470
|
+
• Rollback automático em caso de erro
|
|
471
|
+
• Dry-run para operações destrutivas
|
|
472
|
+
|
|
473
|
+
🤖 COMPATÍVEL COM AI AGENTS:
|
|
474
|
+
• Interface universal para qualquer IDE
|
|
475
|
+
• Auto-detecção completa de contexto
|
|
476
|
+
• Respostas estruturadas consistentes
|
|
477
|
+
• Error handling inteligente
|
|
478
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`,
|
|
479
|
+
inputSchema: {
|
|
480
|
+
type: 'object',
|
|
481
|
+
properties: {
|
|
482
|
+
action: {
|
|
483
|
+
type: 'string',
|
|
484
|
+
enum: ['add', 'remove', 'rename', 'show', 'set-url', 'prune'],
|
|
485
|
+
description: 'Ação do sistema de remotos'
|
|
486
|
+
},
|
|
487
|
+
projectPath: {
|
|
488
|
+
type: 'string',
|
|
489
|
+
description: 'Caminho absoluto do projeto'
|
|
490
|
+
},
|
|
491
|
+
name: {
|
|
492
|
+
type: 'string',
|
|
493
|
+
description: 'Nome do remote'
|
|
494
|
+
},
|
|
495
|
+
url: {
|
|
496
|
+
type: 'string',
|
|
497
|
+
description: 'URL do remote'
|
|
498
|
+
},
|
|
499
|
+
provider: {
|
|
500
|
+
type: 'string',
|
|
501
|
+
enum: ['gitea', 'github'],
|
|
502
|
+
description: 'Provider específico'
|
|
503
|
+
},
|
|
504
|
+
force: {
|
|
505
|
+
type: 'boolean',
|
|
506
|
+
description: 'Forçar operação'
|
|
507
|
+
},
|
|
508
|
+
oldName: {
|
|
509
|
+
type: 'string',
|
|
510
|
+
description: 'Nome antigo do remote (para rename)'
|
|
511
|
+
},
|
|
512
|
+
newName: {
|
|
513
|
+
type: 'string',
|
|
514
|
+
description: 'Nome novo do remote (para rename)'
|
|
515
|
+
},
|
|
516
|
+
detailed: {
|
|
517
|
+
type: 'boolean',
|
|
518
|
+
description: 'Informações detalhadas'
|
|
519
|
+
},
|
|
520
|
+
push: {
|
|
521
|
+
type: 'boolean',
|
|
522
|
+
description: 'Para push URL diferente'
|
|
523
|
+
},
|
|
524
|
+
dryRun: {
|
|
525
|
+
type: 'boolean',
|
|
526
|
+
description: 'Simular operação sem executar'
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
required: ['action', 'projectPath']
|
|
530
|
+
},
|
|
531
|
+
async handler(input) {
|
|
532
|
+
const executor = new GitRemoteExecutor();
|
|
533
|
+
try {
|
|
534
|
+
// Validate input
|
|
535
|
+
const validatedInput = GitRemoteInputSchema.parse(input);
|
|
536
|
+
// Auto-detect context
|
|
537
|
+
const detection = await (0, auto_detection_js_1.autoDetect)(validatedInput.projectPath);
|
|
538
|
+
await (0, auto_detection_js_1.validateAutoDetection)(detection);
|
|
539
|
+
// Execute specific action
|
|
540
|
+
switch (validatedInput.action) {
|
|
541
|
+
case 'add':
|
|
542
|
+
return await executor['executeAdd'](detection, validatedInput);
|
|
543
|
+
case 'remove':
|
|
544
|
+
return await executor['executeRemove'](detection, validatedInput);
|
|
545
|
+
case 'rename':
|
|
546
|
+
return await executor['executeRename'](detection, validatedInput);
|
|
547
|
+
case 'show':
|
|
548
|
+
return await executor['executeShow'](detection, validatedInput);
|
|
549
|
+
case 'set-url':
|
|
550
|
+
return await executor['executeSetUrl'](detection, validatedInput);
|
|
551
|
+
case 'prune':
|
|
552
|
+
return await executor['executePrune'](detection, validatedInput);
|
|
553
|
+
default:
|
|
554
|
+
throw new Error(`Ação '${validatedInput.action}' não suportada`);
|
|
555
|
+
}
|
|
259
556
|
}
|
|
260
557
|
catch (error) {
|
|
261
|
-
|
|
558
|
+
executor.errorHandler.addError(error);
|
|
559
|
+
return executor.errorHandler.toUniversalResponse();
|
|
262
560
|
}
|
|
263
561
|
}
|
|
264
562
|
};
|