@andrebuzeli/git-mcp 10.0.6 → 10.0.8
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 +0 -0
- package/README.md +1 -1
- package/dist/scripts/test_e2e.d.ts +1 -0
- package/dist/scripts/test_e2e.js +199 -0
- package/dist/scripts/test_exhaustive.d.ts +1 -0
- package/dist/scripts/test_exhaustive.js +275 -0
- package/dist/scripts/verify_setup.d.ts +1 -0
- package/dist/scripts/verify_setup.js +61 -0
- package/dist/tools/gitAnalytics.js +3 -3
- package/dist/tools/gitBackup.d.ts +2 -2
- package/dist/tools/gitBackup.js +5 -5
- package/dist/tools/gitBranches.js +40 -29
- package/dist/tools/gitConfig.d.ts +2 -2
- package/dist/tools/gitConfig.js +12 -13
- package/dist/tools/gitFix.d.ts +2 -1
- package/dist/tools/gitFix.js +20 -24
- package/dist/tools/gitFix.tool.d.ts +2 -2
- package/dist/tools/gitFix.tool.js +2 -2
- package/dist/tools/gitHistory.js +4 -5
- package/dist/tools/gitIssues.js +8 -8
- package/dist/tools/gitMonitor.js +28 -33
- package/dist/tools/gitPulls.js +8 -8
- package/dist/tools/gitRelease.js +5 -6
- package/dist/tools/gitRemote.d.ts +1 -28
- package/dist/tools/gitRemote.js +19 -23
- package/dist/tools/gitReset.js +6 -7
- package/dist/tools/gitStash.d.ts +1 -12
- package/dist/tools/gitStash.js +11 -22
- package/dist/tools/gitSync.js +44 -36
- package/dist/tools/gitTags.d.ts +8 -0
- package/dist/tools/gitTags.js +44 -34
- package/dist/tools/gitUpdate.d.ts +27 -0
- package/dist/tools/gitUpdate.js +61 -34
- package/dist/tools/gitUpload.js +29 -44
- package/dist/tools/gitWorkflow.js +27 -46
- package/package.json +2 -3
- package/dist/server-new.d.ts +0 -2
- package/dist/server-new.js +0 -224
- package/dist/tools/gitFiles-new.d.ts +0 -89
- package/dist/tools/gitFiles-new.js +0 -335
package/dist/tools/gitPulls.js
CHANGED
|
@@ -75,9 +75,9 @@ export class GitPullsTool {
|
|
|
75
75
|
if (!projectPath)
|
|
76
76
|
throw new MCPError('VALIDATION_ERROR', 'projectPath is required');
|
|
77
77
|
const repoInfo = getRepoInfo(projectPath);
|
|
78
|
-
const repo = repoInfo.repoName;
|
|
79
|
-
const githubOwner = repoInfo.githubOwner || process.env.GITHUB_USERNAME;
|
|
80
|
-
const giteaOwner = repoInfo.giteaOwner || process.env.GITEA_USERNAME;
|
|
78
|
+
const repo = params.repo || repoInfo.repoName;
|
|
79
|
+
const githubOwner = params.owner || repoInfo.githubOwner || process.env.GITHUB_USERNAME;
|
|
80
|
+
const giteaOwner = params.owner || repoInfo.giteaOwner || process.env.GITEA_USERNAME;
|
|
81
81
|
switch (action) {
|
|
82
82
|
case 'create': {
|
|
83
83
|
if (!params.title || !params.head || !params.base) {
|
|
@@ -152,7 +152,7 @@ export class GitPullsTool {
|
|
|
152
152
|
return results;
|
|
153
153
|
}
|
|
154
154
|
case 'get': {
|
|
155
|
-
const pull_number = params.pull_number;
|
|
155
|
+
const pull_number = params.pull_number || params.pullNumber;
|
|
156
156
|
if (!pull_number)
|
|
157
157
|
throw new MCPError('VALIDATION_ERROR', 'pull_number is required');
|
|
158
158
|
const results = { success: true, providers: {} };
|
|
@@ -183,7 +183,7 @@ export class GitPullsTool {
|
|
|
183
183
|
return results;
|
|
184
184
|
}
|
|
185
185
|
case 'update': {
|
|
186
|
-
const pull_number = params.pull_number;
|
|
186
|
+
const pull_number = params.pull_number || params.pullNumber;
|
|
187
187
|
if (!pull_number)
|
|
188
188
|
throw new MCPError('VALIDATION_ERROR', 'pull_number is required');
|
|
189
189
|
const results = { success: true, providers: {} };
|
|
@@ -217,7 +217,7 @@ export class GitPullsTool {
|
|
|
217
217
|
return results;
|
|
218
218
|
}
|
|
219
219
|
case 'merge': {
|
|
220
|
-
const pull_number = params.pull_number;
|
|
220
|
+
const pull_number = params.pull_number || params.pullNumber;
|
|
221
221
|
if (!pull_number)
|
|
222
222
|
throw new MCPError('VALIDATION_ERROR', 'pull_number is required');
|
|
223
223
|
const results = { success: true, providers: {} };
|
|
@@ -255,7 +255,7 @@ export class GitPullsTool {
|
|
|
255
255
|
return results;
|
|
256
256
|
}
|
|
257
257
|
case 'close': {
|
|
258
|
-
const pull_number = params.pull_number;
|
|
258
|
+
const pull_number = params.pull_number || params.pullNumber;
|
|
259
259
|
if (!pull_number)
|
|
260
260
|
throw new MCPError('VALIDATION_ERROR', 'pull_number is required');
|
|
261
261
|
const results = { success: true, providers: {} };
|
|
@@ -287,7 +287,7 @@ export class GitPullsTool {
|
|
|
287
287
|
return results;
|
|
288
288
|
}
|
|
289
289
|
case 'review': {
|
|
290
|
-
const pull_number = params.pull_number;
|
|
290
|
+
const pull_number = params.pull_number || params.pullNumber;
|
|
291
291
|
const event = params.event;
|
|
292
292
|
if (!pull_number || !event) {
|
|
293
293
|
throw new MCPError('VALIDATION_ERROR', 'pull_number and event are required');
|
package/dist/tools/gitRelease.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import simpleGit from 'simple-git';
|
|
2
1
|
import { MCPError } from '../utils/errors.js';
|
|
3
2
|
import { normalizeToolParams, getRepoInfo } from '../utils/repoHelpers.js';
|
|
4
3
|
import axios from 'axios';
|
|
@@ -59,16 +58,16 @@ export class GitReleaseTool {
|
|
|
59
58
|
if (!projectPath)
|
|
60
59
|
throw new MCPError('VALIDATION_ERROR', 'projectPath is required');
|
|
61
60
|
const repoInfo = getRepoInfo(projectPath);
|
|
62
|
-
const repo = repoInfo.repoName;
|
|
63
|
-
const githubOwner = repoInfo.githubOwner || process.env.GITHUB_USERNAME;
|
|
64
|
-
const giteaOwner = repoInfo.giteaOwner || process.env.GITEA_USERNAME;
|
|
61
|
+
const repo = params.repo || repoInfo.repoName;
|
|
62
|
+
const githubOwner = params.owner || repoInfo.githubOwner || process.env.GITHUB_USERNAME;
|
|
63
|
+
const giteaOwner = params.owner || repoInfo.giteaOwner || process.env.GITEA_USERNAME;
|
|
65
64
|
switch (action) {
|
|
66
65
|
case 'create': {
|
|
67
66
|
const tagName = params.tagName;
|
|
68
67
|
if (!tagName)
|
|
69
68
|
throw new MCPError('VALIDATION_ERROR', 'tagName is required');
|
|
70
|
-
const git =
|
|
71
|
-
await git.
|
|
69
|
+
const git = ctx.gitAdapter;
|
|
70
|
+
await git.createTag(projectPath, tagName, 'HEAD', params.description || tagName);
|
|
72
71
|
const results = { success: true, localTag: tagName, providers: {} };
|
|
73
72
|
if (ctx.providerManager.github) {
|
|
74
73
|
try {
|
|
@@ -30,45 +30,18 @@ export declare class GitRemoteTool implements Tool {
|
|
|
30
30
|
remote: any;
|
|
31
31
|
url: any;
|
|
32
32
|
removed?: undefined;
|
|
33
|
-
renamed?: undefined;
|
|
34
|
-
to?: undefined;
|
|
35
33
|
remotes?: undefined;
|
|
36
|
-
pruned?: undefined;
|
|
37
34
|
} | {
|
|
38
35
|
success: boolean;
|
|
39
36
|
removed: any;
|
|
40
37
|
remote?: undefined;
|
|
41
38
|
url?: undefined;
|
|
42
|
-
renamed?: undefined;
|
|
43
|
-
to?: undefined;
|
|
44
39
|
remotes?: undefined;
|
|
45
|
-
pruned?: undefined;
|
|
46
40
|
} | {
|
|
47
41
|
success: boolean;
|
|
48
|
-
|
|
49
|
-
to: any;
|
|
42
|
+
remotes: import("../utils/gitAdapter.js").RemoteInfo[];
|
|
50
43
|
remote?: undefined;
|
|
51
44
|
url?: undefined;
|
|
52
45
|
removed?: undefined;
|
|
53
|
-
remotes?: undefined;
|
|
54
|
-
pruned?: undefined;
|
|
55
|
-
} | {
|
|
56
|
-
success: boolean;
|
|
57
|
-
remotes: import("simple-git").RemoteWithoutRefs[];
|
|
58
|
-
remote?: undefined;
|
|
59
|
-
url?: undefined;
|
|
60
|
-
removed?: undefined;
|
|
61
|
-
renamed?: undefined;
|
|
62
|
-
to?: undefined;
|
|
63
|
-
pruned?: undefined;
|
|
64
|
-
} | {
|
|
65
|
-
success: boolean;
|
|
66
|
-
pruned: any;
|
|
67
|
-
remote?: undefined;
|
|
68
|
-
url?: undefined;
|
|
69
|
-
removed?: undefined;
|
|
70
|
-
renamed?: undefined;
|
|
71
|
-
to?: undefined;
|
|
72
|
-
remotes?: undefined;
|
|
73
46
|
}>;
|
|
74
47
|
}
|
package/dist/tools/gitRemote.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import simpleGit from 'simple-git';
|
|
2
1
|
import { MCPError } from '../utils/errors.js';
|
|
3
2
|
import { getRepoInfo, buildGitHubUrl, buildGiteaUrl } from '../utils/repoHelpers.js';
|
|
4
3
|
export class GitRemoteTool {
|
|
@@ -35,10 +34,12 @@ export class GitRemoteTool {
|
|
|
35
34
|
if (!action || !projectPath) {
|
|
36
35
|
throw new MCPError('VALIDATION_ERROR', 'action and projectPath are required');
|
|
37
36
|
}
|
|
38
|
-
|
|
37
|
+
if (!ctx.gitAdapter) {
|
|
38
|
+
throw new MCPError('INTERNAL_ERROR', 'Git adapter not available');
|
|
39
|
+
}
|
|
39
40
|
switch (action) {
|
|
40
41
|
case 'add': {
|
|
41
|
-
const name = params.
|
|
42
|
+
const name = params.remoteName || 'origin';
|
|
42
43
|
let url = params.url;
|
|
43
44
|
// Auto-construct URL if not provided
|
|
44
45
|
if (!url) {
|
|
@@ -57,31 +58,22 @@ export class GitRemoteTool {
|
|
|
57
58
|
throw new MCPError('VALIDATION_ERROR', 'url is required or set GITHUB_USERNAME/GITEA_USERNAME in environment');
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
await
|
|
61
|
+
await ctx.gitAdapter.addRemote(projectPath, name, url);
|
|
61
62
|
return { success: true, remote: name, url };
|
|
62
63
|
}
|
|
63
64
|
case 'remove': {
|
|
64
|
-
const name = params.
|
|
65
|
+
const name = params.remoteName;
|
|
65
66
|
if (!name)
|
|
66
|
-
throw new MCPError('VALIDATION_ERROR', '
|
|
67
|
-
await
|
|
67
|
+
throw new MCPError('VALIDATION_ERROR', 'remoteName is required');
|
|
68
|
+
await ctx.gitAdapter.removeRemote(projectPath, name);
|
|
68
69
|
return { success: true, removed: name };
|
|
69
70
|
}
|
|
70
|
-
case 'rename': {
|
|
71
|
-
const name = params.name;
|
|
72
|
-
const newName = params.newName;
|
|
73
|
-
if (!name || !newName)
|
|
74
|
-
throw new MCPError('VALIDATION_ERROR', 'name and newName are required');
|
|
75
|
-
await git.remote(['rename', name, newName]);
|
|
76
|
-
return { success: true, renamed: name, to: newName };
|
|
77
|
-
}
|
|
78
|
-
case 'show':
|
|
79
71
|
case 'list': {
|
|
80
|
-
const remotes = await
|
|
72
|
+
const remotes = await ctx.gitAdapter.listRemotes(projectPath);
|
|
81
73
|
return { success: true, remotes };
|
|
82
74
|
}
|
|
83
75
|
case 'set-url': {
|
|
84
|
-
const name = params.
|
|
76
|
+
const name = params.remoteName || 'origin';
|
|
85
77
|
let url = params.url;
|
|
86
78
|
// Auto-construct URL if not provided
|
|
87
79
|
if (!url) {
|
|
@@ -100,13 +92,17 @@ export class GitRemoteTool {
|
|
|
100
92
|
throw new MCPError('VALIDATION_ERROR', 'url is required or set GITHUB_USERNAME/GITEA_USERNAME in environment');
|
|
101
93
|
}
|
|
102
94
|
}
|
|
103
|
-
|
|
95
|
+
// Use setConfig to update remote URL
|
|
96
|
+
await ctx.gitAdapter.setConfig(projectPath, `remote.${name}.url`, url);
|
|
104
97
|
return { success: true, remote: name, url };
|
|
105
98
|
}
|
|
106
|
-
case '
|
|
107
|
-
const name = params.
|
|
108
|
-
await
|
|
109
|
-
|
|
99
|
+
case 'get-url': {
|
|
100
|
+
const name = params.remoteName || 'origin';
|
|
101
|
+
const url = await ctx.gitAdapter.getConfig(projectPath, `remote.${name}.url`);
|
|
102
|
+
if (!url) {
|
|
103
|
+
throw new MCPError('NOT_FOUND', `Remote '${name}' not found`);
|
|
104
|
+
}
|
|
105
|
+
return { success: true, remote: name, url };
|
|
110
106
|
}
|
|
111
107
|
default:
|
|
112
108
|
throw new MCPError('VALIDATION_ERROR', `Unsupported action: ${action}`);
|
package/dist/tools/gitReset.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import simpleGit from 'simple-git';
|
|
2
1
|
import { MCPError } from '../utils/errors.js';
|
|
3
2
|
import { requireConfirmationIfDestructive } from '../utils/safetyController.js';
|
|
4
3
|
export class GitResetTool {
|
|
@@ -36,21 +35,21 @@ export class GitResetTool {
|
|
|
36
35
|
throw new MCPError('VALIDATION_ERROR', 'action and projectPath are required');
|
|
37
36
|
}
|
|
38
37
|
requireConfirmationIfDestructive(action, params);
|
|
39
|
-
const git =
|
|
38
|
+
const git = ctx.gitAdapter;
|
|
40
39
|
switch (action) {
|
|
41
40
|
case 'soft': {
|
|
42
41
|
const target = params.target || 'HEAD~1';
|
|
43
|
-
await git.reset(
|
|
42
|
+
await git.reset(projectPath, target, 'soft');
|
|
44
43
|
return { success: true, mode: 'soft', target };
|
|
45
44
|
}
|
|
46
45
|
case 'mixed': {
|
|
47
46
|
const target = params.target || 'HEAD~1';
|
|
48
|
-
await git.reset(
|
|
47
|
+
await git.reset(projectPath, target, 'mixed');
|
|
49
48
|
return { success: true, mode: 'mixed', target };
|
|
50
49
|
}
|
|
51
50
|
case 'hard': {
|
|
52
51
|
const target = params.target || 'HEAD~1';
|
|
53
|
-
await git.reset(
|
|
52
|
+
await git.reset(projectPath, target, 'hard');
|
|
54
53
|
return {
|
|
55
54
|
success: true,
|
|
56
55
|
mode: 'hard',
|
|
@@ -63,14 +62,14 @@ export class GitResetTool {
|
|
|
63
62
|
if (!commit)
|
|
64
63
|
throw new MCPError('VALIDATION_ERROR', 'commit is required');
|
|
65
64
|
const mode = params.mode || 'mixed';
|
|
66
|
-
await git.reset(
|
|
65
|
+
await git.reset(projectPath, commit, mode);
|
|
67
66
|
return { success: true, mode, commit };
|
|
68
67
|
}
|
|
69
68
|
case 'reset-branch': {
|
|
70
69
|
const branch = params.branch;
|
|
71
70
|
if (!branch)
|
|
72
71
|
throw new MCPError('VALIDATION_ERROR', 'branch is required');
|
|
73
|
-
await git.reset(
|
|
72
|
+
await git.reset(projectPath, `origin/${branch}`, 'hard');
|
|
74
73
|
return { success: true, branch, warning: 'Branch reset to match origin' };
|
|
75
74
|
}
|
|
76
75
|
default:
|
package/dist/tools/gitStash.d.ts
CHANGED
|
@@ -38,28 +38,18 @@ export declare class GitStashTool implements Tool {
|
|
|
38
38
|
message: string;
|
|
39
39
|
stash?: undefined;
|
|
40
40
|
stashes?: undefined;
|
|
41
|
-
details?: undefined;
|
|
42
41
|
dropped?: undefined;
|
|
43
42
|
} | {
|
|
44
43
|
success: boolean;
|
|
45
44
|
stash: any;
|
|
46
45
|
message: string;
|
|
47
46
|
stashes?: undefined;
|
|
48
|
-
details?: undefined;
|
|
49
47
|
dropped?: undefined;
|
|
50
48
|
} | {
|
|
51
49
|
success: boolean;
|
|
52
|
-
stashes:
|
|
50
|
+
stashes: import("../utils/gitAdapter.js").StashEntry[];
|
|
53
51
|
message?: undefined;
|
|
54
52
|
stash?: undefined;
|
|
55
|
-
details?: undefined;
|
|
56
|
-
dropped?: undefined;
|
|
57
|
-
} | {
|
|
58
|
-
success: boolean;
|
|
59
|
-
stash: any;
|
|
60
|
-
details: string;
|
|
61
|
-
message?: undefined;
|
|
62
|
-
stashes?: undefined;
|
|
63
53
|
dropped?: undefined;
|
|
64
54
|
} | {
|
|
65
55
|
success: boolean;
|
|
@@ -67,6 +57,5 @@ export declare class GitStashTool implements Tool {
|
|
|
67
57
|
message?: undefined;
|
|
68
58
|
stash?: undefined;
|
|
69
59
|
stashes?: undefined;
|
|
70
|
-
details?: undefined;
|
|
71
60
|
}>;
|
|
72
61
|
}
|
package/dist/tools/gitStash.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import simpleGit from 'simple-git';
|
|
2
1
|
import { MCPError } from '../utils/errors.js';
|
|
3
2
|
export class GitStashTool {
|
|
4
3
|
constructor() {
|
|
@@ -42,46 +41,36 @@ export class GitStashTool {
|
|
|
42
41
|
if (!action || !projectPath) {
|
|
43
42
|
throw new MCPError('VALIDATION_ERROR', 'action and projectPath are required');
|
|
44
43
|
}
|
|
45
|
-
const git =
|
|
44
|
+
const git = ctx.gitAdapter;
|
|
46
45
|
switch (action) {
|
|
47
|
-
case '
|
|
46
|
+
case 'save':
|
|
47
|
+
case 'stash': { // Support both for compatibility
|
|
48
48
|
const message = params.message;
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
options.push('-u');
|
|
52
|
-
if (params.keepIndex)
|
|
53
|
-
options.push('--keep-index');
|
|
54
|
-
if (message)
|
|
55
|
-
options.push('-m', message);
|
|
56
|
-
await git.stash(['push', ...options]);
|
|
49
|
+
const includeUntracked = params.includeUntracked;
|
|
50
|
+
await git.saveStash(projectPath, message, includeUntracked);
|
|
57
51
|
return { success: true, message: 'Changes stashed' };
|
|
58
52
|
}
|
|
59
53
|
case 'pop': {
|
|
60
54
|
const stashRef = params.stashRef || 'stash@{0}';
|
|
61
|
-
await git.
|
|
55
|
+
await git.popStash(projectPath, stashRef);
|
|
62
56
|
return { success: true, stash: stashRef, message: 'Stash applied and removed' };
|
|
63
57
|
}
|
|
64
58
|
case 'apply': {
|
|
65
59
|
const stashRef = params.stashRef || 'stash@{0}';
|
|
66
|
-
await git.
|
|
60
|
+
await git.applyStash(projectPath, stashRef);
|
|
67
61
|
return { success: true, stash: stashRef, message: 'Stash applied (kept in list)' };
|
|
68
62
|
}
|
|
69
63
|
case 'list': {
|
|
70
|
-
const
|
|
71
|
-
return { success: true, stashes
|
|
72
|
-
}
|
|
73
|
-
case 'show': {
|
|
74
|
-
const stashRef = params.stashRef || 'stash@{0}';
|
|
75
|
-
const result = await git.show([stashRef]);
|
|
76
|
-
return { success: true, stash: stashRef, details: result };
|
|
64
|
+
const stashes = await git.listStash(projectPath);
|
|
65
|
+
return { success: true, stashes };
|
|
77
66
|
}
|
|
78
67
|
case 'drop': {
|
|
79
68
|
const stashRef = params.stashRef || 'stash@{0}';
|
|
80
|
-
await git.
|
|
69
|
+
await git.dropStash(projectPath, stashRef);
|
|
81
70
|
return { success: true, dropped: stashRef };
|
|
82
71
|
}
|
|
83
72
|
case 'clear': {
|
|
84
|
-
await git.
|
|
73
|
+
await git.clearStash(projectPath);
|
|
85
74
|
return { success: true, message: 'All stashes cleared' };
|
|
86
75
|
}
|
|
87
76
|
default:
|
package/dist/tools/gitSync.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import simpleGit from 'simple-git';
|
|
2
1
|
import { MCPError } from '../utils/errors.js';
|
|
3
2
|
export class GitSyncTool {
|
|
4
3
|
constructor() {
|
|
@@ -39,12 +38,14 @@ export class GitSyncTool {
|
|
|
39
38
|
if (!action || !projectPath) {
|
|
40
39
|
throw new MCPError('VALIDATION_ERROR', 'action and projectPath are required');
|
|
41
40
|
}
|
|
42
|
-
|
|
41
|
+
if (!ctx.gitAdapter) {
|
|
42
|
+
throw new MCPError('INTERNAL_ERROR', 'Git adapter not available');
|
|
43
|
+
}
|
|
43
44
|
switch (action) {
|
|
44
45
|
case 'fetch': {
|
|
45
46
|
const remote = params.remote || 'origin';
|
|
46
47
|
try {
|
|
47
|
-
await
|
|
48
|
+
await ctx.gitAdapter.fetch(projectPath, remote);
|
|
48
49
|
return { success: true, projectPath, remote, action: 'fetch' };
|
|
49
50
|
}
|
|
50
51
|
catch (err) {
|
|
@@ -53,15 +54,13 @@ export class GitSyncTool {
|
|
|
53
54
|
}
|
|
54
55
|
case 'pull': {
|
|
55
56
|
const remote = params.remote || 'origin';
|
|
56
|
-
|
|
57
|
+
let branch = params.branch;
|
|
57
58
|
try {
|
|
58
|
-
if (branch) {
|
|
59
|
-
await
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
await git.pull(remote);
|
|
59
|
+
if (!branch) {
|
|
60
|
+
branch = await ctx.gitAdapter.getCurrentBranch(projectPath);
|
|
63
61
|
}
|
|
64
|
-
|
|
62
|
+
await ctx.gitAdapter.pull(projectPath, remote, branch);
|
|
63
|
+
return { success: true, projectPath, remote, branch, action: 'pull' };
|
|
65
64
|
}
|
|
66
65
|
catch (err) {
|
|
67
66
|
throw new MCPError('PULL_ERROR', `Failed to pull from ${remote}: ${err.message}`);
|
|
@@ -69,16 +68,20 @@ export class GitSyncTool {
|
|
|
69
68
|
}
|
|
70
69
|
case 'push': {
|
|
71
70
|
const remote = params.remote || 'origin';
|
|
72
|
-
|
|
71
|
+
let branch = params.branch;
|
|
72
|
+
const force = params.force || false;
|
|
73
73
|
try {
|
|
74
|
-
|
|
74
|
+
if (!branch) {
|
|
75
|
+
branch = await ctx.gitAdapter.getCurrentBranch(projectPath);
|
|
76
|
+
}
|
|
77
|
+
await ctx.gitAdapter.push(projectPath, remote, branch, force);
|
|
75
78
|
return {
|
|
76
79
|
success: true,
|
|
77
80
|
projectPath,
|
|
78
81
|
remote,
|
|
79
|
-
branch
|
|
82
|
+
branch,
|
|
80
83
|
action: 'push',
|
|
81
|
-
|
|
84
|
+
message: 'Push successful'
|
|
82
85
|
};
|
|
83
86
|
}
|
|
84
87
|
catch (err) {
|
|
@@ -87,14 +90,20 @@ export class GitSyncTool {
|
|
|
87
90
|
}
|
|
88
91
|
case 'sync': {
|
|
89
92
|
const remote = params.remote || 'origin';
|
|
90
|
-
|
|
93
|
+
let branch = params.branch;
|
|
91
94
|
try {
|
|
92
|
-
if (branch) {
|
|
93
|
-
await
|
|
95
|
+
if (!branch) {
|
|
96
|
+
branch = await ctx.gitAdapter.getCurrentBranch(projectPath);
|
|
97
|
+
}
|
|
98
|
+
// Checkout if needed (not strictly necessary if we are already on the branch, but good for safety)
|
|
99
|
+
const currentBranch = await ctx.gitAdapter.getCurrentBranch(projectPath);
|
|
100
|
+
if (branch !== currentBranch) {
|
|
101
|
+
await ctx.gitAdapter.checkout(projectPath, branch);
|
|
94
102
|
}
|
|
95
|
-
await
|
|
96
|
-
await
|
|
97
|
-
|
|
103
|
+
await ctx.gitAdapter.fetch(projectPath, remote);
|
|
104
|
+
await ctx.gitAdapter.pull(projectPath, remote, branch);
|
|
105
|
+
await ctx.gitAdapter.push(projectPath, remote, branch);
|
|
106
|
+
return { success: true, projectPath, remote, branch, message: 'Repository synced' };
|
|
98
107
|
}
|
|
99
108
|
catch (err) {
|
|
100
109
|
throw new MCPError('SYNC_ERROR', `Failed to sync with ${remote}: ${err.message}`);
|
|
@@ -102,8 +111,8 @@ export class GitSyncTool {
|
|
|
102
111
|
}
|
|
103
112
|
case 'status': {
|
|
104
113
|
try {
|
|
105
|
-
const status = await
|
|
106
|
-
const remotes = await
|
|
114
|
+
const status = await ctx.gitAdapter.status(projectPath);
|
|
115
|
+
const remotes = await ctx.gitAdapter.listRemotes(projectPath);
|
|
107
116
|
return {
|
|
108
117
|
success: true,
|
|
109
118
|
projectPath,
|
|
@@ -114,7 +123,7 @@ export class GitSyncTool {
|
|
|
114
123
|
modified: status.modified,
|
|
115
124
|
created: status.created,
|
|
116
125
|
deleted: status.deleted,
|
|
117
|
-
clean: status.isClean
|
|
126
|
+
clean: status.isClean,
|
|
118
127
|
},
|
|
119
128
|
remotes,
|
|
120
129
|
};
|
|
@@ -126,7 +135,7 @@ export class GitSyncTool {
|
|
|
126
135
|
case 'one-shot': {
|
|
127
136
|
// One-shot sync: fetch, pull, and push in a single operation
|
|
128
137
|
const remote = params.remote || 'origin';
|
|
129
|
-
|
|
138
|
+
let branch = params.branch;
|
|
130
139
|
const results = {
|
|
131
140
|
success: true,
|
|
132
141
|
projectPath,
|
|
@@ -135,31 +144,30 @@ export class GitSyncTool {
|
|
|
135
144
|
steps: [],
|
|
136
145
|
};
|
|
137
146
|
try {
|
|
147
|
+
if (!branch) {
|
|
148
|
+
branch = await ctx.gitAdapter.getCurrentBranch(projectPath);
|
|
149
|
+
results.branch = branch;
|
|
150
|
+
}
|
|
138
151
|
// Step 1: Fetch
|
|
139
152
|
results.steps.push({ action: 'fetch', timestamp: new Date().toISOString() });
|
|
140
|
-
await
|
|
153
|
+
await ctx.gitAdapter.fetch(projectPath, remote);
|
|
141
154
|
// Step 2: Pull
|
|
142
155
|
results.steps.push({ action: 'pull', timestamp: new Date().toISOString() });
|
|
143
|
-
|
|
144
|
-
await git.pull(remote, branch);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
await git.pull(remote);
|
|
148
|
-
}
|
|
156
|
+
await ctx.gitAdapter.pull(projectPath, remote, branch);
|
|
149
157
|
// Step 3: Push
|
|
150
158
|
results.steps.push({ action: 'push', timestamp: new Date().toISOString() });
|
|
151
|
-
|
|
159
|
+
await ctx.gitAdapter.push(projectPath, remote, branch, false, true);
|
|
152
160
|
results.pushResult = {
|
|
153
|
-
pushed:
|
|
154
|
-
|
|
161
|
+
pushed: true, // Isomorphic git doesn't return detailed push stats easily
|
|
162
|
+
message: 'Push successful'
|
|
155
163
|
};
|
|
156
164
|
// Step 4: Final status
|
|
157
|
-
const finalStatus = await
|
|
165
|
+
const finalStatus = await ctx.gitAdapter.status(projectPath);
|
|
158
166
|
results.finalStatus = {
|
|
159
167
|
branch: finalStatus.current,
|
|
160
168
|
ahead: finalStatus.ahead,
|
|
161
169
|
behind: finalStatus.behind,
|
|
162
|
-
clean: finalStatus.isClean
|
|
170
|
+
clean: finalStatus.isClean,
|
|
163
171
|
};
|
|
164
172
|
return results;
|
|
165
173
|
}
|
package/dist/tools/gitTags.d.ts
CHANGED
|
@@ -26,10 +26,18 @@ export declare class GitTagsTool implements Tool {
|
|
|
26
26
|
type: string;
|
|
27
27
|
description: string;
|
|
28
28
|
};
|
|
29
|
+
annotated: {
|
|
30
|
+
type: string;
|
|
31
|
+
description: string;
|
|
32
|
+
};
|
|
29
33
|
force: {
|
|
30
34
|
type: string;
|
|
31
35
|
description: string;
|
|
32
36
|
};
|
|
37
|
+
remote: {
|
|
38
|
+
type: string;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
33
41
|
};
|
|
34
42
|
required: string[];
|
|
35
43
|
};
|