@andrebuzeli/git-mcp 10.0.9 → 11.0.0
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/README.md +34 -428
- package/bin/git-mcp.js +21 -0
- package/docs/TOOLS.md +110 -0
- package/mcp.json.template +12 -0
- package/package.json +9 -76
- package/src/local/git.js +14 -0
- package/src/providers/gitea.js +13 -0
- package/src/providers/github.js +13 -0
- package/src/server.js +63 -0
- package/src/tools/git-actions.js +19 -0
- package/src/tools/git-activity.js +28 -0
- package/src/tools/git-admin.js +20 -0
- package/src/tools/git-checks.js +14 -0
- package/src/tools/git-commits.js +34 -0
- package/src/tools/git-contents.js +30 -0
- package/src/tools/git-deployments.js +21 -0
- package/src/tools/git-gists.js +15 -0
- package/src/tools/git-gitdata.js +19 -0
- package/src/tools/git-issues-prs.js +44 -0
- package/src/tools/git-issues.js +12 -0
- package/src/tools/git-local.js +66 -0
- package/src/tools/git-meta.js +19 -0
- package/src/tools/git-misc.js +21 -0
- package/src/tools/git-orgs.js +26 -0
- package/src/tools/git-packages.js +12 -0
- package/src/tools/git-raw.js +14 -0
- package/src/tools/git-releases.js +17 -0
- package/src/tools/git-remote.js +29 -0
- package/src/tools/git-repos.js +60 -0
- package/src/tools/git-search.js +18 -0
- package/src/tools/git-sync.js +40 -0
- package/src/tools/git-user.js +26 -0
- package/src/tools/schema.js +3 -0
- package/src/utils/fs.js +29 -0
- package/src/utils/project.js +7 -0
- package/tests/errors.js +26 -0
- package/tests/full_suite.js +98 -0
- package/tests/run.js +50 -0
- package/LICENSE +0 -21
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -224
- package/dist/prompts/gitPrompts.d.ts +0 -93
- package/dist/prompts/gitPrompts.js +0 -177
- package/dist/providers/giteaProvider.d.ts +0 -3
- package/dist/providers/giteaProvider.js +0 -6
- package/dist/providers/githubProvider.d.ts +0 -2
- package/dist/providers/githubProvider.js +0 -4
- package/dist/providers/providerManager.d.ts +0 -11
- package/dist/providers/providerManager.js +0 -49
- package/dist/resources/toolsGuide.d.ts +0 -12
- package/dist/resources/toolsGuide.js +0 -1713
- package/dist/scripts/test_e2e.d.ts +0 -1
- package/dist/scripts/test_e2e.js +0 -199
- package/dist/scripts/test_exhaustive.d.ts +0 -1
- package/dist/scripts/test_exhaustive.js +0 -275
- package/dist/scripts/test_gitea_creation.d.ts +0 -1
- package/dist/scripts/test_gitea_creation.js +0 -116
- package/dist/scripts/verify_setup.d.ts +0 -1
- package/dist/scripts/verify_setup.js +0 -61
- package/dist/server.d.ts +0 -9
- package/dist/server.js +0 -73
- package/dist/tools/gitAnalytics.d.ts +0 -35
- package/dist/tools/gitAnalytics.js +0 -220
- package/dist/tools/gitArchive.d.ts +0 -119
- package/dist/tools/gitArchive.js +0 -150
- package/dist/tools/gitBackup.d.ts +0 -116
- package/dist/tools/gitBackup.js +0 -156
- package/dist/tools/gitBranches.d.ts +0 -54
- package/dist/tools/gitBranches.js +0 -282
- package/dist/tools/gitChangelog.d.ts +0 -37
- package/dist/tools/gitChangelog.js +0 -67
- package/dist/tools/gitConfig.d.ts +0 -97
- package/dist/tools/gitConfig.js +0 -125
- package/dist/tools/gitFiles.d.ts +0 -129
- package/dist/tools/gitFiles.js +0 -213
- package/dist/tools/gitFix.d.ts +0 -4
- package/dist/tools/gitFix.js +0 -159
- package/dist/tools/gitFix.tool.d.ts +0 -31
- package/dist/tools/gitFix.tool.js +0 -92
- package/dist/tools/gitHistory.d.ts +0 -41
- package/dist/tools/gitHistory.js +0 -349
- package/dist/tools/gitIgnore.d.ts +0 -214
- package/dist/tools/gitIgnore.js +0 -338
- package/dist/tools/gitIssues.d.ts +0 -80
- package/dist/tools/gitIssues.js +0 -363
- package/dist/tools/gitLog.d.ts +0 -30
- package/dist/tools/gitLog.js +0 -46
- package/dist/tools/gitMonitor.d.ts +0 -30
- package/dist/tools/gitMonitor.js +0 -284
- package/dist/tools/gitPackages.d.ts +0 -180
- package/dist/tools/gitPackages.js +0 -214
- package/dist/tools/gitPulls.d.ts +0 -66
- package/dist/tools/gitPulls.js +0 -347
- package/dist/tools/gitPush.d.ts +0 -40
- package/dist/tools/gitPush.js +0 -59
- package/dist/tools/gitRelease.d.ts +0 -49
- package/dist/tools/gitRelease.js +0 -359
- package/dist/tools/gitRemote.d.ts +0 -47
- package/dist/tools/gitRemote.js +0 -111
- package/dist/tools/gitReset.d.ts +0 -57
- package/dist/tools/gitReset.js +0 -79
- package/dist/tools/gitStash.d.ts +0 -61
- package/dist/tools/gitStash.js +0 -80
- package/dist/tools/gitSync.d.ts +0 -34
- package/dist/tools/gitSync.js +0 -182
- package/dist/tools/gitTags.d.ts +0 -45
- package/dist/tools/gitTags.js +0 -251
- package/dist/tools/gitUpdate.d.ts +0 -60
- package/dist/tools/gitUpdate.js +0 -474
- package/dist/tools/gitUpload.d.ts +0 -35
- package/dist/tools/gitUpload.js +0 -385
- package/dist/tools/gitWorkflow.d.ts +0 -117
- package/dist/tools/gitWorkflow.js +0 -472
- package/dist/types.d.ts +0 -20
- package/dist/types.js +0 -1
- package/dist/utils/agentHelpers.d.ts +0 -11
- package/dist/utils/agentHelpers.js +0 -41
- package/dist/utils/apiHelpers.d.ts +0 -29
- package/dist/utils/apiHelpers.js +0 -125
- package/dist/utils/cache.d.ts +0 -96
- package/dist/utils/cache.js +0 -208
- package/dist/utils/contextDetector.d.ts +0 -0
- package/dist/utils/contextDetector.js +0 -1
- package/dist/utils/errors.d.ts +0 -13
- package/dist/utils/errors.js +0 -17
- package/dist/utils/gitAdapter.d.ts +0 -224
- package/dist/utils/gitAdapter.js +0 -1162
- package/dist/utils/logger.d.ts +0 -45
- package/dist/utils/logger.js +0 -140
- package/dist/utils/rateLimiter.d.ts +0 -113
- package/dist/utils/rateLimiter.js +0 -257
- package/dist/utils/repoHelpers.d.ts +0 -44
- package/dist/utils/repoHelpers.js +0 -122
- package/dist/utils/safetyController.d.ts +0 -1
- package/dist/utils/safetyController.js +0 -12
- package/dist/utils/validation.d.ts +0 -115
- package/dist/utils/validation.js +0 -270
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { ProviderManager } from '../providers/providerManager.js';
|
|
2
|
-
import { IsomorphicGitAdapter } from '../utils/gitAdapter.js';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import * as fs from 'fs';
|
|
5
|
-
async function verify() {
|
|
6
|
-
console.log('🔍 Verifying setup and credentials...');
|
|
7
|
-
// 1. Check Environment Variables
|
|
8
|
-
console.log('\n1. Environment Variables:');
|
|
9
|
-
const vars = ['GITHUB_TOKEN', 'GITHUB_USERNAME', 'GITEA_TOKEN', 'GITEA_URL', 'GITEA_USERNAME'];
|
|
10
|
-
const missing = [];
|
|
11
|
-
for (const v of vars) {
|
|
12
|
-
if (process.env[v]) {
|
|
13
|
-
console.log(` ✅ ${v} is set`);
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
console.log(` ❌ ${v} is MISSING`);
|
|
17
|
-
missing.push(v);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
// 2. Validate Providers
|
|
21
|
-
console.log('\n2. Provider Connection:');
|
|
22
|
-
const providerManager = new ProviderManager();
|
|
23
|
-
const results = await providerManager.validateConfiguredProviders();
|
|
24
|
-
if (results.github) {
|
|
25
|
-
console.log(` GitHub: ${results.github.ok ? '✅ Connected' : '❌ Failed: ' + results.github.error}`);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
console.log(' GitHub: ⚠️ Not configured');
|
|
29
|
-
}
|
|
30
|
-
if (results.gitea) {
|
|
31
|
-
console.log(` Gitea: ${results.gitea.ok ? '✅ Connected' : '❌ Failed: ' + results.gitea.error}`);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
console.log(' Gitea: ⚠️ Not configured');
|
|
35
|
-
}
|
|
36
|
-
// 3. Validate GitAdapter
|
|
37
|
-
console.log('\n3. GitAdapter Initialization:');
|
|
38
|
-
try {
|
|
39
|
-
const gitAdapter = new IsomorphicGitAdapter(providerManager);
|
|
40
|
-
console.log(' ✅ GitAdapter initialized successfully');
|
|
41
|
-
// Try a simple local operation if we are in a git repo
|
|
42
|
-
const currentDir = process.cwd();
|
|
43
|
-
if (fs.existsSync(path.join(currentDir, '.git'))) {
|
|
44
|
-
try {
|
|
45
|
-
const branch = await gitAdapter.getCurrentBranch(currentDir);
|
|
46
|
-
console.log(` ✅ Local Git check passed (Current branch: ${branch})`);
|
|
47
|
-
}
|
|
48
|
-
catch (e) {
|
|
49
|
-
console.log(` ❌ Local Git check failed: ${e.message}`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
console.log(' ℹ️ Current directory is not a git repo, skipping local check');
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
catch (err) {
|
|
57
|
-
console.log(` ❌ GitAdapter initialization failed: ${err.message}`);
|
|
58
|
-
}
|
|
59
|
-
console.log('\n🏁 Verification Complete');
|
|
60
|
-
}
|
|
61
|
-
verify().catch(console.error);
|
package/dist/server.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ProviderManager } from './providers/providerManager.js';
|
|
2
|
-
import { GitAdapter } from './utils/gitAdapter.js';
|
|
3
|
-
import { Tool, Resource } from './types.js';
|
|
4
|
-
export declare function createServer(opts: {
|
|
5
|
-
tools: Tool[];
|
|
6
|
-
providerManager: ProviderManager;
|
|
7
|
-
gitAdapter: GitAdapter;
|
|
8
|
-
resources?: Resource[];
|
|
9
|
-
}): import("express-serve-static-core").Express;
|
package/dist/server.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import bodyParser from 'body-parser';
|
|
3
|
-
import Ajv from 'ajv';
|
|
4
|
-
import { createErrorResponse } from './utils/errors.js';
|
|
5
|
-
export function createServer(opts) {
|
|
6
|
-
const app = express();
|
|
7
|
-
app.use(bodyParser.json({ limit: '1mb' }));
|
|
8
|
-
const ajv = new Ajv({ allErrors: true, removeAdditional: false });
|
|
9
|
-
const toolRegistry = new Map();
|
|
10
|
-
for (const t of opts.tools)
|
|
11
|
-
toolRegistry.set(t.name, t);
|
|
12
|
-
const resourceRegistry = new Map();
|
|
13
|
-
if (opts.resources) {
|
|
14
|
-
for (const r of opts.resources)
|
|
15
|
-
resourceRegistry.set(r.uri, r);
|
|
16
|
-
}
|
|
17
|
-
// List all available resources
|
|
18
|
-
app.get('/resources', (req, res) => {
|
|
19
|
-
const resources = Array.from(resourceRegistry.values()).map(r => ({
|
|
20
|
-
uri: r.uri,
|
|
21
|
-
name: r.name,
|
|
22
|
-
description: r.description,
|
|
23
|
-
mimeType: r.mimeType
|
|
24
|
-
}));
|
|
25
|
-
res.json({ success: true, resources });
|
|
26
|
-
});
|
|
27
|
-
// Get specific resource
|
|
28
|
-
app.get('/resources/:uri(*)', (req, res) => {
|
|
29
|
-
const uri = req.params.uri;
|
|
30
|
-
const resource = resourceRegistry.get(uri);
|
|
31
|
-
if (!resource) {
|
|
32
|
-
return res.status(404).json(createErrorResponse('RESOURCE_NOT_FOUND', `Resource not found: ${uri}`));
|
|
33
|
-
}
|
|
34
|
-
res.json({
|
|
35
|
-
success: true,
|
|
36
|
-
resource: {
|
|
37
|
-
uri: resource.uri,
|
|
38
|
-
name: resource.name,
|
|
39
|
-
description: resource.description,
|
|
40
|
-
mimeType: resource.mimeType,
|
|
41
|
-
content: resource.content
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
app.post('/call', async (req, res) => {
|
|
46
|
-
const { tool, params } = req.body ?? {};
|
|
47
|
-
if (!tool)
|
|
48
|
-
return res.status(400).json(createErrorResponse('VALIDATION_ERROR', 'Missing tool name'));
|
|
49
|
-
const t = toolRegistry.get(tool);
|
|
50
|
-
if (!t)
|
|
51
|
-
return res.status(404).json(createErrorResponse('TOOL_NOT_FOUND', `Tool not found: ${tool}`));
|
|
52
|
-
try {
|
|
53
|
-
// Validate params via JSON Schema if available
|
|
54
|
-
if (t.inputSchema) {
|
|
55
|
-
const validate = ajv.compile(t.inputSchema);
|
|
56
|
-
const valid = validate(params ?? {});
|
|
57
|
-
if (!valid) {
|
|
58
|
-
const errors = validate.errors?.map(e => `${e.instancePath} ${e.message}`).join(', ') || 'Invalid parameters';
|
|
59
|
-
return res.status(400).json(createErrorResponse('VALIDATION_ERROR', `Invalid parameters: ${errors}`));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
const result = await t.handle(params ?? {}, { providerManager: opts.providerManager, gitAdapter: opts.gitAdapter });
|
|
63
|
-
res.json({ success: true, result });
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
console.error(`Error in tool ${tool}:`, err);
|
|
67
|
-
const errorCode = err.status || err.code || 'INTERNAL_ERROR';
|
|
68
|
-
const errorMsg = err.message || String(err);
|
|
69
|
-
res.status(500).json(createErrorResponse(errorCode, errorMsg));
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
return app;
|
|
73
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Tool, MCPContext } from '../types.js';
|
|
2
|
-
export declare class GitAnalyticsTool implements Tool {
|
|
3
|
-
name: string;
|
|
4
|
-
description: string;
|
|
5
|
-
inputSchema: {
|
|
6
|
-
type: "object";
|
|
7
|
-
properties: {
|
|
8
|
-
projectPath: {
|
|
9
|
-
type: string;
|
|
10
|
-
description: string;
|
|
11
|
-
examples: string[];
|
|
12
|
-
};
|
|
13
|
-
action: {
|
|
14
|
-
type: string;
|
|
15
|
-
enum: string[];
|
|
16
|
-
description: string;
|
|
17
|
-
};
|
|
18
|
-
limit: {
|
|
19
|
-
type: string;
|
|
20
|
-
description: string;
|
|
21
|
-
};
|
|
22
|
-
since: {
|
|
23
|
-
type: string;
|
|
24
|
-
description: string;
|
|
25
|
-
};
|
|
26
|
-
until: {
|
|
27
|
-
type: string;
|
|
28
|
-
description: string;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
required: string[];
|
|
32
|
-
additionalProperties: boolean;
|
|
33
|
-
};
|
|
34
|
-
handle(params: Record<string, any>, ctx: MCPContext): Promise<any>;
|
|
35
|
-
}
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { MCPError } from '../utils/errors.js';
|
|
2
|
-
import axios from 'axios';
|
|
3
|
-
import { getRepoInfo, normalizeToolParams } from '../utils/repoHelpers.js';
|
|
4
|
-
export class GitAnalyticsTool {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.name = 'git-analytics';
|
|
7
|
-
this.description = 'Repository analytics and statistics - automatic dual-provider execution using GitHub and Gitea APIs';
|
|
8
|
-
this.inputSchema = {
|
|
9
|
-
type: "object",
|
|
10
|
-
properties: {
|
|
11
|
-
projectPath: {
|
|
12
|
-
type: "string",
|
|
13
|
-
description: "The absolute path to the Git repository directory on the local filesystem. This should be the root directory containing the .git folder. For example: '/home/user/my-project' on Linux/Mac or 'C:\\Users\\user\\my-project' on Windows.",
|
|
14
|
-
examples: ["/home/user/my-repo", "C:\\Users\\user\\my-repo"]
|
|
15
|
-
},
|
|
16
|
-
action: {
|
|
17
|
-
type: "string",
|
|
18
|
-
enum: ["stats", "commits", "contributors"],
|
|
19
|
-
description: "The analytics operation to perform: 'stats' for repository statistics, 'commits' for commit history analysis, 'contributors' for contributor statistics."
|
|
20
|
-
},
|
|
21
|
-
limit: {
|
|
22
|
-
type: "number",
|
|
23
|
-
description: "Maximum number of commits to return (optional, default: 100, only used for 'commits' action)"
|
|
24
|
-
},
|
|
25
|
-
since: {
|
|
26
|
-
type: "string",
|
|
27
|
-
description: "Start date for filtering commits/contributors in ISO 8601 format (optional, e.g., '2023-01-01T00:00:00Z')"
|
|
28
|
-
},
|
|
29
|
-
until: {
|
|
30
|
-
type: "string",
|
|
31
|
-
description: "End date for filtering commits/contributors in ISO 8601 format (optional, e.g., '2024-01-01T00:00:00Z')"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
required: ["projectPath", "action"],
|
|
35
|
-
additionalProperties: true
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
async handle(params, ctx) {
|
|
39
|
-
params = normalizeToolParams(params);
|
|
40
|
-
const action = params.action;
|
|
41
|
-
const projectPath = params.projectPath;
|
|
42
|
-
if (!action)
|
|
43
|
-
throw new MCPError('VALIDATION_ERROR', 'action is required');
|
|
44
|
-
if (!projectPath)
|
|
45
|
-
throw new MCPError('VALIDATION_ERROR', 'projectPath is required');
|
|
46
|
-
// Auto-extract repo info from projectPath
|
|
47
|
-
const repoInfo = getRepoInfo(projectPath);
|
|
48
|
-
const repo = params.repo || repoInfo.repoName;
|
|
49
|
-
// Each provider uses its own username from env
|
|
50
|
-
const githubOwner = params.owner || process.env.GITHUB_USERNAME;
|
|
51
|
-
const giteaOwner = params.owner || process.env.GITEA_USERNAME;
|
|
52
|
-
switch (action) {
|
|
53
|
-
case 'stats': {
|
|
54
|
-
const results = { success: true, providers: {} };
|
|
55
|
-
// GitHub API
|
|
56
|
-
if (ctx.providerManager.github && githubOwner) {
|
|
57
|
-
try {
|
|
58
|
-
const repoData = await ctx.providerManager.github.rest.repos.get({
|
|
59
|
-
owner: githubOwner,
|
|
60
|
-
repo: repo,
|
|
61
|
-
});
|
|
62
|
-
const branches = await ctx.providerManager.github.rest.repos.listBranches({
|
|
63
|
-
owner: githubOwner,
|
|
64
|
-
repo: repo,
|
|
65
|
-
});
|
|
66
|
-
const tags = await ctx.providerManager.github.rest.repos.listTags({
|
|
67
|
-
owner: githubOwner,
|
|
68
|
-
repo: repo,
|
|
69
|
-
});
|
|
70
|
-
const commits = await ctx.providerManager.github.rest.repos.listCommits({
|
|
71
|
-
owner: githubOwner,
|
|
72
|
-
repo: repo,
|
|
73
|
-
per_page: 1,
|
|
74
|
-
});
|
|
75
|
-
results.providers.github = {
|
|
76
|
-
success: true,
|
|
77
|
-
stats: {
|
|
78
|
-
totalCommits: repoData.data.size,
|
|
79
|
-
branches: branches.data.length,
|
|
80
|
-
tags: tags.data.length,
|
|
81
|
-
defaultBranch: repoData.data.default_branch,
|
|
82
|
-
latestCommit: commits.data[0] || null,
|
|
83
|
-
size: repoData.data.size,
|
|
84
|
-
language: repoData.data.language,
|
|
85
|
-
stars: repoData.data.stargazers_count,
|
|
86
|
-
forks: repoData.data.forks_count,
|
|
87
|
-
openIssues: repoData.data.open_issues_count,
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
catch (err) {
|
|
92
|
-
results.providers.github = { success: false, error: err.message };
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
// Gitea API
|
|
96
|
-
if (ctx.providerManager.giteaBaseUrl && giteaOwner) {
|
|
97
|
-
try {
|
|
98
|
-
const repoData = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
99
|
-
const branches = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/branches`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
100
|
-
const tags = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/tags`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
101
|
-
const commits = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/commits`, {
|
|
102
|
-
params: { limit: 1 },
|
|
103
|
-
headers: { Authorization: `token ${ctx.providerManager.giteaToken}` }
|
|
104
|
-
});
|
|
105
|
-
results.providers.gitea = {
|
|
106
|
-
success: true,
|
|
107
|
-
stats: {
|
|
108
|
-
totalCommits: repoData.data.size,
|
|
109
|
-
branches: branches.data.length,
|
|
110
|
-
tags: tags.data.length,
|
|
111
|
-
defaultBranch: repoData.data.default_branch,
|
|
112
|
-
latestCommit: commits.data[0] || null,
|
|
113
|
-
size: repoData.data.size,
|
|
114
|
-
language: repoData.data.language,
|
|
115
|
-
stars: repoData.data.stars_count,
|
|
116
|
-
forks: repoData.data.forks_count,
|
|
117
|
-
openIssues: repoData.data.open_issues_count,
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
catch (err) {
|
|
122
|
-
results.providers.gitea = { success: false, error: err.message };
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return results;
|
|
126
|
-
}
|
|
127
|
-
case 'commits': {
|
|
128
|
-
const results = { success: true, providers: {} };
|
|
129
|
-
// GitHub API
|
|
130
|
-
if (ctx.providerManager.github && githubOwner) {
|
|
131
|
-
try {
|
|
132
|
-
const commits = await ctx.providerManager.github.rest.repos.listCommits({
|
|
133
|
-
owner: githubOwner,
|
|
134
|
-
repo: repo,
|
|
135
|
-
since: params.since,
|
|
136
|
-
until: params.until,
|
|
137
|
-
per_page: params.limit || 100,
|
|
138
|
-
});
|
|
139
|
-
results.providers.github = {
|
|
140
|
-
success: true,
|
|
141
|
-
commits: commits.data.length,
|
|
142
|
-
details: commits.data,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
catch (err) {
|
|
146
|
-
results.providers.github = { success: false, error: err.message };
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
// Gitea API
|
|
150
|
-
if (ctx.providerManager.giteaBaseUrl && giteaOwner) {
|
|
151
|
-
try {
|
|
152
|
-
const commits = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/commits`, {
|
|
153
|
-
params: {
|
|
154
|
-
since: params.since,
|
|
155
|
-
until: params.until,
|
|
156
|
-
limit: params.limit || 100,
|
|
157
|
-
},
|
|
158
|
-
headers: { Authorization: `token ${ctx.providerManager.giteaToken}` }
|
|
159
|
-
});
|
|
160
|
-
results.providers.gitea = {
|
|
161
|
-
success: true,
|
|
162
|
-
commits: commits.data.length,
|
|
163
|
-
details: commits.data,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
catch (err) {
|
|
167
|
-
results.providers.gitea = { success: false, error: err.message };
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return results;
|
|
171
|
-
}
|
|
172
|
-
case 'contributors': {
|
|
173
|
-
const results = { success: true, providers: {} };
|
|
174
|
-
// GitHub API
|
|
175
|
-
if (ctx.providerManager.github && githubOwner) {
|
|
176
|
-
try {
|
|
177
|
-
const contributors = await ctx.providerManager.github.rest.repos.listContributors({
|
|
178
|
-
owner: githubOwner,
|
|
179
|
-
repo: repo,
|
|
180
|
-
per_page: 100,
|
|
181
|
-
});
|
|
182
|
-
results.providers.github = {
|
|
183
|
-
success: true,
|
|
184
|
-
contributors: contributors.data.map((c) => ({
|
|
185
|
-
login: c.login,
|
|
186
|
-
name: c.login,
|
|
187
|
-
contributions: c.contributions,
|
|
188
|
-
avatar_url: c.avatar_url,
|
|
189
|
-
})),
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
catch (err) {
|
|
193
|
-
results.providers.github = { success: false, error: err.message };
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
// Gitea API
|
|
197
|
-
if (ctx.providerManager.giteaBaseUrl && giteaOwner) {
|
|
198
|
-
try {
|
|
199
|
-
const contributors = await axios.get(`${ctx.providerManager.giteaBaseUrl}/api/v1/repos/${giteaOwner}/${repo}/contributors`, { headers: { Authorization: `token ${ctx.providerManager.giteaToken}` } });
|
|
200
|
-
results.providers.gitea = {
|
|
201
|
-
success: true,
|
|
202
|
-
contributors: contributors.data.map((c) => ({
|
|
203
|
-
login: c.login,
|
|
204
|
-
name: c.name || c.login,
|
|
205
|
-
contributions: c.contributions,
|
|
206
|
-
avatar_url: c.avatar_url,
|
|
207
|
-
})),
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
catch (err) {
|
|
211
|
-
results.providers.gitea = { success: false, error: err.message };
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return results;
|
|
215
|
-
}
|
|
216
|
-
default:
|
|
217
|
-
throw new MCPError('VALIDATION_ERROR', `Unsupported action: ${action}`);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { Tool, MCPContext } from '../types.js';
|
|
2
|
-
export declare class GitArchiveTool implements Tool {
|
|
3
|
-
name: string;
|
|
4
|
-
description: string;
|
|
5
|
-
inputSchema: {
|
|
6
|
-
type: "object";
|
|
7
|
-
properties: {
|
|
8
|
-
projectPath: {
|
|
9
|
-
type: string;
|
|
10
|
-
description: string;
|
|
11
|
-
};
|
|
12
|
-
action: {
|
|
13
|
-
type: string;
|
|
14
|
-
enum: string[];
|
|
15
|
-
description: string;
|
|
16
|
-
};
|
|
17
|
-
outputPath: {
|
|
18
|
-
type: string;
|
|
19
|
-
description: string;
|
|
20
|
-
};
|
|
21
|
-
format: {
|
|
22
|
-
type: string;
|
|
23
|
-
enum: string[];
|
|
24
|
-
description: string;
|
|
25
|
-
};
|
|
26
|
-
ref: {
|
|
27
|
-
type: string;
|
|
28
|
-
description: string;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
required: string[];
|
|
32
|
-
additionalProperties: boolean;
|
|
33
|
-
};
|
|
34
|
-
handle(params: Record<string, any>, ctx: MCPContext): Promise<{
|
|
35
|
-
success: boolean;
|
|
36
|
-
archivePath: string;
|
|
37
|
-
message: string;
|
|
38
|
-
archives?: undefined;
|
|
39
|
-
count?: undefined;
|
|
40
|
-
archivesDir?: undefined;
|
|
41
|
-
valid?: undefined;
|
|
42
|
-
archive?: undefined;
|
|
43
|
-
error?: undefined;
|
|
44
|
-
extracted?: undefined;
|
|
45
|
-
extractTo?: undefined;
|
|
46
|
-
metadataPath?: undefined;
|
|
47
|
-
note?: undefined;
|
|
48
|
-
} | {
|
|
49
|
-
success: boolean;
|
|
50
|
-
archives: string[];
|
|
51
|
-
count: number;
|
|
52
|
-
archivesDir: any;
|
|
53
|
-
archivePath?: undefined;
|
|
54
|
-
message?: undefined;
|
|
55
|
-
valid?: undefined;
|
|
56
|
-
archive?: undefined;
|
|
57
|
-
error?: undefined;
|
|
58
|
-
extracted?: undefined;
|
|
59
|
-
extractTo?: undefined;
|
|
60
|
-
metadataPath?: undefined;
|
|
61
|
-
note?: undefined;
|
|
62
|
-
} | {
|
|
63
|
-
success: boolean;
|
|
64
|
-
archives: never[];
|
|
65
|
-
count: number;
|
|
66
|
-
message: string;
|
|
67
|
-
archivePath?: undefined;
|
|
68
|
-
archivesDir?: undefined;
|
|
69
|
-
valid?: undefined;
|
|
70
|
-
archive?: undefined;
|
|
71
|
-
error?: undefined;
|
|
72
|
-
extracted?: undefined;
|
|
73
|
-
extractTo?: undefined;
|
|
74
|
-
metadataPath?: undefined;
|
|
75
|
-
note?: undefined;
|
|
76
|
-
} | {
|
|
77
|
-
success: boolean;
|
|
78
|
-
valid: boolean;
|
|
79
|
-
archive: any;
|
|
80
|
-
message: string;
|
|
81
|
-
archivePath?: undefined;
|
|
82
|
-
archives?: undefined;
|
|
83
|
-
count?: undefined;
|
|
84
|
-
archivesDir?: undefined;
|
|
85
|
-
error?: undefined;
|
|
86
|
-
extracted?: undefined;
|
|
87
|
-
extractTo?: undefined;
|
|
88
|
-
metadataPath?: undefined;
|
|
89
|
-
note?: undefined;
|
|
90
|
-
} | {
|
|
91
|
-
success: boolean;
|
|
92
|
-
valid: boolean;
|
|
93
|
-
error: any;
|
|
94
|
-
archivePath?: undefined;
|
|
95
|
-
message?: undefined;
|
|
96
|
-
archives?: undefined;
|
|
97
|
-
count?: undefined;
|
|
98
|
-
archivesDir?: undefined;
|
|
99
|
-
archive?: undefined;
|
|
100
|
-
extracted?: undefined;
|
|
101
|
-
extractTo?: undefined;
|
|
102
|
-
metadataPath?: undefined;
|
|
103
|
-
note?: undefined;
|
|
104
|
-
} | {
|
|
105
|
-
success: boolean;
|
|
106
|
-
extracted: boolean;
|
|
107
|
-
archivePath: any;
|
|
108
|
-
extractTo: any;
|
|
109
|
-
archive: any;
|
|
110
|
-
metadataPath: string;
|
|
111
|
-
message: string;
|
|
112
|
-
note: string;
|
|
113
|
-
archives?: undefined;
|
|
114
|
-
count?: undefined;
|
|
115
|
-
archivesDir?: undefined;
|
|
116
|
-
valid?: undefined;
|
|
117
|
-
error?: undefined;
|
|
118
|
-
}>;
|
|
119
|
-
}
|
package/dist/tools/gitArchive.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { MCPError } from '../utils/errors.js';
|
|
4
|
-
export class GitArchiveTool {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.name = 'git-archive';
|
|
7
|
-
this.description = 'Repository archive operations';
|
|
8
|
-
this.inputSchema = {
|
|
9
|
-
type: "object",
|
|
10
|
-
properties: {
|
|
11
|
-
projectPath: {
|
|
12
|
-
type: "string",
|
|
13
|
-
description: "The absolute path to the Git repository directory on the local filesystem. This should be the root directory containing the .git folder. For example: '/home/user/my-project' on Linux/Mac or 'C:\\Users\\user\\my-project' on Windows."
|
|
14
|
-
},
|
|
15
|
-
action: {
|
|
16
|
-
type: "string",
|
|
17
|
-
enum: ["create", "extract"],
|
|
18
|
-
description: "Archive operation to perform: create (create archive), extract (extract archive)"
|
|
19
|
-
},
|
|
20
|
-
outputPath: {
|
|
21
|
-
type: "string",
|
|
22
|
-
description: "Output archive file path (required for create)"
|
|
23
|
-
},
|
|
24
|
-
format: {
|
|
25
|
-
type: "string",
|
|
26
|
-
enum: ["tar", "tar.gz", "zip"],
|
|
27
|
-
description: "Archive format (optional for create, default: tar.gz)"
|
|
28
|
-
},
|
|
29
|
-
ref: {
|
|
30
|
-
type: "string",
|
|
31
|
-
description: "Git reference to archive (optional for create, default: HEAD)"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
required: ["projectPath", "action"],
|
|
35
|
-
additionalProperties: true
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
async handle(params, ctx) {
|
|
39
|
-
const action = params.action;
|
|
40
|
-
const projectPath = params.projectPath;
|
|
41
|
-
if (!action || !projectPath) {
|
|
42
|
-
throw new MCPError('VALIDATION_ERROR', 'action and projectPath are required');
|
|
43
|
-
}
|
|
44
|
-
switch (action) {
|
|
45
|
-
case 'create': {
|
|
46
|
-
const archiveName = params.archiveName || `archive-${Date.now()}.json`;
|
|
47
|
-
const outputPath = params.outputPath || path.join(projectPath, '.git-archives');
|
|
48
|
-
try {
|
|
49
|
-
// Criar diretório de archives se não existir
|
|
50
|
-
await fs.mkdir(outputPath, { recursive: true });
|
|
51
|
-
const archivePath = path.join(outputPath, archiveName);
|
|
52
|
-
const archiveData = {
|
|
53
|
-
projectPath,
|
|
54
|
-
timestamp: new Date().toISOString(),
|
|
55
|
-
type: 'git-archive',
|
|
56
|
-
};
|
|
57
|
-
await fs.writeFile(archivePath, JSON.stringify(archiveData, null, 2));
|
|
58
|
-
return {
|
|
59
|
-
success: true,
|
|
60
|
-
archivePath,
|
|
61
|
-
message: 'Archive created successfully',
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
throw new MCPError('FILE_ERROR', `Failed to create archive: ${error.message}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
case 'list': {
|
|
69
|
-
const archivesDir = params.archivesDir || path.join(projectPath, '.git-archives');
|
|
70
|
-
try {
|
|
71
|
-
const files = await fs.readdir(archivesDir);
|
|
72
|
-
const archives = files.filter(f => f.endsWith('.json'));
|
|
73
|
-
return {
|
|
74
|
-
success: true,
|
|
75
|
-
archives,
|
|
76
|
-
count: archives.length,
|
|
77
|
-
archivesDir,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
return {
|
|
82
|
-
success: true,
|
|
83
|
-
archives: [],
|
|
84
|
-
count: 0,
|
|
85
|
-
message: 'No archives directory found',
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
case 'verify': {
|
|
90
|
-
const archivePath = params.archivePath;
|
|
91
|
-
if (!archivePath)
|
|
92
|
-
throw new MCPError('VALIDATION_ERROR', 'archivePath is required');
|
|
93
|
-
try {
|
|
94
|
-
const content = await fs.readFile(archivePath, 'utf-8');
|
|
95
|
-
const archive = JSON.parse(content);
|
|
96
|
-
return {
|
|
97
|
-
success: true,
|
|
98
|
-
valid: true,
|
|
99
|
-
archive,
|
|
100
|
-
message: 'Archive is valid',
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
return {
|
|
105
|
-
success: false,
|
|
106
|
-
valid: false,
|
|
107
|
-
error: error.message,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
case 'extract': {
|
|
112
|
-
const archivePath = params.archivePath;
|
|
113
|
-
const extractTo = params.extractTo || projectPath;
|
|
114
|
-
if (!archivePath)
|
|
115
|
-
throw new MCPError('VALIDATION_ERROR', 'archivePath is required');
|
|
116
|
-
if (!extractTo)
|
|
117
|
-
throw new MCPError('VALIDATION_ERROR', 'extractTo is required');
|
|
118
|
-
try {
|
|
119
|
-
// Ler o arquivo de archive
|
|
120
|
-
const content = await fs.readFile(archivePath, 'utf-8');
|
|
121
|
-
const archive = JSON.parse(content);
|
|
122
|
-
// Verificar se é um archive válido
|
|
123
|
-
if (!archive.projectPath || !archive.timestamp) {
|
|
124
|
-
throw new MCPError('VALIDATION_ERROR', 'Invalid archive format');
|
|
125
|
-
}
|
|
126
|
-
// Criar diretório de extração
|
|
127
|
-
await fs.mkdir(extractTo, { recursive: true });
|
|
128
|
-
// Copiar informações do archive para um arquivo de metadados
|
|
129
|
-
const metadataPath = path.join(extractTo, '.archive-metadata.json');
|
|
130
|
-
await fs.writeFile(metadataPath, JSON.stringify(archive, null, 2), 'utf-8');
|
|
131
|
-
return {
|
|
132
|
-
success: true,
|
|
133
|
-
extracted: true,
|
|
134
|
-
archivePath,
|
|
135
|
-
extractTo,
|
|
136
|
-
archive,
|
|
137
|
-
metadataPath,
|
|
138
|
-
message: 'Archive extracted successfully. Metadata saved to .archive-metadata.json',
|
|
139
|
-
note: 'This is a simplified extraction. For full restoration, use git commands or backup tools.',
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
throw new MCPError('EXTRACT_ERROR', `Failed to extract archive: ${error.message}`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
default:
|
|
147
|
-
throw new MCPError('VALIDATION_ERROR', `Unsupported action: ${action}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|