@andrebuzeli/git-mcp 3.3.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +60 -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-tags.js
CHANGED
|
@@ -1,486 +1,615 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.gitTagsTool = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const auto_detection_js_1 = require("../utils/auto-detection.js");
|
|
6
|
+
const error_handler_js_1 = require("../utils/error-handler.js");
|
|
7
|
+
const git_operations_js_1 = require("../utils/git-operations.js");
|
|
7
8
|
/**
|
|
8
|
-
* Tool: tags
|
|
9
|
+
* Tool: git-tags
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* GERENCIAMENTO DE TAGS UNIFICADO
|
|
12
|
+
* Tags inteligentes com versionamento semântico e multi-provider
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* - Listagem e busca de tags
|
|
16
|
-
* - Obtenção de detalhes específicos
|
|
17
|
-
* - Exclusão de tags
|
|
18
|
-
* - Controle de versão
|
|
19
|
-
* - Busca por padrões
|
|
20
|
-
*
|
|
21
|
-
* USO:
|
|
22
|
-
* - Para marcar versões específicas
|
|
23
|
-
* - Para controle de release
|
|
24
|
-
* - Para rollback de código
|
|
25
|
-
* - Para identificação de commits
|
|
26
|
-
*
|
|
27
|
-
* RECOMENDAÇÕES:
|
|
28
|
-
* - Use versionamento semântico
|
|
29
|
-
* - Mantenha tags organizadas
|
|
30
|
-
* - Documente propósito das tags
|
|
31
|
-
* - Use para pontos de referência
|
|
32
|
-
*/
|
|
33
|
-
/**
|
|
34
|
-
* Schema de validação para entrada da tool tags
|
|
35
|
-
*
|
|
36
|
-
* VALIDAÇÕES:
|
|
37
|
-
* - action: Ação obrigatória (create, list, get, delete, search)
|
|
38
|
-
* - Parâmetros específicos por ação
|
|
39
|
-
* - Validação de tipos e formatos
|
|
40
|
-
*
|
|
41
|
-
* RECOMENDAÇÕES:
|
|
42
|
-
* - Sempre valide entrada antes de usar
|
|
43
|
-
* - Use parâmetros opcionais adequadamente
|
|
44
|
-
* - Documente parâmetros obrigatórios
|
|
14
|
+
* DESIGNED FOR: Programador individual autônomo
|
|
15
|
+
* PHILOSOPHY: Tags organizadas automaticamente para versionamento
|
|
45
16
|
*/
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
17
|
+
const GitTagsInputSchema = zod_1.z.discriminatedUnion('action', [
|
|
18
|
+
// CREATE TAG - Criação inteligente
|
|
19
|
+
zod_1.z.object({
|
|
20
|
+
action: zod_1.z.literal('create'),
|
|
21
|
+
projectPath: zod_1.z.string(),
|
|
22
|
+
name: zod_1.z.string(),
|
|
23
|
+
message: zod_1.z.string().optional(), // Auto-generate se não fornecido
|
|
24
|
+
target: zod_1.z.string().optional(), // Commit/branch, default HEAD
|
|
25
|
+
type: zod_1.z.enum(['lightweight', 'annotated']).default('annotated'),
|
|
26
|
+
force: zod_1.z.boolean().default(false)
|
|
27
|
+
}),
|
|
28
|
+
// LIST TAGS - Listagem com filtros
|
|
29
|
+
zod_1.z.object({
|
|
30
|
+
action: zod_1.z.literal('list'),
|
|
31
|
+
projectPath: zod_1.z.string(),
|
|
32
|
+
pattern: zod_1.z.string().optional(), // Filtrar por padrão (ex: v*)
|
|
33
|
+
sort: zod_1.z.enum(['version', 'date', 'name']).default('version'),
|
|
34
|
+
limit: zod_1.z.number().default(20)
|
|
35
|
+
}),
|
|
36
|
+
// GET TAG - Detalhes específicos
|
|
37
|
+
zod_1.z.object({
|
|
38
|
+
action: zod_1.z.literal('get'),
|
|
39
|
+
projectPath: zod_1.z.string(),
|
|
40
|
+
name: zod_1.z.string(),
|
|
41
|
+
detailed: zod_1.z.boolean().default(false)
|
|
42
|
+
}),
|
|
43
|
+
// DELETE TAG - Remoção segura
|
|
44
|
+
zod_1.z.object({
|
|
45
|
+
action: zod_1.z.literal('delete'),
|
|
46
|
+
projectPath: zod_1.z.string(),
|
|
47
|
+
name: zod_1.z.string(),
|
|
48
|
+
remote: zod_1.z.boolean().default(true), // Deletar também do remote
|
|
49
|
+
force: zod_1.z.boolean().default(false)
|
|
50
|
+
}),
|
|
51
|
+
// SEARCH TAGS - Busca avançada
|
|
52
|
+
zod_1.z.object({
|
|
53
|
+
action: zod_1.z.literal('search'),
|
|
54
|
+
projectPath: zod_1.z.string(),
|
|
55
|
+
query: zod_1.z.string(),
|
|
56
|
+
pattern: zod_1.z.string().optional(),
|
|
57
|
+
sort: zod_1.z.enum(['relevance', 'date', 'name']).default('relevance'),
|
|
58
|
+
limit: zod_1.z.number().default(10)
|
|
59
|
+
})
|
|
60
|
+
]);
|
|
67
61
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* ESTRUTURA:
|
|
71
|
-
* - success: Status da operação
|
|
72
|
-
* - action: Ação executada
|
|
73
|
-
* - message: Mensagem descritiva
|
|
74
|
-
* - data: Dados retornados (opcional)
|
|
75
|
-
* - error: Detalhes do erro (opcional)
|
|
62
|
+
* Smart Tag Manager
|
|
63
|
+
* Gerencia operações de tags com inteligência
|
|
76
64
|
*/
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
message: zod_1.z.string(),
|
|
81
|
-
data: zod_1.z.any().optional(),
|
|
82
|
-
error: zod_1.z.string().optional()
|
|
83
|
-
});
|
|
84
|
-
/**
|
|
85
|
-
* Tool: tags
|
|
86
|
-
*
|
|
87
|
-
* DESCRIÇÃO:
|
|
88
|
-
* Gerenciamento completo de tags Gitea com múltiplas ações
|
|
89
|
-
*
|
|
90
|
-
* ACTIONS DISPONÍVEIS:
|
|
91
|
-
*
|
|
92
|
-
* 1. create - Criar nova tag
|
|
93
|
-
* Parâmetros:
|
|
94
|
-
* - owner (obrigatório): Proprietário do repositório
|
|
95
|
-
* - repo (obrigatório): Nome do repositório
|
|
96
|
-
* - tag_name (obrigatório): Nome da tag
|
|
97
|
-
* - message (opcional): Mensagem da tag (para tags anotadas)
|
|
98
|
-
* - target (obrigatório): Commit, branch ou tag alvo
|
|
99
|
-
* - type (opcional): Tipo de tag (lightweight, annotated) - padrão: lightweight
|
|
100
|
-
* - tagger_name (opcional): Nome do tagger (para tags anotadas)
|
|
101
|
-
* - tagger_email (opcional): Email do tagger (para tags anotadas)
|
|
102
|
-
*
|
|
103
|
-
* 2. list - Listar tags
|
|
104
|
-
* Parâmetros:
|
|
105
|
-
* - owner (obrigatório): Proprietário do repositório
|
|
106
|
-
* - repo (obrigatório): Nome do repositório
|
|
107
|
-
* - page (opcional): Página da listagem (padrão: 1)
|
|
108
|
-
* - limit (opcional): Itens por página (padrão: 30, máximo: 100)
|
|
109
|
-
*
|
|
110
|
-
* 3. get - Obter detalhes da tag
|
|
111
|
-
* Parâmetros:
|
|
112
|
-
* - owner (obrigatório): Proprietário do repositório
|
|
113
|
-
* - repo (obrigatório): Nome do repositório
|
|
114
|
-
* - tag (obrigatório): Nome da tag
|
|
115
|
-
*
|
|
116
|
-
* 4. delete - Deletar tag
|
|
117
|
-
* Parâmetros:
|
|
118
|
-
* - owner (obrigatório): Proprietário do repositório
|
|
119
|
-
* - repo (obrigatório): Nome do repositório
|
|
120
|
-
* - tag (obrigatório): Nome da tag
|
|
121
|
-
*
|
|
122
|
-
* 5. search - Buscar tags
|
|
123
|
-
* Parâmetros:
|
|
124
|
-
* - owner (obrigatório): Proprietário do repositório
|
|
125
|
-
* - repo (obrigatório): Nome do repositório
|
|
126
|
-
* - query (opcional): Termo de busca
|
|
127
|
-
* - pattern (opcional): Padrão de busca (ex: v*.*.*)
|
|
128
|
-
*
|
|
129
|
-
* RECOMENDAÇÕES DE USO:
|
|
130
|
-
* - Use convenções de nomenclatura consistentes
|
|
131
|
-
* - Documente propósito das tags
|
|
132
|
-
* - Mantenha tags organizadas
|
|
133
|
-
* - Use versionamento semântico
|
|
134
|
-
* - Use tags anotadas para releases importantes
|
|
135
|
-
* - Limpe tags antigas regularmente
|
|
136
|
-
*/
|
|
137
|
-
exports.tagsTool = {
|
|
138
|
-
name: 'git-tags',
|
|
139
|
-
description: 'tool: Gerencia tags Git para versionamento e releases\n──────────────\naction create: cria nova tag\naction create requires: repo, tag_name, message, target, type, tagger_name, tagger_email, provider\n───────────────\naction list: lista tags do repositório\naction list requires: repo, page,provider\n───────────────\naction get: obtém detalhes de tag\naction get requires: repo, tag, provider\n───────────────\naction delete: remove tag\naction delete requires: repo, tag, provider\n───────────────\naction search: busca tags por critérios\naction search requires: repo, query, pattern, provider',
|
|
140
|
-
inputSchema: {
|
|
141
|
-
type: 'object',
|
|
142
|
-
properties: {
|
|
143
|
-
action: {
|
|
144
|
-
type: 'string',
|
|
145
|
-
enum: ['create', 'list', 'get', 'delete', 'search'],
|
|
146
|
-
description: 'Action to perform on tags'
|
|
147
|
-
},
|
|
148
|
-
repo: { type: 'string', description: 'Repository name' },
|
|
149
|
-
provider: { type: 'string', description: 'Provider to use (github, gitea, or omit for default)' },
|
|
150
|
-
tag_name: { type: 'string', description: 'Tag name' },
|
|
151
|
-
message: { type: 'string', description: 'Tag message (for annotated tags)' },
|
|
152
|
-
target: { type: 'string', description: 'Target commit SHA, branch or tag' },
|
|
153
|
-
type: { type: 'string', enum: ['lightweight', 'annotated'], description: 'Tag type' },
|
|
154
|
-
tagger_name: { type: 'string', description: 'Tagger name' },
|
|
155
|
-
tagger_email: { type: 'string', description: 'Tagger email' },
|
|
156
|
-
tag: { type: 'string', description: 'Tag name for get/delete operations' },
|
|
157
|
-
page: { type: 'number', description: 'Page number', minimum: 1 },
|
|
158
|
-
query: { type: 'string', description: 'Search query' },
|
|
159
|
-
pattern: { type: 'string', description: 'Search pattern (e.g., v*.*.*)' }
|
|
160
|
-
},
|
|
161
|
-
required: ['action', 'provider', 'projectPath']
|
|
162
|
-
},
|
|
163
|
-
/**
|
|
164
|
-
* Handler principal da tool tags
|
|
165
|
-
*
|
|
166
|
-
* FUNCIONALIDADE:
|
|
167
|
-
* - Valida entrada usando Zod schema
|
|
168
|
-
* - Roteia para método específico baseado na ação
|
|
169
|
-
* - Trata erros de forma uniforme
|
|
170
|
-
* - Retorna resultado padronizado
|
|
171
|
-
*
|
|
172
|
-
* FLUXO:
|
|
173
|
-
* 1. Validação de entrada
|
|
174
|
-
* 2. Seleção do provider
|
|
175
|
-
* 3. Roteamento por ação
|
|
176
|
-
* 4. Execução do método específico
|
|
177
|
-
* 5. Tratamento de erros
|
|
178
|
-
* 6. Retorno de resultado
|
|
179
|
-
*
|
|
180
|
-
* TRATAMENTO DE ERROS:
|
|
181
|
-
* - Validação: erro de schema
|
|
182
|
-
* - Execução: erro da operação
|
|
183
|
-
* - Roteamento: ação não suportada
|
|
184
|
-
*
|
|
185
|
-
* RECOMENDAÇÕES:
|
|
186
|
-
* - Sempre valide entrada antes de processar
|
|
187
|
-
* - Trate erros específicos adequadamente
|
|
188
|
-
* - Log detalhes de erro para debug
|
|
189
|
-
* - Retorne mensagens de erro úteis
|
|
190
|
-
*/
|
|
191
|
-
async handler(input) {
|
|
65
|
+
class SmartTagManager {
|
|
66
|
+
static async getAllTags(projectPath) {
|
|
67
|
+
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
192
68
|
try {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const finalInput = await (0, user_detection_js_1.applyAutoUserDetection)(processedInput, processedInput.provider);
|
|
198
|
-
// Usar o provider especificado pelo usuário (obrigatório)
|
|
199
|
-
if (!processedInput.provider) {
|
|
200
|
-
throw new Error("Parâmetro 'provider' é obrigatório e não pode ser omitido");
|
|
201
|
-
}
|
|
202
|
-
const provider = index_js_1.globalProviderFactory.getProvider(processedInput.provider);
|
|
203
|
-
if (!provider) {
|
|
204
|
-
throw new Error(`Provider '${processedInput.provider}' não encontrado`);
|
|
205
|
-
}
|
|
206
|
-
switch (processedInput.action) {
|
|
207
|
-
case 'create':
|
|
208
|
-
return await this.createTag(processedInput, provider);
|
|
209
|
-
case 'list':
|
|
210
|
-
return await this.listTags(processedInput, provider);
|
|
211
|
-
case 'get':
|
|
212
|
-
return await this.getTag(processedInput, provider);
|
|
213
|
-
case 'delete':
|
|
214
|
-
return await this.deleteTag(processedInput, provider);
|
|
215
|
-
case 'search':
|
|
216
|
-
return await this.searchTags(processedInput, provider);
|
|
217
|
-
default:
|
|
218
|
-
throw new Error(`Ação não suportada: ${processedInput.action}`);
|
|
69
|
+
// Get all tags with details
|
|
70
|
+
const tagResult = await gitOps.runCommand('git', ['tag', '-l', '--format=%(refname:short)|%(objectname)|%(creatordate)|%(subject)']);
|
|
71
|
+
if (!tagResult.success) {
|
|
72
|
+
return [];
|
|
219
73
|
}
|
|
74
|
+
const lines = tagResult.output.trim().split('\n');
|
|
75
|
+
const tags = [];
|
|
76
|
+
lines.forEach(line => {
|
|
77
|
+
const parts = line.split('|');
|
|
78
|
+
if (parts.length >= 4) {
|
|
79
|
+
const [name, hash, date, message] = parts;
|
|
80
|
+
tags.push({
|
|
81
|
+
name,
|
|
82
|
+
hash,
|
|
83
|
+
date: new Date(date),
|
|
84
|
+
message: message.trim(),
|
|
85
|
+
type: this.detectTagType(name),
|
|
86
|
+
version: this.parseVersion(name)
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return tags;
|
|
220
91
|
}
|
|
221
92
|
catch (error) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
static async getTagInfo(projectPath, tagName) {
|
|
97
|
+
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
98
|
+
try {
|
|
99
|
+
// Check if tag exists
|
|
100
|
+
const existsResult = await gitOps.runCommand('git', ['tag', '-l', tagName]);
|
|
101
|
+
const exists = existsResult.success && existsResult.output.trim() === tagName;
|
|
102
|
+
if (!exists) {
|
|
103
|
+
return { name: tagName, exists: false };
|
|
104
|
+
}
|
|
105
|
+
// Get detailed info
|
|
106
|
+
const showResult = await gitOps.runCommand('git', ['show', '--quiet', '--format=fuller', tagName]);
|
|
107
|
+
const info = this.parseTagShow(showResult.success ? showResult.output : '');
|
|
222
108
|
return {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
109
|
+
name: tagName,
|
|
110
|
+
exists: true,
|
|
111
|
+
...info,
|
|
112
|
+
type: this.detectTagType(tagName),
|
|
113
|
+
version: this.parseVersion(tagName)
|
|
227
114
|
};
|
|
228
115
|
}
|
|
229
|
-
|
|
116
|
+
catch (error) {
|
|
117
|
+
return { name: tagName, exists: false, error: error instanceof Error ? error.message : String(error) };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
static parseTagShow(output) {
|
|
121
|
+
const lines = output.split('\n');
|
|
122
|
+
let info = {
|
|
123
|
+
hash: '',
|
|
124
|
+
author: '',
|
|
125
|
+
date: null,
|
|
126
|
+
message: ''
|
|
127
|
+
};
|
|
128
|
+
let inMessage = false;
|
|
129
|
+
let messageLines = [];
|
|
130
|
+
lines.forEach(line => {
|
|
131
|
+
if (line.startsWith('commit ')) {
|
|
132
|
+
info.hash = line.substring(7);
|
|
133
|
+
}
|
|
134
|
+
else if (line.startsWith('Tagger:')) {
|
|
135
|
+
info.author = line.substring(7).trim();
|
|
136
|
+
}
|
|
137
|
+
else if (line.startsWith('Date:')) {
|
|
138
|
+
info.date = new Date(line.substring(5).trim());
|
|
139
|
+
}
|
|
140
|
+
else if (line.startsWith('Tag:')) {
|
|
141
|
+
// Lightweight tag
|
|
142
|
+
info.lightweight = true;
|
|
143
|
+
}
|
|
144
|
+
else if (inMessage || (!line.trim() && messageLines.length > 0)) {
|
|
145
|
+
inMessage = true;
|
|
146
|
+
messageLines.push(line);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
info.message = messageLines.join('\n').trim();
|
|
150
|
+
return info;
|
|
151
|
+
}
|
|
152
|
+
static detectTagType(tagName) {
|
|
153
|
+
// Check for semantic versioning
|
|
154
|
+
if (/^v?\d+\.\d+\.\d+/.test(tagName)) {
|
|
155
|
+
return 'semantic';
|
|
156
|
+
}
|
|
157
|
+
// For now, we can't easily distinguish annotated vs lightweight without more git commands
|
|
158
|
+
// This would require checking if the tag points to a tag object or directly to a commit
|
|
159
|
+
return 'other';
|
|
160
|
+
}
|
|
161
|
+
static parseVersion(tagName) {
|
|
162
|
+
const match = tagName.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
|
|
163
|
+
if (!match)
|
|
164
|
+
return null;
|
|
165
|
+
return {
|
|
166
|
+
major: parseInt(match[1]),
|
|
167
|
+
minor: parseInt(match[2]),
|
|
168
|
+
patch: parseInt(match[3]),
|
|
169
|
+
prerelease: match[4]
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
static generateTagMessage(tagName, customMessage) {
|
|
173
|
+
if (customMessage)
|
|
174
|
+
return customMessage;
|
|
175
|
+
const version = this.parseVersion(tagName);
|
|
176
|
+
if (version) {
|
|
177
|
+
return `Release ${tagName}`;
|
|
178
|
+
}
|
|
179
|
+
return `Tag: ${tagName}`;
|
|
180
|
+
}
|
|
181
|
+
static validateTagName(name) {
|
|
182
|
+
// Git tag name rules
|
|
183
|
+
if (!name || name.trim().length === 0) {
|
|
184
|
+
return { valid: false, error: 'Tag name cannot be empty' };
|
|
185
|
+
}
|
|
186
|
+
if (name.includes(' ')) {
|
|
187
|
+
return { valid: false, error: 'Tag name cannot contain spaces' };
|
|
188
|
+
}
|
|
189
|
+
if (name.startsWith('-') || name.endsWith('-')) {
|
|
190
|
+
return { valid: false, error: 'Tag name cannot start or end with dash' };
|
|
191
|
+
}
|
|
192
|
+
// Check for invalid characters
|
|
193
|
+
if (/[^a-zA-Z0-9._-]/g.test(name)) {
|
|
194
|
+
return { valid: false, error: 'Tag name contains invalid characters' };
|
|
195
|
+
}
|
|
196
|
+
return { valid: true };
|
|
197
|
+
}
|
|
198
|
+
static sortTags(tags, sortBy) {
|
|
199
|
+
return tags.sort((a, b) => {
|
|
200
|
+
switch (sortBy) {
|
|
201
|
+
case 'version':
|
|
202
|
+
const aVer = a.version;
|
|
203
|
+
const bVer = b.version;
|
|
204
|
+
if (!aVer && !bVer)
|
|
205
|
+
return a.name.localeCompare(b.name);
|
|
206
|
+
if (!aVer)
|
|
207
|
+
return 1;
|
|
208
|
+
if (!bVer)
|
|
209
|
+
return -1;
|
|
210
|
+
if (aVer.major !== bVer.major)
|
|
211
|
+
return bVer.major - aVer.major;
|
|
212
|
+
if (aVer.minor !== bVer.minor)
|
|
213
|
+
return bVer.minor - aVer.minor;
|
|
214
|
+
return bVer.patch - aVer.patch;
|
|
215
|
+
case 'date':
|
|
216
|
+
return b.date.getTime() - a.date.getTime();
|
|
217
|
+
case 'name':
|
|
218
|
+
default:
|
|
219
|
+
return a.name.localeCompare(b.name);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
static filterTags(tags, pattern) {
|
|
224
|
+
if (!pattern)
|
|
225
|
+
return tags;
|
|
226
|
+
const regex = new RegExp(pattern.replace(/\*/g, '.*'), 'i');
|
|
227
|
+
return tags.filter(tag => regex.test(tag.name));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Classe principal para executar operações Git tags
|
|
232
|
+
*/
|
|
233
|
+
class GitTagsExecutor {
|
|
234
|
+
errorHandler = new error_handler_js_1.UniversalErrorHandler();
|
|
230
235
|
/**
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
* FUNCIONALIDADE:
|
|
234
|
-
* - Cria tag com nome e target especificados
|
|
235
|
-
* - Suporta tags lightweight e anotadas
|
|
236
|
-
* - Permite configuração de tagger
|
|
237
|
-
*
|
|
238
|
-
* PARÂMETROS OBRIGATÓRIOS:
|
|
239
|
-
* - owner: Proprietário do repositório
|
|
240
|
-
* - repo: Nome do repositório
|
|
241
|
-
* - tag_name: Nome da tag
|
|
242
|
-
* - target: Commit, branch ou tag alvo
|
|
243
|
-
*
|
|
244
|
-
* PARÂMETROS OPCIONAIS:
|
|
245
|
-
* - message: Mensagem da tag (para tags anotadas)
|
|
246
|
-
* - type: Tipo de tag (lightweight, annotated) - padrão: lightweight
|
|
247
|
-
* - tagger_name: Nome do tagger (para tags anotadas)
|
|
248
|
-
* - tagger_email: Email do tagger (para tags anotadas)
|
|
249
|
-
*
|
|
250
|
-
* VALIDAÇÕES:
|
|
251
|
-
* - Todos os parâmetros obrigatórios
|
|
252
|
-
* - Nome da tag deve ser único no repositório
|
|
253
|
-
* - Target deve existir
|
|
254
|
-
* - Usuário deve ter permissão de escrita
|
|
255
|
-
*
|
|
256
|
-
* RECOMENDAÇÕES:
|
|
257
|
-
* - Use convenções de nomenclatura consistentes
|
|
258
|
-
* - Use tags anotadas para releases importantes
|
|
259
|
-
* - Documente propósito da tag
|
|
260
|
-
* - Use versionamento semântico
|
|
236
|
+
* Executa operação create
|
|
261
237
|
*/
|
|
262
|
-
async
|
|
238
|
+
async executeCreate(detection, input) {
|
|
263
239
|
try {
|
|
264
|
-
|
|
265
|
-
|
|
240
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
241
|
+
// Validate tag name
|
|
242
|
+
const nameValidation = SmartTagManager.validateTagName(input.name);
|
|
243
|
+
if (!nameValidation.valid) {
|
|
244
|
+
throw new Error(`Invalid tag name: ${nameValidation.error}`);
|
|
266
245
|
}
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
target: params.target
|
|
272
|
-
};
|
|
273
|
-
if (params.type === 'annotated') {
|
|
274
|
-
if (params.message)
|
|
275
|
-
tagData.message = params.message;
|
|
276
|
-
if (params.tagger_name)
|
|
277
|
-
tagData.tagger_name = params.tagger_name;
|
|
278
|
-
if (params.tagger_email)
|
|
279
|
-
tagData.tagger_email = params.tagger_email;
|
|
246
|
+
// Check if tag already exists
|
|
247
|
+
const existingTag = await SmartTagManager.getTagInfo(detection.projectPath, input.name);
|
|
248
|
+
if (existingTag.exists && !input.force) {
|
|
249
|
+
throw new Error(`Tag '${input.name}' already exists. Use force=true to overwrite.`);
|
|
280
250
|
}
|
|
281
|
-
|
|
282
|
-
|
|
251
|
+
// Determine target
|
|
252
|
+
const target = input.target || 'HEAD';
|
|
253
|
+
// Validate target exists
|
|
254
|
+
const targetResult = await gitOps.runCommand('git', ['rev-parse', '--verify', target]);
|
|
255
|
+
if (!targetResult.success) {
|
|
256
|
+
throw new Error(`Invalid target reference: ${target}`);
|
|
257
|
+
}
|
|
258
|
+
// Generate message if not provided
|
|
259
|
+
const message = SmartTagManager.generateTagMessage(input.name, input.message);
|
|
260
|
+
// Create tag
|
|
261
|
+
const tagArgs = input.type === 'annotated' ?
|
|
262
|
+
['tag', '-a', input.name, '-m', message, target] :
|
|
263
|
+
['tag', input.name, target];
|
|
264
|
+
if (input.force) {
|
|
265
|
+
tagArgs.splice(1, 0, '-f');
|
|
266
|
+
}
|
|
267
|
+
const tagResult = await gitOps.runCommand('git', tagArgs);
|
|
268
|
+
if (!tagResult.success) {
|
|
269
|
+
throw new Error(`Failed to create tag: ${tagResult.error}`);
|
|
270
|
+
}
|
|
271
|
+
// Push tag to all providers
|
|
272
|
+
for (const provider of detection.providers) {
|
|
273
|
+
try {
|
|
274
|
+
await gitOps.runCommand('git', ['push', provider, input.name]);
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
console.warn(`Failed to push tag to ${provider}:`, error);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
283
281
|
success: true,
|
|
284
282
|
action: 'create',
|
|
285
|
-
message: `Tag '${
|
|
286
|
-
data:
|
|
287
|
-
|
|
283
|
+
message: `Tag '${input.name}' created successfully`,
|
|
284
|
+
data: {
|
|
285
|
+
tag: input.name,
|
|
286
|
+
message: message,
|
|
287
|
+
target: target,
|
|
288
|
+
type: input.type,
|
|
289
|
+
force: input.force,
|
|
290
|
+
pushed: detection.providers,
|
|
291
|
+
tagType: SmartTagManager.detectTagType(input.name)
|
|
292
|
+
},
|
|
293
|
+
autoDetected: {
|
|
294
|
+
repo: detection.repoName,
|
|
295
|
+
owner: detection.owner,
|
|
296
|
+
providers: detection.providers
|
|
297
|
+
}
|
|
298
|
+
});
|
|
288
299
|
}
|
|
289
300
|
catch (error) {
|
|
290
|
-
|
|
301
|
+
return this.errorHandler.toUniversalResponse();
|
|
291
302
|
}
|
|
292
|
-
}
|
|
303
|
+
}
|
|
293
304
|
/**
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
* FUNCIONALIDADE:
|
|
297
|
-
* - Lista tags com paginação
|
|
298
|
-
* - Retorna informações básicas de cada tag
|
|
299
|
-
* - Inclui commit alvo e URLs de download
|
|
300
|
-
*
|
|
301
|
-
* PARÂMETROS OBRIGATÓRIOS:
|
|
302
|
-
* - owner: Proprietário do repositório
|
|
303
|
-
* - repo: Nome do repositório
|
|
304
|
-
*
|
|
305
|
-
* PARÂMETROS OPCIONAIS:
|
|
306
|
-
* - page: Página da listagem (padrão: 1)
|
|
307
|
-
* - limit: Itens por página (padrão: 30, máximo: 100)
|
|
308
|
-
*
|
|
309
|
-
* VALIDAÇÕES:
|
|
310
|
-
* - e repo obrigatórios
|
|
311
|
-
* - Page deve ser >= 1
|
|
312
|
-
* - Limit deve ser entre 1 e 100
|
|
313
|
-
*
|
|
314
|
-
* RECOMENDAÇÕES:
|
|
315
|
-
* - Use paginação para repositórios com muitas tags
|
|
316
|
-
* - Monitore número total de tags
|
|
317
|
-
* - Verifique commit alvo de cada tag
|
|
318
|
-
* - Mantenha tags organizadas
|
|
305
|
+
* Executa operação list
|
|
319
306
|
*/
|
|
320
|
-
async
|
|
307
|
+
async executeList(detection, input) {
|
|
321
308
|
try {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
const page = params.page || 1;
|
|
328
|
-
const tags = await provider.listTags((await provider.getCurrentUser()).login, params.repo, page);
|
|
329
|
-
return {
|
|
309
|
+
const allTags = await SmartTagManager.getAllTags(detection.projectPath);
|
|
310
|
+
const filteredTags = SmartTagManager.filterTags(allTags, input.pattern);
|
|
311
|
+
const sortedTags = SmartTagManager.sortTags(filteredTags, input.sort);
|
|
312
|
+
const limitedTags = sortedTags.slice(0, input.limit);
|
|
313
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
330
314
|
success: true,
|
|
331
315
|
action: 'list',
|
|
332
|
-
message:
|
|
316
|
+
message: `Found ${limitedTags.length} tags`,
|
|
333
317
|
data: {
|
|
334
|
-
tags,
|
|
335
|
-
|
|
336
|
-
|
|
318
|
+
tags: limitedTags,
|
|
319
|
+
total: allTags.length,
|
|
320
|
+
filtered: filteredTags.length,
|
|
321
|
+
pattern: input.pattern,
|
|
322
|
+
sort: input.sort,
|
|
323
|
+
limit: input.limit
|
|
324
|
+
},
|
|
325
|
+
autoDetected: {
|
|
326
|
+
repo: detection.repoName,
|
|
327
|
+
owner: detection.owner,
|
|
328
|
+
providers: detection.providers
|
|
337
329
|
}
|
|
338
|
-
};
|
|
330
|
+
});
|
|
339
331
|
}
|
|
340
332
|
catch (error) {
|
|
341
|
-
|
|
333
|
+
return this.errorHandler.toUniversalResponse();
|
|
342
334
|
}
|
|
343
|
-
}
|
|
335
|
+
}
|
|
344
336
|
/**
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
* FUNCIONALIDADE:
|
|
348
|
-
* - Retorna informações completas da tag
|
|
349
|
-
* - Inclui nome, commit alvo e URLs
|
|
350
|
-
* - Mostra tipo da tag (lightweight/anotada)
|
|
351
|
-
*
|
|
352
|
-
* PARÂMETROS OBRIGATÓRIOS:
|
|
353
|
-
* - owner: Proprietário do repositório
|
|
354
|
-
* - repo: Nome do repositório
|
|
355
|
-
* - tag: Nome da tag
|
|
356
|
-
*
|
|
357
|
-
* VALIDAÇÕES:
|
|
358
|
-
* - Todos os parâmetros obrigatórios
|
|
359
|
-
* - Tag deve existir no repositório
|
|
360
|
-
* - Nome deve ser válido
|
|
361
|
-
*
|
|
362
|
-
* RECOMENDAÇÕES:
|
|
363
|
-
* - Use para obter detalhes completos
|
|
364
|
-
* - Verifique commit alvo da tag
|
|
365
|
-
* - Analise URLs de download
|
|
366
|
-
* - Monitore mudanças importantes
|
|
337
|
+
* Executa operação get
|
|
367
338
|
*/
|
|
368
|
-
async
|
|
339
|
+
async executeGet(detection, input) {
|
|
369
340
|
try {
|
|
370
|
-
|
|
371
|
-
|
|
341
|
+
const tagInfo = await SmartTagManager.getTagInfo(detection.projectPath, input.name);
|
|
342
|
+
if (!tagInfo.exists) {
|
|
343
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
344
|
+
success: false,
|
|
345
|
+
action: 'get',
|
|
346
|
+
message: `Tag '${input.name}' not found`,
|
|
347
|
+
error: {
|
|
348
|
+
code: 'TAG_NOT_FOUND',
|
|
349
|
+
message: `Tag '${input.name}' does not exist`,
|
|
350
|
+
cause: 'Tag not found in repository',
|
|
351
|
+
suggestion: 'Check tag name or create it first'
|
|
352
|
+
},
|
|
353
|
+
autoDetected: {
|
|
354
|
+
repo: detection.repoName,
|
|
355
|
+
owner: detection.owner,
|
|
356
|
+
providers: detection.providers
|
|
357
|
+
}
|
|
358
|
+
});
|
|
372
359
|
}
|
|
373
|
-
|
|
374
|
-
const owner = currentUser.login;
|
|
375
|
-
// Implementar obtenção de tag específica
|
|
376
|
-
// Por enquanto, retorna mensagem de funcionalidade
|
|
377
|
-
return {
|
|
360
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
378
361
|
success: true,
|
|
379
362
|
action: 'get',
|
|
380
|
-
message: `Tag '${
|
|
363
|
+
message: `Tag '${input.name}' details`,
|
|
381
364
|
data: {
|
|
382
|
-
tag:
|
|
383
|
-
|
|
365
|
+
tag: tagInfo,
|
|
366
|
+
detailed: input.detailed
|
|
367
|
+
},
|
|
368
|
+
autoDetected: {
|
|
369
|
+
repo: detection.repoName,
|
|
370
|
+
owner: detection.owner,
|
|
371
|
+
providers: detection.providers
|
|
384
372
|
}
|
|
385
|
-
};
|
|
373
|
+
});
|
|
386
374
|
}
|
|
387
375
|
catch (error) {
|
|
388
|
-
|
|
376
|
+
return this.errorHandler.toUniversalResponse();
|
|
389
377
|
}
|
|
390
|
-
}
|
|
378
|
+
}
|
|
391
379
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
* FUNCIONALIDADE:
|
|
395
|
-
* - Remove tag especificada
|
|
396
|
-
* - Mantém commit alvo intacto
|
|
397
|
-
* - Confirma exclusão bem-sucedida
|
|
398
|
-
*
|
|
399
|
-
* PARÂMETROS OBRIGATÓRIOS:
|
|
400
|
-
* - owner: Proprietário do repositório
|
|
401
|
-
* - repo: Nome do repositório
|
|
402
|
-
* - tag: Nome da tag
|
|
403
|
-
*
|
|
404
|
-
* VALIDAÇÕES:
|
|
405
|
-
* - Todos os parâmetros obrigatórios
|
|
406
|
-
* - Tag deve existir
|
|
407
|
-
* - Usuário deve ter permissão de exclusão
|
|
408
|
-
*
|
|
409
|
-
* RECOMENDAÇÕES:
|
|
410
|
-
* - Confirme exclusão antes de executar
|
|
411
|
-
* - Verifique se tag não está sendo usada
|
|
412
|
-
* - Mantenha backup se necessário
|
|
413
|
-
* - Documente motivo da exclusão
|
|
380
|
+
* Executa operação delete
|
|
414
381
|
*/
|
|
415
|
-
async
|
|
382
|
+
async executeDelete(detection, input) {
|
|
416
383
|
try {
|
|
417
|
-
|
|
418
|
-
|
|
384
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
385
|
+
// Check if tag exists
|
|
386
|
+
const tagInfo = await SmartTagManager.getTagInfo(detection.projectPath, input.name);
|
|
387
|
+
if (!tagInfo.exists && !input.force) {
|
|
388
|
+
throw new Error(`Tag '${input.name}' does not exist`);
|
|
419
389
|
}
|
|
420
|
-
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
|
|
390
|
+
// Delete local tag
|
|
391
|
+
const deleteArgs = input.force ? ['tag', '-d', input.name] : ['tag', '-d', input.name];
|
|
392
|
+
const deleteResult = await gitOps.runCommand('git', deleteArgs);
|
|
393
|
+
if (!deleteResult.success && !input.force) {
|
|
394
|
+
throw new Error(`Failed to delete tag: ${deleteResult.error}`);
|
|
395
|
+
}
|
|
396
|
+
// Delete from remotes if requested
|
|
397
|
+
const remoteResults = [];
|
|
398
|
+
if (input.remote) {
|
|
399
|
+
for (const provider of detection.providers) {
|
|
400
|
+
try {
|
|
401
|
+
const remoteDeleteResult = await gitOps.runCommand('git', ['push', provider, `:${input.name}`]);
|
|
402
|
+
remoteResults.push({
|
|
403
|
+
provider,
|
|
404
|
+
success: remoteDeleteResult.success,
|
|
405
|
+
error: remoteDeleteResult.error
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
remoteResults.push({
|
|
410
|
+
provider,
|
|
411
|
+
success: false,
|
|
412
|
+
error: error instanceof Error ? error.message : String(error)
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
424
418
|
success: true,
|
|
425
419
|
action: 'delete',
|
|
426
|
-
message: `Tag '${
|
|
427
|
-
data: {
|
|
428
|
-
|
|
420
|
+
message: `Tag '${input.name}' deleted successfully`,
|
|
421
|
+
data: {
|
|
422
|
+
tag: input.name,
|
|
423
|
+
force: input.force,
|
|
424
|
+
remote: input.remote,
|
|
425
|
+
remoteResults: remoteResults,
|
|
426
|
+
existed: tagInfo.exists
|
|
427
|
+
},
|
|
428
|
+
autoDetected: {
|
|
429
|
+
repo: detection.repoName,
|
|
430
|
+
owner: detection.owner,
|
|
431
|
+
providers: detection.providers
|
|
432
|
+
}
|
|
433
|
+
});
|
|
429
434
|
}
|
|
430
435
|
catch (error) {
|
|
431
|
-
|
|
436
|
+
return this.errorHandler.toUniversalResponse();
|
|
432
437
|
}
|
|
433
|
-
}
|
|
438
|
+
}
|
|
434
439
|
/**
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
* FUNCIONALIDADE:
|
|
438
|
-
* - Busca tags por nome ou padrão
|
|
439
|
-
* - Suporta padrões glob (ex: v*.*.*)
|
|
440
|
-
* - Retorna resultados relevantes
|
|
441
|
-
*
|
|
442
|
-
* PARÂMETROS OBRIGATÓRIOS:
|
|
443
|
-
* - owner: Proprietário do repositório
|
|
444
|
-
* - repo: Nome do repositório
|
|
445
|
-
*
|
|
446
|
-
* PARÂMETROS OPCIONAIS:
|
|
447
|
-
* - query: Termo de busca
|
|
448
|
-
* - pattern: Padrão de busca (ex: v*.*.*)
|
|
449
|
-
*
|
|
450
|
-
* VALIDAÇÕES:
|
|
451
|
-
* - e repo obrigatórios
|
|
452
|
-
* - Query ou pattern deve ser fornecido
|
|
453
|
-
* - Repositório deve existir
|
|
454
|
-
*
|
|
455
|
-
* RECOMENDAÇÕES:
|
|
456
|
-
* - Use padrões glob para busca eficiente
|
|
457
|
-
* - Combine com filtros de nome
|
|
458
|
-
* - Analise resultados para relevância
|
|
459
|
-
* - Use para encontrar tags relacionadas
|
|
440
|
+
* Executa operação search
|
|
460
441
|
*/
|
|
461
|
-
async
|
|
442
|
+
async executeSearch(detection, input) {
|
|
462
443
|
try {
|
|
463
|
-
|
|
464
|
-
|
|
444
|
+
const allTags = await SmartTagManager.getAllTags(detection.projectPath);
|
|
445
|
+
// Search by query
|
|
446
|
+
let matchedTags = allTags.filter(tag => tag.name.toLowerCase().includes(input.query.toLowerCase()) ||
|
|
447
|
+
tag.message.toLowerCase().includes(input.query.toLowerCase()));
|
|
448
|
+
// Apply pattern filter if provided
|
|
449
|
+
if (input.pattern) {
|
|
450
|
+
matchedTags = SmartTagManager.filterTags(matchedTags, input.pattern);
|
|
465
451
|
}
|
|
466
|
-
|
|
467
|
-
|
|
452
|
+
// Sort results
|
|
453
|
+
let sortedTags;
|
|
454
|
+
switch (input.sort) {
|
|
455
|
+
case 'date':
|
|
456
|
+
sortedTags = SmartTagManager.sortTags(matchedTags, 'date');
|
|
457
|
+
break;
|
|
458
|
+
case 'name':
|
|
459
|
+
sortedTags = SmartTagManager.sortTags(matchedTags, 'name');
|
|
460
|
+
break;
|
|
461
|
+
case 'relevance':
|
|
462
|
+
default:
|
|
463
|
+
// For relevance, keep current order (already filtered by query)
|
|
464
|
+
sortedTags = matchedTags;
|
|
465
|
+
break;
|
|
468
466
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
return {
|
|
467
|
+
const limitedTags = sortedTags.slice(0, input.limit);
|
|
468
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
472
469
|
success: true,
|
|
473
470
|
action: 'search',
|
|
474
|
-
message: `
|
|
471
|
+
message: `Found ${limitedTags.length} tags matching '${input.query}'`,
|
|
475
472
|
data: {
|
|
476
|
-
query:
|
|
477
|
-
|
|
478
|
-
|
|
473
|
+
query: input.query,
|
|
474
|
+
results: limitedTags,
|
|
475
|
+
total: allTags.length,
|
|
476
|
+
matched: matchedTags.length,
|
|
477
|
+
pattern: input.pattern,
|
|
478
|
+
sort: input.sort,
|
|
479
|
+
limit: input.limit
|
|
480
|
+
},
|
|
481
|
+
autoDetected: {
|
|
482
|
+
repo: detection.repoName,
|
|
483
|
+
owner: detection.owner,
|
|
484
|
+
providers: detection.providers
|
|
479
485
|
}
|
|
480
|
-
};
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
catch (error) {
|
|
489
|
+
return this.errorHandler.toUniversalResponse();
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Tool principal git-tags
|
|
495
|
+
*/
|
|
496
|
+
exports.gitTagsTool = {
|
|
497
|
+
name: 'git-tags',
|
|
498
|
+
description: `🏷️ GERENCIAMENTO DE TAGS UNIFICADO
|
|
499
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
500
|
+
🎯 TAGS INTELIGENTES:
|
|
501
|
+
• create: Criação com auto-detecção de tipo
|
|
502
|
+
• list: Listagem com filtros e ordenação
|
|
503
|
+
• get: Detalhes completos de tags
|
|
504
|
+
• delete: Remoção local e remota
|
|
505
|
+
• search: Busca avançada por nome/mensagem
|
|
506
|
+
|
|
507
|
+
🔍 VERSIONAMENTO SEMÂNTICO:
|
|
508
|
+
• Detecção automática de tags semânticas
|
|
509
|
+
• Suporte a versionamento (major.minor.patch)
|
|
510
|
+
• Validação de nomes de tags
|
|
511
|
+
• Ordenação por versão
|
|
512
|
+
|
|
513
|
+
⚡ OPERAÇÕES MULTI-PROVIDER:
|
|
514
|
+
• Push automático para todos os providers
|
|
515
|
+
• Delete remoto opcional
|
|
516
|
+
• Sincronização automática
|
|
517
|
+
• Validação de consistência
|
|
518
|
+
|
|
519
|
+
🤖 COMPATÍVEL COM AI AGENTS:
|
|
520
|
+
• Interface universal para qualquer IDE
|
|
521
|
+
• Auto-detecção completa de contexto
|
|
522
|
+
• Respostas estruturadas consistentes
|
|
523
|
+
• Error handling inteligente
|
|
524
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`,
|
|
525
|
+
inputSchema: {
|
|
526
|
+
type: 'object',
|
|
527
|
+
properties: {
|
|
528
|
+
action: {
|
|
529
|
+
type: 'string',
|
|
530
|
+
enum: ['create', 'list', 'get', 'delete', 'search'],
|
|
531
|
+
description: 'Ação do sistema de tags'
|
|
532
|
+
},
|
|
533
|
+
projectPath: {
|
|
534
|
+
type: 'string',
|
|
535
|
+
description: 'Caminho absoluto do projeto'
|
|
536
|
+
},
|
|
537
|
+
name: {
|
|
538
|
+
type: 'string',
|
|
539
|
+
description: 'Nome da tag'
|
|
540
|
+
},
|
|
541
|
+
message: {
|
|
542
|
+
type: 'string',
|
|
543
|
+
description: 'Mensagem da tag (para annotated)'
|
|
544
|
+
},
|
|
545
|
+
target: {
|
|
546
|
+
type: 'string',
|
|
547
|
+
description: 'Target da tag (commit/branch)'
|
|
548
|
+
},
|
|
549
|
+
type: {
|
|
550
|
+
type: 'string',
|
|
551
|
+
enum: ['lightweight', 'annotated'],
|
|
552
|
+
description: 'Tipo da tag'
|
|
553
|
+
},
|
|
554
|
+
force: {
|
|
555
|
+
type: 'boolean',
|
|
556
|
+
description: 'Forçar operação'
|
|
557
|
+
},
|
|
558
|
+
pattern: {
|
|
559
|
+
type: 'string',
|
|
560
|
+
description: 'Padrão para filtrar tags'
|
|
561
|
+
},
|
|
562
|
+
sort: {
|
|
563
|
+
type: 'string',
|
|
564
|
+
enum: ['version', 'date', 'name', 'relevance'],
|
|
565
|
+
description: 'Critério de ordenação'
|
|
566
|
+
},
|
|
567
|
+
limit: {
|
|
568
|
+
type: 'number',
|
|
569
|
+
description: 'Limite de resultados'
|
|
570
|
+
},
|
|
571
|
+
detailed: {
|
|
572
|
+
type: 'boolean',
|
|
573
|
+
description: 'Informações detalhadas'
|
|
574
|
+
},
|
|
575
|
+
remote: {
|
|
576
|
+
type: 'boolean',
|
|
577
|
+
description: 'Operação também no remote'
|
|
578
|
+
},
|
|
579
|
+
query: {
|
|
580
|
+
type: 'string',
|
|
581
|
+
description: 'Termo de busca'
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
required: ['action', 'projectPath']
|
|
585
|
+
},
|
|
586
|
+
async handler(input) {
|
|
587
|
+
const executor = new GitTagsExecutor();
|
|
588
|
+
try {
|
|
589
|
+
// Validate input
|
|
590
|
+
const validatedInput = GitTagsInputSchema.parse(input);
|
|
591
|
+
// Auto-detect context
|
|
592
|
+
const detection = await (0, auto_detection_js_1.autoDetect)(validatedInput.projectPath);
|
|
593
|
+
await (0, auto_detection_js_1.validateAutoDetection)(detection);
|
|
594
|
+
// Execute specific action
|
|
595
|
+
switch (validatedInput.action) {
|
|
596
|
+
case 'create':
|
|
597
|
+
return await executor['executeCreate'](detection, validatedInput);
|
|
598
|
+
case 'list':
|
|
599
|
+
return await executor['executeList'](detection, validatedInput);
|
|
600
|
+
case 'get':
|
|
601
|
+
return await executor['executeGet'](detection, validatedInput);
|
|
602
|
+
case 'delete':
|
|
603
|
+
return await executor['executeDelete'](detection, validatedInput);
|
|
604
|
+
case 'search':
|
|
605
|
+
return await executor['executeSearch'](detection, validatedInput);
|
|
606
|
+
default:
|
|
607
|
+
throw new Error(`Ação '${validatedInput.action}' não suportada`);
|
|
608
|
+
}
|
|
481
609
|
}
|
|
482
610
|
catch (error) {
|
|
483
|
-
|
|
611
|
+
executor.errorHandler.addError(error);
|
|
612
|
+
return executor.errorHandler.toUniversalResponse();
|
|
484
613
|
}
|
|
485
614
|
}
|
|
486
615
|
};
|