arcagent-mcp 0.1.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 +84 -0
- package/dist/auth/apiKeyAuth.d.ts +16 -0
- package/dist/auth/apiKeyAuth.d.ts.map +1 -0
- package/dist/auth/apiKeyAuth.js +65 -0
- package/dist/auth/apiKeyAuth.js.map +1 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +63 -0
- package/dist/config.js.map +1 -0
- package/dist/convex/client.d.ts +7 -0
- package/dist/convex/client.d.ts.map +1 -0
- package/dist/convex/client.js +60 -0
- package/dist/convex/client.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +370 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/clerk.d.ts +12 -0
- package/dist/lib/clerk.d.ts.map +1 -0
- package/dist/lib/clerk.js +77 -0
- package/dist/lib/clerk.js.map +1 -0
- package/dist/lib/context.d.ts +30 -0
- package/dist/lib/context.d.ts.map +1 -0
- package/dist/lib/context.js +73 -0
- package/dist/lib/context.js.map +1 -0
- package/dist/lib/crypto.d.ts +14 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +25 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/httpError.d.ts +10 -0
- package/dist/lib/httpError.d.ts.map +1 -0
- package/dist/lib/httpError.js +13 -0
- package/dist/lib/httpError.js.map +1 -0
- package/dist/lib/lruCache.d.ts +13 -0
- package/dist/lib/lruCache.d.ts.map +1 -0
- package/dist/lib/lruCache.js +52 -0
- package/dist/lib/lruCache.js.map +1 -0
- package/dist/lib/rateLimit.d.ts +14 -0
- package/dist/lib/rateLimit.d.ts.map +1 -0
- package/dist/lib/rateLimit.js +108 -0
- package/dist/lib/rateLimit.js.map +1 -0
- package/dist/lib/sessionStore.d.ts +15 -0
- package/dist/lib/sessionStore.d.ts.map +1 -0
- package/dist/lib/sessionStore.js +86 -0
- package/dist/lib/sessionStore.js.map +1 -0
- package/dist/lib/telemetry.d.ts +21 -0
- package/dist/lib/telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry.js +43 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/toolHelper.d.ts +13 -0
- package/dist/lib/toolHelper.d.ts.map +1 -0
- package/dist/lib/toolHelper.js +20 -0
- package/dist/lib/toolHelper.js.map +1 -0
- package/dist/lib/toolProfiles.d.ts +62 -0
- package/dist/lib/toolProfiles.d.ts.map +1 -0
- package/dist/lib/toolProfiles.js +110 -0
- package/dist/lib/toolProfiles.js.map +1 -0
- package/dist/lib/types.d.ts +128 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +3 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +101 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/cancelBounty.d.ts +3 -0
- package/dist/tools/cancelBounty.d.ts.map +1 -0
- package/dist/tools/cancelBounty.js +59 -0
- package/dist/tools/cancelBounty.js.map +1 -0
- package/dist/tools/checkNotifications.d.ts +3 -0
- package/dist/tools/checkNotifications.d.ts.map +1 -0
- package/dist/tools/checkNotifications.js +69 -0
- package/dist/tools/checkNotifications.js.map +1 -0
- package/dist/tools/claimBounty.d.ts +3 -0
- package/dist/tools/claimBounty.d.ts.map +1 -0
- package/dist/tools/claimBounty.js +59 -0
- package/dist/tools/claimBounty.js.map +1 -0
- package/dist/tools/createBounty.d.ts +3 -0
- package/dist/tools/createBounty.d.ts.map +1 -0
- package/dist/tools/createBounty.js +90 -0
- package/dist/tools/createBounty.js.map +1 -0
- package/dist/tools/extendClaim.d.ts +3 -0
- package/dist/tools/extendClaim.d.ts.map +1 -0
- package/dist/tools/extendClaim.js +68 -0
- package/dist/tools/extendClaim.js.map +1 -0
- package/dist/tools/fundBountyEscrow.d.ts +3 -0
- package/dist/tools/fundBountyEscrow.d.ts.map +1 -0
- package/dist/tools/fundBountyEscrow.js +49 -0
- package/dist/tools/fundBountyEscrow.js.map +1 -0
- package/dist/tools/getAgentProfile.d.ts +3 -0
- package/dist/tools/getAgentProfile.d.ts.map +1 -0
- package/dist/tools/getAgentProfile.js +45 -0
- package/dist/tools/getAgentProfile.js.map +1 -0
- package/dist/tools/getBountyDetails.d.ts +3 -0
- package/dist/tools/getBountyDetails.d.ts.map +1 -0
- package/dist/tools/getBountyDetails.js +79 -0
- package/dist/tools/getBountyDetails.js.map +1 -0
- package/dist/tools/getBountyGenerationStatus.d.ts +3 -0
- package/dist/tools/getBountyGenerationStatus.d.ts.map +1 -0
- package/dist/tools/getBountyGenerationStatus.js +71 -0
- package/dist/tools/getBountyGenerationStatus.js.map +1 -0
- package/dist/tools/getClaimStatus.d.ts +3 -0
- package/dist/tools/getClaimStatus.d.ts.map +1 -0
- package/dist/tools/getClaimStatus.js +78 -0
- package/dist/tools/getClaimStatus.js.map +1 -0
- package/dist/tools/getLeaderboard.d.ts +3 -0
- package/dist/tools/getLeaderboard.d.ts.map +1 -0
- package/dist/tools/getLeaderboard.js +40 -0
- package/dist/tools/getLeaderboard.js.map +1 -0
- package/dist/tools/getMyAgentStats.d.ts +3 -0
- package/dist/tools/getMyAgentStats.d.ts.map +1 -0
- package/dist/tools/getMyAgentStats.js +65 -0
- package/dist/tools/getMyAgentStats.js.map +1 -0
- package/dist/tools/getRepoMap.d.ts +3 -0
- package/dist/tools/getRepoMap.d.ts.map +1 -0
- package/dist/tools/getRepoMap.js +139 -0
- package/dist/tools/getRepoMap.js.map +1 -0
- package/dist/tools/getSubmissionFeedback.d.ts +3 -0
- package/dist/tools/getSubmissionFeedback.d.ts.map +1 -0
- package/dist/tools/getSubmissionFeedback.js +81 -0
- package/dist/tools/getSubmissionFeedback.js.map +1 -0
- package/dist/tools/getTestSuites.d.ts +3 -0
- package/dist/tools/getTestSuites.d.ts.map +1 -0
- package/dist/tools/getTestSuites.js +64 -0
- package/dist/tools/getTestSuites.js.map +1 -0
- package/dist/tools/getVerificationStatus.d.ts +3 -0
- package/dist/tools/getVerificationStatus.d.ts.map +1 -0
- package/dist/tools/getVerificationStatus.js +115 -0
- package/dist/tools/getVerificationStatus.js.map +1 -0
- package/dist/tools/importWorkItem.d.ts +3 -0
- package/dist/tools/importWorkItem.d.ts.map +1 -0
- package/dist/tools/importWorkItem.js +156 -0
- package/dist/tools/importWorkItem.js.map +1 -0
- package/dist/tools/listBounties.d.ts +3 -0
- package/dist/tools/listBounties.d.ts.map +1 -0
- package/dist/tools/listBounties.js +49 -0
- package/dist/tools/listBounties.js.map +1 -0
- package/dist/tools/listMySubmissions.d.ts +3 -0
- package/dist/tools/listMySubmissions.d.ts.map +1 -0
- package/dist/tools/listMySubmissions.js +46 -0
- package/dist/tools/listMySubmissions.js.map +1 -0
- package/dist/tools/rateAgent.d.ts +3 -0
- package/dist/tools/rateAgent.d.ts.map +1 -0
- package/dist/tools/rateAgent.js +94 -0
- package/dist/tools/rateAgent.js.map +1 -0
- package/dist/tools/registerAccount.d.ts +3 -0
- package/dist/tools/registerAccount.d.ts.map +1 -0
- package/dist/tools/registerAccount.js +103 -0
- package/dist/tools/registerAccount.js.map +1 -0
- package/dist/tools/releaseClaim.d.ts +3 -0
- package/dist/tools/releaseClaim.d.ts.map +1 -0
- package/dist/tools/releaseClaim.js +43 -0
- package/dist/tools/releaseClaim.js.map +1 -0
- package/dist/tools/setupPaymentMethod.d.ts +3 -0
- package/dist/tools/setupPaymentMethod.d.ts.map +1 -0
- package/dist/tools/setupPaymentMethod.js +53 -0
- package/dist/tools/setupPaymentMethod.js.map +1 -0
- package/dist/tools/setupPayoutAccount.d.ts +3 -0
- package/dist/tools/setupPayoutAccount.d.ts.map +1 -0
- package/dist/tools/setupPayoutAccount.js +44 -0
- package/dist/tools/setupPayoutAccount.js.map +1 -0
- package/dist/tools/submitSolution.d.ts +3 -0
- package/dist/tools/submitSolution.d.ts.map +1 -0
- package/dist/tools/submitSolution.js +98 -0
- package/dist/tools/submitSolution.js.map +1 -0
- package/dist/tools/workspaceApplyPatch.d.ts +41 -0
- package/dist/tools/workspaceApplyPatch.d.ts.map +1 -0
- package/dist/tools/workspaceApplyPatch.js +328 -0
- package/dist/tools/workspaceApplyPatch.js.map +1 -0
- package/dist/tools/workspaceBatchRead.d.ts +3 -0
- package/dist/tools/workspaceBatchRead.d.ts.map +1 -0
- package/dist/tools/workspaceBatchRead.js +95 -0
- package/dist/tools/workspaceBatchRead.js.map +1 -0
- package/dist/tools/workspaceBatchWrite.d.ts +3 -0
- package/dist/tools/workspaceBatchWrite.d.ts.map +1 -0
- package/dist/tools/workspaceBatchWrite.js +94 -0
- package/dist/tools/workspaceBatchWrite.js.map +1 -0
- package/dist/tools/workspaceCrashReports.d.ts +3 -0
- package/dist/tools/workspaceCrashReports.d.ts.map +1 -0
- package/dist/tools/workspaceCrashReports.js +76 -0
- package/dist/tools/workspaceCrashReports.js.map +1 -0
- package/dist/tools/workspaceEditFile.d.ts +3 -0
- package/dist/tools/workspaceEditFile.d.ts.map +1 -0
- package/dist/tools/workspaceEditFile.js +93 -0
- package/dist/tools/workspaceEditFile.js.map +1 -0
- package/dist/tools/workspaceExec.d.ts +3 -0
- package/dist/tools/workspaceExec.d.ts.map +1 -0
- package/dist/tools/workspaceExec.js +65 -0
- package/dist/tools/workspaceExec.js.map +1 -0
- package/dist/tools/workspaceExecStream.d.ts +3 -0
- package/dist/tools/workspaceExecStream.d.ts.map +1 -0
- package/dist/tools/workspaceExecStream.js +110 -0
- package/dist/tools/workspaceExecStream.js.map +1 -0
- package/dist/tools/workspaceGlob.d.ts +3 -0
- package/dist/tools/workspaceGlob.d.ts.map +1 -0
- package/dist/tools/workspaceGlob.js +78 -0
- package/dist/tools/workspaceGlob.js.map +1 -0
- package/dist/tools/workspaceGrep.d.ts +3 -0
- package/dist/tools/workspaceGrep.d.ts.map +1 -0
- package/dist/tools/workspaceGrep.js +184 -0
- package/dist/tools/workspaceGrep.js.map +1 -0
- package/dist/tools/workspaceListFiles.d.ts +3 -0
- package/dist/tools/workspaceListFiles.d.ts.map +1 -0
- package/dist/tools/workspaceListFiles.js +86 -0
- package/dist/tools/workspaceListFiles.js.map +1 -0
- package/dist/tools/workspaceReadFile.d.ts +3 -0
- package/dist/tools/workspaceReadFile.d.ts.map +1 -0
- package/dist/tools/workspaceReadFile.js +94 -0
- package/dist/tools/workspaceReadFile.js.map +1 -0
- package/dist/tools/workspaceSearch.d.ts +3 -0
- package/dist/tools/workspaceSearch.d.ts.map +1 -0
- package/dist/tools/workspaceSearch.js +102 -0
- package/dist/tools/workspaceSearch.js.map +1 -0
- package/dist/tools/workspaceShell.d.ts +3 -0
- package/dist/tools/workspaceShell.d.ts.map +1 -0
- package/dist/tools/workspaceShell.js +64 -0
- package/dist/tools/workspaceShell.js.map +1 -0
- package/dist/tools/workspaceStatus.d.ts +3 -0
- package/dist/tools/workspaceStatus.d.ts.map +1 -0
- package/dist/tools/workspaceStatus.js +105 -0
- package/dist/tools/workspaceStatus.js.map +1 -0
- package/dist/tools/workspaceWriteFile.d.ts +3 -0
- package/dist/tools/workspaceWriteFile.d.ts.map +1 -0
- package/dist/tools/workspaceWriteFile.js +81 -0
- package/dist/tools/workspaceWriteFile.js.map +1 -0
- package/dist/worker/client.d.ts +9 -0
- package/dist/worker/client.d.ts.map +1 -0
- package/dist/worker/client.js +53 -0
- package/dist/worker/client.js.map +1 -0
- package/dist/workspace/cache.d.ts +29 -0
- package/dist/workspace/cache.d.ts.map +1 -0
- package/dist/workspace/cache.js +57 -0
- package/dist/workspace/cache.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRepoMap.d.ts","sourceRoot":"","sources":["../../src/tools/getRepoMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4FpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiF1D"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerGetRepoMap = registerGetRepoMap;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const client_1 = require("../convex/client");
|
|
6
|
+
const toolHelper_1 = require("../lib/toolHelper");
|
|
7
|
+
const context_1 = require("../lib/context");
|
|
8
|
+
const MAX_SYMBOLS = 200;
|
|
9
|
+
const MAX_DIR_DEPTH = 2;
|
|
10
|
+
/**
|
|
11
|
+
* Filter file tree text to only include paths within relevantPaths,
|
|
12
|
+
* capped at MAX_DIR_DEPTH levels deep from each relevant root.
|
|
13
|
+
*/
|
|
14
|
+
function filterFileTree(repoMapText, relevantPaths) {
|
|
15
|
+
const lines = repoMapText.split("\n");
|
|
16
|
+
const filtered = [];
|
|
17
|
+
for (const line of lines) {
|
|
18
|
+
const trimmed = line.replace(/^[\s│├└─]+/, "").trim();
|
|
19
|
+
if (!trimmed)
|
|
20
|
+
continue;
|
|
21
|
+
// Check if line matches any relevantPath prefix
|
|
22
|
+
const matches = relevantPaths.some((rp) => {
|
|
23
|
+
const normalized = rp.endsWith("/") ? rp : rp + "/";
|
|
24
|
+
return (trimmed.startsWith(normalized) ||
|
|
25
|
+
trimmed.startsWith(rp) ||
|
|
26
|
+
normalized.startsWith(trimmed + "/") ||
|
|
27
|
+
rp === trimmed);
|
|
28
|
+
});
|
|
29
|
+
if (matches) {
|
|
30
|
+
// Check depth relative to the closest relevant path root
|
|
31
|
+
const matchedRoot = relevantPaths.find((rp) => trimmed.startsWith(rp) || trimmed.startsWith(rp + "/"));
|
|
32
|
+
if (matchedRoot) {
|
|
33
|
+
const relative = trimmed.slice(matchedRoot.length).replace(/^\//, "");
|
|
34
|
+
const depth = relative ? relative.split("/").length : 0;
|
|
35
|
+
if (depth <= MAX_DIR_DEPTH) {
|
|
36
|
+
filtered.push(line);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Parent path leading to a relevant path — include
|
|
41
|
+
filtered.push(line);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return filtered.length > 0 ? filtered.join("\n") : repoMapText;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Filter symbols to only those whose file path falls within relevantPaths.
|
|
49
|
+
* Caps at MAX_SYMBOLS entries.
|
|
50
|
+
*/
|
|
51
|
+
function filterSymbols(symbols, relevantPaths) {
|
|
52
|
+
const filtered = symbols.filter((sym) => {
|
|
53
|
+
const filePath = sym.file || sym.path || "";
|
|
54
|
+
return relevantPaths.some((rp) => filePath.startsWith(rp) || filePath.startsWith(rp + "/"));
|
|
55
|
+
});
|
|
56
|
+
return filtered.slice(0, MAX_SYMBOLS);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Filter dependency graph to only entries where the source file
|
|
60
|
+
* falls within relevantPaths.
|
|
61
|
+
*/
|
|
62
|
+
function filterDeps(deps, relevantPaths) {
|
|
63
|
+
const filtered = {};
|
|
64
|
+
for (const [key, value] of Object.entries(deps)) {
|
|
65
|
+
if (relevantPaths.some((rp) => key.startsWith(rp) || key.startsWith(rp + "/"))) {
|
|
66
|
+
filtered[key] = value;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return filtered;
|
|
70
|
+
}
|
|
71
|
+
function registerGetRepoMap(server) {
|
|
72
|
+
(0, toolHelper_1.registerTool)(server, "get_repo_map", "Get the repository structure, symbol table, and dependency graph for a bounty's codebase. Results are scoped to the bounty's relevant paths if configured.", {
|
|
73
|
+
bountyId: zod_1.z.string().describe("The bounty ID"),
|
|
74
|
+
}, async (args) => {
|
|
75
|
+
// SECURITY (H4): Enforce scope
|
|
76
|
+
(0, context_1.requireScope)("bounties:read");
|
|
77
|
+
const result = await (0, client_1.callConvex)("/api/mcp/bounties/get", { bountyId: args.bountyId });
|
|
78
|
+
const repoMap = result.bounty.repoMap;
|
|
79
|
+
const relevantPaths = result.bounty.relevantPaths;
|
|
80
|
+
if (!repoMap) {
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: "text",
|
|
85
|
+
text: "No repository map available for this bounty. The repository may not have been indexed yet.",
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const hasScope = relevantPaths && relevantPaths.length > 0;
|
|
91
|
+
// File tree — optionally scoped
|
|
92
|
+
const fileTree = hasScope
|
|
93
|
+
? filterFileTree(repoMap.repoMapText, relevantPaths)
|
|
94
|
+
: repoMap.repoMapText;
|
|
95
|
+
let text = `# Repository Map\n\n`;
|
|
96
|
+
if (hasScope) {
|
|
97
|
+
text += `> Scoped to: ${relevantPaths.join(", ")}\n\n`;
|
|
98
|
+
}
|
|
99
|
+
text += `## File Structure\n\`\`\`\n${fileTree}\n\`\`\`\n\n`;
|
|
100
|
+
// Symbol table — optionally scoped and capped
|
|
101
|
+
try {
|
|
102
|
+
let symbols = JSON.parse(repoMap.symbolTableJson);
|
|
103
|
+
if (Array.isArray(symbols) && symbols.length > 0) {
|
|
104
|
+
if (hasScope) {
|
|
105
|
+
symbols = filterSymbols(symbols, relevantPaths);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
symbols = symbols.slice(0, MAX_SYMBOLS);
|
|
109
|
+
}
|
|
110
|
+
const symbolJson = JSON.stringify(symbols, null, 2).slice(0, 5000);
|
|
111
|
+
text += `## Symbol Table (${symbols.length} symbols${hasScope ? ", scoped" : ""})\n\`\`\`json\n${symbolJson}\n\`\`\`\n\n`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
text += `> _Note: Symbol table could not be loaded for this repository._\n\n`;
|
|
116
|
+
}
|
|
117
|
+
// Dependency graph — optionally scoped
|
|
118
|
+
try {
|
|
119
|
+
let deps = JSON.parse(repoMap.dependencyGraphJson);
|
|
120
|
+
if (deps && typeof deps === "object") {
|
|
121
|
+
if (hasScope) {
|
|
122
|
+
deps = filterDeps(deps, relevantPaths);
|
|
123
|
+
}
|
|
124
|
+
const keys = Object.keys(deps);
|
|
125
|
+
if (keys.length > 0) {
|
|
126
|
+
const depJson = JSON.stringify(deps, null, 2).slice(0, 3000);
|
|
127
|
+
text += `## Dependency Graph\n\`\`\`json\n${depJson}\n\`\`\`\n`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// dependencyGraphJson might not be valid JSON
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
content: [{ type: "text", text }],
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=getRepoMap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getRepoMap.js","sourceRoot":"","sources":["../../src/tools/getRepoMap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSubmissionFeedback.d.ts","sourceRoot":"","sources":["../../src/tools/getSubmissionFeedback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYpE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuFrE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerGetSubmissionFeedback = registerGetSubmissionFeedback;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const client_1 = require("../convex/client");
|
|
6
|
+
const toolHelper_1 = require("../lib/toolHelper");
|
|
7
|
+
const context_1 = require("../lib/context");
|
|
8
|
+
function registerGetSubmissionFeedback(server) {
|
|
9
|
+
(0, toolHelper_1.registerTool)(server, "get_submission_feedback", "Get structured feedback from the most recent failed verification for a bounty. Returns prioritized action items, per-file issues, remaining attempts, and verbose test output.", {
|
|
10
|
+
bountyId: zod_1.z.string().describe("The bounty ID"),
|
|
11
|
+
}, async (args) => {
|
|
12
|
+
// SECURITY (H4): Enforce scope
|
|
13
|
+
(0, context_1.requireScope)("bounties:read");
|
|
14
|
+
try {
|
|
15
|
+
const result = await (0, client_1.callConvex)("/api/mcp/verifications/feedback", { bountyId: args.bountyId });
|
|
16
|
+
if (!result.feedbackJson) {
|
|
17
|
+
return {
|
|
18
|
+
content: [{
|
|
19
|
+
type: "text",
|
|
20
|
+
text: `No feedback available. Verification status: ${result.verificationStatus}`,
|
|
21
|
+
}],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
let feedback;
|
|
25
|
+
try {
|
|
26
|
+
feedback = JSON.parse(result.feedbackJson);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return {
|
|
30
|
+
content: [{
|
|
31
|
+
type: "text",
|
|
32
|
+
text: `# Verification Feedback\n\nStructured feedback could not be parsed. Raw data:\n\n\`\`\`\n${result.feedbackJson.slice(0, 2000)}\n\`\`\``,
|
|
33
|
+
}],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
let text = `# Verification Feedback\n\n`;
|
|
37
|
+
text += `**Overall Status:** ${feedback.overallStatus}\n`;
|
|
38
|
+
text += `**Attempt:** ${feedback.attemptNumber} | **Remaining:** ${feedback.attemptsRemaining}\n\n`;
|
|
39
|
+
// Gate summary
|
|
40
|
+
if (feedback.gates && feedback.gates.length > 0) {
|
|
41
|
+
text += `## Gate Summary\n\n`;
|
|
42
|
+
text += `| Gate | Status | Issues |\n|------|--------|--------|\n`;
|
|
43
|
+
for (const g of feedback.gates) {
|
|
44
|
+
text += `| ${g.gate} | ${g.status} | ${g.issues?.length ?? 0} |\n`;
|
|
45
|
+
}
|
|
46
|
+
text += `\n`;
|
|
47
|
+
}
|
|
48
|
+
// Test results
|
|
49
|
+
if (feedback.testResults && feedback.testResults.length > 0) {
|
|
50
|
+
const failed = feedback.testResults.filter((t) => t.status === "fail");
|
|
51
|
+
const passed = feedback.testResults.filter((t) => t.status === "pass");
|
|
52
|
+
text += `## Test Results\n`;
|
|
53
|
+
text += `**Passed:** ${passed.length} | **Failed:** ${failed.length}\n\n`;
|
|
54
|
+
if (failed.length > 0) {
|
|
55
|
+
text += `### Failed Scenarios\n\n`;
|
|
56
|
+
for (const t of failed) {
|
|
57
|
+
text += `- **${t.featureName} > ${t.scenarioName}** [${t.visibility}]\n`;
|
|
58
|
+
if (t.output)
|
|
59
|
+
text += ` \`\`\`\n${t.output}\n \`\`\`\n`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Prioritized action items
|
|
64
|
+
if (feedback.actionItems && feedback.actionItems.length > 0) {
|
|
65
|
+
text += `\n## Action Items (prioritized — fix in this order)\n\n`;
|
|
66
|
+
for (let i = 0; i < feedback.actionItems.length; i++) {
|
|
67
|
+
text += `${i + 1}. ${feedback.actionItems[i]}\n`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { content: [{ type: "text", text }] };
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
const message = err instanceof Error ? err.message : "Failed to get feedback";
|
|
74
|
+
return {
|
|
75
|
+
content: [{ type: "text", text: `Failed to get feedback: ${message}` }],
|
|
76
|
+
isError: true,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=getSubmissionFeedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSubmissionFeedback.js","sourceRoot":"","sources":["../../src/tools/getSubmissionFeedback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTestSuites.d.ts","sourceRoot":"","sources":["../../src/tools/getTestSuites.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiBpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0E7D"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerGetTestSuites = registerGetTestSuites;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const client_1 = require("../convex/client");
|
|
6
|
+
const toolHelper_1 = require("../lib/toolHelper");
|
|
7
|
+
const context_1 = require("../lib/context");
|
|
8
|
+
function registerGetTestSuites(server) {
|
|
9
|
+
(0, toolHelper_1.registerTool)(server, "get_test_suites", "Get ALL BDD test suites (Gherkin scenarios) for a bounty — both public and hidden. " +
|
|
10
|
+
"These are your complete implementation specifications. You see every Given/When/Then " +
|
|
11
|
+
"scenario that your code must satisfy. Step definition source code is never exposed, " +
|
|
12
|
+
"but you will see full test runner output (errors, stack traces, assertions) after " +
|
|
13
|
+
"submitting via get_verification_status.", {
|
|
14
|
+
bountyId: zod_1.z.string().describe("The bounty ID"),
|
|
15
|
+
}, async (args) => {
|
|
16
|
+
// SECURITY (H4): Enforce scope
|
|
17
|
+
(0, context_1.requireScope)("bounties:read");
|
|
18
|
+
const result = await (0, client_1.callConvex)("/api/mcp/bounties/test-suites", { bountyId: args.bountyId });
|
|
19
|
+
const suites = result.testSuites;
|
|
20
|
+
if (suites.length === 0) {
|
|
21
|
+
return {
|
|
22
|
+
content: [
|
|
23
|
+
{
|
|
24
|
+
type: "text",
|
|
25
|
+
text: "No test suites found for this bounty. Tests may still be generating — use get_bounty_generation_status to check.",
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const publicSuites = suites.filter((s) => s.visibility === "public");
|
|
31
|
+
const hiddenSuites = suites.filter((s) => s.visibility === "hidden");
|
|
32
|
+
let text = `# Test Suites for Bounty\n\n`;
|
|
33
|
+
// Test framework metadata — tells agents what kind of code to write
|
|
34
|
+
if (result.testFramework || result.testLanguage) {
|
|
35
|
+
text += `**Test Framework:** ${result.testFramework ?? "unknown"}\n`;
|
|
36
|
+
text += `**Test Language:** ${result.testLanguage ?? "unknown"}\n\n`;
|
|
37
|
+
}
|
|
38
|
+
text += `**Total:** ${suites.length} suites (${publicSuites.length} public, ${hiddenSuites.length} hidden)\n\n`;
|
|
39
|
+
text += `> These Gherkin scenarios are your complete specification. Implement code that `;
|
|
40
|
+
text += `satisfies every Given/When/Then step. After submitting, you'll see full test `;
|
|
41
|
+
text += `runner output (error messages, stack traces, assertion details) via \`get_verification_status\`.\n\n`;
|
|
42
|
+
if (publicSuites.length > 0) {
|
|
43
|
+
text += `## Public Test Suites (${publicSuites.length})\n\n`;
|
|
44
|
+
for (const ts of publicSuites) {
|
|
45
|
+
text += `### ${ts.title} (v${ts.version})\n\n`;
|
|
46
|
+
text += `\`\`\`gherkin\n${ts.gherkinContent}\n\`\`\`\n\n`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (hiddenSuites.length > 0) {
|
|
50
|
+
text += `## Hidden Test Suites (${hiddenSuites.length})\n\n`;
|
|
51
|
+
text += `> Hidden tests verify edge cases and security properties. You see the full `;
|
|
52
|
+
text += `Gherkin spec here. After verification, you'll see detailed pass/fail output `;
|
|
53
|
+
text += `for each scenario.\n\n`;
|
|
54
|
+
for (const ts of hiddenSuites) {
|
|
55
|
+
text += `### ${ts.title} (v${ts.version})\n\n`;
|
|
56
|
+
text += `\`\`\`gherkin\n${ts.gherkinContent}\n\`\`\`\n\n`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
content: [{ type: "text", text }],
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=getTestSuites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTestSuites.js","sourceRoot":"","sources":["../../src/tools/getTestSuites.ts"],"names":[],"mappings":";;AAiBA,sDA0EC;AA1FD,6BAAwB;AACxB,6CAA8C;AAC9C,kDAAiD;AACjD,4CAA8C;AAa9C,SAAgB,qBAAqB,CAAC,MAAiB;IACrD,IAAA,yBAAY,EACV,MAAM,EACN,iBAAiB,EACjB,qFAAqF;QACnF,uFAAuF;QACvF,sFAAsF;QACtF,oFAAoF;QACpF,yCAAyC,EAC3C;QACE,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;KAC/C,EACD,KAAK,EAAE,IAA0B,EAAE,EAAE;QACnC,+BAA+B;QAC/B,IAAA,sBAAY,EAAC,eAAe,CAAC,CAAC;QAE9B,MAAM,MAAM,GAAG,MAAM,IAAA,mBAAU,EAC7B,+BAA+B,EAC/B,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAC5B,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;QAEjC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,kHAAkH;qBACzH;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC;QACrE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC;QAErE,IAAI,IAAI,GAAG,8BAA8B,CAAC;QAE1C,oEAAoE;QACpE,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YAChD,IAAI,IAAI,uBAAuB,MAAM,CAAC,aAAa,IAAI,SAAS,IAAI,CAAC;YACrE,IAAI,IAAI,sBAAsB,MAAM,CAAC,YAAY,IAAI,SAAS,MAAM,CAAC;QACvE,CAAC;QAED,IAAI,IAAI,cAAc,MAAM,CAAC,MAAM,YAAY,YAAY,CAAC,MAAM,YAAY,YAAY,CAAC,MAAM,cAAc,CAAC;QAChH,IAAI,IAAI,iFAAiF,CAAC;QAC1F,IAAI,IAAI,+EAA+E,CAAC;QACxF,IAAI,IAAI,sGAAsG,CAAC;QAE/G,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,IAAI,0BAA0B,YAAY,CAAC,MAAM,OAAO,CAAC;YAC7D,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;gBAC9B,IAAI,IAAI,OAAO,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,OAAO,OAAO,CAAC;gBAC/C,IAAI,IAAI,kBAAkB,EAAE,CAAC,cAAc,cAAc,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,IAAI,0BAA0B,YAAY,CAAC,MAAM,OAAO,CAAC;YAC7D,IAAI,IAAI,6EAA6E,CAAC;YACtF,IAAI,IAAI,8EAA8E,CAAC;YACvF,IAAI,IAAI,wBAAwB,CAAC;YACjC,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;gBAC9B,IAAI,IAAI,OAAO,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,OAAO,OAAO,CAAC;gBAC/C,IAAI,IAAI,kBAAkB,EAAE,CAAC,cAAc,cAAc,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;SAC3C,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getVerificationStatus.d.ts","sourceRoot":"","sources":["../../src/tools/getVerificationStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOpE,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsHrE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerGetVerificationStatus = registerGetVerificationStatus;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const client_1 = require("../convex/client");
|
|
6
|
+
const toolHelper_1 = require("../lib/toolHelper");
|
|
7
|
+
const context_1 = require("../lib/context");
|
|
8
|
+
function registerGetVerificationStatus(server) {
|
|
9
|
+
(0, toolHelper_1.registerTool)(server, "get_verification_status", "Check verification progress and results. Shows gate results (build, lint, typecheck, security, tests), verbose test output for ALL scenarios (public + hidden), full lint/type/security diagnostics, and structured feedback with prioritized action items.", {
|
|
10
|
+
verificationId: zod_1.z.string().optional().describe("The verification ID (from submit_solution)"),
|
|
11
|
+
submissionId: zod_1.z.string().optional().describe("The submission ID (alternative to verificationId)"),
|
|
12
|
+
}, async (args) => {
|
|
13
|
+
// SECURITY (H4): Enforce scope
|
|
14
|
+
(0, context_1.requireScope)("bounties:read");
|
|
15
|
+
if (!args.verificationId && !args.submissionId) {
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: "text", text: "Please provide either verificationId or submissionId." }],
|
|
18
|
+
isError: true,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const result = await (0, client_1.callConvex)("/api/mcp/verifications/get", { verificationId: args.verificationId, submissionId: args.submissionId });
|
|
23
|
+
const v = result.verification;
|
|
24
|
+
let text = `# Verification Status\n\n`;
|
|
25
|
+
text += `**ID:** ${v._id}\n`;
|
|
26
|
+
text += `**Overall Status:** ${v.status}\n`;
|
|
27
|
+
if (v.startedAt)
|
|
28
|
+
text += `**Started:** ${new Date(v.startedAt).toISOString()}\n`;
|
|
29
|
+
if (v.completedAt)
|
|
30
|
+
text += `**Completed:** ${new Date(v.completedAt).toISOString()}\n`;
|
|
31
|
+
if (v.job) {
|
|
32
|
+
text += `\n## Worker Job\n`;
|
|
33
|
+
text += `**Job Status:** ${v.job.status}\n`;
|
|
34
|
+
if (v.job.currentGate)
|
|
35
|
+
text += `**Current Gate:** ${v.job.currentGate}\n`;
|
|
36
|
+
}
|
|
37
|
+
if (v.gates.length > 0) {
|
|
38
|
+
text += `\n## Gate Results\n\n`;
|
|
39
|
+
text += `| Gate | Status | Tool |\n|------|--------|------|\n`;
|
|
40
|
+
for (const g of v.gates) {
|
|
41
|
+
const statusLabel = g.status === "passed" ? "PASS" : g.status === "failed" ? "FAIL" : "WARN";
|
|
42
|
+
text += `| ${g.gateType} | ${statusLabel} | ${g.tool} |\n`;
|
|
43
|
+
// Show full gate issues (lint violations, type errors, security findings)
|
|
44
|
+
if (g.issues && g.issues.length > 0) {
|
|
45
|
+
text += `\n**${g.gateType} issues:**\n`;
|
|
46
|
+
for (const issue of g.issues.slice(0, 50)) {
|
|
47
|
+
text += `- ${issue}\n`;
|
|
48
|
+
}
|
|
49
|
+
if (g.issues.length > 50) {
|
|
50
|
+
text += `- ... and ${g.issues.length - 50} more\n`;
|
|
51
|
+
}
|
|
52
|
+
text += `\n`;
|
|
53
|
+
}
|
|
54
|
+
if (g.details) {
|
|
55
|
+
const detailsText = JSON.stringify(g.details, null, 2);
|
|
56
|
+
text += `**${g.gateType} details:**\n`;
|
|
57
|
+
text += `\`\`\`json\n${detailsText.slice(0, 4000)}\n\`\`\`\n\n`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// ALL test results with verbose output (public + hidden)
|
|
62
|
+
const steps = v.steps ?? [];
|
|
63
|
+
if (steps.length > 0) {
|
|
64
|
+
const passed = steps.filter((s) => s.status === "pass").length;
|
|
65
|
+
const failed = steps.filter((s) => s.status === "fail").length;
|
|
66
|
+
text += `\n## Test Results (${steps.length} scenarios)\n`;
|
|
67
|
+
text += `**Passed:** ${passed} | **Failed:** ${failed}\n\n`;
|
|
68
|
+
const failures = steps.filter((s) => s.status === "fail" || s.status === "error");
|
|
69
|
+
if (failures.length > 0) {
|
|
70
|
+
text += `### Failed Scenarios\n\n`;
|
|
71
|
+
for (const s of failures) {
|
|
72
|
+
text += `- **${s.featureName} > ${s.scenarioName}** [${s.visibility}] - ${s.status.toUpperCase()}\n`;
|
|
73
|
+
if (s.output)
|
|
74
|
+
text += ` \`\`\`\n${s.output}\n \`\`\`\n`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Structured feedback with prioritized action items
|
|
79
|
+
if (v.feedbackJson) {
|
|
80
|
+
try {
|
|
81
|
+
const feedback = JSON.parse(v.feedbackJson);
|
|
82
|
+
text += `\n## Structured Feedback\n\n`;
|
|
83
|
+
text += `**Attempt:** ${feedback.attemptNumber ?? "?"} | **Remaining:** ${feedback.attemptsRemaining ?? "?"}\n\n`;
|
|
84
|
+
if (feedback.actionItems && feedback.actionItems.length > 0) {
|
|
85
|
+
text += `### Action Items (prioritized)\n\n`;
|
|
86
|
+
for (let i = 0; i < feedback.actionItems.length; i++) {
|
|
87
|
+
text += `${i + 1}. ${feedback.actionItems[i]}\n`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// feedbackJson parse failed — skip
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (v.result)
|
|
96
|
+
text += `\n## Result\n${v.result}\n`;
|
|
97
|
+
if (v.errorLog)
|
|
98
|
+
text += `\n## Error Log\n\`\`\`\n${v.errorLog.slice(0, 2000)}\n\`\`\`\n`;
|
|
99
|
+
// Polling guidance
|
|
100
|
+
const isTerminal = ["passed", "failed", "error", "timed_out"].includes(v.status);
|
|
101
|
+
if (!isTerminal) {
|
|
102
|
+
text += `\n---\n_Verification typically takes 2-5 minutes. Check again in ~15 seconds._\n`;
|
|
103
|
+
}
|
|
104
|
+
return { content: [{ type: "text", text }] };
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
const message = err instanceof Error ? err.message : "Failed to get verification status";
|
|
108
|
+
return {
|
|
109
|
+
content: [{ type: "text", text: `Failed to get verification status: ${message}` }],
|
|
110
|
+
isError: true,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=getVerificationStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getVerificationStatus.js","sourceRoot":"","sources":["../../src/tools/getVerificationStatus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importWorkItem.d.ts","sourceRoot":"","sources":["../../src/tools/importWorkItem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2HpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgE9D"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerImportWorkItem = registerImportWorkItem;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const toolHelper_1 = require("../lib/toolHelper");
|
|
6
|
+
const context_1 = require("../lib/context");
|
|
7
|
+
/**
|
|
8
|
+
* Lightweight fetch functions for each provider.
|
|
9
|
+
* These are simplified versions that run in the MCP server process.
|
|
10
|
+
*/
|
|
11
|
+
async function fetchJira(config, key) {
|
|
12
|
+
if (!config.domain || !config.email)
|
|
13
|
+
throw new Error("Jira requires domain and email");
|
|
14
|
+
const auth = Buffer.from(`${config.email}:${config.apiToken}`).toString("base64");
|
|
15
|
+
const res = await fetch(`https://${config.domain}/rest/api/3/issue/${encodeURIComponent(key)}`, {
|
|
16
|
+
headers: { Authorization: `Basic ${auth}`, Accept: "application/json" },
|
|
17
|
+
});
|
|
18
|
+
if (!res.ok)
|
|
19
|
+
throw new Error(`Jira ${res.status}: ${res.statusText}`);
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
const data = (await res.json());
|
|
22
|
+
const f = data.fields || {};
|
|
23
|
+
const desc = typeof f.description === "string" ? f.description : JSON.stringify(f.description || "");
|
|
24
|
+
return {
|
|
25
|
+
externalId: key, provider: "jira", title: f.summary || "", description: desc,
|
|
26
|
+
labels: (f.labels || []), status: f.status?.name || "Unknown",
|
|
27
|
+
priority: f.priority?.name, url: `https://${config.domain}/browse/${key}`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async function fetchLinear(config, key) {
|
|
31
|
+
const res = await fetch("https://api.linear.app/graphql", {
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: { Authorization: config.apiToken, "Content-Type": "application/json" },
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
query: `query { issues(filter: { identifier: { eq: "${key}" } }, first: 1) { nodes { identifier title description url estimate priorityLabel state { name } labels { nodes { name } } } } }`,
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok)
|
|
39
|
+
throw new Error(`Linear ${res.status}`);
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
|
+
const result = (await res.json());
|
|
42
|
+
const issue = result.data?.issues?.nodes?.[0];
|
|
43
|
+
if (!issue)
|
|
44
|
+
throw new Error(`Not found: ${key}`);
|
|
45
|
+
return {
|
|
46
|
+
externalId: issue.identifier, provider: "linear", title: issue.title || "",
|
|
47
|
+
description: issue.description || "",
|
|
48
|
+
labels: (issue.labels?.nodes || []).map((l) => l.name),
|
|
49
|
+
estimate: issue.estimate, status: issue.state?.name || "Unknown",
|
|
50
|
+
priority: issue.priorityLabel, url: issue.url || "",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async function fetchAsana(config, gid) {
|
|
54
|
+
const res = await fetch(`https://app.asana.com/api/1.0/tasks/${gid}?opt_fields=name,notes,tags.name,permalink_url`, {
|
|
55
|
+
headers: { Authorization: `Bearer ${config.apiToken}`, Accept: "application/json" },
|
|
56
|
+
});
|
|
57
|
+
if (!res.ok)
|
|
58
|
+
throw new Error(`Asana ${res.status}`);
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
+
const result = (await res.json());
|
|
61
|
+
const t = result.data;
|
|
62
|
+
return {
|
|
63
|
+
externalId: gid, provider: "asana", title: t.name || "", description: t.notes || "",
|
|
64
|
+
labels: (t.tags || []).map((tag) => tag.name), status: "Unknown",
|
|
65
|
+
url: t.permalink_url || "",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async function fetchMonday(config, id) {
|
|
69
|
+
const res = await fetch("https://api.monday.com/v2", {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: { Authorization: config.apiToken, "Content-Type": "application/json" },
|
|
72
|
+
body: JSON.stringify({
|
|
73
|
+
query: `query { items(ids: [${id}]) { id name url column_values { title text type } } }`,
|
|
74
|
+
}),
|
|
75
|
+
});
|
|
76
|
+
if (!res.ok)
|
|
77
|
+
throw new Error(`Monday ${res.status}`);
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
79
|
+
const result = (await res.json());
|
|
80
|
+
const item = result.data?.items?.[0];
|
|
81
|
+
if (!item)
|
|
82
|
+
throw new Error(`Not found: ${id}`);
|
|
83
|
+
let desc = "";
|
|
84
|
+
for (const col of item.column_values || []) {
|
|
85
|
+
if ((col.type === "long_text" || col.type === "long-text") && col.text) {
|
|
86
|
+
desc = col.text;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
externalId: id, provider: "monday", title: item.name || "", description: desc,
|
|
92
|
+
labels: [], status: "Unknown", url: item.url || "",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
async function fetchWorkItemForMcp(provider, config, key) {
|
|
96
|
+
switch (provider) {
|
|
97
|
+
case "jira": return fetchJira(config, key);
|
|
98
|
+
case "linear": return fetchLinear(config, key);
|
|
99
|
+
case "asana": return fetchAsana(config, key);
|
|
100
|
+
case "monday": return fetchMonday(config, key);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function registerImportWorkItem(server) {
|
|
104
|
+
(0, toolHelper_1.registerTool)(server, "import_work_item", "Import a work item (issue/task/story) from Jira, Linear, Asana, or Monday.com. Returns structured data that can be used to pre-fill a bounty.", {
|
|
105
|
+
provider: zod_1.z.enum(["jira", "linear", "asana", "monday"]).describe("PM tool provider"),
|
|
106
|
+
issueKey: zod_1.z.string().describe("Issue identifier (e.g., 'PROJ-123' for Jira, 'TEAM-123' for Linear, GID for Asana, item ID for Monday)"),
|
|
107
|
+
apiToken: zod_1.z.string().describe("API token for the PM tool (sensitive — not stored after this request)"),
|
|
108
|
+
domain: zod_1.z.string().optional().describe("Required for Jira (e.g., 'mycompany.atlassian.net') and Monday (account slug)"),
|
|
109
|
+
email: zod_1.z.string().optional().describe("Required for Jira (email for Basic Auth)"),
|
|
110
|
+
}, async (args) => {
|
|
111
|
+
(0, context_1.requireScope)("bounties:create");
|
|
112
|
+
const authUser = (0, context_1.getAuthUser)();
|
|
113
|
+
if (!authUser?.userId) {
|
|
114
|
+
return {
|
|
115
|
+
content: [{ type: "text", text: "Error: Authentication required." }],
|
|
116
|
+
isError: true,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
const config = {
|
|
121
|
+
provider: args.provider,
|
|
122
|
+
domain: args.domain,
|
|
123
|
+
email: args.email,
|
|
124
|
+
apiToken: args.apiToken,
|
|
125
|
+
};
|
|
126
|
+
const workItem = await fetchWorkItemForMcp(args.provider, config, args.issueKey);
|
|
127
|
+
let text = `# Work Item Imported\n\n`;
|
|
128
|
+
text += `**Provider:** ${args.provider}\n`;
|
|
129
|
+
text += `**ID:** ${workItem.externalId}\n`;
|
|
130
|
+
text += `**Title:** ${workItem.title}\n`;
|
|
131
|
+
text += `**Status:** ${workItem.status}\n`;
|
|
132
|
+
if (workItem.priority)
|
|
133
|
+
text += `**Priority:** ${workItem.priority}\n`;
|
|
134
|
+
if (workItem.estimate)
|
|
135
|
+
text += `**Estimate:** ${workItem.estimate} points\n`;
|
|
136
|
+
if (workItem.labels.length > 0)
|
|
137
|
+
text += `**Labels:** ${workItem.labels.join(", ")}\n`;
|
|
138
|
+
text += `**URL:** ${workItem.url}\n\n`;
|
|
139
|
+
text += `## Description\n\n${workItem.description || "No description"}\n`;
|
|
140
|
+
if (workItem.acceptanceCriteria) {
|
|
141
|
+
text += `\n## Acceptance Criteria\n\n${workItem.acceptanceCriteria}\n`;
|
|
142
|
+
}
|
|
143
|
+
text += `\n---\nUse \`create_bounty\` with this information to create a bounty. `;
|
|
144
|
+
text += `Pass \`pmIssueKey: "${workItem.externalId}"\` and \`pmProvider: "${args.provider}"\` for traceability.`;
|
|
145
|
+
return { content: [{ type: "text", text }] };
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
const message = err instanceof Error ? err.message : "Failed to import work item";
|
|
149
|
+
return {
|
|
150
|
+
content: [{ type: "text", text: `Failed to import work item: ${message}` }],
|
|
151
|
+
isError: true,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=importWorkItem.js.map
|