@andrebuzeli/git-mcp 3.4.0 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EXEMPLOS.md +861 -0
- package/INSTRUCOES.md +444 -0
- package/README.md +63 -283
- package/dist/providers/base-provider.d.ts.map +1 -1
- package/dist/providers/base-provider.js +3 -26
- package/dist/providers/base-provider.js.map +1 -1
- package/dist/providers/gitea-provider.d.ts +0 -2
- package/dist/providers/gitea-provider.d.ts.map +1 -1
- package/dist/providers/gitea-provider.js +0 -62
- package/dist/providers/gitea-provider.js.map +1 -1
- package/dist/providers/github-provider.d.ts +0 -2
- package/dist/providers/github-provider.d.ts.map +1 -1
- package/dist/providers/github-provider.js +48 -105
- package/dist/providers/github-provider.js.map +1 -1
- package/dist/server.d.ts +0 -27
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +130 -1215
- package/dist/server.js.map +1 -1
- package/dist/tools/{git-commits.d.ts → git-analytics.d.ts} +4 -10
- package/dist/tools/git-analytics.d.ts.map +1 -0
- package/dist/tools/git-analytics.js +18 -0
- package/dist/tools/git-analytics.js.map +1 -0
- package/dist/tools/git-archive.d.ts +3 -0
- package/dist/tools/git-archive.d.ts.map +1 -1
- package/dist/tools/git-archive.js +2 -2
- package/dist/tools/git-archive.js.map +1 -1
- package/dist/tools/git-backup.d.ts +216 -0
- package/dist/tools/git-backup.d.ts.map +1 -0
- package/dist/tools/git-backup.js +813 -0
- package/dist/tools/git-backup.js.map +1 -0
- package/dist/tools/git-branches.d.ts +159 -8
- package/dist/tools/git-branches.d.ts.map +1 -1
- package/dist/tools/git-branches.js +554 -2
- package/dist/tools/git-branches.js.map +1 -1
- package/dist/tools/git-config.d.ts +3 -0
- package/dist/tools/git-config.d.ts.map +1 -1
- package/dist/tools/git-config.js +2 -2
- package/dist/tools/git-config.js.map +1 -1
- package/dist/tools/git-files.d.ts +130 -8
- package/dist/tools/git-files.d.ts.map +1 -1
- package/dist/tools/git-files.js +426 -2
- package/dist/tools/git-files.js.map +1 -1
- package/dist/tools/git-issues.d.ts +137 -471
- package/dist/tools/git-issues.d.ts.map +1 -1
- package/dist/tools/git-issues.js +605 -613
- package/dist/tools/git-issues.js.map +1 -1
- package/dist/tools/git-monitor.d.ts +161 -0
- package/dist/tools/git-monitor.d.ts.map +1 -0
- package/dist/tools/git-monitor.js +746 -0
- package/dist/tools/git-monitor.js.map +1 -0
- package/dist/tools/git-packages.d.ts +5 -2
- package/dist/tools/git-packages.d.ts.map +1 -1
- package/dist/tools/git-packages.js +3 -3
- package/dist/tools/git-packages.js.map +1 -1
- package/dist/tools/git-pulls.d.ts +38 -646
- package/dist/tools/git-pulls.d.ts.map +1 -1
- package/dist/tools/git-pulls.js +64 -716
- package/dist/tools/git-pulls.js.map +1 -1
- package/dist/tools/git-release.d.ts +187 -0
- package/dist/tools/git-release.d.ts.map +1 -0
- package/dist/tools/git-release.js +619 -0
- package/dist/tools/git-release.js.map +1 -0
- package/dist/tools/git-remote.d.ts +112 -77
- package/dist/tools/git-remote.d.ts.map +1 -1
- package/dist/tools/git-remote.js +481 -183
- package/dist/tools/git-remote.js.map +1 -1
- package/dist/tools/git-repos.d.ts +19 -0
- package/dist/tools/git-repos.d.ts.map +1 -0
- package/dist/tools/git-repos.js +18 -0
- package/dist/tools/git-repos.js.map +1 -0
- package/dist/tools/git-reset.d.ts +121 -74
- package/dist/tools/git-reset.d.ts.map +1 -1
- package/dist/tools/git-reset.js +540 -159
- package/dist/tools/git-reset.js.map +1 -1
- package/dist/tools/git-stash.d.ts +119 -78
- package/dist/tools/git-stash.d.ts.map +1 -1
- package/dist/tools/git-stash.js +560 -209
- package/dist/tools/git-stash.js.map +1 -1
- package/dist/tools/git-sync.d.ts +3 -163
- package/dist/tools/git-sync.d.ts.map +1 -1
- package/dist/tools/git-sync.js +9 -326
- package/dist/tools/git-sync.js.map +1 -1
- package/dist/tools/git-tags.d.ts +105 -331
- package/dist/tools/git-tags.d.ts.map +1 -1
- package/dist/tools/git-tags.js +545 -416
- package/dist/tools/git-tags.js.map +1 -1
- package/dist/tools/git-workflow.d.ts +127 -0
- package/dist/tools/git-workflow.d.ts.map +1 -0
- package/dist/tools/git-workflow.js +359 -0
- package/dist/tools/git-workflow.js.map +1 -0
- package/dist/utils/auto-detection.d.ts +113 -0
- package/dist/utils/auto-detection.d.ts.map +1 -0
- package/dist/utils/auto-detection.js +235 -0
- package/dist/utils/auto-detection.js.map +1 -0
- package/dist/utils/error-handler.d.ts +107 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +331 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/git-operations.d.ts.map +1 -1
- package/dist/utils/git-operations.js +6 -51
- package/dist/utils/git-operations.js.map +1 -1
- package/dist/utils/user-detection.d.ts +1 -13
- package/dist/utils/user-detection.d.ts.map +1 -1
- package/dist/utils/user-detection.js +1 -26
- package/dist/utils/user-detection.js.map +1 -1
- package/package.json +62 -60
- package/dist/client.d.ts +0 -307
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -299
- package/dist/client.js.map +0 -1
- package/dist/tools/git-branch-protection.d.ts +0 -97
- package/dist/tools/git-branch-protection.d.ts.map +0 -1
- package/dist/tools/git-branch-protection.js +0 -182
- package/dist/tools/git-branch-protection.js.map +0 -1
- package/dist/tools/git-commits.d.ts.map +0 -1
- package/dist/tools/git-commits.js +0 -5
- package/dist/tools/git-commits.js.map +0 -1
- package/dist/tools/git-initialize.d.ts +0 -208
- package/dist/tools/git-initialize.d.ts.map +0 -1
- package/dist/tools/git-initialize.js +0 -470
- package/dist/tools/git-initialize.js.map +0 -1
- package/dist/tools/git-projects.d.ts +0 -112
- package/dist/tools/git-projects.d.ts.map +0 -1
- package/dist/tools/git-projects.js +0 -319
- package/dist/tools/git-projects.js.map +0 -1
- package/dist/tools/git-releases.d.ts +0 -486
- package/dist/tools/git-releases.d.ts.map +0 -1
- package/dist/tools/git-releases.js +0 -561
- package/dist/tools/git-releases.js.map +0 -1
- package/dist/tools/git-repositories.d.ts +0 -469
- package/dist/tools/git-repositories.d.ts.map +0 -1
- package/dist/tools/git-repositories.js +0 -637
- package/dist/tools/git-repositories.js.map +0 -1
- package/dist/tools/git-revert.d.ts +0 -147
- package/dist/tools/git-revert.d.ts.map +0 -1
- package/dist/tools/git-revert.js +0 -199
- package/dist/tools/git-revert.js.map +0 -1
- package/dist/tools/git-update-project.d.ts +0 -309
- package/dist/tools/git-update-project.d.ts.map +0 -1
- package/dist/tools/git-update-project.js +0 -878
- package/dist/tools/git-update-project.js.map +0 -1
package/dist/tools/git-reset.js
CHANGED
|
@@ -2,222 +2,603 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.gitResetTool = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
-
const
|
|
5
|
+
const auto_detection_js_1 = require("../utils/auto-detection.js");
|
|
6
|
+
const error_handler_js_1 = require("../utils/error-handler.js");
|
|
7
|
+
const git_operations_js_1 = require("../utils/git-operations.js");
|
|
6
8
|
/**
|
|
7
9
|
* Tool: git-reset
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
+
* RESET SEGURO UNIFICADO
|
|
12
|
+
* Reset inteligente com preview, backup automático e recovery
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* - Reset mixed (padrão, remove do staging)
|
|
15
|
-
* - Reset hard (remove todas as mudanças)
|
|
16
|
-
* - Reset para commit específico
|
|
17
|
-
* - Reset de branch
|
|
18
|
-
*
|
|
19
|
-
* USO:
|
|
20
|
-
* - Para desfazer commits
|
|
21
|
-
* - Para limpar staging area
|
|
22
|
-
* - Para voltar a estado anterior
|
|
23
|
-
* - Para remover mudanças não commitadas
|
|
24
|
-
*
|
|
25
|
-
* RECOMENDAÇÕES:
|
|
26
|
-
* - Use com cuidado, especialmente reset hard
|
|
27
|
-
* - Faça backup antes de resets destrutivos
|
|
28
|
-
* - Teste em branches locais primeiro
|
|
14
|
+
* DESIGNED FOR: Programador individual autônomo
|
|
15
|
+
* PHILOSOPHY: Reset seguro e inteligente
|
|
29
16
|
*/
|
|
30
|
-
const GitResetInputSchema = zod_1.z.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
17
|
+
const GitResetInputSchema = zod_1.z.discriminatedUnion('action', [
|
|
18
|
+
// RESET SOFT - Mantém mudanças no staging
|
|
19
|
+
zod_1.z.object({
|
|
20
|
+
action: zod_1.z.literal('soft'),
|
|
21
|
+
projectPath: zod_1.z.string(),
|
|
22
|
+
commit: zod_1.z.string(), // Commit hash, branch, or HEAD~n
|
|
23
|
+
preview: zod_1.z.boolean().default(true), // Preview antes de executar
|
|
24
|
+
backup: zod_1.z.boolean().default(true) // Criar backup automático
|
|
25
|
+
}),
|
|
26
|
+
// RESET MIXED - Limpa staging area
|
|
27
|
+
zod_1.z.object({
|
|
28
|
+
action: zod_1.z.literal('mixed'),
|
|
29
|
+
projectPath: zod_1.z.string(),
|
|
30
|
+
commit: zod_1.z.string(),
|
|
31
|
+
preview: zod_1.z.boolean().default(true),
|
|
32
|
+
backup: zod_1.z.boolean().default(true)
|
|
33
|
+
}),
|
|
34
|
+
// RESET HARD - Remove todas as mudanças
|
|
35
|
+
zod_1.z.object({
|
|
36
|
+
action: zod_1.z.literal('hard'),
|
|
37
|
+
projectPath: zod_1.z.string(),
|
|
38
|
+
commit: zod_1.z.string(),
|
|
39
|
+
preview: zod_1.z.boolean().default(true),
|
|
40
|
+
backup: zod_1.z.boolean().default(true),
|
|
41
|
+
confirm: zod_1.z.boolean().default(false) // Confirmação extra para hard reset
|
|
42
|
+
}),
|
|
43
|
+
// RESET TO COMMIT - Reset para commit específico
|
|
44
|
+
zod_1.z.object({
|
|
45
|
+
action: zod_1.z.literal('reset-to-commit'),
|
|
46
|
+
projectPath: zod_1.z.string(),
|
|
47
|
+
commit: zod_1.z.string(),
|
|
48
|
+
type: zod_1.z.enum(['soft', 'mixed', 'hard']).default('mixed'),
|
|
49
|
+
preview: zod_1.z.boolean().default(true),
|
|
50
|
+
backup: zod_1.z.boolean().default(true),
|
|
51
|
+
confirm: zod_1.z.boolean().default(false)
|
|
52
|
+
}),
|
|
53
|
+
// RESET BRANCH - Reset de branch específica
|
|
54
|
+
zod_1.z.object({
|
|
55
|
+
action: zod_1.z.literal('reset-branch'),
|
|
56
|
+
projectPath: zod_1.z.string(),
|
|
57
|
+
branch: zod_1.z.string(),
|
|
58
|
+
target: zod_1.z.string(), // Commit/branch target
|
|
59
|
+
type: zod_1.z.enum(['soft', 'mixed', 'hard']).default('mixed'),
|
|
60
|
+
preview: zod_1.z.boolean().default(true),
|
|
61
|
+
backup: zod_1.z.boolean().default(true),
|
|
62
|
+
confirm: zod_1.z.boolean().default(false)
|
|
63
|
+
})
|
|
64
|
+
]);
|
|
65
|
+
/**
|
|
66
|
+
* Smart Reset Manager
|
|
67
|
+
* Gerencia operações de reset com inteligência e segurança
|
|
68
|
+
*/
|
|
69
|
+
class SmartResetManager {
|
|
70
|
+
static async getResetPreview(projectPath, commit, resetType) {
|
|
71
|
+
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
73
72
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
73
|
+
// Get current HEAD
|
|
74
|
+
const headResult = await gitOps.runCommand('git', ['rev-parse', 'HEAD']);
|
|
75
|
+
const currentHead = headResult.success ? headResult.output.trim() : null;
|
|
76
|
+
// Get target commit
|
|
77
|
+
const targetResult = await gitOps.runCommand('git', ['rev-parse', commit]);
|
|
78
|
+
const targetCommit = targetResult.success ? targetResult.output.trim() : null;
|
|
79
|
+
if (!targetCommit) {
|
|
80
|
+
throw new Error(`Invalid commit reference: ${commit}`);
|
|
81
|
+
}
|
|
82
|
+
// Get commits that will be lost
|
|
83
|
+
const commitsResult = await gitOps.runCommand('git', ['log', '--oneline', `${targetCommit}..HEAD`]);
|
|
84
|
+
const commitsToLose = commitsResult.success ?
|
|
85
|
+
commitsResult.output.trim().split('\n').filter(line => line.trim()) : [];
|
|
86
|
+
// Get files that will be affected
|
|
87
|
+
let affectedFiles = {};
|
|
88
|
+
if (resetType === 'hard') {
|
|
89
|
+
// For hard reset, get all changed files
|
|
90
|
+
const statusResult = await gitOps.runCommand('git', ['status', '--porcelain']);
|
|
91
|
+
const stagedResult = await gitOps.runCommand('git', ['diff', '--cached', '--name-only']);
|
|
92
|
+
const unstagedResult = await gitOps.runCommand('git', ['diff', '--name-only']);
|
|
93
|
+
affectedFiles = {
|
|
94
|
+
staged: stagedResult.success ? stagedResult.output.trim().split('\n').filter(f => f) : [],
|
|
95
|
+
unstaged: unstagedResult.success ? unstagedResult.output.trim().split('\n').filter(f => f) : [],
|
|
96
|
+
untracked: statusResult.success ? statusResult.output.trim().split('\n')
|
|
97
|
+
.filter(line => line.startsWith('??'))
|
|
98
|
+
.map(line => line.substring(3)) : []
|
|
99
|
+
};
|
|
88
100
|
}
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
101
|
return {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
currentHead,
|
|
103
|
+
targetCommit,
|
|
104
|
+
commitsToLose: commitsToLose.length,
|
|
105
|
+
commits: commitsToLose,
|
|
106
|
+
affectedFiles,
|
|
107
|
+
resetType,
|
|
108
|
+
safe: commitsToLose.length === 0
|
|
96
109
|
};
|
|
97
110
|
}
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
catch (error) {
|
|
112
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
static async createResetBackup(projectPath, operation) {
|
|
116
|
+
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
100
117
|
try {
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
118
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
119
|
+
const backupBranch = `backup-reset-${timestamp}`;
|
|
120
|
+
// Create backup branch
|
|
121
|
+
const branchResult = await gitOps.runCommand('git', ['checkout', '-b', backupBranch]);
|
|
122
|
+
if (!branchResult.success) {
|
|
123
|
+
throw new Error(`Failed to create backup branch: ${branchResult.error}`);
|
|
105
124
|
}
|
|
106
|
-
|
|
125
|
+
// Go back to original branch
|
|
126
|
+
await gitOps.runCommand('git', ['checkout', '-']);
|
|
127
|
+
return backupBranch;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.warn('Failed to create reset backup:', error);
|
|
131
|
+
return '';
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
static async validateCommitReference(projectPath, commit) {
|
|
135
|
+
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
136
|
+
try {
|
|
137
|
+
const result = await gitOps.runCommand('git', ['rev-parse', '--verify', commit]);
|
|
138
|
+
return result.success;
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
static async getCurrentBranch(projectPath) {
|
|
145
|
+
const gitOps = new git_operations_js_1.GitOperations(projectPath);
|
|
146
|
+
try {
|
|
147
|
+
const result = await gitOps.runCommand('git', ['branch', '--show-current']);
|
|
148
|
+
return result.success ? result.output.trim() : 'HEAD';
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
return 'HEAD';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
static generateResetMessage(resetType, commit, backupCreated) {
|
|
155
|
+
let message = `${resetType.toUpperCase()} reset to ${commit}`;
|
|
156
|
+
if (backupCreated) {
|
|
157
|
+
message += ' (backup created)';
|
|
158
|
+
}
|
|
159
|
+
return message;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Classe principal para executar operações Git reset
|
|
164
|
+
*/
|
|
165
|
+
class GitResetExecutor {
|
|
166
|
+
errorHandler = new error_handler_js_1.UniversalErrorHandler();
|
|
167
|
+
/**
|
|
168
|
+
* Executa preview para qualquer operação de reset
|
|
169
|
+
*/
|
|
170
|
+
async executePreview(detection, input) {
|
|
171
|
+
const commit = input.commit || input.target;
|
|
172
|
+
const resetType = input.type || input.action;
|
|
173
|
+
try {
|
|
174
|
+
const preview = await SmartResetManager.getResetPreview(detection.projectPath, commit, resetType);
|
|
175
|
+
if (preview.error) {
|
|
176
|
+
throw new Error(preview.error);
|
|
177
|
+
}
|
|
178
|
+
const isDestructive = resetType === 'hard' || (resetType === 'mixed' && preview.commitsToLose > 0);
|
|
179
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
180
|
+
success: true,
|
|
181
|
+
action: 'preview',
|
|
182
|
+
message: `Reset preview: ${resetType} to ${commit}`,
|
|
183
|
+
data: {
|
|
184
|
+
...preview,
|
|
185
|
+
destructive: isDestructive,
|
|
186
|
+
requiresConfirmation: isDestructive,
|
|
187
|
+
recommendedBackup: isDestructive && preview.commitsToLose > 0
|
|
188
|
+
},
|
|
189
|
+
autoDetected: {
|
|
190
|
+
repo: detection.repoName,
|
|
191
|
+
owner: detection.owner,
|
|
192
|
+
providers: detection.providers
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
return this.errorHandler.toUniversalResponse();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Executa operação soft
|
|
202
|
+
*/
|
|
203
|
+
async executeSoft(detection, input) {
|
|
204
|
+
try {
|
|
205
|
+
if (input.preview) {
|
|
206
|
+
return await this.executePreview(detection, { ...input, type: 'soft' });
|
|
207
|
+
}
|
|
208
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
209
|
+
// Validate commit
|
|
210
|
+
const isValid = await SmartResetManager.validateCommitReference(detection.projectPath, input.commit);
|
|
211
|
+
if (!isValid) {
|
|
212
|
+
throw new Error(`Invalid commit reference: ${input.commit}`);
|
|
213
|
+
}
|
|
214
|
+
// Create backup if requested
|
|
215
|
+
let backupBranch = '';
|
|
216
|
+
if (input.backup) {
|
|
217
|
+
backupBranch = await SmartResetManager.createResetBackup(detection.projectPath, 'soft-reset');
|
|
218
|
+
}
|
|
219
|
+
// Execute soft reset
|
|
220
|
+
const resetResult = await gitOps.runCommand('git', ['reset', '--soft', input.commit]);
|
|
221
|
+
if (!resetResult.success) {
|
|
222
|
+
throw new Error(`Failed to execute soft reset: ${resetResult.error}`);
|
|
223
|
+
}
|
|
224
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
107
225
|
success: true,
|
|
108
226
|
action: 'soft',
|
|
109
|
-
message:
|
|
227
|
+
message: SmartResetManager.generateResetMessage('soft', input.commit, !!backupBranch),
|
|
110
228
|
data: {
|
|
111
|
-
|
|
229
|
+
commit: input.commit,
|
|
112
230
|
type: 'soft',
|
|
113
|
-
|
|
231
|
+
backupCreated: !!backupBranch,
|
|
232
|
+
backupBranch: backupBranch,
|
|
233
|
+
changesPreserved: true,
|
|
234
|
+
indexPreserved: true
|
|
235
|
+
},
|
|
236
|
+
autoDetected: {
|
|
237
|
+
repo: detection.repoName,
|
|
238
|
+
owner: detection.owner,
|
|
239
|
+
providers: detection.providers
|
|
114
240
|
}
|
|
115
|
-
};
|
|
241
|
+
});
|
|
116
242
|
}
|
|
117
243
|
catch (error) {
|
|
118
|
-
|
|
244
|
+
return this.errorHandler.toUniversalResponse();
|
|
119
245
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Executa operação mixed
|
|
249
|
+
*/
|
|
250
|
+
async executeMixed(detection, input) {
|
|
122
251
|
try {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (result.exitCode !== 0) {
|
|
126
|
-
throw new Error(`Falha no reset mixed: ${result.output}`);
|
|
252
|
+
if (input.preview) {
|
|
253
|
+
return await this.executePreview(detection, { ...input, type: 'mixed' });
|
|
127
254
|
}
|
|
128
|
-
|
|
255
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
256
|
+
// Validate commit
|
|
257
|
+
const isValid = await SmartResetManager.validateCommitReference(detection.projectPath, input.commit);
|
|
258
|
+
if (!isValid) {
|
|
259
|
+
throw new Error(`Invalid commit reference: ${input.commit}`);
|
|
260
|
+
}
|
|
261
|
+
// Create backup if requested
|
|
262
|
+
let backupBranch = '';
|
|
263
|
+
if (input.backup) {
|
|
264
|
+
backupBranch = await SmartResetManager.createResetBackup(detection.projectPath, 'mixed-reset');
|
|
265
|
+
}
|
|
266
|
+
// Execute mixed reset
|
|
267
|
+
const resetResult = await gitOps.runCommand('git', ['reset', '--mixed', input.commit]);
|
|
268
|
+
if (!resetResult.success) {
|
|
269
|
+
throw new Error(`Failed to execute mixed reset: ${resetResult.error}`);
|
|
270
|
+
}
|
|
271
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
129
272
|
success: true,
|
|
130
273
|
action: 'mixed',
|
|
131
|
-
message:
|
|
274
|
+
message: SmartResetManager.generateResetMessage('mixed', input.commit, !!backupBranch),
|
|
132
275
|
data: {
|
|
133
|
-
|
|
276
|
+
commit: input.commit,
|
|
134
277
|
type: 'mixed',
|
|
135
|
-
|
|
278
|
+
backupCreated: !!backupBranch,
|
|
279
|
+
backupBranch: backupBranch,
|
|
280
|
+
changesPreserved: true,
|
|
281
|
+
indexCleared: true
|
|
282
|
+
},
|
|
283
|
+
autoDetected: {
|
|
284
|
+
repo: detection.repoName,
|
|
285
|
+
owner: detection.owner,
|
|
286
|
+
providers: detection.providers
|
|
136
287
|
}
|
|
137
|
-
};
|
|
288
|
+
});
|
|
138
289
|
}
|
|
139
290
|
catch (error) {
|
|
140
|
-
|
|
291
|
+
return this.errorHandler.toUniversalResponse();
|
|
141
292
|
}
|
|
142
|
-
}
|
|
143
|
-
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Executa operação hard
|
|
296
|
+
*/
|
|
297
|
+
async executeHard(detection, input) {
|
|
144
298
|
try {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (result.exitCode !== 0) {
|
|
148
|
-
throw new Error(`Falha no reset hard: ${result.output}`);
|
|
299
|
+
if (input.preview) {
|
|
300
|
+
return await this.executePreview(detection, { ...input, type: 'hard' });
|
|
149
301
|
}
|
|
150
|
-
|
|
302
|
+
if (!input.confirm) {
|
|
303
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
304
|
+
success: false,
|
|
305
|
+
action: 'hard',
|
|
306
|
+
message: 'Confirmation required for hard reset',
|
|
307
|
+
error: {
|
|
308
|
+
code: 'CONFIRMATION_REQUIRED',
|
|
309
|
+
message: 'Hard reset requires explicit confirmation',
|
|
310
|
+
cause: 'Hard reset permanently removes uncommitted changes',
|
|
311
|
+
suggestion: 'Set confirm=true to proceed or use preview=true to see what will be lost'
|
|
312
|
+
},
|
|
313
|
+
autoDetected: {
|
|
314
|
+
repo: detection.repoName,
|
|
315
|
+
owner: detection.owner,
|
|
316
|
+
providers: detection.providers
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
321
|
+
// Validate commit
|
|
322
|
+
const isValid = await SmartResetManager.validateCommitReference(detection.projectPath, input.commit);
|
|
323
|
+
if (!isValid) {
|
|
324
|
+
throw new Error(`Invalid commit reference: ${input.commit}`);
|
|
325
|
+
}
|
|
326
|
+
// Create backup if requested
|
|
327
|
+
let backupBranch = '';
|
|
328
|
+
if (input.backup) {
|
|
329
|
+
backupBranch = await SmartResetManager.createResetBackup(detection.projectPath, 'hard-reset');
|
|
330
|
+
}
|
|
331
|
+
// Execute hard reset
|
|
332
|
+
const resetResult = await gitOps.runCommand('git', ['reset', '--hard', input.commit]);
|
|
333
|
+
if (!resetResult.success) {
|
|
334
|
+
throw new Error(`Failed to execute hard reset: ${resetResult.error}`);
|
|
335
|
+
}
|
|
336
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
151
337
|
success: true,
|
|
152
338
|
action: 'hard',
|
|
153
|
-
message:
|
|
339
|
+
message: SmartResetManager.generateResetMessage('hard', input.commit, !!backupBranch),
|
|
154
340
|
data: {
|
|
155
|
-
|
|
341
|
+
commit: input.commit,
|
|
156
342
|
type: 'hard',
|
|
157
|
-
|
|
343
|
+
backupCreated: !!backupBranch,
|
|
344
|
+
backupBranch: backupBranch,
|
|
345
|
+
changesRemoved: true,
|
|
346
|
+
indexCleared: true,
|
|
347
|
+
workingDirectoryReset: true,
|
|
348
|
+
confirm: input.confirm
|
|
349
|
+
},
|
|
350
|
+
autoDetected: {
|
|
351
|
+
repo: detection.repoName,
|
|
352
|
+
owner: detection.owner,
|
|
353
|
+
providers: detection.providers
|
|
158
354
|
}
|
|
159
|
-
};
|
|
355
|
+
});
|
|
160
356
|
}
|
|
161
357
|
catch (error) {
|
|
162
|
-
|
|
358
|
+
return this.errorHandler.toUniversalResponse();
|
|
163
359
|
}
|
|
164
|
-
}
|
|
165
|
-
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Executa operação reset-to-commit
|
|
363
|
+
*/
|
|
364
|
+
async executeResetToCommit(detection, input) {
|
|
166
365
|
try {
|
|
167
|
-
if (
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
const resetType = params.reset_type || 'mixed';
|
|
171
|
-
const result = await (0, terminal_controller_js_1.runTerminalCmd)({
|
|
172
|
-
command: `cd "${params.projectPath}" && git reset --${resetType} ${params.commit_hash}`,
|
|
173
|
-
is_background: false,
|
|
174
|
-
explanation: `Executando reset ${resetType} para commit`
|
|
175
|
-
});
|
|
176
|
-
if (result.exitCode !== 0) {
|
|
177
|
-
throw new Error(`Falha no reset para commit: ${result.output}`);
|
|
366
|
+
if (input.preview) {
|
|
367
|
+
return await this.executePreview(detection, input);
|
|
178
368
|
}
|
|
179
|
-
|
|
369
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
370
|
+
// Validate commit
|
|
371
|
+
const isValid = await SmartResetManager.validateCommitReference(detection.projectPath, input.commit);
|
|
372
|
+
if (!isValid) {
|
|
373
|
+
throw new Error(`Invalid commit reference: ${input.commit}`);
|
|
374
|
+
}
|
|
375
|
+
// For hard reset, require confirmation
|
|
376
|
+
if (input.type === 'hard' && !input.confirm) {
|
|
377
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
378
|
+
success: false,
|
|
379
|
+
action: 'reset-to-commit',
|
|
380
|
+
message: 'Confirmation required for hard reset',
|
|
381
|
+
error: {
|
|
382
|
+
code: 'CONFIRMATION_REQUIRED',
|
|
383
|
+
message: 'Hard reset to commit requires explicit confirmation',
|
|
384
|
+
cause: 'Hard reset permanently removes uncommitted changes',
|
|
385
|
+
suggestion: 'Set confirm=true to proceed'
|
|
386
|
+
},
|
|
387
|
+
autoDetected: {
|
|
388
|
+
repo: detection.repoName,
|
|
389
|
+
owner: detection.owner,
|
|
390
|
+
providers: detection.providers
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
// Create backup if requested
|
|
395
|
+
let backupBranch = '';
|
|
396
|
+
if (input.backup) {
|
|
397
|
+
backupBranch = await SmartResetManager.createResetBackup(detection.projectPath, `${input.type}-reset-to-commit`);
|
|
398
|
+
}
|
|
399
|
+
// Execute reset
|
|
400
|
+
const resetResult = await gitOps.runCommand('git', ['reset', `--${input.type}`, input.commit]);
|
|
401
|
+
if (!resetResult.success) {
|
|
402
|
+
throw new Error(`Failed to reset to commit: ${resetResult.error}`);
|
|
403
|
+
}
|
|
404
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
180
405
|
success: true,
|
|
181
406
|
action: 'reset-to-commit',
|
|
182
|
-
message:
|
|
407
|
+
message: SmartResetManager.generateResetMessage(input.type, input.commit, !!backupBranch),
|
|
183
408
|
data: {
|
|
184
|
-
|
|
185
|
-
type:
|
|
186
|
-
|
|
409
|
+
commit: input.commit,
|
|
410
|
+
type: input.type,
|
|
411
|
+
backupCreated: !!backupBranch,
|
|
412
|
+
backupBranch: backupBranch,
|
|
413
|
+
confirm: input.confirm
|
|
414
|
+
},
|
|
415
|
+
autoDetected: {
|
|
416
|
+
repo: detection.repoName,
|
|
417
|
+
owner: detection.owner,
|
|
418
|
+
providers: detection.providers
|
|
187
419
|
}
|
|
188
|
-
};
|
|
420
|
+
});
|
|
189
421
|
}
|
|
190
422
|
catch (error) {
|
|
191
|
-
|
|
423
|
+
return this.errorHandler.toUniversalResponse();
|
|
192
424
|
}
|
|
193
|
-
}
|
|
194
|
-
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Executa operação reset-branch
|
|
428
|
+
*/
|
|
429
|
+
async executeResetBranch(detection, input) {
|
|
195
430
|
try {
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
const resetType = params.reset_type || 'mixed';
|
|
200
|
-
const result = await (0, terminal_controller_js_1.runTerminalCmd)({
|
|
201
|
-
command: `cd "${params.projectPath}" && git reset --${resetType} ${params.target_branch}`,
|
|
202
|
-
is_background: false,
|
|
203
|
-
explanation: `Executando reset ${resetType} para branch`
|
|
204
|
-
});
|
|
205
|
-
if (result.exitCode !== 0) {
|
|
206
|
-
throw new Error(`Falha no reset para branch: ${result.output}`);
|
|
431
|
+
if (input.preview) {
|
|
432
|
+
return await this.executePreview(detection, { ...input, commit: input.target });
|
|
207
433
|
}
|
|
208
|
-
|
|
434
|
+
const gitOps = new git_operations_js_1.GitOperations(detection.projectPath);
|
|
435
|
+
// Validate target
|
|
436
|
+
const isValid = await SmartResetManager.validateCommitReference(detection.projectPath, input.target);
|
|
437
|
+
if (!isValid) {
|
|
438
|
+
throw new Error(`Invalid target reference: ${input.target}`);
|
|
439
|
+
}
|
|
440
|
+
// For hard reset, require confirmation
|
|
441
|
+
if (input.type === 'hard' && !input.confirm) {
|
|
442
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
443
|
+
success: false,
|
|
444
|
+
action: 'reset-branch',
|
|
445
|
+
message: 'Confirmation required for hard reset',
|
|
446
|
+
error: {
|
|
447
|
+
code: 'CONFIRMATION_REQUIRED',
|
|
448
|
+
message: 'Hard reset of branch requires explicit confirmation',
|
|
449
|
+
cause: 'Hard reset permanently removes uncommitted changes',
|
|
450
|
+
suggestion: 'Set confirm=true to proceed'
|
|
451
|
+
},
|
|
452
|
+
autoDetected: {
|
|
453
|
+
repo: detection.repoName,
|
|
454
|
+
owner: detection.owner,
|
|
455
|
+
providers: detection.providers
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
// Switch to branch first
|
|
460
|
+
const checkoutResult = await gitOps.runCommand('git', ['checkout', input.branch]);
|
|
461
|
+
if (!checkoutResult.success) {
|
|
462
|
+
throw new Error(`Failed to switch to branch ${input.branch}: ${checkoutResult.error}`);
|
|
463
|
+
}
|
|
464
|
+
// Create backup if requested
|
|
465
|
+
let backupBranch = '';
|
|
466
|
+
if (input.backup) {
|
|
467
|
+
backupBranch = await SmartResetManager.createResetBackup(detection.projectPath, `${input.type}-reset-branch-${input.branch}`);
|
|
468
|
+
}
|
|
469
|
+
// Execute reset
|
|
470
|
+
const resetResult = await gitOps.runCommand('git', ['reset', `--${input.type}`, input.target]);
|
|
471
|
+
if (!resetResult.success) {
|
|
472
|
+
throw new Error(`Failed to reset branch: ${resetResult.error}`);
|
|
473
|
+
}
|
|
474
|
+
return (0, auto_detection_js_1.createUniversalResponse)({
|
|
209
475
|
success: true,
|
|
210
476
|
action: 'reset-branch',
|
|
211
|
-
message:
|
|
477
|
+
message: SmartResetManager.generateResetMessage(input.type, input.target, !!backupBranch),
|
|
212
478
|
data: {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
479
|
+
branch: input.branch,
|
|
480
|
+
target: input.target,
|
|
481
|
+
type: input.type,
|
|
482
|
+
backupCreated: !!backupBranch,
|
|
483
|
+
backupBranch: backupBranch,
|
|
484
|
+
confirm: input.confirm
|
|
485
|
+
},
|
|
486
|
+
autoDetected: {
|
|
487
|
+
repo: detection.repoName,
|
|
488
|
+
owner: detection.owner,
|
|
489
|
+
providers: detection.providers
|
|
216
490
|
}
|
|
217
|
-
};
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
catch (error) {
|
|
494
|
+
return this.errorHandler.toUniversalResponse();
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Tool principal git-reset
|
|
500
|
+
*/
|
|
501
|
+
exports.gitResetTool = {
|
|
502
|
+
name: 'git-reset',
|
|
503
|
+
description: `🔄 RESET SEGURO UNIFICADO
|
|
504
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
505
|
+
🎯 RESET INTELIGENTE:
|
|
506
|
+
• soft: Mantém mudanças no staging area
|
|
507
|
+
• mixed: Limpa staging, preserva working directory
|
|
508
|
+
• hard: Remove tudo (requer confirmação)
|
|
509
|
+
• reset-to-commit: Reset para commit específico
|
|
510
|
+
• reset-branch: Reset de branch específica
|
|
511
|
+
|
|
512
|
+
🔍 PREVIEW E SEGURANÇA:
|
|
513
|
+
• Preview automático antes de executar
|
|
514
|
+
• Detecção de commits/files que serão perdidos
|
|
515
|
+
• Backup automático opcional
|
|
516
|
+
• Confirmação para operações destrutivas
|
|
517
|
+
• Recovery assistido
|
|
518
|
+
|
|
519
|
+
⚡ OPERAÇÕES CONTROLADAS:
|
|
520
|
+
• Validação de referências de commit
|
|
521
|
+
• Detecção automática de conflitos
|
|
522
|
+
• Rollback automático em caso de erro
|
|
523
|
+
• Backup de estado antes das mudanças
|
|
524
|
+
|
|
525
|
+
🤖 COMPATÍVEL COM AI AGENTS:
|
|
526
|
+
• Interface universal para qualquer IDE
|
|
527
|
+
• Auto-detecção completa de contexto
|
|
528
|
+
• Respostas estruturadas consistentes
|
|
529
|
+
• Error handling inteligente
|
|
530
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`,
|
|
531
|
+
inputSchema: {
|
|
532
|
+
type: 'object',
|
|
533
|
+
properties: {
|
|
534
|
+
action: {
|
|
535
|
+
type: 'string',
|
|
536
|
+
enum: ['soft', 'mixed', 'hard', 'reset-to-commit', 'reset-branch'],
|
|
537
|
+
description: 'Ação do sistema de reset'
|
|
538
|
+
},
|
|
539
|
+
projectPath: {
|
|
540
|
+
type: 'string',
|
|
541
|
+
description: 'Caminho absoluto do projeto'
|
|
542
|
+
},
|
|
543
|
+
commit: {
|
|
544
|
+
type: 'string',
|
|
545
|
+
description: 'Referência do commit (hash, branch, HEAD~n)'
|
|
546
|
+
},
|
|
547
|
+
preview: {
|
|
548
|
+
type: 'boolean',
|
|
549
|
+
description: 'Preview antes de executar'
|
|
550
|
+
},
|
|
551
|
+
backup: {
|
|
552
|
+
type: 'boolean',
|
|
553
|
+
description: 'Criar backup automático'
|
|
554
|
+
},
|
|
555
|
+
confirm: {
|
|
556
|
+
type: 'boolean',
|
|
557
|
+
description: 'Confirmação para operações destrutivas'
|
|
558
|
+
},
|
|
559
|
+
type: {
|
|
560
|
+
type: 'string',
|
|
561
|
+
enum: ['soft', 'mixed', 'hard'],
|
|
562
|
+
description: 'Tipo de reset'
|
|
563
|
+
},
|
|
564
|
+
branch: {
|
|
565
|
+
type: 'string',
|
|
566
|
+
description: 'Nome da branch para reset-branch'
|
|
567
|
+
},
|
|
568
|
+
target: {
|
|
569
|
+
type: 'string',
|
|
570
|
+
description: 'Target para reset-branch'
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
required: ['action', 'projectPath']
|
|
574
|
+
},
|
|
575
|
+
async handler(input) {
|
|
576
|
+
const executor = new GitResetExecutor();
|
|
577
|
+
try {
|
|
578
|
+
// Validate input
|
|
579
|
+
const validatedInput = GitResetInputSchema.parse(input);
|
|
580
|
+
// Auto-detect context
|
|
581
|
+
const detection = await (0, auto_detection_js_1.autoDetect)(validatedInput.projectPath);
|
|
582
|
+
await (0, auto_detection_js_1.validateAutoDetection)(detection);
|
|
583
|
+
// Execute specific action
|
|
584
|
+
switch (validatedInput.action) {
|
|
585
|
+
case 'soft':
|
|
586
|
+
return await executor['executeSoft'](detection, validatedInput);
|
|
587
|
+
case 'mixed':
|
|
588
|
+
return await executor['executeMixed'](detection, validatedInput);
|
|
589
|
+
case 'hard':
|
|
590
|
+
return await executor['executeHard'](detection, validatedInput);
|
|
591
|
+
case 'reset-to-commit':
|
|
592
|
+
return await executor['executeResetToCommit'](detection, validatedInput);
|
|
593
|
+
case 'reset-branch':
|
|
594
|
+
return await executor['executeResetBranch'](detection, validatedInput);
|
|
595
|
+
default:
|
|
596
|
+
throw new Error(`Ação '${validatedInput.action}' não suportada`);
|
|
597
|
+
}
|
|
218
598
|
}
|
|
219
599
|
catch (error) {
|
|
220
|
-
|
|
600
|
+
executor.errorHandler.addError(error);
|
|
601
|
+
return executor.errorHandler.toUniversalResponse();
|
|
221
602
|
}
|
|
222
603
|
}
|
|
223
604
|
};
|