@andrebuzeli/git-mcp 9.2.0 → 10.0.1
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/LICENSE +21 -0
- package/README.md +460 -328
- package/dist/.tsbuildinfo +1 -1
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +20 -23
- package/dist/prompts/gitPrompts.d.ts +20 -1
- package/dist/prompts/gitPrompts.d.ts.map +1 -1
- package/dist/prompts/gitPrompts.js +49 -9
- package/dist/prompts/gitPrompts.js.map +1 -1
- package/dist/providers/giteaProvider.d.ts +1 -18
- package/dist/providers/giteaProvider.js +1 -87
- package/dist/providers/githubProvider.d.ts +0 -1
- package/dist/providers/githubProvider.js +0 -1
- package/dist/providers/providerManager.d.ts +0 -15
- package/dist/providers/providerManager.js +0 -65
- package/dist/resources/toolsGuide.d.ts +0 -1
- package/dist/resources/toolsGuide.js +1701 -1702
- package/dist/server.d.ts +0 -1
- package/dist/server.js +11 -2
- package/dist/tools/gitAnalytics.d.ts +4 -5
- package/dist/tools/gitAnalytics.js +12 -19
- package/dist/tools/gitArchive.d.ts +11 -4
- package/dist/tools/gitArchive.d.ts.map +1 -1
- package/dist/tools/gitArchive.js +15 -9
- package/dist/tools/gitArchive.js.map +1 -1
- package/dist/tools/gitBackup.d.ts +6 -7
- package/dist/tools/gitBackup.d.ts.map +1 -1
- package/dist/tools/gitBackup.js +16 -18
- package/dist/tools/gitBackup.js.map +1 -1
- package/dist/tools/gitBranches.d.ts +8 -9
- package/dist/tools/gitBranches.js +47 -63
- package/dist/tools/gitChangelog.d.ts +37 -1
- package/dist/tools/gitChangelog.d.ts.map +1 -1
- package/dist/tools/gitChangelog.js +67 -2
- package/dist/tools/gitChangelog.js.map +1 -1
- package/dist/tools/gitConfig.d.ts +13 -6
- package/dist/tools/gitConfig.js +26 -19
- package/dist/tools/gitFiles.d.ts +22 -8
- package/dist/tools/gitFiles.js +29 -18
- package/dist/tools/gitFix.d.ts +1 -4
- package/dist/tools/gitFix.js +32 -62
- package/dist/tools/gitFix.tool.d.ts +3 -4
- package/dist/tools/gitFix.tool.js +62 -63
- package/dist/tools/gitHistory.d.ts +42 -8
- package/dist/tools/gitHistory.js +251 -191
- package/dist/tools/gitIgnore.d.ts +14 -3
- package/dist/tools/gitIgnore.js +130 -120
- package/dist/tools/gitIssues.d.ts +9 -10
- package/dist/tools/gitIssues.js +36 -69
- package/dist/tools/gitLog.d.ts +30 -1
- package/dist/tools/gitLog.d.ts.map +1 -1
- package/dist/tools/gitLog.js +46 -2
- package/dist/tools/gitLog.js.map +1 -1
- package/dist/tools/gitMonitor.d.ts +0 -5
- package/dist/tools/gitMonitor.js +23 -28
- package/dist/tools/gitPackages.d.ts +146 -34
- package/dist/tools/gitPackages.js +147 -280
- package/dist/tools/gitPulls.d.ts +0 -66
- package/dist/tools/gitPulls.d.ts.map +1 -1
- package/dist/tools/gitPulls.js +7 -93
- package/dist/tools/gitPulls.js.map +1 -1
- package/dist/tools/gitPush.d.ts +0 -1
- package/dist/tools/gitPush.js +0 -1
- package/dist/tools/gitRelease.d.ts +0 -49
- package/dist/tools/gitRelease.js +6 -122
- package/dist/tools/gitRemote.d.ts +1 -31
- package/dist/tools/gitRemote.js +17 -59
- package/dist/tools/gitReset.d.ts +0 -25
- package/dist/tools/gitReset.js +8 -33
- package/dist/tools/gitStash.d.ts +2 -35
- package/dist/tools/gitStash.js +26 -56
- package/dist/tools/gitSync.d.ts +0 -29
- package/dist/tools/gitSync.js +20 -65
- package/dist/tools/gitTags.d.ts +0 -37
- package/dist/tools/gitTags.d.ts.map +1 -1
- package/dist/tools/gitTags.js +26 -53
- package/dist/tools/gitTags.js.map +1 -1
- package/dist/tools/gitUpdate.d.ts +42 -1
- package/dist/tools/gitUpdate.js +348 -61
- package/dist/tools/gitUpload.d.ts +9 -1
- package/dist/tools/gitUpload.js +61 -25
- package/dist/tools/gitWorkflow.d.ts +77 -1
- package/dist/tools/gitWorkflow.js +134 -65
- package/dist/types.d.ts +1 -7
- package/dist/types.js +0 -1
- package/dist/utils/apiHelpers.d.ts +0 -1
- package/dist/utils/apiHelpers.js +0 -1
- package/dist/utils/errors.d.ts +0 -1
- package/dist/utils/errors.js +0 -1
- package/dist/utils/gitAdapter.d.ts +14 -13
- package/dist/utils/gitAdapter.d.ts.map +1 -1
- package/dist/utils/gitAdapter.js +47 -9
- package/dist/utils/gitAdapter.js.map +1 -1
- package/dist/utils/repoHelpers.d.ts +0 -2
- package/dist/utils/repoHelpers.js +3 -16
- package/dist/utils/safetyController.d.ts +0 -1
- package/dist/utils/safetyController.js +0 -1
- package/dist/utils/safetyController.js.map +1 -1
- package/package.json +87 -96
package/dist/tools/gitUpload.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import simpleGit from 'simple-git';
|
|
1
2
|
import { MCPError } from '../utils/errors.js';
|
|
2
3
|
import axios from 'axios';
|
|
4
|
+
import * as fs from 'fs/promises';
|
|
5
|
+
import * as path from 'path';
|
|
3
6
|
import { getRepoNameFromPath } from '../utils/repoHelpers.js';
|
|
4
7
|
/**
|
|
5
8
|
* Git Upload Tool - Envia projeto completo para GitHub e Gitea automaticamente
|
|
@@ -18,15 +21,23 @@ export class GitUploadTool {
|
|
|
18
21
|
},
|
|
19
22
|
repoName: {
|
|
20
23
|
type: "string",
|
|
21
|
-
description: "Repository name (auto-detected from
|
|
24
|
+
description: "Repository name (optional, auto-detected from projectPath)"
|
|
22
25
|
},
|
|
23
26
|
description: {
|
|
24
27
|
type: "string",
|
|
25
|
-
description: "Repository description"
|
|
28
|
+
description: "Repository description (optional, defaults to timestamp-based message)"
|
|
26
29
|
},
|
|
27
30
|
private: {
|
|
28
31
|
type: "boolean",
|
|
29
|
-
description: "Make repository private (default: true)"
|
|
32
|
+
description: "Make repository private (optional, default: true)"
|
|
33
|
+
},
|
|
34
|
+
branch: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Branch to upload (optional, default: 'master')"
|
|
37
|
+
},
|
|
38
|
+
commitMessage: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Commit message (optional, defaults to timestamp-based message)"
|
|
30
41
|
}
|
|
31
42
|
},
|
|
32
43
|
required: ["projectPath"],
|
|
@@ -42,7 +53,7 @@ export class GitUploadTool {
|
|
|
42
53
|
const description = params.description || `Project uploaded via git-upload at ${new Date().toISOString()}`;
|
|
43
54
|
const isPrivate = params.private !== undefined ? params.private : true;
|
|
44
55
|
const branch = params.branch || 'master';
|
|
45
|
-
const git =
|
|
56
|
+
const git = simpleGit({ baseDir: projectPath });
|
|
46
57
|
// Resultado com rastreabilidade completa
|
|
47
58
|
const results = {
|
|
48
59
|
success: true,
|
|
@@ -60,16 +71,16 @@ export class GitUploadTool {
|
|
|
60
71
|
try {
|
|
61
72
|
// 0. Verificar se é um repositório Git, se não for, inicializar
|
|
62
73
|
try {
|
|
63
|
-
await git.status(
|
|
74
|
+
await git.status();
|
|
64
75
|
}
|
|
65
76
|
catch (err) {
|
|
66
|
-
if (err.message.includes('not a git repository')
|
|
77
|
+
if (err.message.includes('not a git repository')) {
|
|
67
78
|
results.traceability.uploadSteps.push({
|
|
68
79
|
step: 0,
|
|
69
80
|
action: 'init_git_repository',
|
|
70
81
|
timestamp: new Date().toISOString(),
|
|
71
82
|
});
|
|
72
|
-
await git.init(
|
|
83
|
+
await git.init();
|
|
73
84
|
}
|
|
74
85
|
else {
|
|
75
86
|
throw err;
|
|
@@ -81,24 +92,25 @@ export class GitUploadTool {
|
|
|
81
92
|
action: 'check_local_status',
|
|
82
93
|
timestamp: new Date().toISOString(),
|
|
83
94
|
});
|
|
84
|
-
const status = await git.status(
|
|
95
|
+
const status = await git.status();
|
|
85
96
|
results.traceability.localChanges = {
|
|
86
97
|
modified: status.modified,
|
|
87
98
|
created: status.created,
|
|
88
99
|
deleted: status.deleted,
|
|
89
100
|
renamed: status.renamed,
|
|
101
|
+
staged: status.staged,
|
|
90
102
|
conflicted: status.conflicted,
|
|
91
|
-
isClean: status.isClean,
|
|
103
|
+
isClean: status.isClean(),
|
|
92
104
|
};
|
|
93
105
|
// 2. Verificar se tem mudanças
|
|
94
|
-
if (!status.isClean) {
|
|
106
|
+
if (!status.isClean()) {
|
|
95
107
|
results.traceability.uploadSteps.push({
|
|
96
108
|
step: 2,
|
|
97
109
|
action: 'stage_all_changes',
|
|
98
110
|
timestamp: new Date().toISOString(),
|
|
99
111
|
files: [...status.modified, ...status.created, ...status.deleted],
|
|
100
112
|
});
|
|
101
|
-
await git.add(
|
|
113
|
+
await git.add('.');
|
|
102
114
|
}
|
|
103
115
|
// 3. Commit com rastreabilidade
|
|
104
116
|
const commitMessage = params.commitMessage || `[git-upload] Upload project at ${new Date().toISOString()}`;
|
|
@@ -110,12 +122,12 @@ export class GitUploadTool {
|
|
|
110
122
|
});
|
|
111
123
|
let commitResult;
|
|
112
124
|
try {
|
|
113
|
-
|
|
114
|
-
const currentBranch = await git.getCurrentBranch(projectPath);
|
|
125
|
+
commitResult = await git.commit(commitMessage);
|
|
115
126
|
results.traceability.commit = {
|
|
116
|
-
hash:
|
|
117
|
-
summary:
|
|
118
|
-
branch:
|
|
127
|
+
hash: commitResult.commit,
|
|
128
|
+
summary: commitResult.summary,
|
|
129
|
+
branch: commitResult.branch,
|
|
130
|
+
author: commitResult.author,
|
|
119
131
|
};
|
|
120
132
|
}
|
|
121
133
|
catch (err) {
|
|
@@ -128,8 +140,8 @@ export class GitUploadTool {
|
|
|
128
140
|
}
|
|
129
141
|
// 4. Criar repositórios remotos em ambos providers
|
|
130
142
|
// Nota: Cada provider precisa usar seu próprio username (Gitea é case-sensitive)
|
|
131
|
-
const githubOwner =
|
|
132
|
-
const giteaOwner =
|
|
143
|
+
const githubOwner = process.env.GITHUB_USERNAME;
|
|
144
|
+
const giteaOwner = process.env.GITEA_USERNAME;
|
|
133
145
|
// GITHUB
|
|
134
146
|
if (ctx.providerManager.github) {
|
|
135
147
|
results.traceability.uploadSteps.push({
|
|
@@ -169,10 +181,10 @@ export class GitUploadTool {
|
|
|
169
181
|
};
|
|
170
182
|
}
|
|
171
183
|
// Adicionar remote se necessário
|
|
172
|
-
const remotes = await git.
|
|
184
|
+
const remotes = await git.getRemotes(true);
|
|
173
185
|
const githubRemote = remotes.find(r => r.name === 'github');
|
|
174
186
|
if (!githubRemote) {
|
|
175
|
-
await git.addRemote(
|
|
187
|
+
await git.addRemote('github', `https://github.com/${githubOwner}/${repoName}.git`);
|
|
176
188
|
results.traceability.uploadSteps.push({
|
|
177
189
|
step: 5,
|
|
178
190
|
action: 'add_github_remote',
|
|
@@ -188,7 +200,7 @@ export class GitUploadTool {
|
|
|
188
200
|
branch,
|
|
189
201
|
});
|
|
190
202
|
try {
|
|
191
|
-
await git.push(
|
|
203
|
+
await git.push('github', branch, ['--set-upstream', '--force']);
|
|
192
204
|
results.providers.github.pushed = true;
|
|
193
205
|
results.providers.github.pushStatus = 'success';
|
|
194
206
|
}
|
|
@@ -256,11 +268,11 @@ export class GitUploadTool {
|
|
|
256
268
|
};
|
|
257
269
|
}
|
|
258
270
|
// Adicionar remote se necessário
|
|
259
|
-
const remotes = await git.
|
|
271
|
+
const remotes = await git.getRemotes(true);
|
|
260
272
|
const giteaRemote = remotes.find(r => r.name === 'gitea');
|
|
261
273
|
if (!giteaRemote) {
|
|
262
274
|
const giteaUrl = `${ctx.providerManager.giteaBaseUrl}/${giteaOwner}/${repoName}.git`;
|
|
263
|
-
await git.addRemote(
|
|
275
|
+
await git.addRemote('gitea', giteaUrl);
|
|
264
276
|
results.traceability.uploadSteps.push({
|
|
265
277
|
step: 8,
|
|
266
278
|
action: 'add_gitea_remote',
|
|
@@ -276,7 +288,7 @@ export class GitUploadTool {
|
|
|
276
288
|
branch,
|
|
277
289
|
});
|
|
278
290
|
try {
|
|
279
|
-
await git.push(
|
|
291
|
+
await git.push('gitea', branch, ['--set-upstream', '--force']);
|
|
280
292
|
results.providers.gitea.pushed = true;
|
|
281
293
|
results.providers.gitea.pushStatus = 'success';
|
|
282
294
|
}
|
|
@@ -305,11 +317,35 @@ export class GitUploadTool {
|
|
|
305
317
|
});
|
|
306
318
|
}
|
|
307
319
|
}
|
|
320
|
+
// 5. Salvar histórico local
|
|
321
|
+
await this.saveUploadHistory(projectPath, results);
|
|
308
322
|
return results;
|
|
309
323
|
}
|
|
310
324
|
catch (err) {
|
|
311
325
|
throw new MCPError('UPLOAD_ERROR', `Failed to upload project: ${err.message}`);
|
|
312
326
|
}
|
|
313
327
|
}
|
|
328
|
+
async saveUploadHistory(projectPath, results) {
|
|
329
|
+
try {
|
|
330
|
+
const historyDir = path.join(projectPath, '.git-mcp-history');
|
|
331
|
+
await fs.mkdir(historyDir, { recursive: true });
|
|
332
|
+
const historyFile = path.join(historyDir, `upload-${Date.now()}.json`);
|
|
333
|
+
await fs.writeFile(historyFile, JSON.stringify(results, null, 2), 'utf-8');
|
|
334
|
+
// Também manter um log consolidado
|
|
335
|
+
const logFile = path.join(historyDir, 'upload-log.jsonl');
|
|
336
|
+
const logEntry = JSON.stringify({
|
|
337
|
+
timestamp: results.timestamp,
|
|
338
|
+
repoName: results.repoName,
|
|
339
|
+
branch: results.branch,
|
|
340
|
+
github: results.providers.github?.success || false,
|
|
341
|
+
gitea: results.providers.gitea?.success || false,
|
|
342
|
+
errors: results.traceability.errors.length,
|
|
343
|
+
}) + '\n';
|
|
344
|
+
await fs.appendFile(logFile, logEntry, 'utf-8');
|
|
345
|
+
}
|
|
346
|
+
catch (err) {
|
|
347
|
+
// Não falhar se não conseguir salvar histórico
|
|
348
|
+
console.warn('Failed to save upload history:', err);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
314
351
|
}
|
|
315
|
-
//# sourceMappingURL=gitUpload.js.map
|
|
@@ -11,6 +11,7 @@ export declare class GitWorkflowTool implements Tool {
|
|
|
11
11
|
};
|
|
12
12
|
action: {
|
|
13
13
|
type: string;
|
|
14
|
+
enum: string[];
|
|
14
15
|
description: string;
|
|
15
16
|
};
|
|
16
17
|
message: {
|
|
@@ -24,10 +25,85 @@ export declare class GitWorkflowTool implements Tool {
|
|
|
24
25
|
};
|
|
25
26
|
description: string;
|
|
26
27
|
};
|
|
28
|
+
remote: {
|
|
29
|
+
type: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
branch: {
|
|
33
|
+
type: string;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
backupPath: {
|
|
37
|
+
type: string;
|
|
38
|
+
description: string;
|
|
39
|
+
};
|
|
40
|
+
name: {
|
|
41
|
+
type: string;
|
|
42
|
+
description: string;
|
|
43
|
+
};
|
|
44
|
+
owner: {
|
|
45
|
+
type: string;
|
|
46
|
+
description: string;
|
|
47
|
+
};
|
|
48
|
+
repo: {
|
|
49
|
+
type: string;
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
description: {
|
|
53
|
+
type: string;
|
|
54
|
+
description: string;
|
|
55
|
+
};
|
|
56
|
+
private: {
|
|
57
|
+
type: string;
|
|
58
|
+
description: string;
|
|
59
|
+
};
|
|
60
|
+
has_issues: {
|
|
61
|
+
type: string;
|
|
62
|
+
description: string;
|
|
63
|
+
};
|
|
64
|
+
has_projects: {
|
|
65
|
+
type: string;
|
|
66
|
+
description: string;
|
|
67
|
+
};
|
|
68
|
+
has_wiki: {
|
|
69
|
+
type: string;
|
|
70
|
+
description: string;
|
|
71
|
+
};
|
|
72
|
+
organization: {
|
|
73
|
+
type: string;
|
|
74
|
+
description: string;
|
|
75
|
+
};
|
|
76
|
+
query: {
|
|
77
|
+
type: string;
|
|
78
|
+
description: string;
|
|
79
|
+
};
|
|
80
|
+
sort: {
|
|
81
|
+
type: string;
|
|
82
|
+
description: string;
|
|
83
|
+
};
|
|
84
|
+
order: {
|
|
85
|
+
type: string;
|
|
86
|
+
description: string;
|
|
87
|
+
};
|
|
88
|
+
limit: {
|
|
89
|
+
type: string;
|
|
90
|
+
description: string;
|
|
91
|
+
};
|
|
92
|
+
force: {
|
|
93
|
+
type: string;
|
|
94
|
+
description: string;
|
|
95
|
+
};
|
|
96
|
+
setUpstream: {
|
|
97
|
+
type: string;
|
|
98
|
+
description: string;
|
|
99
|
+
};
|
|
100
|
+
bare: {
|
|
101
|
+
type: string;
|
|
102
|
+
description: string;
|
|
103
|
+
};
|
|
27
104
|
};
|
|
28
105
|
required: string[];
|
|
29
106
|
additionalProperties: boolean;
|
|
30
107
|
};
|
|
31
108
|
handle(params: Record<string, any>, ctx: MCPContext): Promise<any>;
|
|
32
109
|
}
|
|
33
|
-
//# sourceMappingURL=gitWorkflow.d.ts.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import simpleGit from 'simple-git';
|
|
1
2
|
import { MCPError } from '../utils/errors.js';
|
|
2
3
|
import { normalizeToolParams } from '../utils/repoHelpers.js';
|
|
3
4
|
import axios from 'axios';
|
|
@@ -14,7 +15,8 @@ export class GitWorkflowTool {
|
|
|
14
15
|
},
|
|
15
16
|
action: {
|
|
16
17
|
type: "string",
|
|
17
|
-
|
|
18
|
+
enum: ["init", "status", "commit", "sync", "backup", "create", "list", "get", "update", "delete", "fork", "search", "push"],
|
|
19
|
+
description: "Action to perform: init (initialize repo), status (get repo status), commit (commit changes), sync (fetch/pull/push), backup (create backup), create (create repo on providers), list (list user repos), get (get repo details), update (update repo settings), delete (delete repo), fork (fork repo), search (search repos), push (push to remote)"
|
|
18
20
|
},
|
|
19
21
|
message: {
|
|
20
22
|
type: "string",
|
|
@@ -23,7 +25,83 @@ export class GitWorkflowTool {
|
|
|
23
25
|
files: {
|
|
24
26
|
type: "array",
|
|
25
27
|
items: { type: "string" },
|
|
26
|
-
description: "Files to add (default: ['.'])"
|
|
28
|
+
description: "Files to add (optional for commit, default: ['.'])"
|
|
29
|
+
},
|
|
30
|
+
remote: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "Remote name (optional for sync/push, default: 'origin')"
|
|
33
|
+
},
|
|
34
|
+
branch: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Branch name (optional for sync/push)"
|
|
37
|
+
},
|
|
38
|
+
backupPath: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Path for backup file (optional for backup)"
|
|
41
|
+
},
|
|
42
|
+
name: {
|
|
43
|
+
type: "string",
|
|
44
|
+
description: "Repository name (required for create)"
|
|
45
|
+
},
|
|
46
|
+
owner: {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "Repository owner (optional for create/get/update/delete/fork, uses env vars if not provided)"
|
|
49
|
+
},
|
|
50
|
+
repo: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "Repository name (required for get/update/delete/fork)"
|
|
53
|
+
},
|
|
54
|
+
description: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "Repository description (optional for create/update)"
|
|
57
|
+
},
|
|
58
|
+
private: {
|
|
59
|
+
type: "boolean",
|
|
60
|
+
description: "Make repository private (optional for create/update, default: true)"
|
|
61
|
+
},
|
|
62
|
+
has_issues: {
|
|
63
|
+
type: "boolean",
|
|
64
|
+
description: "Enable issues (optional for update)"
|
|
65
|
+
},
|
|
66
|
+
has_projects: {
|
|
67
|
+
type: "boolean",
|
|
68
|
+
description: "Enable projects (optional for update)"
|
|
69
|
+
},
|
|
70
|
+
has_wiki: {
|
|
71
|
+
type: "boolean",
|
|
72
|
+
description: "Enable wiki (optional for update)"
|
|
73
|
+
},
|
|
74
|
+
organization: {
|
|
75
|
+
type: "string",
|
|
76
|
+
description: "Organization for fork (optional for fork)"
|
|
77
|
+
},
|
|
78
|
+
query: {
|
|
79
|
+
type: "string",
|
|
80
|
+
description: "Search query (required for search)"
|
|
81
|
+
},
|
|
82
|
+
sort: {
|
|
83
|
+
type: "string",
|
|
84
|
+
description: "Sort field (optional for search)"
|
|
85
|
+
},
|
|
86
|
+
order: {
|
|
87
|
+
type: "string",
|
|
88
|
+
description: "Sort order (optional for search)"
|
|
89
|
+
},
|
|
90
|
+
limit: {
|
|
91
|
+
type: "number",
|
|
92
|
+
description: "Result limit (optional for search, default: 30)"
|
|
93
|
+
},
|
|
94
|
+
force: {
|
|
95
|
+
type: "boolean",
|
|
96
|
+
description: "Force push (optional for push, default: false)"
|
|
97
|
+
},
|
|
98
|
+
setUpstream: {
|
|
99
|
+
type: "boolean",
|
|
100
|
+
description: "Set upstream (optional for push, default: false)"
|
|
101
|
+
},
|
|
102
|
+
bare: {
|
|
103
|
+
type: "boolean",
|
|
104
|
+
description: "Initialize as bare repo (optional for init, default: false)"
|
|
27
105
|
}
|
|
28
106
|
},
|
|
29
107
|
required: ["projectPath", "action"],
|
|
@@ -37,63 +115,44 @@ export class GitWorkflowTool {
|
|
|
37
115
|
if (!action)
|
|
38
116
|
throw new MCPError('VALIDATION_ERROR', 'action is required. You can use either "action" or "command" parameter.');
|
|
39
117
|
const projectPath = params.projectPath;
|
|
40
|
-
const git =
|
|
118
|
+
const git = projectPath ? simpleGit({ baseDir: projectPath }) : null;
|
|
41
119
|
switch (action) {
|
|
42
120
|
case 'init': {
|
|
43
|
-
if (!projectPath)
|
|
121
|
+
if (!projectPath || !git)
|
|
44
122
|
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for init');
|
|
45
|
-
await git.init(
|
|
123
|
+
await git.init(params.bare || false);
|
|
46
124
|
return { success: true, path: projectPath };
|
|
47
125
|
}
|
|
48
126
|
case 'status': {
|
|
49
|
-
if (!projectPath)
|
|
127
|
+
if (!projectPath || !git)
|
|
50
128
|
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for status');
|
|
51
|
-
const status = await git.status(
|
|
129
|
+
const status = await git.status();
|
|
52
130
|
return { success: true, status };
|
|
53
131
|
}
|
|
54
132
|
case 'commit': {
|
|
55
|
-
if (!projectPath)
|
|
133
|
+
if (!projectPath || !git)
|
|
56
134
|
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for commit');
|
|
57
135
|
const message = params.message;
|
|
58
136
|
if (!message)
|
|
59
137
|
throw new MCPError('VALIDATION_ERROR', 'Commit message is required');
|
|
60
138
|
const files = params.files || ['.'];
|
|
61
|
-
await git.add(
|
|
62
|
-
const result = await git.commit(
|
|
63
|
-
|
|
64
|
-
const remotes = await git.listRemotes(projectPath);
|
|
65
|
-
const pushResults = {};
|
|
66
|
-
for (const remote of remotes) {
|
|
67
|
-
try {
|
|
68
|
-
const currentBranch = await git.getCurrentBranch(projectPath);
|
|
69
|
-
await git.push(projectPath, remote.name, currentBranch, true);
|
|
70
|
-
pushResults[remote.name] = {
|
|
71
|
-
success: true,
|
|
72
|
-
branch: currentBranch,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
pushResults[remote.name] = {
|
|
77
|
-
success: false,
|
|
78
|
-
error: err.message,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
success: true,
|
|
84
|
-
commit: result,
|
|
85
|
-
pushed: pushResults,
|
|
86
|
-
message: 'Commit created and pushed with --force to all remotes',
|
|
87
|
-
};
|
|
139
|
+
await git.add(files);
|
|
140
|
+
const result = await git.commit(message);
|
|
141
|
+
return { success: true, commit: result };
|
|
88
142
|
}
|
|
89
143
|
case 'sync': {
|
|
90
|
-
if (!projectPath)
|
|
144
|
+
if (!projectPath || !git)
|
|
91
145
|
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for sync');
|
|
92
146
|
const remote = params.remote || 'origin';
|
|
93
|
-
const branch = params.branch
|
|
94
|
-
await git.fetch(
|
|
95
|
-
|
|
96
|
-
|
|
147
|
+
const branch = params.branch;
|
|
148
|
+
await git.fetch(remote);
|
|
149
|
+
if (branch) {
|
|
150
|
+
await git.pull(remote, branch);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
await git.pull();
|
|
154
|
+
}
|
|
155
|
+
await git.push();
|
|
97
156
|
return { success: true, message: 'Repository synced' };
|
|
98
157
|
}
|
|
99
158
|
case 'backup': {
|
|
@@ -104,8 +163,8 @@ export class GitWorkflowTool {
|
|
|
104
163
|
const name = params.name;
|
|
105
164
|
if (!name)
|
|
106
165
|
throw new MCPError('VALIDATION_ERROR', 'name is required');
|
|
107
|
-
const githubOwner =
|
|
108
|
-
const giteaOwner =
|
|
166
|
+
const githubOwner = params.owner || process.env.GITHUB_USERNAME;
|
|
167
|
+
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
109
168
|
const results = { success: true, providers: {} };
|
|
110
169
|
// GitHub
|
|
111
170
|
if (ctx.providerManager.github) {
|
|
@@ -162,11 +221,11 @@ export class GitWorkflowTool {
|
|
|
162
221
|
return results;
|
|
163
222
|
}
|
|
164
223
|
case 'get': {
|
|
165
|
-
const githubOwner =
|
|
166
|
-
const giteaOwner =
|
|
224
|
+
const githubOwner = params.owner || process.env.GITHUB_USERNAME;
|
|
225
|
+
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
167
226
|
const repo = params.repo;
|
|
168
|
-
if (!repo) {
|
|
169
|
-
throw new MCPError('VALIDATION_ERROR', 'repo
|
|
227
|
+
if (!githubOwner || !repo) {
|
|
228
|
+
throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
|
|
170
229
|
}
|
|
171
230
|
const results = { success: true, providers: {} };
|
|
172
231
|
// GitHub
|
|
@@ -192,11 +251,11 @@ export class GitWorkflowTool {
|
|
|
192
251
|
return results;
|
|
193
252
|
}
|
|
194
253
|
case 'update': {
|
|
195
|
-
const githubOwner =
|
|
196
|
-
const giteaOwner =
|
|
254
|
+
const githubOwner = params.owner || process.env.GITHUB_USERNAME;
|
|
255
|
+
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
197
256
|
const repo = params.repo;
|
|
198
|
-
if (!repo) {
|
|
199
|
-
throw new MCPError('VALIDATION_ERROR', 'repo
|
|
257
|
+
if (!githubOwner || !repo) {
|
|
258
|
+
throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
|
|
200
259
|
}
|
|
201
260
|
const results = { success: true, providers: {} };
|
|
202
261
|
// GitHub
|
|
@@ -236,11 +295,11 @@ export class GitWorkflowTool {
|
|
|
236
295
|
return results;
|
|
237
296
|
}
|
|
238
297
|
case 'delete': {
|
|
239
|
-
const githubOwner =
|
|
240
|
-
const giteaOwner =
|
|
298
|
+
const githubOwner = params.owner || process.env.GITHUB_USERNAME;
|
|
299
|
+
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
241
300
|
const repo = params.repo;
|
|
242
|
-
if (!repo) {
|
|
243
|
-
throw new MCPError('VALIDATION_ERROR', 'repo
|
|
301
|
+
if (!githubOwner || !repo) {
|
|
302
|
+
throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
|
|
244
303
|
}
|
|
245
304
|
const results = { success: true, providers: {} };
|
|
246
305
|
// GitHub
|
|
@@ -266,11 +325,11 @@ export class GitWorkflowTool {
|
|
|
266
325
|
return results;
|
|
267
326
|
}
|
|
268
327
|
case 'fork': {
|
|
269
|
-
const githubOwner =
|
|
270
|
-
const giteaOwner =
|
|
328
|
+
const githubOwner = params.owner || process.env.GITHUB_USERNAME;
|
|
329
|
+
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
271
330
|
const repo = params.repo;
|
|
272
|
-
if (!repo) {
|
|
273
|
-
throw new MCPError('VALIDATION_ERROR', 'repo
|
|
331
|
+
if (!githubOwner || !repo) {
|
|
332
|
+
throw new MCPError('VALIDATION_ERROR', 'owner and repo are required');
|
|
274
333
|
}
|
|
275
334
|
const results = { success: true, providers: {} };
|
|
276
335
|
// GitHub
|
|
@@ -335,18 +394,30 @@ export class GitWorkflowTool {
|
|
|
335
394
|
return results;
|
|
336
395
|
}
|
|
337
396
|
case 'push': {
|
|
338
|
-
if (!projectPath)
|
|
397
|
+
if (!projectPath || !git)
|
|
339
398
|
throw new MCPError('VALIDATION_ERROR', 'projectPath is required for push');
|
|
340
399
|
const remote = params.remote || 'origin';
|
|
341
|
-
const branch = params.branch
|
|
400
|
+
const branch = params.branch;
|
|
342
401
|
const force = params.force || false;
|
|
402
|
+
const setUpstream = params.setUpstream || false;
|
|
403
|
+
const pushOptions = [];
|
|
404
|
+
if (force)
|
|
405
|
+
pushOptions.push('--force');
|
|
406
|
+
if (setUpstream)
|
|
407
|
+
pushOptions.push('--set-upstream');
|
|
343
408
|
try {
|
|
344
|
-
await git.push(
|
|
409
|
+
const pushResult = await git.push(remote, branch, pushOptions);
|
|
345
410
|
return {
|
|
346
411
|
success: true,
|
|
347
412
|
remote,
|
|
348
|
-
branch,
|
|
413
|
+
branch: branch || 'current',
|
|
349
414
|
force,
|
|
415
|
+
setUpstream,
|
|
416
|
+
result: {
|
|
417
|
+
pushed: pushResult.pushed || [],
|
|
418
|
+
remoteMessages: pushResult.remoteMessages?.all || [],
|
|
419
|
+
update: pushResult.update,
|
|
420
|
+
},
|
|
350
421
|
};
|
|
351
422
|
}
|
|
352
423
|
catch (err) {
|
|
@@ -354,9 +425,7 @@ export class GitWorkflowTool {
|
|
|
354
425
|
}
|
|
355
426
|
}
|
|
356
427
|
default:
|
|
357
|
-
|
|
358
|
-
throw new MCPError('VALIDATION_ERROR', `Unsupported action: ${action}. Valid actions: ${validActions.join(', ')}`);
|
|
428
|
+
throw new MCPError('VALIDATION_ERROR', `Unsupported action: ${action}`);
|
|
359
429
|
}
|
|
360
430
|
}
|
|
361
431
|
}
|
|
362
|
-
//# sourceMappingURL=gitWorkflow.js.map
|
package/dist/types.d.ts
CHANGED
|
@@ -8,12 +8,7 @@ export type ToolHandleResult = any;
|
|
|
8
8
|
export interface Tool {
|
|
9
9
|
name: string;
|
|
10
10
|
description?: string;
|
|
11
|
-
inputSchema?:
|
|
12
|
-
type: string;
|
|
13
|
-
properties?: Record<string, any>;
|
|
14
|
-
required?: string[];
|
|
15
|
-
additionalProperties?: boolean;
|
|
16
|
-
};
|
|
11
|
+
inputSchema?: any;
|
|
17
12
|
handle(params: Record<string, any>, ctx: MCPContext): Promise<ToolHandleResult>;
|
|
18
13
|
}
|
|
19
14
|
export interface Resource {
|
|
@@ -23,4 +18,3 @@ export interface Resource {
|
|
|
23
18
|
mimeType: string;
|
|
24
19
|
content: string;
|
|
25
20
|
}
|
|
26
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
CHANGED
package/dist/utils/apiHelpers.js
CHANGED
package/dist/utils/errors.d.ts
CHANGED
package/dist/utils/errors.js
CHANGED