patchwork-os 0.2.0-alpha.2 → 0.2.0-alpha.4
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/dist/bridge.js +23 -10
- package/dist/bridge.js.map +1 -1
- package/dist/claudeDriver.d.ts +3 -1
- package/dist/claudeDriver.js +48 -0
- package/dist/claudeDriver.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +5 -2
- package/dist/config.js.map +1 -1
- package/dist/connectors/github.d.ts +58 -8
- package/dist/connectors/github.js +321 -84
- package/dist/connectors/github.js.map +1 -1
- package/dist/connectors/gmail.js +21 -0
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/googleCalendar.d.ts +57 -0
- package/dist/connectors/googleCalendar.js +308 -0
- package/dist/connectors/googleCalendar.js.map +1 -0
- package/dist/connectors/linear.d.ts +100 -0
- package/dist/connectors/linear.js +236 -0
- package/dist/connectors/linear.js.map +1 -0
- package/dist/connectors/mcpClient.d.ts +56 -0
- package/dist/connectors/mcpClient.js +189 -0
- package/dist/connectors/mcpClient.js.map +1 -0
- package/dist/connectors/mcpOAuth.d.ts +73 -0
- package/dist/connectors/mcpOAuth.js +338 -0
- package/dist/connectors/mcpOAuth.js.map +1 -0
- package/dist/connectors/sentry.d.ts +43 -0
- package/dist/connectors/sentry.js +197 -0
- package/dist/connectors/sentry.js.map +1 -0
- package/dist/drivers/claude/api.d.ts +11 -0
- package/dist/drivers/claude/api.js +54 -0
- package/dist/drivers/claude/api.js.map +1 -0
- package/dist/drivers/claude/envSanitizer.d.ts +7 -0
- package/dist/drivers/claude/envSanitizer.js +18 -0
- package/dist/drivers/claude/envSanitizer.js.map +1 -0
- package/dist/drivers/claude/streamParser.d.ts +38 -0
- package/dist/drivers/claude/streamParser.js +34 -0
- package/dist/drivers/claude/streamParser.js.map +1 -0
- package/dist/drivers/claude/subprocess.d.ts +19 -0
- package/dist/drivers/claude/subprocess.js +216 -0
- package/dist/drivers/claude/subprocess.js.map +1 -0
- package/dist/drivers/claude/subprocessSettings.d.ts +9 -0
- package/dist/drivers/claude/subprocessSettings.js +55 -0
- package/dist/drivers/claude/subprocessSettings.js.map +1 -0
- package/dist/drivers/gemini/index.d.ts +14 -0
- package/dist/drivers/gemini/index.js +176 -0
- package/dist/drivers/gemini/index.js.map +1 -0
- package/dist/drivers/grok/index.d.ts +11 -0
- package/dist/drivers/grok/index.js +22 -0
- package/dist/drivers/grok/index.js.map +1 -0
- package/dist/drivers/index.d.ts +18 -0
- package/dist/drivers/index.js +31 -0
- package/dist/drivers/index.js.map +1 -0
- package/dist/drivers/openai/index.d.ts +24 -0
- package/dist/drivers/openai/index.js +110 -0
- package/dist/drivers/openai/index.js.map +1 -0
- package/dist/drivers/types.d.ts +72 -0
- package/dist/drivers/types.js +30 -0
- package/dist/drivers/types.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/recipes/yamlRunner.js +57 -2
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +13 -1
- package/dist/recipesHttp.js +9 -1
- package/dist/recipesHttp.js.map +1 -1
- package/dist/server.d.ts +3 -1
- package/dist/server.js +277 -14
- package/dist/server.js.map +1 -1
- package/dist/tools/createLinearIssue.d.ts +84 -0
- package/dist/tools/createLinearIssue.js +146 -0
- package/dist/tools/createLinearIssue.js.map +1 -0
- package/dist/tools/ctxGetTaskContext.d.ts +4 -1
- package/dist/tools/ctxGetTaskContext.js +45 -2
- package/dist/tools/ctxGetTaskContext.js.map +1 -1
- package/dist/tools/fetchCalendarEvents.d.ts +94 -0
- package/dist/tools/fetchCalendarEvents.js +97 -0
- package/dist/tools/fetchCalendarEvents.js.map +1 -0
- package/dist/tools/fetchGithubIssue.d.ts +80 -0
- package/dist/tools/fetchGithubIssue.js +84 -0
- package/dist/tools/fetchGithubIssue.js.map +1 -0
- package/dist/tools/fetchGithubPR.d.ts +89 -0
- package/dist/tools/fetchGithubPR.js +96 -0
- package/dist/tools/fetchGithubPR.js.map +1 -0
- package/dist/tools/fetchLinearIssue.d.ts +112 -0
- package/dist/tools/fetchLinearIssue.js +129 -0
- package/dist/tools/fetchLinearIssue.js.map +1 -0
- package/dist/tools/fetchSentryIssue.d.ts +143 -0
- package/dist/tools/fetchSentryIssue.js +150 -0
- package/dist/tools/fetchSentryIssue.js.map +1 -0
- package/dist/tools/index.js +12 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +2 -2
- package/scripts/start-all.sh +56 -19
- package/templates/recipes/ctx-loop-test.yaml +75 -0
- package/templates/recipes/morning-brief.yaml +20 -3
- package/templates/recipes/sentry-to-linear.yaml +77 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.1 PKCE helper for upstream MCP servers.
|
|
3
|
+
*
|
|
4
|
+
* Supports two vendor modes:
|
|
5
|
+
* - dyn-reg (Linear, Sentry): RFC 7591 dynamic client registration.
|
|
6
|
+
* Registration data cached alongside tokens so we don't re-register every run.
|
|
7
|
+
* - preregistered (GitHub): uses a hardcoded client_id + PKCE-only flow.
|
|
8
|
+
*
|
|
9
|
+
* Token files: ~/.patchwork/tokens/<vendor>-mcp.json (mode 0600)
|
|
10
|
+
*
|
|
11
|
+
* Flow:
|
|
12
|
+
* 1. startAuthorize({ vendor, config }) -> { url, state }
|
|
13
|
+
* Dashboard opens `url` in a popup; stores `state` to correlate callback.
|
|
14
|
+
* 2. server.ts callback route calls completeAuthorize({ vendor, config, code, state })
|
|
15
|
+
* -> persisted token file.
|
|
16
|
+
* 3. getAccessToken({ vendor }) reads token, refreshes if needed.
|
|
17
|
+
* 4. revoke({ vendor }) hits the revocation endpoint + deletes file.
|
|
18
|
+
*/
|
|
19
|
+
import crypto from "node:crypto";
|
|
20
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
21
|
+
import { homedir } from "node:os";
|
|
22
|
+
import path from "node:path";
|
|
23
|
+
// ── Known vendor configs ─────────────────────────────────────────────────────
|
|
24
|
+
function defaultBridgeBase() {
|
|
25
|
+
const port = process.env.PATCHWORK_BRIDGE_PORT ?? "3101";
|
|
26
|
+
return (process.env.PATCHWORK_BRIDGE_URL ?? `http://localhost:${port}`).replace(/\/$/, "");
|
|
27
|
+
}
|
|
28
|
+
export function vendorConfig(vendor) {
|
|
29
|
+
const bridgeBase = defaultBridgeBase();
|
|
30
|
+
switch (vendor) {
|
|
31
|
+
case "github":
|
|
32
|
+
return {
|
|
33
|
+
vendor,
|
|
34
|
+
issuer: "https://github.com/login/oauth",
|
|
35
|
+
authorizationEndpoint: "https://github.com/login/oauth/authorize",
|
|
36
|
+
tokenEndpoint: "https://github.com/login/oauth/access_token",
|
|
37
|
+
revocationEndpoint: undefined, // GitHub OAuth apps use a different revoke path; best-effort delete only
|
|
38
|
+
scopes: ["repo", "read:org", "read:user"],
|
|
39
|
+
redirectUri: `${bridgeBase}/connections/github/callback`,
|
|
40
|
+
useDynamicRegistration: false,
|
|
41
|
+
preregisteredClientId: process.env.PATCHWORK_GITHUB_CLIENT_ID ?? "",
|
|
42
|
+
preregisteredClientSecret: process.env.PATCHWORK_GITHUB_CLIENT_SECRET,
|
|
43
|
+
clientName: "Patchwork OS",
|
|
44
|
+
};
|
|
45
|
+
case "linear":
|
|
46
|
+
return {
|
|
47
|
+
vendor,
|
|
48
|
+
issuer: "https://mcp.linear.app",
|
|
49
|
+
authorizationEndpoint: "https://mcp.linear.app/authorize",
|
|
50
|
+
tokenEndpoint: "https://mcp.linear.app/token",
|
|
51
|
+
registrationEndpoint: "https://mcp.linear.app/register",
|
|
52
|
+
revocationEndpoint: "https://mcp.linear.app/token", // per discovery doc
|
|
53
|
+
scopes: [],
|
|
54
|
+
redirectUri: `${bridgeBase}/connections/linear/callback`,
|
|
55
|
+
useDynamicRegistration: true,
|
|
56
|
+
clientName: "Patchwork OS",
|
|
57
|
+
};
|
|
58
|
+
case "sentry":
|
|
59
|
+
return {
|
|
60
|
+
vendor,
|
|
61
|
+
issuer: "https://mcp.sentry.dev",
|
|
62
|
+
authorizationEndpoint: "https://mcp.sentry.dev/oauth/authorize",
|
|
63
|
+
tokenEndpoint: "https://mcp.sentry.dev/oauth/token",
|
|
64
|
+
registrationEndpoint: "https://mcp.sentry.dev/oauth/register",
|
|
65
|
+
revocationEndpoint: "https://mcp.sentry.dev/oauth/token",
|
|
66
|
+
scopes: ["org:read", "project:write", "event:write"],
|
|
67
|
+
redirectUri: `${bridgeBase}/connections/sentry/callback`,
|
|
68
|
+
useDynamicRegistration: true,
|
|
69
|
+
clientName: "Patchwork OS",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function tokenPath(vendor) {
|
|
74
|
+
return path.join(homedir(), ".patchwork", "tokens", `${vendor}-mcp.json`);
|
|
75
|
+
}
|
|
76
|
+
export function loadTokenFile(vendor) {
|
|
77
|
+
const p = tokenPath(vendor);
|
|
78
|
+
if (!existsSync(p))
|
|
79
|
+
return null;
|
|
80
|
+
try {
|
|
81
|
+
return JSON.parse(readFileSync(p, "utf-8"));
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function saveTokenFile(file) {
|
|
88
|
+
const p = tokenPath(file.vendor);
|
|
89
|
+
mkdirSync(path.dirname(p), { recursive: true, mode: 0o700 });
|
|
90
|
+
writeFileSync(p, JSON.stringify(file, null, 2), { mode: 0o600 });
|
|
91
|
+
}
|
|
92
|
+
function deleteTokenFile(vendor) {
|
|
93
|
+
const p = tokenPath(vendor);
|
|
94
|
+
if (existsSync(p))
|
|
95
|
+
unlinkSync(p);
|
|
96
|
+
}
|
|
97
|
+
// ── PKCE helpers ─────────────────────────────────────────────────────────────
|
|
98
|
+
function base64url(buf) {
|
|
99
|
+
return buf
|
|
100
|
+
.toString("base64")
|
|
101
|
+
.replace(/=/g, "")
|
|
102
|
+
.replace(/\+/g, "-")
|
|
103
|
+
.replace(/\//g, "_");
|
|
104
|
+
}
|
|
105
|
+
function genVerifier() {
|
|
106
|
+
return base64url(crypto.randomBytes(32));
|
|
107
|
+
}
|
|
108
|
+
function challenge(verifier) {
|
|
109
|
+
return base64url(crypto.createHash("sha256").update(verifier).digest());
|
|
110
|
+
}
|
|
111
|
+
const pending = new Map();
|
|
112
|
+
function gcPending() {
|
|
113
|
+
const now = Date.now();
|
|
114
|
+
for (const [k, v] of pending.entries()) {
|
|
115
|
+
if (v.expiresAt < now)
|
|
116
|
+
pending.delete(k);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async function dynamicRegister(config) {
|
|
120
|
+
if (!config.registrationEndpoint) {
|
|
121
|
+
throw new Error(`${config.vendor}: no registration endpoint configured`);
|
|
122
|
+
}
|
|
123
|
+
const body = {
|
|
124
|
+
client_name: config.clientName ?? "Patchwork OS",
|
|
125
|
+
redirect_uris: [config.redirectUri],
|
|
126
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
127
|
+
response_types: ["code"],
|
|
128
|
+
token_endpoint_auth_method: "none",
|
|
129
|
+
scope: config.scopes.join(" "),
|
|
130
|
+
};
|
|
131
|
+
const res = await fetch(config.registrationEndpoint, {
|
|
132
|
+
method: "POST",
|
|
133
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
134
|
+
body: JSON.stringify(body),
|
|
135
|
+
});
|
|
136
|
+
if (!res.ok) {
|
|
137
|
+
const snippet = (await res.text()).slice(0, 300);
|
|
138
|
+
throw new Error(`${config.vendor} dyn-reg failed ${res.status}: ${snippet}`);
|
|
139
|
+
}
|
|
140
|
+
const json = (await res.json());
|
|
141
|
+
if (!json.client_id)
|
|
142
|
+
throw new Error(`${config.vendor} dyn-reg missing client_id`);
|
|
143
|
+
return { clientId: json.client_id, clientSecret: json.client_secret };
|
|
144
|
+
}
|
|
145
|
+
// ── Authorize flow ───────────────────────────────────────────────────────────
|
|
146
|
+
/**
|
|
147
|
+
* Returns the authorize URL for the popup, and a `state` cookie value
|
|
148
|
+
* the callback must match. For dyn-reg vendors, registers a fresh client
|
|
149
|
+
* if we don't have one yet (re-uses existing one from token file on reconnect).
|
|
150
|
+
*/
|
|
151
|
+
export async function startAuthorize(config) {
|
|
152
|
+
gcPending();
|
|
153
|
+
let clientId = config.preregisteredClientId ?? "";
|
|
154
|
+
let clientSecret = config.preregisteredClientSecret;
|
|
155
|
+
if (config.useDynamicRegistration) {
|
|
156
|
+
// Re-use cached registration if available
|
|
157
|
+
const existing = loadTokenFile(config.vendor);
|
|
158
|
+
if (existing?.client_id) {
|
|
159
|
+
clientId = existing.client_id;
|
|
160
|
+
clientSecret = existing.client_secret;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const reg = await dynamicRegister(config);
|
|
164
|
+
clientId = reg.clientId;
|
|
165
|
+
clientSecret = reg.clientSecret;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (!clientId) {
|
|
169
|
+
throw new Error(`${config.vendor}: client_id not configured (set PATCHWORK_${config.vendor.toUpperCase()}_CLIENT_ID)`);
|
|
170
|
+
}
|
|
171
|
+
if (!config.useDynamicRegistration &&
|
|
172
|
+
config.preregisteredClientSecret === undefined &&
|
|
173
|
+
config.vendor === "github") {
|
|
174
|
+
throw new Error("github: client_secret not configured (set PATCHWORK_GITHUB_CLIENT_SECRET)");
|
|
175
|
+
}
|
|
176
|
+
const verifier = genVerifier();
|
|
177
|
+
const state = base64url(crypto.randomBytes(24));
|
|
178
|
+
pending.set(state, {
|
|
179
|
+
vendor: config.vendor,
|
|
180
|
+
verifier,
|
|
181
|
+
clientId,
|
|
182
|
+
clientSecret,
|
|
183
|
+
expiresAt: Date.now() + 10 * 60 * 1000,
|
|
184
|
+
});
|
|
185
|
+
const params = new URLSearchParams({
|
|
186
|
+
response_type: "code",
|
|
187
|
+
client_id: clientId,
|
|
188
|
+
redirect_uri: config.redirectUri,
|
|
189
|
+
state,
|
|
190
|
+
code_challenge: challenge(verifier),
|
|
191
|
+
code_challenge_method: "S256",
|
|
192
|
+
});
|
|
193
|
+
if (config.scopes.length)
|
|
194
|
+
params.set("scope", config.scopes.join(" "));
|
|
195
|
+
const authorizeUrl = config.authorizationEndpoint;
|
|
196
|
+
if (!authorizeUrl)
|
|
197
|
+
throw new Error(`${config.vendor}: no authorization_endpoint`);
|
|
198
|
+
return { url: `${authorizeUrl}?${params.toString()}`, state };
|
|
199
|
+
}
|
|
200
|
+
async function exchangeCode(config, code, verifier, clientId, clientSecret) {
|
|
201
|
+
if (!config.tokenEndpoint)
|
|
202
|
+
throw new Error(`${config.vendor}: no token_endpoint`);
|
|
203
|
+
const body = new URLSearchParams({
|
|
204
|
+
grant_type: "authorization_code",
|
|
205
|
+
code,
|
|
206
|
+
redirect_uri: config.redirectUri,
|
|
207
|
+
client_id: clientId,
|
|
208
|
+
code_verifier: verifier,
|
|
209
|
+
});
|
|
210
|
+
if (clientSecret)
|
|
211
|
+
body.set("client_secret", clientSecret);
|
|
212
|
+
const res = await fetch(config.tokenEndpoint, {
|
|
213
|
+
method: "POST",
|
|
214
|
+
headers: {
|
|
215
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
216
|
+
Accept: "application/json",
|
|
217
|
+
},
|
|
218
|
+
body: body.toString(),
|
|
219
|
+
});
|
|
220
|
+
if (!res.ok) {
|
|
221
|
+
const snippet = (await res.text()).slice(0, 300);
|
|
222
|
+
throw new Error(`${config.vendor} token exchange ${res.status}: ${snippet}`);
|
|
223
|
+
}
|
|
224
|
+
// GitHub returns form-encoded by default unless Accept: application/json is honored
|
|
225
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
226
|
+
if (ct.includes("application/x-www-form-urlencoded")) {
|
|
227
|
+
const text = await res.text();
|
|
228
|
+
const p = new URLSearchParams(text);
|
|
229
|
+
if (p.get("error"))
|
|
230
|
+
throw new Error(`${config.vendor}: ${p.get("error_description") ?? p.get("error")}`);
|
|
231
|
+
return {
|
|
232
|
+
access_token: p.get("access_token") ?? "",
|
|
233
|
+
refresh_token: p.get("refresh_token") ?? undefined,
|
|
234
|
+
expires_in: p.get("expires_in") ? Number(p.get("expires_in")) : undefined,
|
|
235
|
+
scope: p.get("scope") ?? undefined,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return (await res.json());
|
|
239
|
+
}
|
|
240
|
+
/** Complete the authorize flow. Persists token file. */
|
|
241
|
+
export async function completeAuthorize(config, code, state, profile) {
|
|
242
|
+
gcPending();
|
|
243
|
+
const p = pending.get(state);
|
|
244
|
+
if (!p)
|
|
245
|
+
throw new Error(`${config.vendor}: invalid or expired state`);
|
|
246
|
+
pending.delete(state);
|
|
247
|
+
if (p.vendor !== config.vendor)
|
|
248
|
+
throw new Error(`${config.vendor}: vendor mismatch on state`);
|
|
249
|
+
const tok = await exchangeCode(config, code, p.verifier, p.clientId, p.clientSecret);
|
|
250
|
+
if (!tok.access_token)
|
|
251
|
+
throw new Error(`${config.vendor}: empty access_token`);
|
|
252
|
+
const expiresAt = tok.expires_in
|
|
253
|
+
? Date.now() + tok.expires_in * 1000
|
|
254
|
+
: undefined;
|
|
255
|
+
saveTokenFile({
|
|
256
|
+
vendor: config.vendor,
|
|
257
|
+
client_id: p.clientId,
|
|
258
|
+
client_secret: p.clientSecret,
|
|
259
|
+
access_token: tok.access_token,
|
|
260
|
+
refresh_token: tok.refresh_token,
|
|
261
|
+
expires_at: expiresAt,
|
|
262
|
+
scope: tok.scope,
|
|
263
|
+
connected_at: new Date().toISOString(),
|
|
264
|
+
profile,
|
|
265
|
+
});
|
|
266
|
+
return { ok: true, profile };
|
|
267
|
+
}
|
|
268
|
+
// ── Token refresh ────────────────────────────────────────────────────────────
|
|
269
|
+
async function refreshIfNeeded(config, file) {
|
|
270
|
+
const buffer = 60_000;
|
|
271
|
+
if (!file.expires_at || Date.now() < file.expires_at - buffer)
|
|
272
|
+
return file;
|
|
273
|
+
if (!file.refresh_token)
|
|
274
|
+
return file; // some vendors don't issue refresh tokens
|
|
275
|
+
if (!config.tokenEndpoint)
|
|
276
|
+
return file;
|
|
277
|
+
const body = new URLSearchParams({
|
|
278
|
+
grant_type: "refresh_token",
|
|
279
|
+
refresh_token: file.refresh_token,
|
|
280
|
+
client_id: file.client_id,
|
|
281
|
+
});
|
|
282
|
+
if (file.client_secret)
|
|
283
|
+
body.set("client_secret", file.client_secret);
|
|
284
|
+
const res = await fetch(config.tokenEndpoint, {
|
|
285
|
+
method: "POST",
|
|
286
|
+
headers: {
|
|
287
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
288
|
+
Accept: "application/json",
|
|
289
|
+
},
|
|
290
|
+
body: body.toString(),
|
|
291
|
+
});
|
|
292
|
+
if (!res.ok) {
|
|
293
|
+
// Leave file as-is; caller will get 401 on next API call and re-auth
|
|
294
|
+
return file;
|
|
295
|
+
}
|
|
296
|
+
const json = (await res.json());
|
|
297
|
+
const updated = {
|
|
298
|
+
...file,
|
|
299
|
+
access_token: json.access_token,
|
|
300
|
+
refresh_token: json.refresh_token ?? file.refresh_token,
|
|
301
|
+
expires_at: json.expires_in
|
|
302
|
+
? Date.now() + json.expires_in * 1000
|
|
303
|
+
: undefined,
|
|
304
|
+
};
|
|
305
|
+
saveTokenFile(updated);
|
|
306
|
+
return updated;
|
|
307
|
+
}
|
|
308
|
+
export async function getAccessToken(vendor) {
|
|
309
|
+
const file = loadTokenFile(vendor);
|
|
310
|
+
if (!file)
|
|
311
|
+
throw new Error(`${vendor}: not connected`);
|
|
312
|
+
const config = vendorConfig(vendor);
|
|
313
|
+
const fresh = await refreshIfNeeded(config, file);
|
|
314
|
+
return fresh.access_token;
|
|
315
|
+
}
|
|
316
|
+
// ── Revocation ───────────────────────────────────────────────────────────────
|
|
317
|
+
export async function revoke(vendor) {
|
|
318
|
+
const file = loadTokenFile(vendor);
|
|
319
|
+
const config = vendorConfig(vendor);
|
|
320
|
+
if (file && config.revocationEndpoint) {
|
|
321
|
+
const body = new URLSearchParams({
|
|
322
|
+
token: file.access_token,
|
|
323
|
+
client_id: file.client_id,
|
|
324
|
+
});
|
|
325
|
+
if (file.client_secret)
|
|
326
|
+
body.set("client_secret", file.client_secret);
|
|
327
|
+
await fetch(config.revocationEndpoint, {
|
|
328
|
+
method: "POST",
|
|
329
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
330
|
+
body: body.toString(),
|
|
331
|
+
}).catch(() => { });
|
|
332
|
+
}
|
|
333
|
+
deleteTokenFile(vendor);
|
|
334
|
+
}
|
|
335
|
+
export function isConnected(vendor) {
|
|
336
|
+
return loadTokenFile(vendor) !== null;
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=mcpOAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpOAuth.js","sourceRoot":"","sources":["../../src/connectors/mcpOAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentry connector — routes through Sentry's official MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Endpoint: https://mcp.sentry.dev/mcp
|
|
5
|
+
* Auth: OAuth 2.1 w/ PKCE; dynamic client registration (RFC 7591).
|
|
6
|
+
*
|
|
7
|
+
* HTTP routes (wired in src/server.ts):
|
|
8
|
+
* GET /connections/sentry/authorize — returns { url } for popup
|
|
9
|
+
* GET /connections/sentry/callback — token exchange
|
|
10
|
+
* POST /connections/sentry/test — ping MCP server
|
|
11
|
+
* DELETE /connections/sentry — revoke + delete token
|
|
12
|
+
*
|
|
13
|
+
* MCP tool: fetchSentryIssue — fetches a Sentry issue/event and returns
|
|
14
|
+
* the stack trace string, ready to pass into enrichStackTrace.
|
|
15
|
+
*/
|
|
16
|
+
export interface SentryTokens {
|
|
17
|
+
auth_token: string;
|
|
18
|
+
org?: string;
|
|
19
|
+
connected_at: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ConnectorStatus {
|
|
22
|
+
id: string;
|
|
23
|
+
status: "connected" | "disconnected";
|
|
24
|
+
lastSync?: string;
|
|
25
|
+
org?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ConnectorHandlerResult {
|
|
28
|
+
status: number;
|
|
29
|
+
body: string;
|
|
30
|
+
contentType?: string;
|
|
31
|
+
redirect?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function loadTokens(): SentryTokens | null;
|
|
34
|
+
export declare function getStatus(): ConnectorStatus;
|
|
35
|
+
export declare function fetchIssueStackTrace(issueIdOrUrl: string, signal?: AbortSignal): Promise<{
|
|
36
|
+
stackTrace: string;
|
|
37
|
+
title: string;
|
|
38
|
+
issueId: string;
|
|
39
|
+
}>;
|
|
40
|
+
export declare function handleSentryAuthorize(): Promise<ConnectorHandlerResult>;
|
|
41
|
+
export declare function handleSentryCallback(code: string | null, state: string | null, error: string | null): Promise<ConnectorHandlerResult>;
|
|
42
|
+
export declare function handleSentryTest(): Promise<ConnectorHandlerResult>;
|
|
43
|
+
export declare function handleSentryDisconnect(): Promise<ConnectorHandlerResult>;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentry connector — routes through Sentry's official MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Endpoint: https://mcp.sentry.dev/mcp
|
|
5
|
+
* Auth: OAuth 2.1 w/ PKCE; dynamic client registration (RFC 7591).
|
|
6
|
+
*
|
|
7
|
+
* HTTP routes (wired in src/server.ts):
|
|
8
|
+
* GET /connections/sentry/authorize — returns { url } for popup
|
|
9
|
+
* GET /connections/sentry/callback — token exchange
|
|
10
|
+
* POST /connections/sentry/test — ping MCP server
|
|
11
|
+
* DELETE /connections/sentry — revoke + delete token
|
|
12
|
+
*
|
|
13
|
+
* MCP tool: fetchSentryIssue — fetches a Sentry issue/event and returns
|
|
14
|
+
* the stack trace string, ready to pass into enrichStackTrace.
|
|
15
|
+
*/
|
|
16
|
+
import { McpClient } from "./mcpClient.js";
|
|
17
|
+
import { completeAuthorize, getAccessToken, loadTokenFile, revoke, startAuthorize, vendorConfig, } from "./mcpOAuth.js";
|
|
18
|
+
const SENTRY_MCP_ENDPOINT = "https://mcp.sentry.dev/mcp";
|
|
19
|
+
// ── MCP client ───────────────────────────────────────────────────────────────
|
|
20
|
+
let _client = null;
|
|
21
|
+
function client() {
|
|
22
|
+
if (!_client) {
|
|
23
|
+
_client = new McpClient(SENTRY_MCP_ENDPOINT, () => getAccessToken("sentry"));
|
|
24
|
+
}
|
|
25
|
+
return _client;
|
|
26
|
+
}
|
|
27
|
+
// ── Back-compat ──────────────────────────────────────────────────────────────
|
|
28
|
+
export function loadTokens() {
|
|
29
|
+
const file = loadTokenFile("sentry");
|
|
30
|
+
if (!file)
|
|
31
|
+
return null;
|
|
32
|
+
return {
|
|
33
|
+
auth_token: file.access_token,
|
|
34
|
+
org: file.profile?.org,
|
|
35
|
+
connected_at: file.connected_at,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function getStatus() {
|
|
39
|
+
const file = loadTokenFile("sentry");
|
|
40
|
+
return {
|
|
41
|
+
id: "sentry",
|
|
42
|
+
status: file ? "connected" : "disconnected",
|
|
43
|
+
lastSync: file?.connected_at,
|
|
44
|
+
org: file?.profile?.org,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// ── Issue fetch ──────────────────────────────────────────────────────────────
|
|
48
|
+
function extractIssueId(issueIdOrUrl) {
|
|
49
|
+
const urlMatch = issueIdOrUrl.match(/\/issues\/(\d+)/);
|
|
50
|
+
if (urlMatch)
|
|
51
|
+
return urlMatch[1];
|
|
52
|
+
const trimmed = issueIdOrUrl.trim();
|
|
53
|
+
if (/^\d+$/.test(trimmed))
|
|
54
|
+
return trimmed;
|
|
55
|
+
throw new Error(`Cannot parse Sentry issue ID from: ${issueIdOrUrl}`);
|
|
56
|
+
}
|
|
57
|
+
function extractOrgSlug(issueIdOrUrl) {
|
|
58
|
+
const m = issueIdOrUrl.match(/https?:\/\/([^.]+)\.sentry\.io/);
|
|
59
|
+
return m ? m[1] : null;
|
|
60
|
+
}
|
|
61
|
+
function buildSentryIssueUrl(issueId, orgSlug) {
|
|
62
|
+
return `https://${orgSlug}.sentry.io/issues/${issueId}/`;
|
|
63
|
+
}
|
|
64
|
+
export async function fetchIssueStackTrace(issueIdOrUrl, signal) {
|
|
65
|
+
if (!loadTokens())
|
|
66
|
+
throw new Error("Sentry not connected. GET /connections/sentry/authorize first.");
|
|
67
|
+
const issueId = extractIssueId(issueIdOrUrl);
|
|
68
|
+
const orgSlug = extractOrgSlug(issueIdOrUrl) ?? loadTokenFile("sentry")?.profile?.org;
|
|
69
|
+
if (!orgSlug)
|
|
70
|
+
throw new Error("Cannot determine Sentry org slug. Pass full sentry.io issue URL.");
|
|
71
|
+
const issueUrl = buildSentryIssueUrl(issueId, orgSlug);
|
|
72
|
+
const res = await client().callTool("get_sentry_resource", { url: issueUrl }, { signal });
|
|
73
|
+
// get_sentry_resource returns markdown text — extract title and stacktrace
|
|
74
|
+
const text = res.content?.[0]?.text ?? "";
|
|
75
|
+
const titleMatch = text.match(/\*\*Description\*\*:\s*(.+)/);
|
|
76
|
+
const title = titleMatch
|
|
77
|
+
? titleMatch[1].trim()
|
|
78
|
+
: `Sentry issue ${issueId}`;
|
|
79
|
+
// Extract stacktrace block
|
|
80
|
+
const stMatch = text.match(/```(?:\w+)?\n([\s\S]*?)\n```/);
|
|
81
|
+
if (!stMatch) {
|
|
82
|
+
throw new Error(`Sentry returned no stack trace for issue ${issueId}`);
|
|
83
|
+
}
|
|
84
|
+
const stackTrace = stMatch[1].trim();
|
|
85
|
+
return { stackTrace, title, issueId };
|
|
86
|
+
}
|
|
87
|
+
// ── HTTP handlers ────────────────────────────────────────────────────────────
|
|
88
|
+
export async function handleSentryAuthorize() {
|
|
89
|
+
try {
|
|
90
|
+
const { url } = await startAuthorize(vendorConfig("sentry"));
|
|
91
|
+
return { status: 302, body: "", redirect: url };
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
return {
|
|
95
|
+
status: 400,
|
|
96
|
+
contentType: "application/json",
|
|
97
|
+
body: JSON.stringify({
|
|
98
|
+
ok: false,
|
|
99
|
+
error: err instanceof Error ? err.message : String(err),
|
|
100
|
+
}),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export async function handleSentryCallback(code, state, error) {
|
|
105
|
+
if (error) {
|
|
106
|
+
return {
|
|
107
|
+
status: 400,
|
|
108
|
+
contentType: "text/html",
|
|
109
|
+
body: `<html><body><h2>Sentry connect failed</h2><pre>${error}</pre></body></html>`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (!code || !state) {
|
|
113
|
+
return {
|
|
114
|
+
status: 400,
|
|
115
|
+
contentType: "text/html",
|
|
116
|
+
body: `<html><body><h2>Sentry connect failed</h2><pre>missing code/state</pre></body></html>`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
await completeAuthorize(vendorConfig("sentry"), code, state);
|
|
121
|
+
// Best-effort org capture
|
|
122
|
+
try {
|
|
123
|
+
const res = await client().callTool("find_organizations", {}, {
|
|
124
|
+
timeoutMs: 10_000,
|
|
125
|
+
});
|
|
126
|
+
const orgs = McpClient.extractJson(res);
|
|
127
|
+
const first = Array.isArray(orgs)
|
|
128
|
+
? orgs[0]
|
|
129
|
+
: (orgs.organizations ?? [])[0];
|
|
130
|
+
const org = first?.slug;
|
|
131
|
+
if (org) {
|
|
132
|
+
const file = loadTokenFile("sentry");
|
|
133
|
+
if (file) {
|
|
134
|
+
const { writeFileSync, mkdirSync } = await import("node:fs");
|
|
135
|
+
const { homedir } = await import("node:os");
|
|
136
|
+
const path = await import("node:path");
|
|
137
|
+
const p = path.join(homedir(), ".patchwork", "tokens", "sentry-mcp.json");
|
|
138
|
+
mkdirSync(path.dirname(p), { recursive: true, mode: 0o700 });
|
|
139
|
+
file.profile = { ...(file.profile ?? {}), org };
|
|
140
|
+
writeFileSync(p, JSON.stringify(file, null, 2), { mode: 0o600 });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// Profile fetch is best-effort
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
status: 200,
|
|
149
|
+
contentType: "text/html",
|
|
150
|
+
body: `<html><body><h2>Sentry connected</h2><script>window.close();</script></body></html>`,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
return {
|
|
155
|
+
status: 400,
|
|
156
|
+
contentType: "text/html",
|
|
157
|
+
body: `<html><body><h2>Sentry connect failed</h2><pre>${err instanceof Error ? err.message : String(err)}</pre></body></html>`,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
export async function handleSentryTest() {
|
|
162
|
+
if (!loadTokens()) {
|
|
163
|
+
return {
|
|
164
|
+
status: 400,
|
|
165
|
+
contentType: "application/json",
|
|
166
|
+
body: JSON.stringify({ ok: false, error: "Sentry not connected" }),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const ok = await client().ping({ timeoutMs: 10_000 });
|
|
171
|
+
return {
|
|
172
|
+
status: ok ? 200 : 400,
|
|
173
|
+
contentType: "application/json",
|
|
174
|
+
body: JSON.stringify({ ok, message: ok ? "connected" : "ping failed" }),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
return {
|
|
179
|
+
status: 400,
|
|
180
|
+
contentType: "application/json",
|
|
181
|
+
body: JSON.stringify({
|
|
182
|
+
ok: false,
|
|
183
|
+
error: err instanceof Error ? err.message : String(err),
|
|
184
|
+
}),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export async function handleSentryDisconnect() {
|
|
189
|
+
await revoke("sentry");
|
|
190
|
+
_client = null;
|
|
191
|
+
return {
|
|
192
|
+
status: 200,
|
|
193
|
+
contentType: "application/json",
|
|
194
|
+
body: JSON.stringify({ ok: true }),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=sentry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentry.js","sourceRoot":"","sources":["../../src/connectors/sentry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProviderDriver, ProviderTaskInput, ProviderTaskResult } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* ApiDriver — uses @anthropic-ai/sdk directly.
|
|
4
|
+
* Requires ANTHROPIC_API_KEY env var and @anthropic-ai/sdk package.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ApiDriver implements ProviderDriver {
|
|
7
|
+
private readonly log;
|
|
8
|
+
readonly name = "api";
|
|
9
|
+
constructor(log: (msg: string) => void);
|
|
10
|
+
run(input: ProviderTaskInput): Promise<ProviderTaskResult>;
|
|
11
|
+
}
|