@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-backup.js
CHANGED
|
@@ -1,815 +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.gitBackupTool = 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
|
-
const git_operations_js_1 = require("../utils/git-operations.js");
|
|
41
|
-
/**
|
|
42
|
-
* Tool: git-backup
|
|
43
|
-
*
|
|
44
|
-
* SISTEMA DE BACKUP INTELIGENTE
|
|
45
|
-
* Backup incremental, restore granular, verificação de integridade
|
|
46
|
-
*
|
|
47
|
-
* DESIGNED FOR: Programador individual autônomo
|
|
48
|
-
* PHILOSOPHY: Backup confiável e automático em uma única ferramenta
|
|
49
|
-
*/
|
|
50
|
-
const GitBackupInputSchema = zod_1.z.discriminatedUnion('action', [
|
|
51
|
-
// CREATE BACKUP - Backup imediato
|
|
52
|
-
zod_1.z.object({
|
|
53
|
-
action: zod_1.z.literal('create'),
|
|
54
|
-
projectPath: zod_1.z.string(),
|
|
55
|
-
type: zod_1.z.enum(['full', 'incremental', 'checkpoint']).default('full'),
|
|
56
|
-
name: zod_1.z.string().optional(),
|
|
57
|
-
description: zod_1.z.string().optional(),
|
|
58
|
-
includeUntracked: zod_1.z.boolean().default(false),
|
|
59
|
-
compress: zod_1.z.boolean().default(true)
|
|
60
|
-
}),
|
|
61
|
-
// RESTORE BACKUP - Restauração granular
|
|
62
|
-
zod_1.z.object({
|
|
63
|
-
action: zod_1.z.literal('restore'),
|
|
64
|
-
projectPath: zod_1.z.string(),
|
|
65
|
-
backupId: zod_1.z.string(),
|
|
66
|
-
preview: zod_1.z.boolean().default(true), // Preview before restore
|
|
67
|
-
force: zod_1.z.boolean().default(false), // Force restore even with conflicts
|
|
68
|
-
targetPath: zod_1.z.string().optional() // Restore to different location
|
|
69
|
-
}),
|
|
70
|
-
// LIST BACKUPS - Gerenciar backups
|
|
71
|
-
zod_1.z.object({
|
|
72
|
-
action: zod_1.z.literal('list'),
|
|
73
|
-
projectPath: zod_1.z.string(),
|
|
74
|
-
filter: zod_1.z.enum(['all', 'full', 'incremental', 'checkpoint']).default('all'),
|
|
75
|
-
limit: zod_1.z.number().default(20),
|
|
76
|
-
sortBy: zod_1.z.enum(['date', 'size', 'type']).default('date')
|
|
77
|
-
}),
|
|
78
|
-
// AUTO BACKUP - Configuração automática
|
|
79
|
-
zod_1.z.object({
|
|
80
|
-
action: zod_1.z.literal('auto'),
|
|
81
|
-
projectPath: zod_1.z.string(),
|
|
82
|
-
enabled: zod_1.z.boolean().default(true),
|
|
83
|
-
schedule: zod_1.z.enum(['commit', 'daily', 'weekly', 'manual']).default('commit'),
|
|
84
|
-
retention: zod_1.z.number().default(30), // Days to keep backups
|
|
85
|
-
maxBackups: zod_1.z.number().default(50)
|
|
86
|
-
}),
|
|
87
|
-
// VERIFY BACKUP - Verificação de integridade
|
|
88
|
-
zod_1.z.object({
|
|
89
|
-
action: zod_1.z.literal('verify'),
|
|
90
|
-
projectPath: zod_1.z.string(),
|
|
91
|
-
backupId: zod_1.z.string().optional(), // Specific backup or all
|
|
92
|
-
deep: zod_1.z.boolean().default(false), // Deep verification
|
|
93
|
-
repair: zod_1.z.boolean().default(false) // Attempt repair if corrupted
|
|
94
|
-
})
|
|
95
|
-
]);
|
|
96
|
-
/**
|
|
97
|
-
* Backup Manager
|
|
98
|
-
* Gerencia operações de backup e restauração
|
|
99
|
-
*/
|
|
100
|
-
class BackupManager {
|
|
101
|
-
static BACKUP_DIR = '.git/backups';
|
|
102
|
-
static BACKUP_PREFIX = 'backup-';
|
|
103
|
-
static async createBackup(projectPath, options) {
|
|
104
|
-
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
105
|
-
try {
|
|
106
|
-
// Ensure backup directory exists
|
|
107
|
-
await this.ensureBackupDirectory(projectPath);
|
|
108
|
-
// Generate backup ID
|
|
109
|
-
const backupId = this.generateBackupId();
|
|
110
|
-
const backupPath = `${projectPath}/${this.BACKUP_DIR}/${backupId}`;
|
|
111
|
-
// Create backup based on type
|
|
112
|
-
let backupData = {
|
|
113
|
-
id: backupId,
|
|
114
|
-
type: options.type,
|
|
115
|
-
name: options.name || `Backup ${new Date().toLocaleString()}`,
|
|
116
|
-
description: options.description || '',
|
|
117
|
-
createdAt: new Date().toISOString(),
|
|
118
|
-
projectPath: projectPath,
|
|
119
|
-
gitCommit: null,
|
|
120
|
-
files: [],
|
|
121
|
-
metadata: {}
|
|
122
|
-
};
|
|
123
|
-
if (options.type === 'full' || options.type === 'checkpoint') {
|
|
124
|
-
// Create full backup or checkpoint
|
|
125
|
-
backupData = await this.createFullBackup(gitOps, backupPath, backupData, options);
|
|
126
|
-
}
|
|
127
|
-
else if (options.type === 'incremental') {
|
|
128
|
-
// Create incremental backup
|
|
129
|
-
const lastBackup = await this.findLastBackup(projectPath);
|
|
130
|
-
backupData = await this.createIncrementalBackup(gitOps, backupPath, backupData, lastBackup, options);
|
|
131
|
-
}
|
|
132
|
-
// Save backup manifest
|
|
133
|
-
await this.saveBackupManifest(projectPath, backupData);
|
|
134
|
-
// Verify backup integrity
|
|
135
|
-
const verification = await this.verifyBackupIntegrity(backupData);
|
|
136
|
-
backupData.verification = verification;
|
|
137
|
-
return backupData;
|
|
138
|
-
}
|
|
139
|
-
catch (error) {
|
|
140
|
-
throw new Error(`Backup creation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
static async restoreBackup(projectPath, backupId, options) {
|
|
144
|
-
try {
|
|
145
|
-
// Load backup manifest
|
|
146
|
-
const backupData = await this.loadBackupManifest(projectPath, backupId);
|
|
147
|
-
if (!backupData) {
|
|
148
|
-
throw new Error(`Backup ${backupId} not found`);
|
|
149
|
-
}
|
|
150
|
-
// Preview mode
|
|
151
|
-
if (options.preview) {
|
|
152
|
-
return {
|
|
153
|
-
preview: true,
|
|
154
|
-
backup: backupData,
|
|
155
|
-
willRestore: {
|
|
156
|
-
files: backupData.files.length,
|
|
157
|
-
gitCommit: backupData.gitCommit,
|
|
158
|
-
targetPath: options.targetPath || projectPath
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
// Perform restore
|
|
163
|
-
const restoreResult = await this.performRestore(projectPath, backupData, options);
|
|
164
|
-
return {
|
|
165
|
-
preview: false,
|
|
166
|
-
backup: backupData,
|
|
167
|
-
restored: restoreResult,
|
|
168
|
-
targetPath: options.targetPath || projectPath
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
throw new Error(`Backup restore failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
static async listBackups(projectPath, filter, limit, sortBy) {
|
|
176
|
-
try {
|
|
177
|
-
await this.ensureBackupDirectory(projectPath);
|
|
178
|
-
const backups = [];
|
|
179
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
180
|
-
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
181
|
-
try {
|
|
182
|
-
const files = await fs.readdir(`${projectPath}/${this.BACKUP_DIR}`);
|
|
183
|
-
for (const file of files) {
|
|
184
|
-
if (file.endsWith('.json')) {
|
|
185
|
-
try {
|
|
186
|
-
const content = await fs.readFile(`${projectPath}/${this.BACKUP_DIR}/${file}`, 'utf-8');
|
|
187
|
-
const backup = JSON.parse(content);
|
|
188
|
-
backups.push(backup);
|
|
189
|
-
}
|
|
190
|
-
catch (e) {
|
|
191
|
-
// Skip corrupted manifest
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
catch (e) {
|
|
197
|
-
// Backup directory doesn't exist
|
|
198
|
-
}
|
|
199
|
-
// Filter backups
|
|
200
|
-
let filtered = backups;
|
|
201
|
-
if (filter !== 'all') {
|
|
202
|
-
filtered = backups.filter(b => b.type === filter);
|
|
203
|
-
}
|
|
204
|
-
// Sort backups
|
|
205
|
-
filtered.sort((a, b) => {
|
|
206
|
-
switch (sortBy) {
|
|
207
|
-
case 'date':
|
|
208
|
-
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
|
|
209
|
-
case 'size':
|
|
210
|
-
return (b.size || 0) - (a.size || 0);
|
|
211
|
-
case 'type':
|
|
212
|
-
return a.type.localeCompare(b.type);
|
|
213
|
-
default:
|
|
214
|
-
return 0;
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
return filtered.slice(0, limit);
|
|
218
|
-
}
|
|
219
|
-
catch (error) {
|
|
220
|
-
throw new Error(`Failed to list backups: ${error instanceof Error ? error.message : String(error)}`);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
static async ensureBackupDirectory(projectPath) {
|
|
224
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
225
|
-
const path = await Promise.resolve().then(() => __importStar(require('path')));
|
|
226
|
-
try {
|
|
227
|
-
await fs.access(`${projectPath}/${this.BACKUP_DIR}`);
|
|
228
|
-
}
|
|
229
|
-
catch (e) {
|
|
230
|
-
// Create directory
|
|
231
|
-
await fs.mkdir(`${projectPath}/${this.BACKUP_DIR}`, { recursive: true });
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
static generateBackupId() {
|
|
235
|
-
return `${this.BACKUP_PREFIX}${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
236
|
-
}
|
|
237
|
-
static async createFullBackup(gitOps, backupPath, backupData, options) {
|
|
238
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
239
|
-
// Get current Git status
|
|
240
|
-
const statusResult = await gitOps.status({});
|
|
241
|
-
backupData.gitStatus = statusResult;
|
|
242
|
-
// Create Git commit if there are changes
|
|
243
|
-
if (options.includeUntracked || statusResult.output?.includes('Changes')) {
|
|
244
|
-
await gitOps.addFiles(['.']);
|
|
245
|
-
const commitResult = await gitOps.commit(`Backup: ${backupData.name}`);
|
|
246
|
-
if (commitResult.success) {
|
|
247
|
-
backupData.gitCommit = commitResult.output;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
// Archive current state
|
|
251
|
-
const archiveResult = await gitOps.runCommand('git', ['archive', '--format=zip', '--output', `${backupPath}.zip`, 'HEAD']);
|
|
252
|
-
if (archiveResult.success) {
|
|
253
|
-
backupData.archivePath = `${backupPath}.zip`;
|
|
254
|
-
// Get archive size
|
|
255
|
-
try {
|
|
256
|
-
const stats = await fs.stat(`${backupPath}.zip`);
|
|
257
|
-
backupData.size = stats.size;
|
|
258
|
-
}
|
|
259
|
-
catch (e) {
|
|
260
|
-
backupData.size = 0;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
// List files in backup
|
|
264
|
-
const lsResult = await gitOps.runCommand('git', ['ls-tree', '-r', '--name-only', 'HEAD']);
|
|
265
|
-
backupData.files = lsResult.success ?
|
|
266
|
-
lsResult.output.trim().split('\n').filter(line => line.trim()) : [];
|
|
267
|
-
return backupData;
|
|
268
|
-
}
|
|
269
|
-
static async createIncrementalBackup(gitOps, backupPath, backupData, lastBackup, options) {
|
|
270
|
-
// For incremental backup, store only changes since last backup
|
|
271
|
-
const sinceCommit = lastBackup?.gitCommit;
|
|
272
|
-
if (!sinceCommit) {
|
|
273
|
-
// Fallback to full backup if no previous commit
|
|
274
|
-
return this.createFullBackup(gitOps, backupPath, backupData, options);
|
|
275
|
-
}
|
|
276
|
-
// Get changes since last backup
|
|
277
|
-
const changesResult = await gitOps.runCommand('git', ['diff', '--name-only', sinceCommit]);
|
|
278
|
-
backupData.files = changesResult.success ?
|
|
279
|
-
changesResult.output.trim().split('\n').filter(line => line.trim()) : [];
|
|
280
|
-
backupData.parentBackup = lastBackup.id;
|
|
281
|
-
backupData.incrementalFrom = sinceCommit;
|
|
282
|
-
// Create patch file
|
|
283
|
-
const patchResult = await gitOps.runCommand('git', ['diff', sinceCommit, '--binary', '>.patch']);
|
|
284
|
-
if (patchResult.success) {
|
|
285
|
-
// Move patch to backup location
|
|
286
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
287
|
-
try {
|
|
288
|
-
await fs.rename('.patch', `${backupPath}.patch`);
|
|
289
|
-
backupData.patchPath = `${backupPath}.patch`;
|
|
290
|
-
}
|
|
291
|
-
catch (e) {
|
|
292
|
-
// Ignore patch creation errors
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
return backupData;
|
|
296
|
-
}
|
|
297
|
-
static async findLastBackup(projectPath) {
|
|
298
|
-
try {
|
|
299
|
-
const backups = await this.listBackups(projectPath, 'all', 1, 'date');
|
|
300
|
-
return backups.length > 0 ? backups[0] : null;
|
|
301
|
-
}
|
|
302
|
-
catch (e) {
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
static async saveBackupManifest(projectPath, backupData) {
|
|
307
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
308
|
-
const manifestPath = `${projectPath}/${this.BACKUP_DIR}/${backupData.id}.json`;
|
|
309
|
-
await fs.writeFile(manifestPath, JSON.stringify(backupData, null, 2), 'utf-8');
|
|
310
|
-
}
|
|
311
|
-
static async loadBackupManifest(projectPath, backupId) {
|
|
312
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
313
|
-
try {
|
|
314
|
-
const manifestPath = `${projectPath}/${this.BACKUP_DIR}/${backupId}.json`;
|
|
315
|
-
const content = await fs.readFile(manifestPath, 'utf-8');
|
|
316
|
-
return JSON.parse(content);
|
|
317
|
-
}
|
|
318
|
-
catch (e) {
|
|
319
|
-
return null;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
static async verifyBackupIntegrity(backupData) {
|
|
323
|
-
try {
|
|
324
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
325
|
-
let integrity = { valid: true, issues: [] };
|
|
326
|
-
// Check if files exist
|
|
327
|
-
if (backupData.archivePath) {
|
|
328
|
-
try {
|
|
329
|
-
await fs.access(backupData.archivePath);
|
|
330
|
-
}
|
|
331
|
-
catch (e) {
|
|
332
|
-
integrity.valid = false;
|
|
333
|
-
integrity.issues.push('Archive file missing');
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
if (backupData.patchPath) {
|
|
337
|
-
try {
|
|
338
|
-
await fs.access(backupData.patchPath);
|
|
339
|
-
}
|
|
340
|
-
catch (e) {
|
|
341
|
-
integrity.valid = false;
|
|
342
|
-
integrity.issues.push('Patch file missing');
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
// Verify manifest integrity
|
|
346
|
-
if (!backupData.id || !backupData.createdAt) {
|
|
347
|
-
integrity.valid = false;
|
|
348
|
-
integrity.issues.push('Invalid backup manifest');
|
|
349
|
-
}
|
|
350
|
-
return integrity;
|
|
351
|
-
}
|
|
352
|
-
catch (error) {
|
|
353
|
-
return { valid: false, issues: ['Verification failed'], error: error instanceof Error ? error.message : String(error) };
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
static async performRestore(projectPath, backupData, options) {
|
|
357
|
-
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
358
|
-
const targetPath = options.targetPath || projectPath;
|
|
359
|
-
try {
|
|
360
|
-
let restoreResult = { success: true, steps: [], warnings: [] };
|
|
361
|
-
if (backupData.archivePath) {
|
|
362
|
-
// Extract archive
|
|
363
|
-
const extractResult = await gitOps.runCommand('unzip', ['-o', backupData.archivePath, '-d', targetPath]);
|
|
364
|
-
if (extractResult.success) {
|
|
365
|
-
restoreResult.steps.push('Archive extracted successfully');
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
restoreResult.success = false;
|
|
369
|
-
restoreResult.steps.push('Failed to extract archive');
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
else if (backupData.patchPath) {
|
|
373
|
-
// Apply incremental patch
|
|
374
|
-
const patchResult = await gitOps.runCommand('git', ['apply', backupData.patchPath]);
|
|
375
|
-
if (patchResult.success) {
|
|
376
|
-
restoreResult.steps.push('Incremental patch applied successfully');
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
restoreResult.success = false;
|
|
380
|
-
restoreResult.steps.push('Failed to apply incremental patch');
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
// Restore Git commit if available
|
|
384
|
-
if (backupData.gitCommit && !options.force) {
|
|
385
|
-
restoreResult.warnings.push('Git commit history may need manual restoration');
|
|
386
|
-
}
|
|
387
|
-
return restoreResult;
|
|
388
|
-
}
|
|
389
|
-
catch (error) {
|
|
390
|
-
return {
|
|
391
|
-
success: false,
|
|
392
|
-
error: error instanceof Error ? error.message : String(error),
|
|
393
|
-
steps: []
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Auto Backup Manager
|
|
400
|
-
* Gerencia backups automáticos
|
|
401
|
-
*/
|
|
402
|
-
class AutoBackupManager {
|
|
403
|
-
static async configureAutoBackup(projectPath, config) {
|
|
404
|
-
try {
|
|
405
|
-
// Create auto-backup configuration
|
|
406
|
-
const configPath = `${projectPath}/.git/auto-backup.json`;
|
|
407
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
408
|
-
const autoConfig = {
|
|
409
|
-
enabled: config.enabled,
|
|
410
|
-
schedule: config.schedule,
|
|
411
|
-
retention: config.retention,
|
|
412
|
-
maxBackups: config.maxBackups,
|
|
413
|
-
lastBackup: null,
|
|
414
|
-
nextBackup: this.calculateNextBackup(config.schedule),
|
|
415
|
-
createdAt: new Date().toISOString()
|
|
416
|
-
};
|
|
417
|
-
await fs.writeFile(configPath, JSON.stringify(autoConfig, null, 2), 'utf-8');
|
|
418
|
-
return {
|
|
419
|
-
configured: true,
|
|
420
|
-
config: autoConfig,
|
|
421
|
-
message: `Auto-backup ${config.enabled ? 'enabled' : 'disabled'} with ${config.schedule} schedule`
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
catch (error) {
|
|
425
|
-
throw new Error(`Auto-backup configuration failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
static calculateNextBackup(schedule) {
|
|
429
|
-
const now = new Date();
|
|
430
|
-
switch (schedule) {
|
|
431
|
-
case 'daily':
|
|
432
|
-
now.setDate(now.getDate() + 1);
|
|
433
|
-
break;
|
|
434
|
-
case 'weekly':
|
|
435
|
-
now.setDate(now.getDate() + 7);
|
|
436
|
-
break;
|
|
437
|
-
case 'commit':
|
|
438
|
-
// Next backup on next commit
|
|
439
|
-
return 'on-next-commit';
|
|
440
|
-
case 'manual':
|
|
441
|
-
return 'manual';
|
|
442
|
-
}
|
|
443
|
-
return now.toISOString();
|
|
444
|
-
}
|
|
445
|
-
static async shouldCreateBackup(projectPath) {
|
|
446
|
-
try {
|
|
447
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
448
|
-
const configPath = `${projectPath}/.git/auto-backup.json`;
|
|
449
|
-
const configContent = await fs.readFile(configPath, 'utf-8');
|
|
450
|
-
const config = JSON.parse(configContent);
|
|
451
|
-
if (!config.enabled)
|
|
452
|
-
return false;
|
|
453
|
-
const now = new Date();
|
|
454
|
-
if (config.schedule === 'commit') {
|
|
455
|
-
// Check if there are uncommitted changes
|
|
456
|
-
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
457
|
-
const status = await gitOps.status({});
|
|
458
|
-
return status.output?.includes('Changes') || false;
|
|
459
|
-
}
|
|
460
|
-
if (config.nextBackup && config.nextBackup !== 'manual' && config.nextBackup !== 'on-next-commit') {
|
|
461
|
-
const nextBackup = new Date(config.nextBackup);
|
|
462
|
-
return now >= nextBackup;
|
|
463
|
-
}
|
|
464
|
-
return false;
|
|
465
|
-
}
|
|
466
|
-
catch (e) {
|
|
467
|
-
return false;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* Classe principal para executar operações Git backup
|
|
473
|
-
*/
|
|
474
|
-
class GitBackupExecutor {
|
|
475
|
-
errorHandler = new error_handler_js_1.UniversalErrorHandler();
|
|
476
|
-
/**
|
|
477
|
-
* Executa operação create
|
|
478
|
-
*/
|
|
479
|
-
async executeCreate(detection, input) {
|
|
480
|
-
try {
|
|
481
|
-
const backupData = await BackupManager.createBackup(detection.projectPath, {
|
|
482
|
-
type: input.type,
|
|
483
|
-
name: input.name,
|
|
484
|
-
description: input.description,
|
|
485
|
-
includeUntracked: input.includeUntracked,
|
|
486
|
-
compress: input.compress
|
|
487
|
-
});
|
|
488
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
489
|
-
success: true,
|
|
490
|
-
action: 'create',
|
|
491
|
-
message: `Backup ${backupData.type} created successfully`,
|
|
492
|
-
data: {
|
|
493
|
-
backup: backupData,
|
|
494
|
-
verification: backupData.verification
|
|
495
|
-
},
|
|
496
|
-
autoDetected: {
|
|
497
|
-
repo: detection.repoName,
|
|
498
|
-
owner: detection.owner,
|
|
499
|
-
providers: detection.providers
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
catch (error) {
|
|
504
|
-
return this.errorHandler.toUniversalResponse();
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Executa operação restore
|
|
509
|
-
*/
|
|
510
|
-
async executeRestore(detection, input) {
|
|
511
|
-
try {
|
|
512
|
-
const result = await BackupManager.restoreBackup(detection.projectPath, input.backupId, {
|
|
513
|
-
preview: input.preview,
|
|
514
|
-
force: input.force,
|
|
515
|
-
targetPath: input.targetPath
|
|
516
|
-
});
|
|
517
|
-
const message = input.preview ?
|
|
518
|
-
`Backup ${input.backupId} preview generated` :
|
|
519
|
-
`Backup ${input.backupId} restored successfully`;
|
|
520
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
521
|
-
success: true,
|
|
522
|
-
action: 'restore',
|
|
523
|
-
message: message,
|
|
524
|
-
data: result,
|
|
525
|
-
autoDetected: {
|
|
526
|
-
repo: detection.repoName,
|
|
527
|
-
owner: detection.owner,
|
|
528
|
-
providers: detection.providers
|
|
529
|
-
}
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
catch (error) {
|
|
533
|
-
return this.errorHandler.toUniversalResponse();
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
/**
|
|
537
|
-
* Executa operação list
|
|
538
|
-
*/
|
|
539
|
-
async executeList(detection, input) {
|
|
540
|
-
try {
|
|
541
|
-
const backups = await BackupManager.listBackups(detection.projectPath, input.filter, input.limit, input.sortBy);
|
|
542
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
543
|
-
success: true,
|
|
544
|
-
action: 'list',
|
|
545
|
-
message: `Found ${backups.length} backups`,
|
|
546
|
-
data: {
|
|
547
|
-
backups: backups,
|
|
548
|
-
filter: input.filter,
|
|
549
|
-
limit: input.limit,
|
|
550
|
-
sortBy: input.sortBy,
|
|
551
|
-
total: backups.length
|
|
552
|
-
},
|
|
553
|
-
autoDetected: {
|
|
554
|
-
repo: detection.repoName,
|
|
555
|
-
owner: detection.owner,
|
|
556
|
-
providers: detection.providers
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
catch (error) {
|
|
561
|
-
return this.errorHandler.toUniversalResponse();
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Executa operação auto
|
|
566
|
-
*/
|
|
567
|
-
async executeAuto(detection, input) {
|
|
568
|
-
try {
|
|
569
|
-
const config = await AutoBackupManager.configureAutoBackup(detection.projectPath, {
|
|
570
|
-
enabled: input.enabled,
|
|
571
|
-
schedule: input.schedule,
|
|
572
|
-
retention: input.retention,
|
|
573
|
-
maxBackups: input.maxBackups
|
|
574
|
-
});
|
|
575
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
576
|
-
success: true,
|
|
577
|
-
action: 'auto',
|
|
578
|
-
message: config.message,
|
|
579
|
-
data: {
|
|
580
|
-
config: config.config,
|
|
581
|
-
enabled: input.enabled,
|
|
582
|
-
schedule: input.schedule
|
|
583
|
-
},
|
|
584
|
-
autoDetected: {
|
|
585
|
-
repo: detection.repoName,
|
|
586
|
-
owner: detection.owner,
|
|
587
|
-
providers: detection.providers
|
|
588
|
-
}
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
catch (error) {
|
|
592
|
-
return this.errorHandler.toUniversalResponse();
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Executa operação verify
|
|
597
|
-
*/
|
|
598
|
-
async executeVerify(detection, input) {
|
|
599
|
-
try {
|
|
600
|
-
let results = [];
|
|
601
|
-
if (input.backupId) {
|
|
602
|
-
// Verify specific backup
|
|
603
|
-
const backupData = await BackupManager['loadBackupManifest'](detection.projectPath, input.backupId);
|
|
604
|
-
if (backupData) {
|
|
605
|
-
const verification = await BackupManager['verifyBackupIntegrity'](backupData);
|
|
606
|
-
results.push({
|
|
607
|
-
backupId: input.backupId,
|
|
608
|
-
...verification
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
|
-
else {
|
|
612
|
-
results.push({
|
|
613
|
-
backupId: input.backupId,
|
|
614
|
-
valid: false,
|
|
615
|
-
issues: ['Backup not found']
|
|
616
|
-
});
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
else {
|
|
620
|
-
// Verify all backups
|
|
621
|
-
const backups = await BackupManager.listBackups(detection.projectPath, 'all', 100, 'date');
|
|
622
|
-
for (const backup of backups) {
|
|
623
|
-
const verification = await BackupManager['verifyBackupIntegrity'](backup);
|
|
624
|
-
results.push({
|
|
625
|
-
backupId: backup.id,
|
|
626
|
-
...verification
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
const validCount = results.filter(r => r.valid).length;
|
|
631
|
-
const totalCount = results.length;
|
|
632
|
-
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
633
|
-
success: true,
|
|
634
|
-
action: 'verify',
|
|
635
|
-
message: `Verification completed: ${validCount}/${totalCount} backups valid`,
|
|
636
|
-
data: {
|
|
637
|
-
results: results,
|
|
638
|
-
summary: {
|
|
639
|
-
total: totalCount,
|
|
640
|
-
valid: validCount,
|
|
641
|
-
invalid: totalCount - validCount,
|
|
642
|
-
deep: input.deep,
|
|
643
|
-
repair: input.repair
|
|
644
|
-
}
|
|
645
|
-
},
|
|
646
|
-
autoDetected: {
|
|
647
|
-
repo: detection.repoName,
|
|
648
|
-
owner: detection.owner,
|
|
649
|
-
providers: detection.providers
|
|
650
|
-
}
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
catch (error) {
|
|
654
|
-
return this.errorHandler.toUniversalResponse();
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Tool principal git-backup
|
|
660
|
-
*/
|
|
661
5
|
exports.gitBackupTool = {
|
|
662
6
|
name: 'git-backup',
|
|
663
|
-
description:
|
|
664
|
-
|
|
665
|
-
🎯 BACKUP COMPLETO E AUTOMÁTICO:
|
|
666
|
-
• create: Backup imediato (full, incremental, checkpoint)
|
|
667
|
-
• restore: Restauração granular com preview
|
|
668
|
-
• list: Gerenciamento de backups existentes
|
|
669
|
-
• auto: Configuração de backup automático
|
|
670
|
-
• verify: Verificação de integridade
|
|
671
|
-
|
|
672
|
-
🔄 BACKUP INTELIGENTE:
|
|
673
|
-
• Backup incremental para eficiência
|
|
674
|
-
• Full backup para segurança completa
|
|
675
|
-
• Checkpoint para pontos de restauração
|
|
676
|
-
• Compressão automática
|
|
677
|
-
• Verificação de integridade
|
|
678
|
-
|
|
679
|
-
⚡ RECUPERAÇÃO GARANTIDA:
|
|
680
|
-
• Preview antes da restauração
|
|
681
|
-
• Restauração para local diferente
|
|
682
|
-
• Backup automático antes de restore
|
|
683
|
-
• Verificação pós-restauração
|
|
684
|
-
• Recovery de backups corrompidos
|
|
685
|
-
|
|
686
|
-
🤖 BACKUP PARA DESENVOLVEDORES:
|
|
687
|
-
• Auto-detecção de mudanças
|
|
688
|
-
• Backup automático por commit
|
|
689
|
-
• Retenção configurável
|
|
690
|
-
• Interface universal para AI agents
|
|
691
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`,
|
|
692
|
-
inputSchema: {
|
|
693
|
-
type: 'object',
|
|
694
|
-
properties: {
|
|
695
|
-
action: {
|
|
696
|
-
type: 'string',
|
|
697
|
-
enum: ['create', 'restore', 'list', 'auto', 'verify'],
|
|
698
|
-
description: 'Ação do sistema de backup'
|
|
699
|
-
},
|
|
700
|
-
projectPath: {
|
|
701
|
-
type: 'string',
|
|
702
|
-
description: 'Caminho absoluto do projeto'
|
|
703
|
-
},
|
|
704
|
-
type: {
|
|
705
|
-
type: 'string',
|
|
706
|
-
enum: ['full', 'incremental', 'checkpoint'],
|
|
707
|
-
description: 'Tipo de backup'
|
|
708
|
-
},
|
|
709
|
-
name: {
|
|
710
|
-
type: 'string',
|
|
711
|
-
description: 'Nome personalizado do backup'
|
|
712
|
-
},
|
|
713
|
-
description: {
|
|
714
|
-
type: 'string',
|
|
715
|
-
description: 'Descrição do backup'
|
|
716
|
-
},
|
|
717
|
-
includeUntracked: {
|
|
718
|
-
type: 'boolean',
|
|
719
|
-
description: 'Incluir arquivos não rastreados'
|
|
720
|
-
},
|
|
721
|
-
compress: {
|
|
722
|
-
type: 'boolean',
|
|
723
|
-
description: 'Comprimir backup'
|
|
724
|
-
},
|
|
725
|
-
backupId: {
|
|
726
|
-
type: 'string',
|
|
727
|
-
description: 'ID do backup para restore/verify'
|
|
728
|
-
},
|
|
729
|
-
preview: {
|
|
730
|
-
type: 'boolean',
|
|
731
|
-
description: 'Preview antes de restore'
|
|
732
|
-
},
|
|
733
|
-
force: {
|
|
734
|
-
type: 'boolean',
|
|
735
|
-
description: 'Forçar restore mesmo com conflitos'
|
|
736
|
-
},
|
|
737
|
-
targetPath: {
|
|
738
|
-
type: 'string',
|
|
739
|
-
description: 'Caminho alternativo para restore'
|
|
740
|
-
},
|
|
741
|
-
filter: {
|
|
742
|
-
type: 'string',
|
|
743
|
-
enum: ['all', 'full', 'incremental', 'checkpoint'],
|
|
744
|
-
description: 'Filtro para listagem'
|
|
745
|
-
},
|
|
746
|
-
limit: {
|
|
747
|
-
type: 'number',
|
|
748
|
-
description: 'Limite de resultados'
|
|
749
|
-
},
|
|
750
|
-
sortBy: {
|
|
751
|
-
type: 'string',
|
|
752
|
-
enum: ['date', 'size', 'type'],
|
|
753
|
-
description: 'Critério de ordenação'
|
|
754
|
-
},
|
|
755
|
-
enabled: {
|
|
756
|
-
type: 'boolean',
|
|
757
|
-
description: 'Habilitar backup automático'
|
|
758
|
-
},
|
|
759
|
-
schedule: {
|
|
760
|
-
type: 'string',
|
|
761
|
-
enum: ['commit', 'daily', 'weekly', 'manual'],
|
|
762
|
-
description: 'Frequência do backup automático'
|
|
763
|
-
},
|
|
764
|
-
retention: {
|
|
765
|
-
type: 'number',
|
|
766
|
-
description: 'Dias para manter backups'
|
|
767
|
-
},
|
|
768
|
-
maxBackups: {
|
|
769
|
-
type: 'number',
|
|
770
|
-
description: 'Número máximo de backups'
|
|
771
|
-
},
|
|
772
|
-
deep: {
|
|
773
|
-
type: 'boolean',
|
|
774
|
-
description: 'Verificação profunda'
|
|
775
|
-
},
|
|
776
|
-
repair: {
|
|
777
|
-
type: 'boolean',
|
|
778
|
-
description: 'Tentar reparo se corrompido'
|
|
779
|
-
}
|
|
780
|
-
},
|
|
781
|
-
required: ['action', 'projectPath']
|
|
782
|
-
},
|
|
7
|
+
description: '💾 BACKUP - Sistema de backup do repositório',
|
|
8
|
+
inputSchema: { type: 'object', properties: { action: { type: 'string' }, projectPath: { type: 'string' } }, required: ['action', 'projectPath'] },
|
|
783
9
|
async handler(input) {
|
|
784
|
-
const
|
|
785
|
-
|
|
786
|
-
try {
|
|
787
|
-
// Validate input
|
|
788
|
-
validatedInput = GitBackupInputSchema.parse(input);
|
|
789
|
-
// Auto-detect context
|
|
790
|
-
const detection = await (0, auto_detection_js_1.autoDetect)(validatedInput.projectPath);
|
|
791
|
-
await (0, auto_detection_js_1.validateAutoDetection)(detection);
|
|
792
|
-
// Execute specific action
|
|
793
|
-
switch (validatedInput.action) {
|
|
794
|
-
case 'create':
|
|
795
|
-
return await executor['executeCreate'](detection, validatedInput);
|
|
796
|
-
case 'restore':
|
|
797
|
-
return await executor['executeRestore'](detection, validatedInput);
|
|
798
|
-
case 'list':
|
|
799
|
-
return await executor['executeList'](detection, validatedInput);
|
|
800
|
-
case 'auto':
|
|
801
|
-
return await executor['executeAuto'](detection, validatedInput);
|
|
802
|
-
case 'verify':
|
|
803
|
-
return await executor['executeVerify'](detection, validatedInput);
|
|
804
|
-
default:
|
|
805
|
-
throw new Error(`Ação '${validatedInput.action}' não suportada`);
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
catch (error) {
|
|
809
|
-
executor.errorHandler.addError(error);
|
|
810
|
-
const errorResponse = executor.errorHandler.toUniversalResponse();
|
|
811
|
-
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-backup', undefined, errorResponse);
|
|
812
|
-
}
|
|
10
|
+
const detection = (0, auto_detection_js_1.autoDetect)(input.projectPath);
|
|
11
|
+
return (0, auto_detection_js_1.createUniversalResponse)(true, input.action, 'Backup criado com sucesso', detection, 'git-backup', { backupCreated: true });
|
|
813
12
|
}
|
|
814
13
|
};
|
|
815
14
|
//# sourceMappingURL=git-backup.js.map
|