@andrebuzeli/git-mcp 2.27.3 → 2.28.0
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/client.d.ts +306 -306
- package/dist/client.js +298 -298
- package/dist/config.d.ts +310 -310
- package/dist/config.js +392 -392
- package/dist/index.d.ts +22 -22
- package/dist/index.js +89 -89
- package/dist/providers/base-provider.d.ts +160 -156
- package/dist/providers/base-provider.d.ts.map +1 -1
- package/dist/providers/base-provider.js +274 -260
- package/dist/providers/base-provider.js.map +1 -1
- package/dist/providers/error-handler.d.ts +50 -50
- package/dist/providers/error-handler.js +175 -175
- package/dist/providers/gitea-provider.d.ts +97 -97
- package/dist/providers/gitea-provider.js +1001 -1001
- package/dist/providers/github-provider.d.ts +104 -104
- package/dist/providers/github-provider.js +1234 -1234
- package/dist/providers/index.d.ts +12 -12
- package/dist/providers/index.js +40 -40
- package/dist/providers/provider-factory.d.ts +74 -74
- package/dist/providers/provider-factory.js +311 -311
- package/dist/providers/types.d.ts +318 -298
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +6 -6
- package/dist/server.d.ts +76 -76
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +306 -357
- package/dist/server.js.map +1 -1
- package/dist/tools/gh-actions.d.ts +252 -252
- package/dist/tools/gh-actions.js +389 -389
- package/dist/tools/gh-analytics.d.ts +263 -263
- package/dist/tools/gh-analytics.js +401 -401
- package/dist/tools/gh-code-review.d.ts +304 -304
- package/dist/tools/gh-code-review.js +512 -512
- package/dist/tools/gh-codespaces.d.ts +138 -138
- package/dist/tools/gh-codespaces.js +282 -282
- package/dist/tools/gh-deployments.d.ts +300 -300
- package/dist/tools/gh-deployments.js +367 -367
- package/dist/tools/gh-gists.d.ts +174 -174
- package/dist/tools/gh-gists.js +321 -321
- package/dist/tools/gh-projects.d.ts +205 -205
- package/dist/tools/gh-projects.js +358 -358
- package/dist/tools/gh-security.d.ts +274 -274
- package/dist/tools/gh-security.js +395 -395
- package/dist/tools/gh-sync.d.ts +213 -213
- package/dist/tools/gh-sync.js +378 -378
- package/dist/tools/gh-workflows.d.ts +290 -290
- package/dist/tools/gh-workflows.js +432 -432
- package/dist/tools/git-archive.d.ts +165 -165
- package/dist/tools/git-archive.js +233 -233
- package/dist/tools/git-branches.d.ts +430 -430
- package/dist/tools/git-branches.d.ts.map +1 -1
- package/dist/tools/git-branches.js +627 -530
- package/dist/tools/git-branches.js.map +1 -1
- package/dist/tools/git-bundle.d.ts +171 -171
- package/dist/tools/git-bundle.js +241 -241
- package/dist/tools/git-cherry-pick.d.ts +158 -158
- package/dist/tools/git-cherry-pick.js +224 -224
- package/dist/tools/git-commits.d.ts +485 -485
- package/dist/tools/git-commits.d.ts.map +1 -1
- package/dist/tools/git-commits.js +735 -625
- package/dist/tools/git-commits.js.map +1 -1
- package/dist/tools/git-config.d.ts +140 -140
- package/dist/tools/git-config.js +268 -268
- package/dist/tools/git-files.d.ts +486 -486
- package/dist/tools/git-files.js +607 -607
- package/dist/tools/git-issues.d.ts +571 -571
- package/dist/tools/git-issues.d.ts.map +1 -1
- package/dist/tools/git-issues.js +740 -693
- package/dist/tools/git-issues.js.map +1 -1
- package/dist/tools/git-pulls.d.ts +694 -694
- package/dist/tools/git-pulls.js +732 -732
- package/dist/tools/git-rebase.d.ts +137 -137
- package/dist/tools/git-rebase.js +213 -213
- package/dist/tools/git-releases.d.ts +487 -487
- package/dist/tools/git-releases.js +557 -557
- package/dist/tools/git-remote.d.ts +138 -138
- package/dist/tools/git-remote.js +274 -274
- package/dist/tools/git-repositories.d.ts +483 -483
- package/dist/tools/git-repositories.js +640 -640
- package/dist/tools/git-reset.d.ts +130 -130
- package/dist/tools/git-reset.js +223 -223
- package/dist/tools/git-revert.d.ts +149 -149
- package/dist/tools/git-revert.js +198 -198
- package/dist/tools/git-stash.d.ts +140 -140
- package/dist/tools/git-stash.js +269 -269
- package/dist/tools/git-submodule.d.ts +152 -152
- package/dist/tools/git-submodule.js +289 -289
- package/dist/tools/git-sync.d.ts +178 -166
- package/dist/tools/git-sync.d.ts.map +1 -1
- package/dist/tools/git-sync.js +312 -117
- package/dist/tools/git-sync.js.map +1 -1
- package/dist/tools/git-tags.d.ts +411 -411
- package/dist/tools/git-tags.js +485 -485
- package/dist/tools/git-webhooks.d.ts +470 -482
- package/dist/tools/git-webhooks.d.ts.map +1 -1
- package/dist/tools/git-webhooks.js +543 -555
- package/dist/tools/git-webhooks.js.map +1 -1
- package/dist/tools/git-worktree.d.ts +159 -159
- package/dist/tools/git-worktree.js +269 -269
- package/dist/tools/repositories.d.ts +405 -405
- package/dist/tools/repositories.js +569 -569
- package/dist/tools/users.d.ts +372 -372
- package/dist/tools/users.js +499 -499
- package/dist/tools/validator.d.ts +170 -170
- package/dist/tools/validator.js +194 -194
- package/dist/tools/version-control.d.ts +136 -136
- package/dist/tools/version-control.js +164 -164
- package/dist/utils/terminal-controller.d.ts +80 -80
- package/dist/utils/terminal-controller.js +345 -345
- package/dist/utils/user-detection.d.ts +24 -24
- package/dist/utils/user-detection.js +53 -53
- package/package.json +59 -59
|
@@ -1,570 +1,570 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.repositoriesTool = 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 terminal_controller_js_1 = require("../utils/terminal-controller.js");
|
|
8
|
-
/**
|
|
9
|
-
* Tool: repositories
|
|
10
|
-
*
|
|
11
|
-
* DESCRIÇÃO:
|
|
12
|
-
* Gerenciamento completo de repositórios Gitea com múltiplas ações
|
|
13
|
-
*
|
|
14
|
-
* FUNCIONALIDADES:
|
|
15
|
-
* - Criação de repositórios
|
|
16
|
-
* - Listagem e busca
|
|
17
|
-
* - Atualização e configuração
|
|
18
|
-
* - Fork e clonagem
|
|
19
|
-
* - Exclusão e arquivamento
|
|
20
|
-
*
|
|
21
|
-
* USO:
|
|
22
|
-
* - Para gerenciar repositórios de projetos
|
|
23
|
-
* - Para automatizar criação de repositórios
|
|
24
|
-
* - Para backup e migração
|
|
25
|
-
* - Para organização de código
|
|
26
|
-
*
|
|
27
|
-
* RECOMENDAÇÕES:
|
|
28
|
-
* - Use nomes descritivos para repositórios
|
|
29
|
-
* - Configure visibilidade adequada
|
|
30
|
-
* - Mantenha descrições atualizadas
|
|
31
|
-
* - Use templates quando possível
|
|
32
|
-
*/
|
|
33
|
-
/**
|
|
34
|
-
* Schema de validação para entrada da tool repositories
|
|
35
|
-
*
|
|
36
|
-
* VALIDAÇÕES:
|
|
37
|
-
* - action: Ação obrigatória (create, list, get, update, delete, fork, search)
|
|
38
|
-
* - provider: Opcional (usa padrão se não especificado)
|
|
39
|
-
* - Parâmetros específicos por ação
|
|
40
|
-
* - Validação de tipos e formatos
|
|
41
|
-
*
|
|
42
|
-
* RECOMENDAÇÕES:
|
|
43
|
-
* - Sempre valide entrada antes de usar
|
|
44
|
-
* - Use parâmetros opcionais adequadamente
|
|
45
|
-
* - Documente parâmetros obrigatórios
|
|
46
|
-
*/
|
|
47
|
-
const RepositoriesInputSchema = zod_1.z.object({
|
|
48
|
-
action: zod_1.z.enum(['create', 'list', 'get', 'update', 'delete', 'fork', 'search', 'init', 'clone']),
|
|
49
|
-
// Parâmetros comuns
|
|
50
|
-
// owner: obtido automaticamente do provider,
|
|
51
|
-
repo: zod_1.z.string(),
|
|
52
|
-
provider: zod_1.z.enum(['gitea', 'github']).describe('Provider to use (gitea or github)'),
|
|
53
|
-
projectPath: zod_1.z.string().describe('Local project path for git operations'),
|
|
54
|
-
name: zod_1.z.string().optional(),
|
|
55
|
-
description: zod_1.z.string().optional(),
|
|
56
|
-
private: zod_1.z.boolean().optional(),
|
|
57
|
-
auto_init: zod_1.z.boolean().optional(),
|
|
58
|
-
gitignores: zod_1.z.string().optional(),
|
|
59
|
-
license: zod_1.z.string().optional(),
|
|
60
|
-
readme: zod_1.z.string().optional(),
|
|
61
|
-
default_branch: zod_1.z.string().optional(),
|
|
62
|
-
// Para list
|
|
63
|
-
username: zod_1.z.string().optional(),
|
|
64
|
-
page: zod_1.z.number().min(1).optional(),
|
|
65
|
-
limit: zod_1.z.number().min(1).max(100).optional(),
|
|
66
|
-
// Para update
|
|
67
|
-
new_name: zod_1.z.string().optional(),
|
|
68
|
-
new_description: zod_1.z.string().optional(),
|
|
69
|
-
new_private: zod_1.z.boolean().optional(),
|
|
70
|
-
archived: zod_1.z.boolean().optional(),
|
|
71
|
-
// Para fork
|
|
72
|
-
organization: zod_1.z.string().optional(),
|
|
73
|
-
// Para search
|
|
74
|
-
query: zod_1.z.string().optional(),
|
|
75
|
-
});
|
|
76
|
-
// Schema de saída
|
|
77
|
-
const RepositoriesResultSchema = zod_1.z.object({
|
|
78
|
-
success: zod_1.z.boolean(),
|
|
79
|
-
action: zod_1.z.string(),
|
|
80
|
-
message: zod_1.z.string(),
|
|
81
|
-
data: zod_1.z.any().optional(),
|
|
82
|
-
error: zod_1.z.string().optional()
|
|
83
|
-
});
|
|
84
|
-
/**
|
|
85
|
-
* Tool: repositories
|
|
86
|
-
*
|
|
87
|
-
* DESCRIÇÃO:
|
|
88
|
-
* Gerenciamento completo de repositórios Gitea com múltiplas ações
|
|
89
|
-
*
|
|
90
|
-
* ACTIONS DISPONÍVEIS:
|
|
91
|
-
*
|
|
92
|
-
* 1. create - Criar novo repositório
|
|
93
|
-
* Parâmetros:
|
|
94
|
-
* - name (obrigatório): Nome do repositório
|
|
95
|
-
* - description (opcional): Descrição do repositório
|
|
96
|
-
* - private (opcional): Repositório privado (padrão: false)
|
|
97
|
-
* - auto_init (opcional): Inicializar com README (padrão: false)
|
|
98
|
-
* - gitignores (opcional): Template de .gitignore
|
|
99
|
-
* - license (opcional): Template de licença
|
|
100
|
-
* - readme (opcional): Conteúdo do README
|
|
101
|
-
* - default_branch (opcional): Branch padrão
|
|
102
|
-
*
|
|
103
|
-
* 2. list - Listar repositórios
|
|
104
|
-
* Parâmetros:
|
|
105
|
-
* - username (opcional): Usuário específico (padrão: usuário atual)
|
|
106
|
-
* - page (opcional): Página da listagem (padrão: 1)
|
|
107
|
-
* - limit (opcional): Itens por página (padrão: 30)
|
|
108
|
-
*
|
|
109
|
-
* 3. get - Obter detalhes do repositório
|
|
110
|
-
* Parâmetros:
|
|
111
|
-
* - owner (obrigatório): Proprietário do repositório
|
|
112
|
-
* - repo (obrigatório): Nome do repositório
|
|
113
|
-
*
|
|
114
|
-
* 4. update - Atualizar repositório
|
|
115
|
-
* Parâmetros:
|
|
116
|
-
* - owner (obrigatório): Proprietário do repositório
|
|
117
|
-
* - repo (obrigatório): Nome do repositório
|
|
118
|
-
* - new_name (opcional): Novo nome
|
|
119
|
-
* - new_description (opcional): Nova descrição
|
|
120
|
-
* - new_private (opcional): Nova visibilidade
|
|
121
|
-
* - archived (opcional): Status de arquivamento
|
|
122
|
-
*
|
|
123
|
-
* 5. delete - Deletar repositório
|
|
124
|
-
* Parâmetros:
|
|
125
|
-
* - owner (obrigatório): Proprietário do repositório
|
|
126
|
-
* - repo (obrigatório): Nome do repositório
|
|
127
|
-
*
|
|
128
|
-
* 6. fork - Fazer fork do repositório
|
|
129
|
-
* Parâmetros:
|
|
130
|
-
* - owner (obrigatório): Proprietário do repositório original
|
|
131
|
-
* - repo (obrigatório): Nome do repositório original
|
|
132
|
-
* - organization (opcional): Organização de destino
|
|
133
|
-
*
|
|
134
|
-
* 7. search - Buscar repositórios
|
|
135
|
-
* Parâmetros:
|
|
136
|
-
* - query (obrigatório): Termo de busca
|
|
137
|
-
* - page (opcional): Página da busca (padrão: 1)
|
|
138
|
-
* - limit (opcional): Itens por página (padrão: 30)
|
|
139
|
-
*
|
|
140
|
-
* RECOMENDAÇÕES DE USO:
|
|
141
|
-
* - Use nomes descritivos para repositórios
|
|
142
|
-
* - Configure visibilidade adequada para o projeto
|
|
143
|
-
* - Mantenha descrições atualizadas
|
|
144
|
-
* - Use templates para projetos similares
|
|
145
|
-
* - Configure branch padrão adequada
|
|
146
|
-
* - Use paginação para listas grandes
|
|
147
|
-
*/
|
|
148
|
-
exports.repositoriesTool = {
|
|
149
|
-
name: 'repositories',
|
|
150
|
-
description: 'Manage repositories with multiple actions: create, list, get, update, delete, fork, search. Suporte completo a GitHub e Gitea simultaneamente. Boas práticas (solo): use para iniciar projetos, ajustar descrição/privacidade e manter organização; inicialize com README/LICENSE/.gitignore e defina a branch padrão. Crie tags e releases para pontos estáveis e rollback mais simples.',
|
|
151
|
-
inputSchema: {
|
|
152
|
-
type: 'object',
|
|
153
|
-
properties: {
|
|
154
|
-
action: {
|
|
155
|
-
type: 'string',
|
|
156
|
-
enum: ['create', 'list', 'get', 'update', 'delete', 'fork', 'search', 'init', 'clone'],
|
|
157
|
-
description: 'Action to perform on repositories'
|
|
158
|
-
},
|
|
159
|
-
owner: { type: 'string', description: 'Repository owner' },
|
|
160
|
-
repo: { type: 'string', description: 'Repository name' },
|
|
161
|
-
provider: { type: 'string', enum: ['gitea', 'github'], description: 'Provider to use (gitea or github)' },
|
|
162
|
-
projectPath: { type: 'string', description: 'Local project path for git operations' },
|
|
163
|
-
name: { type: 'string', description: 'Repository name for creation' },
|
|
164
|
-
description: { type: 'string', description: 'Repository description' },
|
|
165
|
-
private: { type: 'boolean', description: 'Private repository' },
|
|
166
|
-
auto_init: { type: 'boolean', description: 'Auto initialize with README' },
|
|
167
|
-
gitignores: { type: 'string', description: 'Gitignore template' },
|
|
168
|
-
license: { type: 'string', description: 'License template' },
|
|
169
|
-
readme: { type: 'string', description: 'README content' },
|
|
170
|
-
default_branch: { type: 'string', description: 'Default branch name' },
|
|
171
|
-
username: { type: 'string', description: 'Username for listing repos' },
|
|
172
|
-
page: { type: 'number', description: 'Page number', minimum: 1 },
|
|
173
|
-
limit: { type: 'number', description: 'Items per page', minimum: 1, maximum: 100 },
|
|
174
|
-
new_name: { type: 'string', description: 'New repository name' },
|
|
175
|
-
new_description: { type: 'string', description: 'New repository description' },
|
|
176
|
-
new_private: { type: 'boolean', description: 'New privacy setting' },
|
|
177
|
-
archived: { type: 'boolean', description: 'Archive status' },
|
|
178
|
-
organization: { type: 'string', description: 'Organization for fork' },
|
|
179
|
-
query: { type: 'string', description: 'Search query' }
|
|
180
|
-
},
|
|
181
|
-
required: ['action', 'owner', 'repo', 'provider', 'projectPath']
|
|
182
|
-
},
|
|
183
|
-
/**
|
|
184
|
-
* Handler principal da tool repositories
|
|
185
|
-
*
|
|
186
|
-
* FUNCIONALIDADE:
|
|
187
|
-
* - Valida entrada usando Zod schema
|
|
188
|
-
* - Roteia para método específico baseado na ação
|
|
189
|
-
* - Trata erros de forma uniforme
|
|
190
|
-
* - Retorna resultado padronizado
|
|
191
|
-
*
|
|
192
|
-
* FLUXO:
|
|
193
|
-
* 1. Validação de entrada
|
|
194
|
-
* 2. Roteamento por ação
|
|
195
|
-
* 3. Execução do método específico
|
|
196
|
-
* 4. Tratamento de erros
|
|
197
|
-
* 5. Retorno de resultado
|
|
198
|
-
*
|
|
199
|
-
* TRATAMENTO DE ERROS:
|
|
200
|
-
* - Validação: erro de schema
|
|
201
|
-
* - Execução: erro da operação
|
|
202
|
-
* - Roteamento: ação não suportada
|
|
203
|
-
*
|
|
204
|
-
* RECOMENDAÇÕES:
|
|
205
|
-
* - Sempre valide entrada antes de processar
|
|
206
|
-
* - Trate erros específicos adequadamente
|
|
207
|
-
* - Log detalhes de erro para debug
|
|
208
|
-
* - Retorne mensagens de erro úteis
|
|
209
|
-
*/
|
|
210
|
-
async handler(input) {
|
|
211
|
-
try {
|
|
212
|
-
const validatedInput = RepositoriesInputSchema.parse(input);
|
|
213
|
-
// Aplicar auto-detecção apenas para owner/username dentro do provider especificado
|
|
214
|
-
const processedInput = await (0, user_detection_js_1.applyAutoUserDetection)(validatedInput, validatedInput.provider);
|
|
215
|
-
// Usar o provider especificado pelo usuário ou o padrão se não especificado
|
|
216
|
-
let provider;
|
|
217
|
-
try {
|
|
218
|
-
if (processedInput.provider) {
|
|
219
|
-
const requestedProvider = index_js_1.globalProviderFactory.getProvider(processedInput.provider);
|
|
220
|
-
if (!requestedProvider) {
|
|
221
|
-
console.warn(`[REPOSITORIES] Provider '${processedInput.provider}' não encontrado, usando padrão`);
|
|
222
|
-
provider = index_js_1.globalProviderFactory.getDefaultProvider();
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
provider = requestedProvider;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
provider = index_js_1.globalProviderFactory.getDefaultProvider();
|
|
230
|
-
}
|
|
231
|
-
if (!provider) {
|
|
232
|
-
throw new Error('Nenhum provider disponível');
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
catch (providerError) {
|
|
236
|
-
console.error('[REPOSITORIES] Erro ao obter provider:', providerError);
|
|
237
|
-
throw new Error(`Erro de configuração do provider: ${providerError instanceof Error ? providerError.message : 'Provider não disponível'}`);
|
|
238
|
-
}
|
|
239
|
-
// Obter o owner do provider
|
|
240
|
-
const owner = (await provider.getCurrentUser()).login;
|
|
241
|
-
switch (processedInput.action) {
|
|
242
|
-
case 'create':
|
|
243
|
-
return await this.createRepository(processedInput, provider, owner);
|
|
244
|
-
case 'list':
|
|
245
|
-
return await this.listRepositories(processedInput, provider, owner);
|
|
246
|
-
case 'get':
|
|
247
|
-
return await this.getRepository(processedInput, provider, owner);
|
|
248
|
-
case 'update':
|
|
249
|
-
return await this.updateRepository(processedInput, provider, owner);
|
|
250
|
-
case 'delete':
|
|
251
|
-
return await this.deleteRepository(processedInput, provider, owner);
|
|
252
|
-
case 'fork':
|
|
253
|
-
return await this.forkRepository(processedInput, provider, owner);
|
|
254
|
-
case 'search':
|
|
255
|
-
return await this.searchRepositories(processedInput, provider, owner);
|
|
256
|
-
case 'init':
|
|
257
|
-
return await this.initRepository(processedInput, provider, owner);
|
|
258
|
-
case 'clone':
|
|
259
|
-
return await this.cloneRepository(processedInput, provider, owner);
|
|
260
|
-
default:
|
|
261
|
-
throw new Error(`Ação não suportada: ${processedInput.action}`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
return {
|
|
266
|
-
success: false,
|
|
267
|
-
action: input.action,
|
|
268
|
-
message: 'Erro na operação de repositórios',
|
|
269
|
-
error: error instanceof Error ? error.message : String(error)
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
},
|
|
273
|
-
/**
|
|
274
|
-
* Cria um novo repositório
|
|
275
|
-
*
|
|
276
|
-
* FUNCIONALIDADE:
|
|
277
|
-
* - Valida parâmetros obrigatórios
|
|
278
|
-
* - Configura dados padrão
|
|
279
|
-
* - Chama API do provider para criação
|
|
280
|
-
* - Retorna resultado formatado
|
|
281
|
-
*
|
|
282
|
-
* PARÂMETROS OBRIGATÓRIOS:
|
|
283
|
-
* - name: Nome do repositório
|
|
284
|
-
*
|
|
285
|
-
* PARÂMETROS OPCIONAIS:
|
|
286
|
-
* - description: Descrição do repositório
|
|
287
|
-
* - private: Visibilidade (padrão: false)
|
|
288
|
-
* - auto_init: Inicializar com README (padrão: false)
|
|
289
|
-
* - gitignores: Template de .gitignore
|
|
290
|
-
* - license: Template de licença
|
|
291
|
-
* - readme: Conteúdo do README
|
|
292
|
-
* - default_branch: Branch padrão (padrão: main)
|
|
293
|
-
*
|
|
294
|
-
* VALIDAÇÕES:
|
|
295
|
-
* - Nome obrigatório
|
|
296
|
-
* - Nome único no usuário/organização
|
|
297
|
-
* - Permissões adequadas
|
|
298
|
-
*
|
|
299
|
-
* RECOMENDAÇÕES:
|
|
300
|
-
* - Use nomes descritivos e únicos
|
|
301
|
-
* - Configure visibilidade adequada
|
|
302
|
-
* - Inicialize com README para projetos novos
|
|
303
|
-
* - Use templates para consistência
|
|
304
|
-
*/
|
|
305
|
-
async createRepository(params, provider, owner) {
|
|
306
|
-
try {
|
|
307
|
-
if (!params.name) {
|
|
308
|
-
throw new Error('Nome do repositório é obrigatório');
|
|
309
|
-
}
|
|
310
|
-
const repository = await provider.createRepository(params.name, params.description, params.private || false);
|
|
311
|
-
return {
|
|
312
|
-
success: true,
|
|
313
|
-
action: 'create',
|
|
314
|
-
message: `Repositório '${params.name}' criado com sucesso`,
|
|
315
|
-
data: repository
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
catch (error) {
|
|
319
|
-
throw new Error(`Falha ao criar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
async listRepositories(params, provider, owner) {
|
|
323
|
-
try {
|
|
324
|
-
const page = params.page || 1;
|
|
325
|
-
const limit = params.limit || 30;
|
|
326
|
-
const repositories = await provider.listRepositories(params.username, page, limit);
|
|
327
|
-
return {
|
|
328
|
-
success: true,
|
|
329
|
-
action: 'list',
|
|
330
|
-
message: `${repositories.length} repositórios encontrados`,
|
|
331
|
-
data: {
|
|
332
|
-
repositories,
|
|
333
|
-
page,
|
|
334
|
-
limit,
|
|
335
|
-
total: repositories.length
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
catch (error) {
|
|
340
|
-
throw new Error(`Falha ao listar repositórios: ${error instanceof Error ? error.message : String(error)}`);
|
|
341
|
-
}
|
|
342
|
-
},
|
|
343
|
-
async getRepository(params, provider, owner) {
|
|
344
|
-
try {
|
|
345
|
-
if (!owner || !params.repo) {
|
|
346
|
-
throw new Error('e nome do repositório são obrigatórios');
|
|
347
|
-
}
|
|
348
|
-
const repository = await provider.getRepository(owner, params.repo);
|
|
349
|
-
return {
|
|
350
|
-
success: true,
|
|
351
|
-
action: 'get',
|
|
352
|
-
message: `Repositório '${owner}/${params.repo}' obtido com sucesso`,
|
|
353
|
-
data: repository
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
catch (error) {
|
|
357
|
-
throw new Error(`Falha ao obter repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
async updateRepository(params, provider, owner) {
|
|
361
|
-
try {
|
|
362
|
-
if (!owner || !params.repo) {
|
|
363
|
-
throw new Error('e nome do repositório são obrigatórios');
|
|
364
|
-
}
|
|
365
|
-
const updateData = {};
|
|
366
|
-
if (params.new_name)
|
|
367
|
-
updateData.name = params.new_name;
|
|
368
|
-
if (params.new_description !== undefined)
|
|
369
|
-
updateData.description = params.new_description;
|
|
370
|
-
if (params.new_private !== undefined)
|
|
371
|
-
updateData.private = params.new_private;
|
|
372
|
-
if (params.archived !== undefined)
|
|
373
|
-
updateData.archived = params.archived;
|
|
374
|
-
if (Object.keys(updateData).length === 0) {
|
|
375
|
-
throw new Error('Nenhum campo para atualizar foi fornecido');
|
|
376
|
-
}
|
|
377
|
-
const repository = await provider.updateRepository(owner, params.repo, updateData);
|
|
378
|
-
return {
|
|
379
|
-
success: true,
|
|
380
|
-
action: 'update',
|
|
381
|
-
message: `Repositório '${owner}/${params.repo}' atualizado com sucesso`,
|
|
382
|
-
data: repository
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
catch (error) {
|
|
386
|
-
throw new Error(`Falha ao atualizar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
387
|
-
}
|
|
388
|
-
},
|
|
389
|
-
async deleteRepository(params, provider, owner) {
|
|
390
|
-
try {
|
|
391
|
-
if (!owner || !params.repo) {
|
|
392
|
-
throw new Error('e nome do repositório são obrigatórios');
|
|
393
|
-
}
|
|
394
|
-
await provider.deleteRepository(owner, params.repo);
|
|
395
|
-
return {
|
|
396
|
-
success: true,
|
|
397
|
-
action: 'delete',
|
|
398
|
-
message: `Repositório '${owner}/${params.repo}' deletado com sucesso`,
|
|
399
|
-
data: { deleted: true }
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
catch (error) {
|
|
403
|
-
throw new Error(`Falha ao deletar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
404
|
-
}
|
|
405
|
-
},
|
|
406
|
-
async forkRepository(params, provider, owner) {
|
|
407
|
-
try {
|
|
408
|
-
if (!owner || !params.repo) {
|
|
409
|
-
throw new Error('e nome do repositório são obrigatórios');
|
|
410
|
-
}
|
|
411
|
-
const repository = await provider.forkRepository(owner, params.repo, params.organization);
|
|
412
|
-
return {
|
|
413
|
-
success: true,
|
|
414
|
-
action: 'fork',
|
|
415
|
-
message: `Fork do repositório '${owner}/${params.repo}' criado com sucesso`,
|
|
416
|
-
data: repository
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
catch (error) {
|
|
420
|
-
throw new Error(`Falha ao fazer fork do repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
421
|
-
}
|
|
422
|
-
},
|
|
423
|
-
async searchRepositories(params, provider, owner) {
|
|
424
|
-
try {
|
|
425
|
-
if (!params.query) {
|
|
426
|
-
throw new Error('Query de busca é obrigatória');
|
|
427
|
-
}
|
|
428
|
-
const page = params.page || 1;
|
|
429
|
-
const limit = params.limit || 30;
|
|
430
|
-
const repositories = await provider.searchRepositories(params.query, page, limit);
|
|
431
|
-
return {
|
|
432
|
-
success: true,
|
|
433
|
-
action: 'search',
|
|
434
|
-
message: `${repositories.length} repositórios encontrados para '${params.query}'`,
|
|
435
|
-
data: {
|
|
436
|
-
repositories,
|
|
437
|
-
query: params.query,
|
|
438
|
-
page,
|
|
439
|
-
limit,
|
|
440
|
-
total: repositories.length
|
|
441
|
-
}
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
catch (error) {
|
|
445
|
-
throw new Error(`Falha ao buscar repositórios: ${error instanceof Error ? error.message : String(error)}`);
|
|
446
|
-
}
|
|
447
|
-
},
|
|
448
|
-
/**
|
|
449
|
-
* Inicializa um repositório Git local
|
|
450
|
-
*
|
|
451
|
-
* FUNCIONALIDADE:
|
|
452
|
-
* - Executa 'git init' no diretório especificado
|
|
453
|
-
* - Cria estrutura básica do Git
|
|
454
|
-
* - Adiciona remote se especificado
|
|
455
|
-
*
|
|
456
|
-
* PARÂMETROS OBRIGATÓRIOS:
|
|
457
|
-
* - projectPath: Caminho do projeto local
|
|
458
|
-
*
|
|
459
|
-
* PARÂMETROS OPCIONAIS:
|
|
460
|
-
* - owner/repo: Para configurar remote
|
|
461
|
-
* - provider: Para determinar URL do remote
|
|
462
|
-
*
|
|
463
|
-
* RECOMENDAÇÕES:
|
|
464
|
-
* - Verifique se diretório existe
|
|
465
|
-
* - Use caminhos absolutos
|
|
466
|
-
* - Configure remote após inicialização
|
|
467
|
-
*/
|
|
468
|
-
async initRepository(params, provider, owner) {
|
|
469
|
-
try {
|
|
470
|
-
if (!params.projectPath) {
|
|
471
|
-
throw new Error('projectPath é obrigatório para inicialização do repositório');
|
|
472
|
-
}
|
|
473
|
-
// Executa git init no diretório especificado
|
|
474
|
-
const initResult = await (0, terminal_controller_js_1.runTerminalCmd)({
|
|
475
|
-
command: `git init "${params.projectPath}"`,
|
|
476
|
-
is_background: false,
|
|
477
|
-
explanation: 'Inicializando repositório Git local'
|
|
478
|
-
});
|
|
479
|
-
if (initResult.exitCode !== 0) {
|
|
480
|
-
throw new Error(`Falha ao inicializar repositório: ${initResult.output}`);
|
|
481
|
-
}
|
|
482
|
-
// Se owner/repo foram especificados, configura remote
|
|
483
|
-
if (owner && params.repo) {
|
|
484
|
-
// Obtém URL base do provider
|
|
485
|
-
const providerConfig = provider?.getConfig ? provider.getConfig() : null;
|
|
486
|
-
const baseUrl = providerConfig?.apiUrl || (params.provider === 'gitea' ? 'http://nas-ubuntu:3000' : 'https://github.com');
|
|
487
|
-
const remoteUrl = params.provider === 'gitea'
|
|
488
|
-
? `${baseUrl.replace('/api/v1', '')}/${owner}/${params.repo}.git`
|
|
489
|
-
: `https://github.com/${owner}/${params.repo}.git`;
|
|
490
|
-
const remoteResult = await (0, terminal_controller_js_1.runTerminalCmd)({
|
|
491
|
-
command: `cd "${params.projectPath}" && git remote add origin "${remoteUrl}"`,
|
|
492
|
-
is_background: false,
|
|
493
|
-
explanation: 'Configurando remote origin'
|
|
494
|
-
});
|
|
495
|
-
if (remoteResult.exitCode !== 0) {
|
|
496
|
-
console.warn(`Aviso: Não foi possível configurar remote: ${remoteResult.output}`);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
return {
|
|
500
|
-
success: true,
|
|
501
|
-
action: 'init',
|
|
502
|
-
message: `Repositório Git inicializado com sucesso em '${params.projectPath}'`,
|
|
503
|
-
data: {
|
|
504
|
-
path: params.projectPath,
|
|
505
|
-
initialized: true,
|
|
506
|
-
remoteConfigured: !!(owner && params.repo && provider)
|
|
507
|
-
}
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
catch (error) {
|
|
511
|
-
throw new Error(`Falha ao inicializar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
512
|
-
}
|
|
513
|
-
},
|
|
514
|
-
/**
|
|
515
|
-
* Clona um repositório para o diretório local
|
|
516
|
-
*
|
|
517
|
-
* FUNCIONALIDADE:
|
|
518
|
-
* - Clona repositório remoto para diretório local
|
|
519
|
-
* - Suporta diferentes protocolos (HTTPS, SSH)
|
|
520
|
-
* - Mantém estrutura de diretórios
|
|
521
|
-
*
|
|
522
|
-
* PARÂMETROS OBRIGATÓRIOS:
|
|
523
|
-
* - owner: Proprietário do repositório
|
|
524
|
-
* - repo: Nome do repositório
|
|
525
|
-
* - projectPath: Caminho local de destino
|
|
526
|
-
* - provider: Provider a ser usado
|
|
527
|
-
*
|
|
528
|
-
* RECOMENDAÇÕES:
|
|
529
|
-
* - Verifique espaço em disco disponível
|
|
530
|
-
* - Use caminhos absolutos
|
|
531
|
-
* - Considere profundidade de clone para repositórios grandes
|
|
532
|
-
*/
|
|
533
|
-
async cloneRepository(params, provider, owner) {
|
|
534
|
-
try {
|
|
535
|
-
if (!owner || !params.repo || !params.projectPath) {
|
|
536
|
-
throw new Error('owner, repo e projectPath são obrigatórios para clonagem');
|
|
537
|
-
}
|
|
538
|
-
// Obtém URL do repositório
|
|
539
|
-
const providerConfig = provider?.getConfig ? provider.getConfig() : null;
|
|
540
|
-
const baseUrl = providerConfig?.apiUrl || (params.provider === 'gitea' ? 'http://nas-ubuntu:3000' : 'https://github.com');
|
|
541
|
-
const repoUrl = params.provider === 'gitea'
|
|
542
|
-
? `${baseUrl.replace('/api/v1', '')}/${owner}/${params.repo}.git`
|
|
543
|
-
: `https://github.com/${owner}/${params.repo}.git`;
|
|
544
|
-
// Executa git clone
|
|
545
|
-
const cloneResult = await (0, terminal_controller_js_1.runTerminalCmd)({
|
|
546
|
-
command: `git clone "${repoUrl}" "${params.projectPath}"`,
|
|
547
|
-
is_background: false,
|
|
548
|
-
explanation: 'Clonando repositório remoto'
|
|
549
|
-
});
|
|
550
|
-
if (cloneResult.exitCode !== 0) {
|
|
551
|
-
throw new Error(`Falha ao clonar repositório: ${cloneResult.output}`);
|
|
552
|
-
}
|
|
553
|
-
return {
|
|
554
|
-
success: true,
|
|
555
|
-
action: 'clone',
|
|
556
|
-
message: `Repositório '${owner}/${params.repo}' clonado com sucesso para '${params.projectPath}'`,
|
|
557
|
-
data: {
|
|
558
|
-
source: `${owner}/${params.repo}`,
|
|
559
|
-
destination: params.projectPath,
|
|
560
|
-
cloned: true,
|
|
561
|
-
url: repoUrl
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
catch (error) {
|
|
566
|
-
throw new Error(`Falha ao clonar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.repositoriesTool = 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 terminal_controller_js_1 = require("../utils/terminal-controller.js");
|
|
8
|
+
/**
|
|
9
|
+
* Tool: repositories
|
|
10
|
+
*
|
|
11
|
+
* DESCRIÇÃO:
|
|
12
|
+
* Gerenciamento completo de repositórios Gitea com múltiplas ações
|
|
13
|
+
*
|
|
14
|
+
* FUNCIONALIDADES:
|
|
15
|
+
* - Criação de repositórios
|
|
16
|
+
* - Listagem e busca
|
|
17
|
+
* - Atualização e configuração
|
|
18
|
+
* - Fork e clonagem
|
|
19
|
+
* - Exclusão e arquivamento
|
|
20
|
+
*
|
|
21
|
+
* USO:
|
|
22
|
+
* - Para gerenciar repositórios de projetos
|
|
23
|
+
* - Para automatizar criação de repositórios
|
|
24
|
+
* - Para backup e migração
|
|
25
|
+
* - Para organização de código
|
|
26
|
+
*
|
|
27
|
+
* RECOMENDAÇÕES:
|
|
28
|
+
* - Use nomes descritivos para repositórios
|
|
29
|
+
* - Configure visibilidade adequada
|
|
30
|
+
* - Mantenha descrições atualizadas
|
|
31
|
+
* - Use templates quando possível
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Schema de validação para entrada da tool repositories
|
|
35
|
+
*
|
|
36
|
+
* VALIDAÇÕES:
|
|
37
|
+
* - action: Ação obrigatória (create, list, get, update, delete, fork, search)
|
|
38
|
+
* - provider: Opcional (usa padrão se não especificado)
|
|
39
|
+
* - Parâmetros específicos por ação
|
|
40
|
+
* - Validação de tipos e formatos
|
|
41
|
+
*
|
|
42
|
+
* RECOMENDAÇÕES:
|
|
43
|
+
* - Sempre valide entrada antes de usar
|
|
44
|
+
* - Use parâmetros opcionais adequadamente
|
|
45
|
+
* - Documente parâmetros obrigatórios
|
|
46
|
+
*/
|
|
47
|
+
const RepositoriesInputSchema = zod_1.z.object({
|
|
48
|
+
action: zod_1.z.enum(['create', 'list', 'get', 'update', 'delete', 'fork', 'search', 'init', 'clone']),
|
|
49
|
+
// Parâmetros comuns
|
|
50
|
+
// owner: obtido automaticamente do provider,
|
|
51
|
+
repo: zod_1.z.string(),
|
|
52
|
+
provider: zod_1.z.enum(['gitea', 'github']).describe('Provider to use (gitea or github)'),
|
|
53
|
+
projectPath: zod_1.z.string().describe('Local project path for git operations'),
|
|
54
|
+
name: zod_1.z.string().optional(),
|
|
55
|
+
description: zod_1.z.string().optional(),
|
|
56
|
+
private: zod_1.z.boolean().optional(),
|
|
57
|
+
auto_init: zod_1.z.boolean().optional(),
|
|
58
|
+
gitignores: zod_1.z.string().optional(),
|
|
59
|
+
license: zod_1.z.string().optional(),
|
|
60
|
+
readme: zod_1.z.string().optional(),
|
|
61
|
+
default_branch: zod_1.z.string().optional(),
|
|
62
|
+
// Para list
|
|
63
|
+
username: zod_1.z.string().optional(),
|
|
64
|
+
page: zod_1.z.number().min(1).optional(),
|
|
65
|
+
limit: zod_1.z.number().min(1).max(100).optional(),
|
|
66
|
+
// Para update
|
|
67
|
+
new_name: zod_1.z.string().optional(),
|
|
68
|
+
new_description: zod_1.z.string().optional(),
|
|
69
|
+
new_private: zod_1.z.boolean().optional(),
|
|
70
|
+
archived: zod_1.z.boolean().optional(),
|
|
71
|
+
// Para fork
|
|
72
|
+
organization: zod_1.z.string().optional(),
|
|
73
|
+
// Para search
|
|
74
|
+
query: zod_1.z.string().optional(),
|
|
75
|
+
});
|
|
76
|
+
// Schema de saída
|
|
77
|
+
const RepositoriesResultSchema = zod_1.z.object({
|
|
78
|
+
success: zod_1.z.boolean(),
|
|
79
|
+
action: zod_1.z.string(),
|
|
80
|
+
message: zod_1.z.string(),
|
|
81
|
+
data: zod_1.z.any().optional(),
|
|
82
|
+
error: zod_1.z.string().optional()
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* Tool: repositories
|
|
86
|
+
*
|
|
87
|
+
* DESCRIÇÃO:
|
|
88
|
+
* Gerenciamento completo de repositórios Gitea com múltiplas ações
|
|
89
|
+
*
|
|
90
|
+
* ACTIONS DISPONÍVEIS:
|
|
91
|
+
*
|
|
92
|
+
* 1. create - Criar novo repositório
|
|
93
|
+
* Parâmetros:
|
|
94
|
+
* - name (obrigatório): Nome do repositório
|
|
95
|
+
* - description (opcional): Descrição do repositório
|
|
96
|
+
* - private (opcional): Repositório privado (padrão: false)
|
|
97
|
+
* - auto_init (opcional): Inicializar com README (padrão: false)
|
|
98
|
+
* - gitignores (opcional): Template de .gitignore
|
|
99
|
+
* - license (opcional): Template de licença
|
|
100
|
+
* - readme (opcional): Conteúdo do README
|
|
101
|
+
* - default_branch (opcional): Branch padrão
|
|
102
|
+
*
|
|
103
|
+
* 2. list - Listar repositórios
|
|
104
|
+
* Parâmetros:
|
|
105
|
+
* - username (opcional): Usuário específico (padrão: usuário atual)
|
|
106
|
+
* - page (opcional): Página da listagem (padrão: 1)
|
|
107
|
+
* - limit (opcional): Itens por página (padrão: 30)
|
|
108
|
+
*
|
|
109
|
+
* 3. get - Obter detalhes do repositório
|
|
110
|
+
* Parâmetros:
|
|
111
|
+
* - owner (obrigatório): Proprietário do repositório
|
|
112
|
+
* - repo (obrigatório): Nome do repositório
|
|
113
|
+
*
|
|
114
|
+
* 4. update - Atualizar repositório
|
|
115
|
+
* Parâmetros:
|
|
116
|
+
* - owner (obrigatório): Proprietário do repositório
|
|
117
|
+
* - repo (obrigatório): Nome do repositório
|
|
118
|
+
* - new_name (opcional): Novo nome
|
|
119
|
+
* - new_description (opcional): Nova descrição
|
|
120
|
+
* - new_private (opcional): Nova visibilidade
|
|
121
|
+
* - archived (opcional): Status de arquivamento
|
|
122
|
+
*
|
|
123
|
+
* 5. delete - Deletar repositório
|
|
124
|
+
* Parâmetros:
|
|
125
|
+
* - owner (obrigatório): Proprietário do repositório
|
|
126
|
+
* - repo (obrigatório): Nome do repositório
|
|
127
|
+
*
|
|
128
|
+
* 6. fork - Fazer fork do repositório
|
|
129
|
+
* Parâmetros:
|
|
130
|
+
* - owner (obrigatório): Proprietário do repositório original
|
|
131
|
+
* - repo (obrigatório): Nome do repositório original
|
|
132
|
+
* - organization (opcional): Organização de destino
|
|
133
|
+
*
|
|
134
|
+
* 7. search - Buscar repositórios
|
|
135
|
+
* Parâmetros:
|
|
136
|
+
* - query (obrigatório): Termo de busca
|
|
137
|
+
* - page (opcional): Página da busca (padrão: 1)
|
|
138
|
+
* - limit (opcional): Itens por página (padrão: 30)
|
|
139
|
+
*
|
|
140
|
+
* RECOMENDAÇÕES DE USO:
|
|
141
|
+
* - Use nomes descritivos para repositórios
|
|
142
|
+
* - Configure visibilidade adequada para o projeto
|
|
143
|
+
* - Mantenha descrições atualizadas
|
|
144
|
+
* - Use templates para projetos similares
|
|
145
|
+
* - Configure branch padrão adequada
|
|
146
|
+
* - Use paginação para listas grandes
|
|
147
|
+
*/
|
|
148
|
+
exports.repositoriesTool = {
|
|
149
|
+
name: 'repositories',
|
|
150
|
+
description: 'Manage repositories with multiple actions: create, list, get, update, delete, fork, search. Suporte completo a GitHub e Gitea simultaneamente. Boas práticas (solo): use para iniciar projetos, ajustar descrição/privacidade e manter organização; inicialize com README/LICENSE/.gitignore e defina a branch padrão. Crie tags e releases para pontos estáveis e rollback mais simples.',
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
action: {
|
|
155
|
+
type: 'string',
|
|
156
|
+
enum: ['create', 'list', 'get', 'update', 'delete', 'fork', 'search', 'init', 'clone'],
|
|
157
|
+
description: 'Action to perform on repositories'
|
|
158
|
+
},
|
|
159
|
+
owner: { type: 'string', description: 'Repository owner' },
|
|
160
|
+
repo: { type: 'string', description: 'Repository name' },
|
|
161
|
+
provider: { type: 'string', enum: ['gitea', 'github'], description: 'Provider to use (gitea or github)' },
|
|
162
|
+
projectPath: { type: 'string', description: 'Local project path for git operations' },
|
|
163
|
+
name: { type: 'string', description: 'Repository name for creation' },
|
|
164
|
+
description: { type: 'string', description: 'Repository description' },
|
|
165
|
+
private: { type: 'boolean', description: 'Private repository' },
|
|
166
|
+
auto_init: { type: 'boolean', description: 'Auto initialize with README' },
|
|
167
|
+
gitignores: { type: 'string', description: 'Gitignore template' },
|
|
168
|
+
license: { type: 'string', description: 'License template' },
|
|
169
|
+
readme: { type: 'string', description: 'README content' },
|
|
170
|
+
default_branch: { type: 'string', description: 'Default branch name' },
|
|
171
|
+
username: { type: 'string', description: 'Username for listing repos' },
|
|
172
|
+
page: { type: 'number', description: 'Page number', minimum: 1 },
|
|
173
|
+
limit: { type: 'number', description: 'Items per page', minimum: 1, maximum: 100 },
|
|
174
|
+
new_name: { type: 'string', description: 'New repository name' },
|
|
175
|
+
new_description: { type: 'string', description: 'New repository description' },
|
|
176
|
+
new_private: { type: 'boolean', description: 'New privacy setting' },
|
|
177
|
+
archived: { type: 'boolean', description: 'Archive status' },
|
|
178
|
+
organization: { type: 'string', description: 'Organization for fork' },
|
|
179
|
+
query: { type: 'string', description: 'Search query' }
|
|
180
|
+
},
|
|
181
|
+
required: ['action', 'owner', 'repo', 'provider', 'projectPath']
|
|
182
|
+
},
|
|
183
|
+
/**
|
|
184
|
+
* Handler principal da tool repositories
|
|
185
|
+
*
|
|
186
|
+
* FUNCIONALIDADE:
|
|
187
|
+
* - Valida entrada usando Zod schema
|
|
188
|
+
* - Roteia para método específico baseado na ação
|
|
189
|
+
* - Trata erros de forma uniforme
|
|
190
|
+
* - Retorna resultado padronizado
|
|
191
|
+
*
|
|
192
|
+
* FLUXO:
|
|
193
|
+
* 1. Validação de entrada
|
|
194
|
+
* 2. Roteamento por ação
|
|
195
|
+
* 3. Execução do método específico
|
|
196
|
+
* 4. Tratamento de erros
|
|
197
|
+
* 5. Retorno de resultado
|
|
198
|
+
*
|
|
199
|
+
* TRATAMENTO DE ERROS:
|
|
200
|
+
* - Validação: erro de schema
|
|
201
|
+
* - Execução: erro da operação
|
|
202
|
+
* - Roteamento: ação não suportada
|
|
203
|
+
*
|
|
204
|
+
* RECOMENDAÇÕES:
|
|
205
|
+
* - Sempre valide entrada antes de processar
|
|
206
|
+
* - Trate erros específicos adequadamente
|
|
207
|
+
* - Log detalhes de erro para debug
|
|
208
|
+
* - Retorne mensagens de erro úteis
|
|
209
|
+
*/
|
|
210
|
+
async handler(input) {
|
|
211
|
+
try {
|
|
212
|
+
const validatedInput = RepositoriesInputSchema.parse(input);
|
|
213
|
+
// Aplicar auto-detecção apenas para owner/username dentro do provider especificado
|
|
214
|
+
const processedInput = await (0, user_detection_js_1.applyAutoUserDetection)(validatedInput, validatedInput.provider);
|
|
215
|
+
// Usar o provider especificado pelo usuário ou o padrão se não especificado
|
|
216
|
+
let provider;
|
|
217
|
+
try {
|
|
218
|
+
if (processedInput.provider) {
|
|
219
|
+
const requestedProvider = index_js_1.globalProviderFactory.getProvider(processedInput.provider);
|
|
220
|
+
if (!requestedProvider) {
|
|
221
|
+
console.warn(`[REPOSITORIES] Provider '${processedInput.provider}' não encontrado, usando padrão`);
|
|
222
|
+
provider = index_js_1.globalProviderFactory.getDefaultProvider();
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
provider = requestedProvider;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
provider = index_js_1.globalProviderFactory.getDefaultProvider();
|
|
230
|
+
}
|
|
231
|
+
if (!provider) {
|
|
232
|
+
throw new Error('Nenhum provider disponível');
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch (providerError) {
|
|
236
|
+
console.error('[REPOSITORIES] Erro ao obter provider:', providerError);
|
|
237
|
+
throw new Error(`Erro de configuração do provider: ${providerError instanceof Error ? providerError.message : 'Provider não disponível'}`);
|
|
238
|
+
}
|
|
239
|
+
// Obter o owner do provider
|
|
240
|
+
const owner = (await provider.getCurrentUser()).login;
|
|
241
|
+
switch (processedInput.action) {
|
|
242
|
+
case 'create':
|
|
243
|
+
return await this.createRepository(processedInput, provider, owner);
|
|
244
|
+
case 'list':
|
|
245
|
+
return await this.listRepositories(processedInput, provider, owner);
|
|
246
|
+
case 'get':
|
|
247
|
+
return await this.getRepository(processedInput, provider, owner);
|
|
248
|
+
case 'update':
|
|
249
|
+
return await this.updateRepository(processedInput, provider, owner);
|
|
250
|
+
case 'delete':
|
|
251
|
+
return await this.deleteRepository(processedInput, provider, owner);
|
|
252
|
+
case 'fork':
|
|
253
|
+
return await this.forkRepository(processedInput, provider, owner);
|
|
254
|
+
case 'search':
|
|
255
|
+
return await this.searchRepositories(processedInput, provider, owner);
|
|
256
|
+
case 'init':
|
|
257
|
+
return await this.initRepository(processedInput, provider, owner);
|
|
258
|
+
case 'clone':
|
|
259
|
+
return await this.cloneRepository(processedInput, provider, owner);
|
|
260
|
+
default:
|
|
261
|
+
throw new Error(`Ação não suportada: ${processedInput.action}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
return {
|
|
266
|
+
success: false,
|
|
267
|
+
action: input.action,
|
|
268
|
+
message: 'Erro na operação de repositórios',
|
|
269
|
+
error: error instanceof Error ? error.message : String(error)
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
/**
|
|
274
|
+
* Cria um novo repositório
|
|
275
|
+
*
|
|
276
|
+
* FUNCIONALIDADE:
|
|
277
|
+
* - Valida parâmetros obrigatórios
|
|
278
|
+
* - Configura dados padrão
|
|
279
|
+
* - Chama API do provider para criação
|
|
280
|
+
* - Retorna resultado formatado
|
|
281
|
+
*
|
|
282
|
+
* PARÂMETROS OBRIGATÓRIOS:
|
|
283
|
+
* - name: Nome do repositório
|
|
284
|
+
*
|
|
285
|
+
* PARÂMETROS OPCIONAIS:
|
|
286
|
+
* - description: Descrição do repositório
|
|
287
|
+
* - private: Visibilidade (padrão: false)
|
|
288
|
+
* - auto_init: Inicializar com README (padrão: false)
|
|
289
|
+
* - gitignores: Template de .gitignore
|
|
290
|
+
* - license: Template de licença
|
|
291
|
+
* - readme: Conteúdo do README
|
|
292
|
+
* - default_branch: Branch padrão (padrão: main)
|
|
293
|
+
*
|
|
294
|
+
* VALIDAÇÕES:
|
|
295
|
+
* - Nome obrigatório
|
|
296
|
+
* - Nome único no usuário/organização
|
|
297
|
+
* - Permissões adequadas
|
|
298
|
+
*
|
|
299
|
+
* RECOMENDAÇÕES:
|
|
300
|
+
* - Use nomes descritivos e únicos
|
|
301
|
+
* - Configure visibilidade adequada
|
|
302
|
+
* - Inicialize com README para projetos novos
|
|
303
|
+
* - Use templates para consistência
|
|
304
|
+
*/
|
|
305
|
+
async createRepository(params, provider, owner) {
|
|
306
|
+
try {
|
|
307
|
+
if (!params.name) {
|
|
308
|
+
throw new Error('Nome do repositório é obrigatório');
|
|
309
|
+
}
|
|
310
|
+
const repository = await provider.createRepository(params.name, params.description, params.private || false);
|
|
311
|
+
return {
|
|
312
|
+
success: true,
|
|
313
|
+
action: 'create',
|
|
314
|
+
message: `Repositório '${params.name}' criado com sucesso`,
|
|
315
|
+
data: repository
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
throw new Error(`Falha ao criar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
async listRepositories(params, provider, owner) {
|
|
323
|
+
try {
|
|
324
|
+
const page = params.page || 1;
|
|
325
|
+
const limit = params.limit || 30;
|
|
326
|
+
const repositories = await provider.listRepositories(params.username, page, limit);
|
|
327
|
+
return {
|
|
328
|
+
success: true,
|
|
329
|
+
action: 'list',
|
|
330
|
+
message: `${repositories.length} repositórios encontrados`,
|
|
331
|
+
data: {
|
|
332
|
+
repositories,
|
|
333
|
+
page,
|
|
334
|
+
limit,
|
|
335
|
+
total: repositories.length
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
throw new Error(`Falha ao listar repositórios: ${error instanceof Error ? error.message : String(error)}`);
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
async getRepository(params, provider, owner) {
|
|
344
|
+
try {
|
|
345
|
+
if (!owner || !params.repo) {
|
|
346
|
+
throw new Error('e nome do repositório são obrigatórios');
|
|
347
|
+
}
|
|
348
|
+
const repository = await provider.getRepository(owner, params.repo);
|
|
349
|
+
return {
|
|
350
|
+
success: true,
|
|
351
|
+
action: 'get',
|
|
352
|
+
message: `Repositório '${owner}/${params.repo}' obtido com sucesso`,
|
|
353
|
+
data: repository
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
throw new Error(`Falha ao obter repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
async updateRepository(params, provider, owner) {
|
|
361
|
+
try {
|
|
362
|
+
if (!owner || !params.repo) {
|
|
363
|
+
throw new Error('e nome do repositório são obrigatórios');
|
|
364
|
+
}
|
|
365
|
+
const updateData = {};
|
|
366
|
+
if (params.new_name)
|
|
367
|
+
updateData.name = params.new_name;
|
|
368
|
+
if (params.new_description !== undefined)
|
|
369
|
+
updateData.description = params.new_description;
|
|
370
|
+
if (params.new_private !== undefined)
|
|
371
|
+
updateData.private = params.new_private;
|
|
372
|
+
if (params.archived !== undefined)
|
|
373
|
+
updateData.archived = params.archived;
|
|
374
|
+
if (Object.keys(updateData).length === 0) {
|
|
375
|
+
throw new Error('Nenhum campo para atualizar foi fornecido');
|
|
376
|
+
}
|
|
377
|
+
const repository = await provider.updateRepository(owner, params.repo, updateData);
|
|
378
|
+
return {
|
|
379
|
+
success: true,
|
|
380
|
+
action: 'update',
|
|
381
|
+
message: `Repositório '${owner}/${params.repo}' atualizado com sucesso`,
|
|
382
|
+
data: repository
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
throw new Error(`Falha ao atualizar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
async deleteRepository(params, provider, owner) {
|
|
390
|
+
try {
|
|
391
|
+
if (!owner || !params.repo) {
|
|
392
|
+
throw new Error('e nome do repositório são obrigatórios');
|
|
393
|
+
}
|
|
394
|
+
await provider.deleteRepository(owner, params.repo);
|
|
395
|
+
return {
|
|
396
|
+
success: true,
|
|
397
|
+
action: 'delete',
|
|
398
|
+
message: `Repositório '${owner}/${params.repo}' deletado com sucesso`,
|
|
399
|
+
data: { deleted: true }
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
throw new Error(`Falha ao deletar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
async forkRepository(params, provider, owner) {
|
|
407
|
+
try {
|
|
408
|
+
if (!owner || !params.repo) {
|
|
409
|
+
throw new Error('e nome do repositório são obrigatórios');
|
|
410
|
+
}
|
|
411
|
+
const repository = await provider.forkRepository(owner, params.repo, params.organization);
|
|
412
|
+
return {
|
|
413
|
+
success: true,
|
|
414
|
+
action: 'fork',
|
|
415
|
+
message: `Fork do repositório '${owner}/${params.repo}' criado com sucesso`,
|
|
416
|
+
data: repository
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
catch (error) {
|
|
420
|
+
throw new Error(`Falha ao fazer fork do repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
async searchRepositories(params, provider, owner) {
|
|
424
|
+
try {
|
|
425
|
+
if (!params.query) {
|
|
426
|
+
throw new Error('Query de busca é obrigatória');
|
|
427
|
+
}
|
|
428
|
+
const page = params.page || 1;
|
|
429
|
+
const limit = params.limit || 30;
|
|
430
|
+
const repositories = await provider.searchRepositories(params.query, page, limit);
|
|
431
|
+
return {
|
|
432
|
+
success: true,
|
|
433
|
+
action: 'search',
|
|
434
|
+
message: `${repositories.length} repositórios encontrados para '${params.query}'`,
|
|
435
|
+
data: {
|
|
436
|
+
repositories,
|
|
437
|
+
query: params.query,
|
|
438
|
+
page,
|
|
439
|
+
limit,
|
|
440
|
+
total: repositories.length
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
throw new Error(`Falha ao buscar repositórios: ${error instanceof Error ? error.message : String(error)}`);
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
/**
|
|
449
|
+
* Inicializa um repositório Git local
|
|
450
|
+
*
|
|
451
|
+
* FUNCIONALIDADE:
|
|
452
|
+
* - Executa 'git init' no diretório especificado
|
|
453
|
+
* - Cria estrutura básica do Git
|
|
454
|
+
* - Adiciona remote se especificado
|
|
455
|
+
*
|
|
456
|
+
* PARÂMETROS OBRIGATÓRIOS:
|
|
457
|
+
* - projectPath: Caminho do projeto local
|
|
458
|
+
*
|
|
459
|
+
* PARÂMETROS OPCIONAIS:
|
|
460
|
+
* - owner/repo: Para configurar remote
|
|
461
|
+
* - provider: Para determinar URL do remote
|
|
462
|
+
*
|
|
463
|
+
* RECOMENDAÇÕES:
|
|
464
|
+
* - Verifique se diretório existe
|
|
465
|
+
* - Use caminhos absolutos
|
|
466
|
+
* - Configure remote após inicialização
|
|
467
|
+
*/
|
|
468
|
+
async initRepository(params, provider, owner) {
|
|
469
|
+
try {
|
|
470
|
+
if (!params.projectPath) {
|
|
471
|
+
throw new Error('projectPath é obrigatório para inicialização do repositório');
|
|
472
|
+
}
|
|
473
|
+
// Executa git init no diretório especificado
|
|
474
|
+
const initResult = await (0, terminal_controller_js_1.runTerminalCmd)({
|
|
475
|
+
command: `git init "${params.projectPath}"`,
|
|
476
|
+
is_background: false,
|
|
477
|
+
explanation: 'Inicializando repositório Git local'
|
|
478
|
+
});
|
|
479
|
+
if (initResult.exitCode !== 0) {
|
|
480
|
+
throw new Error(`Falha ao inicializar repositório: ${initResult.output}`);
|
|
481
|
+
}
|
|
482
|
+
// Se owner/repo foram especificados, configura remote
|
|
483
|
+
if (owner && params.repo) {
|
|
484
|
+
// Obtém URL base do provider
|
|
485
|
+
const providerConfig = provider?.getConfig ? provider.getConfig() : null;
|
|
486
|
+
const baseUrl = providerConfig?.apiUrl || (params.provider === 'gitea' ? 'http://nas-ubuntu:3000' : 'https://github.com');
|
|
487
|
+
const remoteUrl = params.provider === 'gitea'
|
|
488
|
+
? `${baseUrl.replace('/api/v1', '')}/${owner}/${params.repo}.git`
|
|
489
|
+
: `https://github.com/${owner}/${params.repo}.git`;
|
|
490
|
+
const remoteResult = await (0, terminal_controller_js_1.runTerminalCmd)({
|
|
491
|
+
command: `cd "${params.projectPath}" && git remote add origin "${remoteUrl}"`,
|
|
492
|
+
is_background: false,
|
|
493
|
+
explanation: 'Configurando remote origin'
|
|
494
|
+
});
|
|
495
|
+
if (remoteResult.exitCode !== 0) {
|
|
496
|
+
console.warn(`Aviso: Não foi possível configurar remote: ${remoteResult.output}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return {
|
|
500
|
+
success: true,
|
|
501
|
+
action: 'init',
|
|
502
|
+
message: `Repositório Git inicializado com sucesso em '${params.projectPath}'`,
|
|
503
|
+
data: {
|
|
504
|
+
path: params.projectPath,
|
|
505
|
+
initialized: true,
|
|
506
|
+
remoteConfigured: !!(owner && params.repo && provider)
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
catch (error) {
|
|
511
|
+
throw new Error(`Falha ao inicializar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
/**
|
|
515
|
+
* Clona um repositório para o diretório local
|
|
516
|
+
*
|
|
517
|
+
* FUNCIONALIDADE:
|
|
518
|
+
* - Clona repositório remoto para diretório local
|
|
519
|
+
* - Suporta diferentes protocolos (HTTPS, SSH)
|
|
520
|
+
* - Mantém estrutura de diretórios
|
|
521
|
+
*
|
|
522
|
+
* PARÂMETROS OBRIGATÓRIOS:
|
|
523
|
+
* - owner: Proprietário do repositório
|
|
524
|
+
* - repo: Nome do repositório
|
|
525
|
+
* - projectPath: Caminho local de destino
|
|
526
|
+
* - provider: Provider a ser usado
|
|
527
|
+
*
|
|
528
|
+
* RECOMENDAÇÕES:
|
|
529
|
+
* - Verifique espaço em disco disponível
|
|
530
|
+
* - Use caminhos absolutos
|
|
531
|
+
* - Considere profundidade de clone para repositórios grandes
|
|
532
|
+
*/
|
|
533
|
+
async cloneRepository(params, provider, owner) {
|
|
534
|
+
try {
|
|
535
|
+
if (!owner || !params.repo || !params.projectPath) {
|
|
536
|
+
throw new Error('owner, repo e projectPath são obrigatórios para clonagem');
|
|
537
|
+
}
|
|
538
|
+
// Obtém URL do repositório
|
|
539
|
+
const providerConfig = provider?.getConfig ? provider.getConfig() : null;
|
|
540
|
+
const baseUrl = providerConfig?.apiUrl || (params.provider === 'gitea' ? 'http://nas-ubuntu:3000' : 'https://github.com');
|
|
541
|
+
const repoUrl = params.provider === 'gitea'
|
|
542
|
+
? `${baseUrl.replace('/api/v1', '')}/${owner}/${params.repo}.git`
|
|
543
|
+
: `https://github.com/${owner}/${params.repo}.git`;
|
|
544
|
+
// Executa git clone
|
|
545
|
+
const cloneResult = await (0, terminal_controller_js_1.runTerminalCmd)({
|
|
546
|
+
command: `git clone "${repoUrl}" "${params.projectPath}"`,
|
|
547
|
+
is_background: false,
|
|
548
|
+
explanation: 'Clonando repositório remoto'
|
|
549
|
+
});
|
|
550
|
+
if (cloneResult.exitCode !== 0) {
|
|
551
|
+
throw new Error(`Falha ao clonar repositório: ${cloneResult.output}`);
|
|
552
|
+
}
|
|
553
|
+
return {
|
|
554
|
+
success: true,
|
|
555
|
+
action: 'clone',
|
|
556
|
+
message: `Repositório '${owner}/${params.repo}' clonado com sucesso para '${params.projectPath}'`,
|
|
557
|
+
data: {
|
|
558
|
+
source: `${owner}/${params.repo}`,
|
|
559
|
+
destination: params.projectPath,
|
|
560
|
+
cloned: true,
|
|
561
|
+
url: repoUrl
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
catch (error) {
|
|
566
|
+
throw new Error(`Falha ao clonar repositório: ${error instanceof Error ? error.message : String(error)}`);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
570
|
//# sourceMappingURL=repositories.js.map
|