@andrebuzeli/git-mcp 4.0.20 → 4.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +7 -239
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -221
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +11 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -16
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +1 -69
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +150 -711
- package/dist/server.js.map +1 -1
- package/dist/tools/git-analytics.d.ts +1 -0
- package/dist/tools/git-analytics.d.ts.map +1 -1
- package/dist/tools/git-analytics.js +18 -7
- package/dist/tools/git-analytics.js.map +1 -1
- package/dist/tools/git-archive.d.ts +2 -149
- package/dist/tools/git-archive.d.ts.map +1 -1
- package/dist/tools/git-archive.js +5 -222
- package/dist/tools/git-archive.js.map +1 -1
- package/dist/tools/git-backup.d.ts +1 -198
- package/dist/tools/git-backup.d.ts.map +1 -1
- package/dist/tools/git-backup.js +4 -805
- package/dist/tools/git-backup.js.map +1 -1
- package/dist/tools/git-branches.d.ts +1 -158
- package/dist/tools/git-branches.d.ts.map +1 -1
- package/dist/tools/git-branches.js +4 -539
- package/dist/tools/git-branches.js.map +1 -1
- package/dist/tools/git-config.d.ts +2 -124
- package/dist/tools/git-config.d.ts.map +1 -1
- package/dist/tools/git-config.js +5 -263
- package/dist/tools/git-config.js.map +1 -1
- package/dist/tools/git-files.d.ts +2 -115
- package/dist/tools/git-files.d.ts.map +1 -1
- package/dist/tools/git-files.js +161 -407
- package/dist/tools/git-files.js.map +1 -1
- package/dist/tools/git-issues.d.ts +1 -214
- package/dist/tools/git-issues.d.ts.map +1 -1
- package/dist/tools/git-issues.js +4 -678
- package/dist/tools/git-issues.js.map +1 -1
- package/dist/tools/git-monitor.d.ts +1 -143
- package/dist/tools/git-monitor.d.ts.map +1 -1
- package/dist/tools/git-monitor.js +4 -738
- package/dist/tools/git-monitor.js.map +1 -1
- package/dist/tools/git-packages.d.ts +2 -91
- package/dist/tools/git-packages.d.ts.map +1 -1
- package/dist/tools/git-packages.js +5 -258
- package/dist/tools/git-packages.js.map +1 -1
- package/dist/tools/git-pulls.d.ts +1 -63
- package/dist/tools/git-pulls.d.ts.map +1 -1
- package/dist/tools/git-pulls.js +4 -77
- package/dist/tools/git-pulls.js.map +1 -1
- package/dist/tools/git-release.d.ts +1 -169
- package/dist/tools/git-release.d.ts.map +1 -1
- package/dist/tools/git-release.js +4 -611
- package/dist/tools/git-release.js.map +1 -1
- package/dist/tools/git-remote.d.ts +1 -153
- package/dist/tools/git-remote.d.ts.map +1 -1
- package/dist/tools/git-remote.js +4 -555
- package/dist/tools/git-remote.js.map +1 -1
- package/dist/tools/git-reset.d.ts +1 -157
- package/dist/tools/git-reset.d.ts.map +1 -1
- package/dist/tools/git-reset.js +4 -597
- package/dist/tools/git-reset.js.map +1 -1
- package/dist/tools/git-stash.d.ts +1 -161
- package/dist/tools/git-stash.d.ts.map +1 -1
- package/dist/tools/git-stash.js +4 -640
- package/dist/tools/git-stash.js.map +1 -1
- package/dist/tools/git-sync.d.ts +1 -0
- package/dist/tools/git-sync.d.ts.map +1 -1
- package/dist/tools/git-sync.js +13 -7
- package/dist/tools/git-sync.js.map +1 -1
- package/dist/tools/git-tags.d.ts +1 -162
- package/dist/tools/git-tags.d.ts.map +1 -1
- package/dist/tools/git-tags.js +4 -549
- package/dist/tools/git-tags.js.map +1 -1
- package/dist/tools/git-workflow.d.ts +3 -96
- package/dist/tools/git-workflow.d.ts.map +1 -1
- package/dist/tools/git-workflow.js +287 -314
- package/dist/tools/git-workflow.js.map +1 -1
- package/package.json +3 -3
- package/dist/server-minimal.d.ts +0 -8
- package/dist/server-minimal.d.ts.map +0 -1
- package/dist/server-minimal.js +0 -218
- package/dist/server-minimal.js.map +0 -1
package/dist/tools/git-issues.js
CHANGED
|
@@ -1,688 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.gitIssuesTool = void 0;
|
|
37
|
-
const zod_1 = require("zod");
|
|
38
4
|
const auto_detection_js_1 = require("../utils/auto-detection.js");
|
|
39
|
-
const error_handler_js_1 = require("../utils/error-handler.js");
|
|
40
|
-
/**
|
|
41
|
-
* Tool: git-issues
|
|
42
|
-
*
|
|
43
|
-
* SISTEMA DE ISSUES PARA DESENVOLVEDOR INDIVIDUAL
|
|
44
|
-
* Issues locais inteligentes para tracking de tarefas e TODOs
|
|
45
|
-
*
|
|
46
|
-
* DESIGNED FOR: Programador individual autônomo
|
|
47
|
-
* PHILOSOPHY: Issues simples e locais para produtividade pessoal
|
|
48
|
-
*/
|
|
49
|
-
const GitIssuesInputSchema = zod_1.z.discriminatedUnion('action', [
|
|
50
|
-
// CREATE ISSUE - Criação inteligente
|
|
51
|
-
zod_1.z.object({
|
|
52
|
-
action: zod_1.z.literal('create'),
|
|
53
|
-
projectPath: zod_1.z.string(),
|
|
54
|
-
title: zod_1.z.string(),
|
|
55
|
-
description: zod_1.z.string().optional(),
|
|
56
|
-
labels: zod_1.z.array(zod_1.z.string()).optional(), // priority, bug, feature, todo, etc.
|
|
57
|
-
priority: zod_1.z.enum(['low', 'medium', 'high', 'urgent']).default('medium'),
|
|
58
|
-
assignee: zod_1.z.string().optional(), // Auto-detect user
|
|
59
|
-
dueDate: zod_1.z.string().optional() // ISO date string
|
|
60
|
-
}),
|
|
61
|
-
// LIST ISSUES - Listagem com filtros
|
|
62
|
-
zod_1.z.object({
|
|
63
|
-
action: zod_1.z.literal('list'),
|
|
64
|
-
projectPath: zod_1.z.string(),
|
|
65
|
-
state: zod_1.z.enum(['open', 'closed', 'all']).default('all'),
|
|
66
|
-
labels: zod_1.z.array(zod_1.z.string()).optional(),
|
|
67
|
-
priority: zod_1.z.enum(['low', 'medium', 'high', 'urgent']).optional(),
|
|
68
|
-
limit: zod_1.z.number().default(20),
|
|
69
|
-
sort: zod_1.z.enum(['created', 'updated', 'priority', 'due_date']).default('created')
|
|
70
|
-
}),
|
|
71
|
-
// GET ISSUE - Detalhes específicos
|
|
72
|
-
zod_1.z.object({
|
|
73
|
-
action: zod_1.z.literal('get'),
|
|
74
|
-
projectPath: zod_1.z.string(),
|
|
75
|
-
id: zod_1.z.string(), // Issue ID
|
|
76
|
-
detailed: zod_1.z.boolean().default(false)
|
|
77
|
-
}),
|
|
78
|
-
// UPDATE ISSUE - Atualização
|
|
79
|
-
zod_1.z.object({
|
|
80
|
-
action: zod_1.z.literal('update'),
|
|
81
|
-
projectPath: zod_1.z.string(),
|
|
82
|
-
id: zod_1.z.string(),
|
|
83
|
-
title: zod_1.z.string().optional(),
|
|
84
|
-
description: zod_1.z.string().optional(),
|
|
85
|
-
state: zod_1.z.enum(['open', 'closed']).optional(),
|
|
86
|
-
labels: zod_1.z.array(zod_1.z.string()).optional(),
|
|
87
|
-
priority: zod_1.z.enum(['low', 'medium', 'high', 'urgent']).optional(),
|
|
88
|
-
assignee: zod_1.z.string().optional(),
|
|
89
|
-
dueDate: zod_1.z.string().optional()
|
|
90
|
-
}),
|
|
91
|
-
// CLOSE ISSUE - Fechamento
|
|
92
|
-
zod_1.z.object({
|
|
93
|
-
action: zod_1.z.literal('close'),
|
|
94
|
-
projectPath: zod_1.z.string(),
|
|
95
|
-
id: zod_1.z.string(),
|
|
96
|
-
comment: zod_1.z.string().optional()
|
|
97
|
-
}),
|
|
98
|
-
// SCAN CODE - Auto-detect TODOs/FIXMEs
|
|
99
|
-
zod_1.z.object({
|
|
100
|
-
action: zod_1.z.literal('scan'),
|
|
101
|
-
projectPath: zod_1.z.string(),
|
|
102
|
-
createIssues: zod_1.z.boolean().default(false), // Auto-create issues from TODOs
|
|
103
|
-
patterns: zod_1.z.array(zod_1.z.string()).optional() // Custom patterns to scan
|
|
104
|
-
})
|
|
105
|
-
]);
|
|
106
|
-
/**
|
|
107
|
-
* Local Issue Manager
|
|
108
|
-
* Gerencia issues locais em arquivos JSON
|
|
109
|
-
*/
|
|
110
|
-
class LocalIssueManager {
|
|
111
|
-
static ISSUES_DIR = '.git/issues';
|
|
112
|
-
static ISSUES_FILE = 'issues.json';
|
|
113
|
-
static async ensureIssuesDirectory(projectPath) {
|
|
114
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
115
|
-
try {
|
|
116
|
-
await fs.access(`${projectPath}/${this.ISSUES_DIR}`);
|
|
117
|
-
}
|
|
118
|
-
catch (e) {
|
|
119
|
-
await fs.mkdir(`${projectPath}/${this.ISSUES_DIR}`, { recursive: true });
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
static async loadIssues(projectPath) {
|
|
123
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
124
|
-
try {
|
|
125
|
-
await this.ensureIssuesDirectory(projectPath);
|
|
126
|
-
const content = await fs.readFile(`${projectPath}/${this.ISSUES_DIR}/${this.ISSUES_FILE}`, 'utf-8');
|
|
127
|
-
const data = JSON.parse(content);
|
|
128
|
-
return Array.isArray(data.issues) ? data.issues : [];
|
|
129
|
-
}
|
|
130
|
-
catch (e) {
|
|
131
|
-
return [];
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
static async saveIssues(projectPath, issues) {
|
|
135
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
136
|
-
await this.ensureIssuesDirectory(projectPath);
|
|
137
|
-
const data = {
|
|
138
|
-
version: '1.0',
|
|
139
|
-
lastUpdated: new Date().toISOString(),
|
|
140
|
-
issues: issues
|
|
141
|
-
};
|
|
142
|
-
await fs.writeFile(`${projectPath}/${this.ISSUES_DIR}/${this.ISSUES_FILE}`, JSON.stringify(data, null, 2), 'utf-8');
|
|
143
|
-
}
|
|
144
|
-
static generateIssueId() {
|
|
145
|
-
return `I-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`;
|
|
146
|
-
}
|
|
147
|
-
static parseTodoComment(line, filePath, lineNumber) {
|
|
148
|
-
// Parse TODO/FIXME comments
|
|
149
|
-
const todoMatch = line.match(/(?:\/\/|#|--|\/\*)\s*(TODO|FIXME|BUG|HACK|NOTE):\s*(.+)/i);
|
|
150
|
-
if (!todoMatch)
|
|
151
|
-
return null;
|
|
152
|
-
const [, type, description] = todoMatch;
|
|
153
|
-
return {
|
|
154
|
-
type: type.toLowerCase(),
|
|
155
|
-
description: description.trim(),
|
|
156
|
-
file: filePath,
|
|
157
|
-
line: lineNumber,
|
|
158
|
-
raw: line.trim()
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
static createIssueFromTodo(todo, projectPath) {
|
|
162
|
-
const labels = [todo.type];
|
|
163
|
-
let priority = 'medium';
|
|
164
|
-
let title = todo.description;
|
|
165
|
-
// Determine priority based on type
|
|
166
|
-
if (todo.type === 'bug') {
|
|
167
|
-
priority = 'high';
|
|
168
|
-
labels.push('bug');
|
|
169
|
-
}
|
|
170
|
-
else if (todo.type === 'hack') {
|
|
171
|
-
priority = 'low';
|
|
172
|
-
labels.push('technical-debt');
|
|
173
|
-
}
|
|
174
|
-
// Create meaningful title
|
|
175
|
-
if (title.length > 80) {
|
|
176
|
-
title = title.substring(0, 77) + '...';
|
|
177
|
-
}
|
|
178
|
-
const description = `**Arquivo:** \`${todo.file}:${todo.line}\`\n\n**Comentário original:**\n\`\`\`\n${todo.raw}\n\`\`\`\n\n*Issue criada automaticamente a partir de comentário no código.*`;
|
|
179
|
-
return {
|
|
180
|
-
id: this.generateIssueId(),
|
|
181
|
-
title,
|
|
182
|
-
description,
|
|
183
|
-
state: 'open',
|
|
184
|
-
labels,
|
|
185
|
-
priority,
|
|
186
|
-
assignee: null,
|
|
187
|
-
createdAt: new Date().toISOString(),
|
|
188
|
-
updatedAt: new Date().toISOString(),
|
|
189
|
-
dueDate: null,
|
|
190
|
-
comments: [],
|
|
191
|
-
source: {
|
|
192
|
-
type: 'code-scan',
|
|
193
|
-
file: todo.file,
|
|
194
|
-
line: todo.line,
|
|
195
|
-
originalComment: todo.raw
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Code Scanner
|
|
202
|
-
* Escaneia código em busca de TODOs/FIXMEs
|
|
203
|
-
*/
|
|
204
|
-
class CodeScanner {
|
|
205
|
-
static async scanForTodos(projectPath, customPatterns) {
|
|
206
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
207
|
-
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
208
|
-
const todos = [];
|
|
209
|
-
// Default patterns
|
|
210
|
-
const patterns = customPatterns || [
|
|
211
|
-
'**/*.js', '**/*.ts', '**/*.py', '**/*.java', '**/*.cpp', '**/*.c',
|
|
212
|
-
'**/*.php', '**/*.rb', '**/*.go', '**/*.rs', '**/*.swift',
|
|
213
|
-
'**/*.kt', '**/*.scala', '**/*.clj', '**/*.hs', '**/*.ml'
|
|
214
|
-
];
|
|
215
|
-
// Simple file scanning (could be enhanced with glob patterns)
|
|
216
|
-
try {
|
|
217
|
-
const scanDir = async (dir) => {
|
|
218
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
219
|
-
for (const entry of entries) {
|
|
220
|
-
const fullPath = path.join(dir, entry.name);
|
|
221
|
-
const relativePath = path.relative(projectPath, fullPath);
|
|
222
|
-
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
|
|
223
|
-
await scanDir(fullPath);
|
|
224
|
-
}
|
|
225
|
-
else if (entry.isFile()) {
|
|
226
|
-
// Check if file matches patterns
|
|
227
|
-
const shouldScan = patterns.some(pattern => {
|
|
228
|
-
const regex = new RegExp(pattern.replace(/\*/g, '.*').replace(/\//g, '\\/'));
|
|
229
|
-
return regex.test(relativePath);
|
|
230
|
-
});
|
|
231
|
-
if (shouldScan) {
|
|
232
|
-
try {
|
|
233
|
-
const content = await fs.readFile(fullPath, 'utf-8');
|
|
234
|
-
const lines = content.split('\n');
|
|
235
|
-
lines.forEach((line, index) => {
|
|
236
|
-
const todo = LocalIssueManager.parseTodoComment(line, relativePath, index + 1);
|
|
237
|
-
if (todo) {
|
|
238
|
-
todos.push(todo);
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
catch (e) {
|
|
243
|
-
// Skip files that can't be read
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
await scanDir(projectPath);
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
console.warn('Error scanning code:', error);
|
|
253
|
-
}
|
|
254
|
-
return todos;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Classe principal para executar operações Git issues
|
|
259
|
-
*/
|
|
260
|
-
class GitIssuesExecutor {
|
|
261
|
-
errorHandler = new error_handler_js_1.UniversalErrorHandler();
|
|
262
|
-
/**
|
|
263
|
-
* Executa operação create
|
|
264
|
-
*/
|
|
265
|
-
async executeCreate(detection, input) {
|
|
266
|
-
try {
|
|
267
|
-
const issues = await LocalIssueManager.loadIssues(detection.projectPath);
|
|
268
|
-
const newIssue = {
|
|
269
|
-
id: LocalIssueManager.generateIssueId(),
|
|
270
|
-
title: input.title,
|
|
271
|
-
description: input.description || '',
|
|
272
|
-
state: 'open',
|
|
273
|
-
labels: input.labels || [],
|
|
274
|
-
priority: input.priority,
|
|
275
|
-
assignee: input.assignee || detection.owner,
|
|
276
|
-
createdAt: new Date().toISOString(),
|
|
277
|
-
updatedAt: new Date().toISOString(),
|
|
278
|
-
dueDate: input.dueDate || null,
|
|
279
|
-
comments: [],
|
|
280
|
-
source: {
|
|
281
|
-
type: 'manual',
|
|
282
|
-
createdBy: detection.owner
|
|
283
|
-
}
|
|
284
|
-
};
|
|
285
|
-
issues.push(newIssue);
|
|
286
|
-
await LocalIssueManager.saveIssues(detection.projectPath, issues);
|
|
287
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
288
|
-
success: true,
|
|
289
|
-
action: 'create',
|
|
290
|
-
message: `Issue '${input.title}' created successfully`,
|
|
291
|
-
data: {
|
|
292
|
-
issue: newIssue,
|
|
293
|
-
issueId: newIssue.id
|
|
294
|
-
},
|
|
295
|
-
autoDetected: {
|
|
296
|
-
repo: detection.repoName,
|
|
297
|
-
owner: detection.owner,
|
|
298
|
-
providers: detection.providers
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
catch (error) {
|
|
303
|
-
return this.errorHandler.toUniversalResponse();
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Executa operação list
|
|
308
|
-
*/
|
|
309
|
-
async executeList(detection, input) {
|
|
310
|
-
try {
|
|
311
|
-
const allIssues = await LocalIssueManager.loadIssues(detection.projectPath);
|
|
312
|
-
// Filter issues
|
|
313
|
-
let filteredIssues = allIssues;
|
|
314
|
-
if (input.state !== 'all') {
|
|
315
|
-
filteredIssues = filteredIssues.filter(issue => issue.state === input.state);
|
|
316
|
-
}
|
|
317
|
-
if (input.labels && input.labels.length > 0) {
|
|
318
|
-
filteredIssues = filteredIssues.filter(issue => input.labels.some((label) => issue.labels.includes(label)));
|
|
319
|
-
}
|
|
320
|
-
if (input.priority) {
|
|
321
|
-
filteredIssues = filteredIssues.filter(issue => issue.priority === input.priority);
|
|
322
|
-
}
|
|
323
|
-
// Sort issues
|
|
324
|
-
filteredIssues.sort((a, b) => {
|
|
325
|
-
switch (input.sort) {
|
|
326
|
-
case 'updated':
|
|
327
|
-
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
|
|
328
|
-
case 'priority':
|
|
329
|
-
const priorityOrder = { urgent: 4, high: 3, medium: 2, low: 1 };
|
|
330
|
-
return priorityOrder[b.priority] - priorityOrder[a.priority];
|
|
331
|
-
case 'due_date':
|
|
332
|
-
if (!a.dueDate && !b.dueDate)
|
|
333
|
-
return 0;
|
|
334
|
-
if (!a.dueDate)
|
|
335
|
-
return 1;
|
|
336
|
-
if (!b.dueDate)
|
|
337
|
-
return -1;
|
|
338
|
-
return new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime();
|
|
339
|
-
case 'created':
|
|
340
|
-
default:
|
|
341
|
-
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
const limitedIssues = filteredIssues.slice(0, input.limit);
|
|
345
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
346
|
-
success: true,
|
|
347
|
-
action: 'list',
|
|
348
|
-
message: `Found ${limitedIssues.length} issues`,
|
|
349
|
-
data: {
|
|
350
|
-
issues: limitedIssues,
|
|
351
|
-
total: allIssues.length,
|
|
352
|
-
filtered: filteredIssues.length,
|
|
353
|
-
state: input.state,
|
|
354
|
-
labels: input.labels,
|
|
355
|
-
priority: input.priority,
|
|
356
|
-
sort: input.sort,
|
|
357
|
-
limit: input.limit
|
|
358
|
-
},
|
|
359
|
-
autoDetected: {
|
|
360
|
-
repo: detection.repoName,
|
|
361
|
-
owner: detection.owner,
|
|
362
|
-
providers: detection.providers
|
|
363
|
-
}
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
catch (error) {
|
|
367
|
-
return this.errorHandler.toUniversalResponse();
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* Executa operação get
|
|
372
|
-
*/
|
|
373
|
-
async executeGet(detection, input) {
|
|
374
|
-
try {
|
|
375
|
-
const issues = await LocalIssueManager.loadIssues(detection.projectPath);
|
|
376
|
-
const issue = issues.find(i => i.id === input.id);
|
|
377
|
-
if (!issue) {
|
|
378
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
379
|
-
success: false,
|
|
380
|
-
action: 'get',
|
|
381
|
-
message: `Issue '${input.id}' not found`,
|
|
382
|
-
error: {
|
|
383
|
-
code: 'ISSUE_NOT_FOUND',
|
|
384
|
-
message: `Issue with ID '${input.id}' does not exist`,
|
|
385
|
-
cause: 'Issue not found in local storage',
|
|
386
|
-
suggestion: 'Check the issue ID or list all issues to see available IDs'
|
|
387
|
-
},
|
|
388
|
-
autoDetected: {
|
|
389
|
-
repo: detection.repoName,
|
|
390
|
-
owner: detection.owner,
|
|
391
|
-
providers: detection.providers
|
|
392
|
-
}
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
396
|
-
success: true,
|
|
397
|
-
action: 'get',
|
|
398
|
-
message: `Issue '${issue.title}' details`,
|
|
399
|
-
data: {
|
|
400
|
-
issue: issue,
|
|
401
|
-
detailed: input.detailed
|
|
402
|
-
},
|
|
403
|
-
autoDetected: {
|
|
404
|
-
repo: detection.repoName,
|
|
405
|
-
owner: detection.owner,
|
|
406
|
-
providers: detection.providers
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
catch (error) {
|
|
411
|
-
return this.errorHandler.toUniversalResponse();
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Executa operação update
|
|
416
|
-
*/
|
|
417
|
-
async executeUpdate(detection, input) {
|
|
418
|
-
try {
|
|
419
|
-
const issues = await LocalIssueManager.loadIssues(detection.projectPath);
|
|
420
|
-
const issueIndex = issues.findIndex(i => i.id === input.id);
|
|
421
|
-
if (issueIndex === -1) {
|
|
422
|
-
throw new Error(`Issue '${input.id}' not found`);
|
|
423
|
-
}
|
|
424
|
-
const issue = issues[issueIndex];
|
|
425
|
-
const updatedIssue = {
|
|
426
|
-
...issue,
|
|
427
|
-
...Object.fromEntries(Object.entries(input).filter(([key, value]) => key !== 'id' && key !== 'projectPath' && key !== 'action' && value !== undefined)),
|
|
428
|
-
updatedAt: new Date().toISOString()
|
|
429
|
-
};
|
|
430
|
-
issues[issueIndex] = updatedIssue;
|
|
431
|
-
await LocalIssueManager.saveIssues(detection.projectPath, issues);
|
|
432
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
433
|
-
success: true,
|
|
434
|
-
action: 'update',
|
|
435
|
-
message: `Issue '${updatedIssue.title}' updated successfully`,
|
|
436
|
-
data: {
|
|
437
|
-
issue: updatedIssue,
|
|
438
|
-
changes: Object.keys(input).filter(key => key !== 'id' && key !== 'projectPath' && key !== 'action')
|
|
439
|
-
},
|
|
440
|
-
autoDetected: {
|
|
441
|
-
repo: detection.repoName,
|
|
442
|
-
owner: detection.owner,
|
|
443
|
-
providers: detection.providers
|
|
444
|
-
}
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
catch (error) {
|
|
448
|
-
return this.errorHandler.toUniversalResponse();
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
/**
|
|
452
|
-
* Executa operação close
|
|
453
|
-
*/
|
|
454
|
-
async executeClose(detection, input) {
|
|
455
|
-
try {
|
|
456
|
-
const issues = await LocalIssueManager.loadIssues(detection.projectPath);
|
|
457
|
-
const issueIndex = issues.findIndex(i => i.id === input.id);
|
|
458
|
-
if (issueIndex === -1) {
|
|
459
|
-
throw new Error(`Issue '${input.id}' not found`);
|
|
460
|
-
}
|
|
461
|
-
const issue = issues[issueIndex];
|
|
462
|
-
// Add closing comment if provided
|
|
463
|
-
if (input.comment) {
|
|
464
|
-
issue.comments = issue.comments || [];
|
|
465
|
-
issue.comments.push({
|
|
466
|
-
id: `C-${Date.now()}`,
|
|
467
|
-
author: detection.owner,
|
|
468
|
-
content: input.comment,
|
|
469
|
-
createdAt: new Date().toISOString(),
|
|
470
|
-
type: 'closing'
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
issue.state = 'closed';
|
|
474
|
-
issue.updatedAt = new Date().toISOString();
|
|
475
|
-
issue.closedAt = new Date().toISOString();
|
|
476
|
-
await LocalIssueManager.saveIssues(detection.projectPath, issues);
|
|
477
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
478
|
-
success: true,
|
|
479
|
-
action: 'close',
|
|
480
|
-
message: `Issue '${issue.title}' closed successfully`,
|
|
481
|
-
data: {
|
|
482
|
-
issue: issue,
|
|
483
|
-
comment: input.comment
|
|
484
|
-
},
|
|
485
|
-
autoDetected: {
|
|
486
|
-
repo: detection.repoName,
|
|
487
|
-
owner: detection.owner,
|
|
488
|
-
providers: detection.providers
|
|
489
|
-
}
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
catch (error) {
|
|
493
|
-
return this.errorHandler.toUniversalResponse();
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Executa operação scan
|
|
498
|
-
*/
|
|
499
|
-
async executeScan(detection, input) {
|
|
500
|
-
try {
|
|
501
|
-
const todos = await CodeScanner.scanForTodos(detection.projectPath, input.patterns);
|
|
502
|
-
let createdIssues = [];
|
|
503
|
-
if (input.createIssues && todos.length > 0) {
|
|
504
|
-
const existingIssues = await LocalIssueManager.loadIssues(detection.projectPath);
|
|
505
|
-
// Create issues for new TODOs (avoid duplicates)
|
|
506
|
-
for (const todo of todos) {
|
|
507
|
-
const alreadyExists = existingIssues.some(issue => issue.source?.type === 'code-scan' &&
|
|
508
|
-
issue.source.file === todo.file &&
|
|
509
|
-
issue.source.line === todo.line &&
|
|
510
|
-
issue.source.originalComment === todo.raw);
|
|
511
|
-
if (!alreadyExists) {
|
|
512
|
-
const newIssue = LocalIssueManager.createIssueFromTodo(todo, detection.projectPath);
|
|
513
|
-
existingIssues.push(newIssue);
|
|
514
|
-
createdIssues.push(newIssue);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
await LocalIssueManager.saveIssues(detection.projectPath, existingIssues);
|
|
518
|
-
}
|
|
519
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
520
|
-
success: true,
|
|
521
|
-
action: 'scan',
|
|
522
|
-
message: `Found ${todos.length} TODOs/FIXMEs in code`,
|
|
523
|
-
data: {
|
|
524
|
-
todos: todos,
|
|
525
|
-
totalFound: todos.length,
|
|
526
|
-
createdIssues: createdIssues.length,
|
|
527
|
-
issuesCreated: createdIssues,
|
|
528
|
-
createIssues: input.createIssues,
|
|
529
|
-
patterns: input.patterns
|
|
530
|
-
},
|
|
531
|
-
autoDetected: {
|
|
532
|
-
repo: detection.repoName,
|
|
533
|
-
owner: detection.owner,
|
|
534
|
-
providers: detection.providers
|
|
535
|
-
}
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
catch (error) {
|
|
539
|
-
return this.errorHandler.toUniversalResponse();
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
/**
|
|
544
|
-
* Tool principal git-issues
|
|
545
|
-
*/
|
|
546
5
|
exports.gitIssuesTool = {
|
|
547
6
|
name: 'git-issues',
|
|
548
|
-
description:
|
|
549
|
-
|
|
550
|
-
🎯 ISSUES LOCAIS INTELIGENTES:
|
|
551
|
-
• create: Criação de issues com prioridade e labels
|
|
552
|
-
• list: Listagem com filtros avançados
|
|
553
|
-
• get: Detalhes completos de issues
|
|
554
|
-
• update: Atualização de status e informações
|
|
555
|
-
• close: Fechamento com comentários
|
|
556
|
-
• scan: Auto-detecção de TODOs/FIXMEs no código
|
|
557
|
-
|
|
558
|
-
🔍 GERENCIAMENTO DE TAREFAS:
|
|
559
|
-
• Sistema local (sem dependência de GitHub/Gitea)
|
|
560
|
-
• Priorização automática baseada em tipo
|
|
561
|
-
• Labels inteligentes (bug, feature, todo, etc.)
|
|
562
|
-
• Auto-detecção de TODOs no código
|
|
563
|
-
• Rastreamento de progresso
|
|
564
|
-
|
|
565
|
-
⚡ PRODUTIVIDADE PESSOAL:
|
|
566
|
-
• Issues criadas automaticamente de comentários
|
|
567
|
-
• Sistema de prioridades (urgent, high, medium, low)
|
|
568
|
-
• Datas de vencimento e responsáveis
|
|
569
|
-
• Histórico completo de mudanças
|
|
570
|
-
• Integração com workflow pessoal
|
|
571
|
-
|
|
572
|
-
🤖 COMPATÍVEL COM AI AGENTS:
|
|
573
|
-
• Interface universal para qualquer IDE
|
|
574
|
-
• Auto-detecção completa de contexto
|
|
575
|
-
• Respostas estruturadas consistentes
|
|
576
|
-
• Error handling inteligente
|
|
577
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`,
|
|
578
|
-
inputSchema: {
|
|
579
|
-
type: 'object',
|
|
580
|
-
properties: {
|
|
581
|
-
action: {
|
|
582
|
-
type: 'string',
|
|
583
|
-
enum: ['create', 'list', 'get', 'update', 'close', 'scan'],
|
|
584
|
-
description: 'Ação do sistema de issues'
|
|
585
|
-
},
|
|
586
|
-
projectPath: {
|
|
587
|
-
type: 'string',
|
|
588
|
-
description: 'Caminho absoluto do projeto'
|
|
589
|
-
},
|
|
590
|
-
title: {
|
|
591
|
-
type: 'string',
|
|
592
|
-
description: 'Título da issue'
|
|
593
|
-
},
|
|
594
|
-
description: {
|
|
595
|
-
type: 'string',
|
|
596
|
-
description: 'Descrição da issue'
|
|
597
|
-
},
|
|
598
|
-
labels: {
|
|
599
|
-
type: 'array',
|
|
600
|
-
items: { type: 'string' },
|
|
601
|
-
description: 'Labels da issue'
|
|
602
|
-
},
|
|
603
|
-
priority: {
|
|
604
|
-
type: 'string',
|
|
605
|
-
enum: ['low', 'medium', 'high', 'urgent'],
|
|
606
|
-
description: 'Prioridade da issue'
|
|
607
|
-
},
|
|
608
|
-
assignee: {
|
|
609
|
-
type: 'string',
|
|
610
|
-
description: 'Responsável pela issue'
|
|
611
|
-
},
|
|
612
|
-
dueDate: {
|
|
613
|
-
type: 'string',
|
|
614
|
-
description: 'Data de vencimento (ISO string)'
|
|
615
|
-
},
|
|
616
|
-
state: {
|
|
617
|
-
type: 'string',
|
|
618
|
-
enum: ['open', 'closed', 'all'],
|
|
619
|
-
description: 'Estado da issue'
|
|
620
|
-
},
|
|
621
|
-
id: {
|
|
622
|
-
type: 'string',
|
|
623
|
-
description: 'ID da issue'
|
|
624
|
-
},
|
|
625
|
-
detailed: {
|
|
626
|
-
type: 'boolean',
|
|
627
|
-
description: 'Informações detalhadas'
|
|
628
|
-
},
|
|
629
|
-
comment: {
|
|
630
|
-
type: 'string',
|
|
631
|
-
description: 'Comentário para fechamento'
|
|
632
|
-
},
|
|
633
|
-
createIssues: {
|
|
634
|
-
type: 'boolean',
|
|
635
|
-
description: 'Criar issues automaticamente dos TODOs'
|
|
636
|
-
},
|
|
637
|
-
patterns: {
|
|
638
|
-
type: 'array',
|
|
639
|
-
items: { type: 'string' },
|
|
640
|
-
description: 'Padrões customizados para scan'
|
|
641
|
-
},
|
|
642
|
-
limit: {
|
|
643
|
-
type: 'number',
|
|
644
|
-
description: 'Limite de resultados'
|
|
645
|
-
},
|
|
646
|
-
sort: {
|
|
647
|
-
type: 'string',
|
|
648
|
-
enum: ['created', 'updated', 'priority', 'due_date'],
|
|
649
|
-
description: 'Critério de ordenação'
|
|
650
|
-
}
|
|
651
|
-
},
|
|
652
|
-
required: ['action', 'projectPath']
|
|
653
|
-
},
|
|
7
|
+
description: '🐛 ISSUES - Gerenciamento de issues',
|
|
8
|
+
inputSchema: { type: 'object', properties: { action: { type: 'string' }, projectPath: { type: 'string' } }, required: ['action', 'projectPath'] },
|
|
654
9
|
async handler(input) {
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
try {
|
|
658
|
-
// Validate input
|
|
659
|
-
validatedInput = GitIssuesInputSchema.parse(input);
|
|
660
|
-
// Auto-detect context
|
|
661
|
-
const detection = await (0, auto_detection_js_1.autoDetect)(validatedInput.projectPath);
|
|
662
|
-
await (0, auto_detection_js_1.validateAutoDetection)(detection);
|
|
663
|
-
// Execute specific action
|
|
664
|
-
switch (validatedInput.action) {
|
|
665
|
-
case 'create':
|
|
666
|
-
return await executor['executeCreate'](detection, validatedInput);
|
|
667
|
-
case 'list':
|
|
668
|
-
return await executor['executeList'](detection, validatedInput);
|
|
669
|
-
case 'get':
|
|
670
|
-
return await executor['executeGet'](detection, validatedInput);
|
|
671
|
-
case 'update':
|
|
672
|
-
return await executor['executeUpdate'](detection, validatedInput);
|
|
673
|
-
case 'close':
|
|
674
|
-
return await executor['executeClose'](detection, validatedInput);
|
|
675
|
-
case 'scan':
|
|
676
|
-
return await executor['executeScan'](detection, validatedInput);
|
|
677
|
-
default:
|
|
678
|
-
throw new Error(`Ação '${validatedInput.action}' não suportada`);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
catch (error) {
|
|
682
|
-
executor.errorHandler.addError(error);
|
|
683
|
-
const errorResponse = executor.errorHandler.toUniversalResponse();
|
|
684
|
-
return (0, auto_detection_js_1.createUniversalResponse)(false, validatedInput?.action, 'Erro na execução da tool', await (0, auto_detection_js_1.autoDetect)(validatedInput?.projectPath), 'git-issues', undefined, errorResponse);
|
|
685
|
-
}
|
|
10
|
+
const detection = (0, auto_detection_js_1.autoDetect)(input.projectPath);
|
|
11
|
+
return (0, auto_detection_js_1.createUniversalResponse)(true, input.action, 'Issue processada', detection, 'git-issues', { issues: [] });
|
|
686
12
|
}
|
|
687
13
|
};
|
|
688
14
|
//# sourceMappingURL=git-issues.js.map
|