@cursor/july 0.1.9 → 0.1.11
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/AGENTS.md +1 -0
- package/dist/bin/agent-serve.js +26 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +2 -1
- package/dist/channels/github/types.d.ts +4 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/dispatch.d.ts +13 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +36 -11
- package/dist/channels/slack/eval-directive.d.ts +63 -0
- package/dist/channels/slack/eval-directive.d.ts.map +1 -0
- package/dist/channels/slack/eval-directive.js +283 -0
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +4 -2
- package/dist/channels/slack/types.d.ts +7 -0
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +10 -5
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +10 -5
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.Ciosf24M.js → app.BcXUGca7.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BIbvK8M1.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BcRDly7n.js → VPLocalSearchBox.CWur6XGZ.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CMpbjdfx.js → theme.BnvulOX2.js} +2 -2
- package/dist/docs/assets/{deployment.md.DC5-ImcM.js → deployment.md.TecHo0_2.js} +3 -3
- package/dist/docs/assets/{deployment.md.DC5-ImcM.lean.js → deployment.md.TecHo0_2.lean.js} +1 -1
- package/dist/docs/assets/guides_mcp-oauth.md.DqmEOQY1.js +29 -0
- package/dist/docs/assets/guides_mcp-oauth.md.DqmEOQY1.lean.js +1 -0
- package/dist/docs/assets/{index.md.COiu-1jL.js → index.md.t0TM2Qzz.js} +3 -3
- package/dist/docs/assets/{index.md.COiu-1jL.lean.js → index.md.t0TM2Qzz.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.D189RBCH.js → reference_cli.md.B74NrVzb.js} +5 -4
- package/dist/docs/assets/{reference_cli.md.D189RBCH.lean.js → reference_cli.md.B74NrVzb.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.zaEYCLHT.js → reference_connections.md.CsSr3rDz.js} +9 -4
- package/dist/docs/assets/{reference_connections.md.zaEYCLHT.lean.js → reference_connections.md.CsSr3rDz.lean.js} +1 -1
- package/dist/docs/assets/reference_prompt.md.BaiweQxE.js +1 -0
- package/dist/docs/assets/reference_prompt.md.BaiweQxE.lean.js +1 -0
- package/dist/docs/assets/{reference_tools.md.CqgJroI0.js → reference_tools.md.BRSDnTbN.js} +16 -3
- package/dist/docs/assets/{reference_tools.md.CqgJroI0.lean.js → reference_tools.md.BRSDnTbN.lean.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.DkovjS7h.js → troubleshooting.md.CmQkmnzC.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.DkovjS7h.lean.js → troubleshooting.md.CmQkmnzC.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/evals.html +4 -4
- package/dist/docs/example-agents/approval-buddy.html +4 -4
- package/dist/docs/example-agents/benny.html +4 -4
- package/dist/docs/example-agents/bugbot.html +4 -4
- package/dist/docs/example-agents/codebase-wiki.html +4 -4
- package/dist/docs/example-agents/codeowners-review.html +4 -4
- package/dist/docs/example-agents/concierge.html +4 -4
- package/dist/docs/example-agents/fsd.html +4 -4
- package/dist/docs/example-agents/index.html +4 -4
- package/dist/docs/example-agents/knowledge-base.html +4 -4
- package/dist/docs/example-agents/oncall.html +4 -4
- package/dist/docs/example-agents/security-reviewer.html +4 -4
- package/dist/docs/example-agents/slack-agent.html +4 -4
- package/dist/docs/example-agents/weather-agent.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +53 -0
- package/dist/docs/guides/slack.html +4 -4
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +8 -7
- package/dist/docs/reference/connections.html +13 -8
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +4 -4
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.html +33 -0
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +5 -5
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +20 -7
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/evals.d.ts +39 -0
- package/dist/evals.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +7 -4
- package/dist/internal/cli-mcp-oauth.d.ts +16 -0
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -0
- package/dist/internal/cli-mcp-oauth.js +194 -0
- package/dist/internal/cli-mcp.d.ts +4 -1
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +19 -1
- package/dist/internal/corp-ca.d.ts +9 -0
- package/dist/internal/corp-ca.d.ts.map +1 -0
- package/dist/internal/corp-ca.js +44 -0
- package/dist/internal/cursor/account-mcp.d.ts +17 -4
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +105 -17
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +64 -10
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/logs-client.js +1 -1
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +49 -26
- package/dist/internal/mcp-oauth.d.ts +88 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -0
- package/dist/internal/mcp-oauth.js +385 -0
- package/dist/internal/resolved-connections.d.ts +6 -0
- package/dist/internal/resolved-connections.d.ts.map +1 -1
- package/dist/internal/resolved-connections.js +10 -3
- package/dist/internal/sdk-runner.d.ts +9 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +28 -2
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +24 -6
- package/dist/internal/session-engine.d.ts +30 -10
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +166 -74
- package/dist/internal/sessions-client.d.ts +16 -2
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +30 -13
- package/dist/internal/storage-coordinator.d.ts +11 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +30 -0
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +8 -4
- package/dist/internal/turn-governor.d.ts +54 -0
- package/dist/internal/turn-governor.d.ts.map +1 -0
- package/dist/internal/turn-governor.js +111 -0
- package/dist/playground/assets/{index-C0-QEG4O.js → index-BIGLubwK.js} +46 -46
- package/dist/playground/assets/{index-z3JY9O2x.css → index-C17ZQKDG.css} +1 -1
- package/dist/playground/index.html +2 -2
- package/dist/prompt.d.ts +39 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +70 -0
- package/dist/storage-backends/cursor-hosted.d.ts +10 -0
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +14 -0
- package/dist/types.d.ts +93 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/docs/README.md +4 -0
- package/docs/deployment.md +6 -1
- package/docs/guides/mcp-oauth.md +157 -0
- package/docs/reference/cli.md +30 -0
- package/docs/reference/connections.md +32 -2
- package/docs/reference/prompt.md +47 -0
- package/docs/reference/tools.md +21 -0
- package/docs/troubleshooting.md +11 -0
- package/package.json +9 -2
- package/skills/create-agent/SKILL.md +7 -3
- package/skills/framework-map/SKILL.md +1 -0
- package/skills/mcp-auth/SKILL.md +138 -0
- package/src/bin/agent-serve.ts +30 -3
- package/src/channels/github/github-channel.ts +2 -0
- package/src/channels/github/types.ts +4 -0
- package/src/channels/slack/cursor-account.ts +2 -0
- package/src/channels/slack/dispatch.ts +49 -0
- package/src/channels/slack/eval-directive.ts +348 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/slack-channel.ts +3 -0
- package/src/channels/slack/types.ts +7 -0
- package/src/connections.ts +10 -5
- package/src/evals.ts +43 -0
- package/src/index.ts +3 -0
- package/src/internal/cli-ax.ts +10 -4
- package/src/internal/cli-mcp-oauth.ts +254 -0
- package/src/internal/cli-mcp.ts +25 -2
- package/src/internal/cursor/account-mcp.ts +153 -41
- package/src/internal/discovery.ts +70 -8
- package/src/internal/distribution.ts +1 -0
- package/src/internal/logs-client.ts +1 -1
- package/src/internal/mcp-host.ts +33 -9
- package/src/internal/mcp-oauth.ts +496 -0
- package/src/internal/resolved-connections.ts +20 -5
- package/src/internal/sdk-runner.ts +37 -1
- package/src/internal/server.ts +28 -6
- package/src/internal/session-engine.ts +192 -76
- package/src/internal/sessions-client.ts +51 -15
- package/src/internal/storage-coordinator.ts +36 -0
- package/src/internal/stream-progress.ts +8 -0
- package/src/internal/turn-governor.ts +145 -0
- package/src/prompt.ts +83 -0
- package/src/storage-backends/cursor-hosted.ts +21 -0
- package/src/types.ts +92 -6
- package/dist/docs/assets/chunks/@localSearchIndexroot.D154Detj.js +0 -1
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-side MCP OAuth for `defineConnection({ url, oauth: true })`.
|
|
3
|
+
* Local: mcp-auth.json. Prod secrets: `mcp oauth <name> --store`.
|
|
4
|
+
*/
|
|
5
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
import { execFile } from "node:child_process";
|
|
15
|
+
import { randomUUID } from "node:crypto";
|
|
16
|
+
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
17
|
+
import { createServer } from "node:http";
|
|
18
|
+
import { dirname, join } from "node:path";
|
|
19
|
+
import { configDirPath } from "./cursor/credentials.js";
|
|
20
|
+
export const MCP_OAUTH_CALLBACK_PORT = 8787;
|
|
21
|
+
export const MCP_OAUTH_CALLBACK_PATH = "/callback";
|
|
22
|
+
export const MCP_OAUTH_CALLBACK_URL = `http://localhost:${MCP_OAUTH_CALLBACK_PORT}${MCP_OAUTH_CALLBACK_PATH}`;
|
|
23
|
+
/** `anytool` → `MCP_OAUTH_ANYTOOL`. */
|
|
24
|
+
export function mcpOauthEnvPrefix(connection) {
|
|
25
|
+
const key = connection
|
|
26
|
+
.trim()
|
|
27
|
+
.toUpperCase()
|
|
28
|
+
.replace(/[^A-Z0-9]+/g, "_")
|
|
29
|
+
.replace(/^_+|_+$/g, "");
|
|
30
|
+
return `MCP_OAUTH_${key.length > 0 ? key : "CONNECTION"}`;
|
|
31
|
+
}
|
|
32
|
+
export function mcpOauthSecretNames(connection) {
|
|
33
|
+
const prefix = mcpOauthEnvPrefix(connection);
|
|
34
|
+
return {
|
|
35
|
+
accessToken: `${prefix}_ACCESS_TOKEN`,
|
|
36
|
+
refreshToken: `${prefix}_REFRESH_TOKEN`,
|
|
37
|
+
clientId: `${prefix}_CLIENT_ID`,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function tokensFromEnv(connection, env = process.env) {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
const names = mcpOauthSecretNames(connection);
|
|
43
|
+
const access = (_a = env[names.accessToken]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
44
|
+
if (access === undefined || access === "") {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const refresh = (_b = env[names.refreshToken]) === null || _b === void 0 ? void 0 : _b.trim();
|
|
48
|
+
return {
|
|
49
|
+
access_token: access,
|
|
50
|
+
refresh_token: refresh === undefined || refresh === "" ? undefined : refresh,
|
|
51
|
+
token_type: "Bearer",
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function clientIdFromEnv(connection, env = process.env) {
|
|
55
|
+
var _a;
|
|
56
|
+
const clientId = (_a = env[mcpOauthSecretNames(connection).clientId]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
57
|
+
if (clientId === undefined || clientId === "") {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
client_id: clientId,
|
|
62
|
+
redirect_uris: [MCP_OAUTH_CALLBACK_URL],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const locks = new Map();
|
|
66
|
+
/** Sibling of `credentials.json` under `~/.config/agent-serve/`. */
|
|
67
|
+
export function defaultMcpAuthPath() {
|
|
68
|
+
return join(configDirPath(), "mcp-auth.json");
|
|
69
|
+
}
|
|
70
|
+
/** Canonical MCP resource key for binding stored tokens to a server URL. */
|
|
71
|
+
export function normalizeMcpResourceUrl(url) {
|
|
72
|
+
const parsed = new URL(url);
|
|
73
|
+
parsed.hash = "";
|
|
74
|
+
parsed.search = "";
|
|
75
|
+
// Drop default ports so http://h:80 and http://h match.
|
|
76
|
+
if ((parsed.protocol === "https:" && parsed.port === "443") ||
|
|
77
|
+
(parsed.protocol === "http:" && parsed.port === "80")) {
|
|
78
|
+
parsed.port = "";
|
|
79
|
+
}
|
|
80
|
+
let path = parsed.pathname;
|
|
81
|
+
if (path.length > 1 && path.endsWith("/")) {
|
|
82
|
+
path = path.slice(0, -1);
|
|
83
|
+
}
|
|
84
|
+
return `${parsed.origin}${path === "/" ? "" : path}`;
|
|
85
|
+
}
|
|
86
|
+
export class FileMcpOAuthStore {
|
|
87
|
+
constructor(path = defaultMcpAuthPath()) {
|
|
88
|
+
this.path = path;
|
|
89
|
+
}
|
|
90
|
+
loadTokens(id, resourceUrl) {
|
|
91
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
var _a;
|
|
93
|
+
return (_a = (yield this.entryFor(id, resourceUrl))) === null || _a === void 0 ? void 0 : _a.tokens;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
loadClientInformation(id, resourceUrl) {
|
|
97
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
+
var _a;
|
|
99
|
+
return (_a = (yield this.entryFor(id, resourceUrl))) === null || _a === void 0 ? void 0 : _a.clientInfo;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
saveTokens(id, resourceUrl, tokens) {
|
|
103
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
yield this.update(id, resourceUrl, (entry) => {
|
|
105
|
+
entry.tokens = tokens;
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
saveClientInformation(id, resourceUrl, clientInfo) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
yield this.update(id, resourceUrl, (entry) => {
|
|
112
|
+
entry.clientInfo = clientInfo;
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
deleteCredentials(id) {
|
|
117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
yield this.withLock(() => __awaiter(this, void 0, void 0, function* () {
|
|
119
|
+
const data = yield this.read();
|
|
120
|
+
delete data[id];
|
|
121
|
+
yield this.write(data);
|
|
122
|
+
}));
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
entryFor(id, resourceUrl) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
const entry = (yield this.read())[id];
|
|
128
|
+
if (entry === undefined) {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
const bound = entry.resourceUrl;
|
|
132
|
+
if (bound === undefined || bound !== normalizeMcpResourceUrl(resourceUrl)) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
return entry;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
update(id, resourceUrl, mutate) {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
const normalized = normalizeMcpResourceUrl(resourceUrl);
|
|
141
|
+
yield this.withLock(() => __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
const data = yield this.read();
|
|
143
|
+
const existing = data[id];
|
|
144
|
+
const entry = (existing === null || existing === void 0 ? void 0 : existing.resourceUrl) === normalized ? Object.assign({}, existing) : {};
|
|
145
|
+
entry.resourceUrl = normalized;
|
|
146
|
+
mutate(entry);
|
|
147
|
+
data[id] = entry;
|
|
148
|
+
yield this.write(data);
|
|
149
|
+
}));
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
read() {
|
|
153
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
154
|
+
var _a;
|
|
155
|
+
if (this.cache !== undefined) {
|
|
156
|
+
return this.cache;
|
|
157
|
+
}
|
|
158
|
+
(_a = this.loading) !== null && _a !== void 0 ? _a : (this.loading = this.readDisk().then((data) => {
|
|
159
|
+
this.cache = data;
|
|
160
|
+
return data;
|
|
161
|
+
}));
|
|
162
|
+
return this.loading;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
readDisk() {
|
|
166
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
167
|
+
try {
|
|
168
|
+
const parsed = JSON.parse(yield readFile(this.path, "utf8"));
|
|
169
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
170
|
+
return {};
|
|
171
|
+
}
|
|
172
|
+
return parsed;
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
if (typeof error === "object" &&
|
|
176
|
+
error !== null &&
|
|
177
|
+
"code" in error &&
|
|
178
|
+
error.code === "ENOENT") {
|
|
179
|
+
return {};
|
|
180
|
+
}
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
write(data) {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
this.cache = data;
|
|
188
|
+
yield mkdir(dirname(this.path), { recursive: true, mode: 0o700 });
|
|
189
|
+
yield writeFile(this.path, `${JSON.stringify(data, null, 2)}\n`, {
|
|
190
|
+
mode: 0o600,
|
|
191
|
+
});
|
|
192
|
+
yield chmod(this.path, 0o600);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
withLock(fn) {
|
|
196
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
197
|
+
var _a;
|
|
198
|
+
const prev = (_a = locks.get(this.path)) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
199
|
+
let release;
|
|
200
|
+
locks.set(this.path, new Promise((resolve) => {
|
|
201
|
+
release = resolve;
|
|
202
|
+
}));
|
|
203
|
+
try {
|
|
204
|
+
yield prev;
|
|
205
|
+
return yield fn();
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
release();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
export class HostMcpOAuthProvider {
|
|
214
|
+
constructor(args) {
|
|
215
|
+
var _a;
|
|
216
|
+
this.args = args;
|
|
217
|
+
this.tokensValue = args.tokens;
|
|
218
|
+
this.clientInfo = args.clientInformation;
|
|
219
|
+
this.meta = {
|
|
220
|
+
redirect_uris: [(_a = args.redirectUrl) !== null && _a !== void 0 ? _a : MCP_OAUTH_CALLBACK_URL],
|
|
221
|
+
token_endpoint_auth_method: "none",
|
|
222
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
223
|
+
response_types: ["code"],
|
|
224
|
+
client_name: "agentkit",
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
get redirectUrl() {
|
|
228
|
+
var _a;
|
|
229
|
+
return (_a = this.args.redirectUrl) !== null && _a !== void 0 ? _a : MCP_OAUTH_CALLBACK_URL;
|
|
230
|
+
}
|
|
231
|
+
get clientMetadata() {
|
|
232
|
+
return this.meta;
|
|
233
|
+
}
|
|
234
|
+
get lastRedirectUrl() {
|
|
235
|
+
return this.redirect;
|
|
236
|
+
}
|
|
237
|
+
state() {
|
|
238
|
+
return randomUUID();
|
|
239
|
+
}
|
|
240
|
+
clientInformation() {
|
|
241
|
+
return this.clientInfo;
|
|
242
|
+
}
|
|
243
|
+
saveClientInformation(info) {
|
|
244
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
245
|
+
this.clientInfo = info;
|
|
246
|
+
yield this.args.store.saveClientInformation(this.args.identifier, this.args.resourceUrl, info);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
tokens() {
|
|
250
|
+
return this.tokensValue;
|
|
251
|
+
}
|
|
252
|
+
saveTokens(tokens) {
|
|
253
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
254
|
+
this.tokensValue = tokens;
|
|
255
|
+
yield this.args.store.saveTokens(this.args.identifier, this.args.resourceUrl, tokens);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
redirectToAuthorization(url) {
|
|
259
|
+
var _a, _b;
|
|
260
|
+
this.redirect = url;
|
|
261
|
+
(_b = (_a = this.args).onRedirect) === null || _b === void 0 ? void 0 : _b.call(_a, url);
|
|
262
|
+
}
|
|
263
|
+
saveCodeVerifier(codeVerifier) {
|
|
264
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
265
|
+
this.verifier = codeVerifier;
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
codeVerifier() {
|
|
269
|
+
if (this.verifier === undefined) {
|
|
270
|
+
throw new Error("No PKCE code verifier saved for this OAuth attempt.");
|
|
271
|
+
}
|
|
272
|
+
return this.verifier;
|
|
273
|
+
}
|
|
274
|
+
invalidateCredentials(scope) {
|
|
275
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
276
|
+
if (scope === "tokens" || scope === "all") {
|
|
277
|
+
this.tokensValue = undefined;
|
|
278
|
+
}
|
|
279
|
+
if (scope === "client" || scope === "all") {
|
|
280
|
+
this.clientInfo = undefined;
|
|
281
|
+
}
|
|
282
|
+
if (scope === "verifier" || scope === "all") {
|
|
283
|
+
this.verifier = undefined;
|
|
284
|
+
this.redirect = undefined;
|
|
285
|
+
}
|
|
286
|
+
if (scope === "all") {
|
|
287
|
+
yield this.args.store.deleteCredentials(this.args.identifier);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
export function createHostMcpOAuthProvider(args) {
|
|
293
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
294
|
+
var _a;
|
|
295
|
+
const store = (_a = args.store) !== null && _a !== void 0 ? _a : new FileMcpOAuthStore();
|
|
296
|
+
const [fileTokens, fileClient] = yield Promise.all([
|
|
297
|
+
store.loadTokens(args.identifier, args.resourceUrl),
|
|
298
|
+
store.loadClientInformation(args.identifier, args.resourceUrl),
|
|
299
|
+
]);
|
|
300
|
+
return new HostMcpOAuthProvider({
|
|
301
|
+
identifier: args.identifier,
|
|
302
|
+
resourceUrl: args.resourceUrl,
|
|
303
|
+
store,
|
|
304
|
+
tokens: fileTokens !== null && fileTokens !== void 0 ? fileTokens : tokensFromEnv(args.identifier),
|
|
305
|
+
clientInformation: fileClient !== null && fileClient !== void 0 ? fileClient : clientIdFromEnv(args.identifier),
|
|
306
|
+
onRedirect: args.onRedirect,
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
export function waitForMcpOAuthCallback(args) {
|
|
311
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
312
|
+
var _a, _b, _c;
|
|
313
|
+
const port = (_a = args === null || args === void 0 ? void 0 : args.port) !== null && _a !== void 0 ? _a : MCP_OAUTH_CALLBACK_PORT;
|
|
314
|
+
const path = (_b = args === null || args === void 0 ? void 0 : args.path) !== null && _b !== void 0 ? _b : MCP_OAUTH_CALLBACK_PATH;
|
|
315
|
+
const timeoutMs = (_c = args === null || args === void 0 ? void 0 : args.timeoutMs) !== null && _c !== void 0 ? _c : 5 * 60 * 1000;
|
|
316
|
+
return new Promise((resolve, reject) => {
|
|
317
|
+
let done = false;
|
|
318
|
+
const finish = (result, error) => {
|
|
319
|
+
if (done) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
done = true;
|
|
323
|
+
clearTimeout(timer);
|
|
324
|
+
server.close();
|
|
325
|
+
if (error !== undefined) {
|
|
326
|
+
reject(error);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (result !== undefined) {
|
|
330
|
+
resolve(result);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
const server = createServer((req, res) => {
|
|
334
|
+
var _a, _b;
|
|
335
|
+
if (req.url === "/favicon.ico") {
|
|
336
|
+
res.writeHead(404).end();
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const url = new URL((_a = req.url) !== null && _a !== void 0 ? _a : "", `http://localhost:${port}`);
|
|
340
|
+
if (url.pathname !== path) {
|
|
341
|
+
res.writeHead(404).end("Not found");
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const code = url.searchParams.get("code");
|
|
345
|
+
const oauthError = url.searchParams.get("error");
|
|
346
|
+
const state = (_b = url.searchParams.get("state")) !== null && _b !== void 0 ? _b : undefined;
|
|
347
|
+
if (code) {
|
|
348
|
+
res
|
|
349
|
+
.writeHead(200, { "content-type": "text/html; charset=utf-8" })
|
|
350
|
+
.end("<!doctype html><html><body><h1>Authorized</h1><p>Return to agentkit.</p></body></html>");
|
|
351
|
+
finish({ code, state });
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
res
|
|
355
|
+
.writeHead(400, { "content-type": "text/html; charset=utf-8" })
|
|
356
|
+
.end(`<!doctype html><html><body><h1>Authorization failed</h1><p>${oauthError !== null && oauthError !== void 0 ? oauthError : "missing code"}</p></body></html>`);
|
|
357
|
+
finish(undefined, new Error(`OAuth authorization failed: ${oauthError !== null && oauthError !== void 0 ? oauthError : "missing code"}`));
|
|
358
|
+
});
|
|
359
|
+
const timer = setTimeout(() => {
|
|
360
|
+
finish(undefined, new Error(`Timed out waiting for OAuth callback on http://localhost:${port}${path}`));
|
|
361
|
+
}, timeoutMs);
|
|
362
|
+
server.on("error", (error) => {
|
|
363
|
+
finish(undefined, new Error(`OAuth callback port ${port} failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
364
|
+
});
|
|
365
|
+
server.listen(port, "127.0.0.1");
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
export function openBrowser(url) {
|
|
370
|
+
const parsed = new URL(url);
|
|
371
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
372
|
+
throw new Error(`Refusing to open non-http(s) authorization URL: ${parsed.protocol}`);
|
|
373
|
+
}
|
|
374
|
+
const href = parsed.href;
|
|
375
|
+
if (process.platform === "darwin") {
|
|
376
|
+
execFile("open", [href], () => undefined);
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
if (process.platform === "win32") {
|
|
380
|
+
// Avoid `cmd /c start` — authorize URLs with `&` are shell-metachar risks.
|
|
381
|
+
execFile("rundll32", ["url.dll,FileProtocolHandler", href], () => undefined);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
execFile("xdg-open", [href], () => undefined);
|
|
385
|
+
}
|
|
@@ -25,6 +25,12 @@ export declare function assertCloudCanHonorAccountServersFilters(args: {
|
|
|
25
25
|
/** Fail closed when anonymous HTTP admission would expose account connectors. */
|
|
26
26
|
export declare function assertAccountConnectionsNotAnonymous(args: {
|
|
27
27
|
allowAnonymous?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Opt in when every admitted caller is already trusted (e.g. behind an
|
|
30
|
+
* authenticating proxy / hosted alias token). Same trust model as
|
|
31
|
+
* `--allow-anonymous-cursor-github`.
|
|
32
|
+
*/
|
|
33
|
+
allowAnonymousCursorAccountMcp?: boolean;
|
|
28
34
|
hasAccountConnections: boolean;
|
|
29
35
|
}): void;
|
|
30
36
|
export declare function resolveMountConnections(args: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolved-connections.d.ts","sourceRoot":"","sources":["../../src/internal/resolved-connections.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAE5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,+EAA+E;AAC/E,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"resolved-connections.d.ts","sourceRoot":"","sources":["../../src/internal/resolved-connections.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAE5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,+EAA+E;AAC/E,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CA4BP;AAED,qEAAqE;AACrE,wBAAgB,wCAAwC,CAAC,IAAI,EAAE;IAC7D,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IAC3B,mBAAmB,EAAE,SAAS,wBAAwB,EAAE,CAAC;CAC1D,GAAG,IAAI,CAmBP;AAED,iFAAiF;AACjF,wBAAgB,oCAAoC,CAAC,IAAI,EAAE;IACzD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,qBAAqB,EAAE,OAAO,CAAC;CAChC,GAAG,IAAI,CAUP;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC,GAAG,wBAAwB,EAAE,CA6C7B"}
|
|
@@ -19,7 +19,10 @@ export function validateMountConnectionsConfig(args) {
|
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
const label = args.slug === "" ? args.project.name : args.slug;
|
|
22
|
-
const
|
|
22
|
+
const hostOnlyNames = new Set(agent.connections
|
|
23
|
+
.filter((connection) => connection.hostOnly === true)
|
|
24
|
+
.map((connection) => connection.name));
|
|
25
|
+
const filteredRefs = args.accountRefs.filter((ref) => ref.servers !== undefined && !hostOnlyNames.has(ref.name));
|
|
23
26
|
if (filteredRefs.length === 0) {
|
|
24
27
|
return;
|
|
25
28
|
}
|
|
@@ -43,9 +46,13 @@ export function assertCloudCanHonorAccountServersFilters(args) {
|
|
|
43
46
|
}
|
|
44
47
|
/** Fail closed when anonymous HTTP admission would expose account connectors. */
|
|
45
48
|
export function assertAccountConnectionsNotAnonymous(args) {
|
|
46
|
-
if (args.allowAnonymous
|
|
47
|
-
|
|
49
|
+
if (args.allowAnonymous !== true || !args.hasAccountConnections) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (args.allowAnonymousCursorAccountMcp === true) {
|
|
53
|
+
return;
|
|
48
54
|
}
|
|
55
|
+
throw new Error("[agentkit] --allow-anonymous cannot be used with Cursor account MCP connections (defineConnection({ cursorAccount: true })); use --bearer-token, or opt in with --allow-anonymous-cursor-account-mcp behind a trusted boundary.");
|
|
49
56
|
}
|
|
50
57
|
export function resolveMountConnections(args) {
|
|
51
58
|
const agent = args.project.agent;
|
|
@@ -21,6 +21,8 @@ export interface CursorSdkRunnerOptions {
|
|
|
21
21
|
* `LocalAgentStore` for heavy multi-session concurrency.
|
|
22
22
|
*/
|
|
23
23
|
store?: LocalAgentStore;
|
|
24
|
+
/** Diagnostics for degraded paths (resume-miss fallback). */
|
|
25
|
+
logger?: (line: string) => void;
|
|
24
26
|
}
|
|
25
27
|
export declare class CursorSdkRunner implements AgentRunner {
|
|
26
28
|
private readonly options;
|
|
@@ -37,5 +39,12 @@ export declare class CursorSdkRunner implements AgentRunner {
|
|
|
37
39
|
}
|
|
38
40
|
/** Cloud agent ids minted by the server are `bc-…`; those always resume. */
|
|
39
41
|
export declare function isServerMintedCloudAgentId(id: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* `Agent.resume` on a store with no row for the agent ("Agent <id> not
|
|
44
|
+
* found", surfaced by every built-in {@link LocalAgentStore} backend).
|
|
45
|
+
* Deliberately narrow: transient store/transport failures must propagate
|
|
46
|
+
* rather than silently fork the thread onto a fresh conversation.
|
|
47
|
+
*/
|
|
48
|
+
export declare function isLocalAgentNotFoundError(error: unknown, agentId: string): boolean;
|
|
40
49
|
export declare function toModelSelection(model: ModelSetting): ModelSelection;
|
|
41
50
|
//# sourceMappingURL=sdk-runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../src/internal/sdk-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAC;AAErB,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../src/internal/sdk-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,cAAc,EAGpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAC;AAErB,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,qBAAa,eAAgB,YAAW,WAAW;IAIrC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+C;IAEtE,YAA6B,OAAO,GAAE,sBAA2B,EAAI;IAE/D,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CA0D9D;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ7B;IAED,OAAO,CAAC,QAAQ;YAYF,SAAS;YA2BT,cAAc;YAyCd,cAAc;IAqC5B,OAAO,CAAC,QAAQ;CAUjB;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAMT;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,cAAc,CAQpE"}
|
|
@@ -121,7 +121,7 @@ export class CursorSdkRunner {
|
|
|
121
121
|
}
|
|
122
122
|
openLocalAgent(request, shared) {
|
|
123
123
|
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
-
var _a, _b, _c;
|
|
124
|
+
var _a, _b, _c, _d;
|
|
125
125
|
const store = (_a = this.options.store) !== null && _a !== void 0 ? _a : (yield this.getStore(request.runnerStateDir));
|
|
126
126
|
const options = Object.assign(Object.assign({}, shared), { local: {
|
|
127
127
|
cwd: request.workspaceDir,
|
|
@@ -131,7 +131,22 @@ export class CursorSdkRunner {
|
|
|
131
131
|
if (request.isFirstTurn || request.sdkAgentId === undefined) {
|
|
132
132
|
return Agent.create(Object.assign(Object.assign({}, options), { agentId: (_b = request.sdkAgentId) !== null && _b !== void 0 ? _b : request.sessionId }));
|
|
133
133
|
}
|
|
134
|
-
|
|
134
|
+
const agentId = (_c = request.sdkAgentId) !== null && _c !== void 0 ? _c : request.sessionId;
|
|
135
|
+
try {
|
|
136
|
+
return yield Agent.resume(agentId, options);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (!isLocalAgentNotFoundError(error, agentId)) {
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
// Host replacement: the session record survived in durable storage,
|
|
143
|
+
// but the conversation store died with the old pod. A fresh
|
|
144
|
+
// conversation under the same id beats failing this thread's turns
|
|
145
|
+
// forever ("Agent … not found" on every follow-up). The channel's
|
|
146
|
+
// warm-turn prompt context re-hydrates the thread history.
|
|
147
|
+
((_d = this.options.logger) !== null && _d !== void 0 ? _d : (() => { }))(`[agentkit] no stored conversation for ${agentId} on this host; starting a fresh one`);
|
|
148
|
+
return Agent.create(Object.assign(Object.assign({}, options), { agentId }));
|
|
149
|
+
}
|
|
135
150
|
});
|
|
136
151
|
}
|
|
137
152
|
openCloudAgent(request, shared) {
|
|
@@ -175,6 +190,17 @@ export class CursorSdkRunner {
|
|
|
175
190
|
export function isServerMintedCloudAgentId(id) {
|
|
176
191
|
return id.startsWith("bc-");
|
|
177
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* `Agent.resume` on a store with no row for the agent ("Agent <id> not
|
|
195
|
+
* found", surfaced by every built-in {@link LocalAgentStore} backend).
|
|
196
|
+
* Deliberately narrow: transient store/transport failures must propagate
|
|
197
|
+
* rather than silently fork the thread onto a fresh conversation.
|
|
198
|
+
*/
|
|
199
|
+
export function isLocalAgentNotFoundError(error, agentId) {
|
|
200
|
+
return (error instanceof Error &&
|
|
201
|
+
error.message.includes(agentId) &&
|
|
202
|
+
/\bnot found\b/i.test(error.message));
|
|
203
|
+
}
|
|
178
204
|
export function toModelSelection(model) {
|
|
179
205
|
if (typeof model === "string") {
|
|
180
206
|
return { id: model };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAmFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAunB3B"}
|
package/dist/internal/server.js
CHANGED
|
@@ -42,7 +42,7 @@ import { assertSlackCursorAgentName } from "../channels/slack/types.js";
|
|
|
42
42
|
import { allowAll, bearerAuth, localDevStrict } from "../channels.js";
|
|
43
43
|
import { CursorAccountMcpBridge, collectCursorAccountConnections, cursorAccountMcpPath, } from "./cursor/account-mcp.js";
|
|
44
44
|
import { CursorBackendClient } from "./cursor/backend-client.js";
|
|
45
|
-
import {
|
|
45
|
+
import { cursorExternalApiUrl, resolveApiKey, SIGN_IN_HINT, } from "./cursor/credentials.js";
|
|
46
46
|
import { CursorGithubCredentialProvider } from "./cursor/github-credentials.js";
|
|
47
47
|
import { CursorEventRelay, formatCursorScmEventLog, scmMetadataToGitHubPayload, } from "./cursor-event-relay.js";
|
|
48
48
|
import { CursorSlackRelay, createCursorSlackApiCaller, formatCursorSlackEventLog, } from "./cursor-slack-relay.js";
|
|
@@ -163,7 +163,7 @@ export function startServer(mounts_1) {
|
|
|
163
163
|
if (options.allowAnonymous === true) {
|
|
164
164
|
logger("[agentkit] warning: --allow-anonymous admits every HTTP caller as the same principal; use only on a trusted network (e.g. Tailscale) and prefer --bearer-token for shared hosts");
|
|
165
165
|
}
|
|
166
|
-
const runner = (_l = options.runner) !== null && _l !== void 0 ? _l : new CursorSdkRunner(accountKey === undefined ? {} : { apiKey: accountKey.apiKey });
|
|
166
|
+
const runner = (_l = options.runner) !== null && _l !== void 0 ? _l : new CursorSdkRunner(Object.assign(Object.assign({}, (accountKey === undefined ? {} : { apiKey: accountKey.apiKey })), { logger }));
|
|
167
167
|
const router = new Router();
|
|
168
168
|
const runtimes = [];
|
|
169
169
|
const channelStopHooks = [];
|
|
@@ -179,8 +179,14 @@ export function startServer(mounts_1) {
|
|
|
179
179
|
const accountRefsBySlug = collectCursorAccountConnections(mounts);
|
|
180
180
|
assertAccountConnectionsNotAnonymous({
|
|
181
181
|
allowAnonymous: options.allowAnonymous,
|
|
182
|
+
allowAnonymousCursorAccountMcp: options.allowAnonymousCursorAccountMcp,
|
|
182
183
|
hasAccountConnections: accountRefsBySlug.size > 0,
|
|
183
184
|
});
|
|
185
|
+
if (options.allowAnonymous === true &&
|
|
186
|
+
options.allowAnonymousCursorAccountMcp === true &&
|
|
187
|
+
accountRefsBySlug.size > 0) {
|
|
188
|
+
logger("[agentkit] warning: --allow-anonymous-cursor-account-mcp — every admitted HTTP caller can drive Cursor account MCP connectors; serve this only behind a trusted boundary (e.g. an SSO proxy or hosted alias token)");
|
|
189
|
+
}
|
|
184
190
|
let accountBridge;
|
|
185
191
|
if (accountRefsBySlug.size > 0) {
|
|
186
192
|
if (accountKey === undefined) {
|
|
@@ -236,6 +242,12 @@ export function startServer(mounts_1) {
|
|
|
236
242
|
cancelForContinuation: (token, reason) => reminderRunner.cancelForContinuation(token, reason),
|
|
237
243
|
dispatch: (id) => reminderRunner.dispatch(id),
|
|
238
244
|
});
|
|
245
|
+
engine.setEvals({
|
|
246
|
+
list: () => evalRuns.list(),
|
|
247
|
+
get: (runId) => evalRuns.get(runId),
|
|
248
|
+
listRunsWithActive: () => evalRuns.listRunsWithActive(),
|
|
249
|
+
start: (input) => evalRuns.start(input),
|
|
250
|
+
});
|
|
239
251
|
const runtime = {
|
|
240
252
|
slug,
|
|
241
253
|
project,
|
|
@@ -696,8 +708,12 @@ function mountAgentRoutes(router, runtime, args) {
|
|
|
696
708
|
(relaxSessionReadAuthBeyondLoopback ||
|
|
697
709
|
(typeof ctx.requestIp === "string" &&
|
|
698
710
|
isLoopbackAddress(ctx.requestIp)));
|
|
711
|
+
const listed = yield engine.listSessionsWithSource(ctx.auth, {
|
|
712
|
+
includeAll,
|
|
713
|
+
});
|
|
699
714
|
return jsonResponse({
|
|
700
|
-
sessions:
|
|
715
|
+
sessions: listed.sessions,
|
|
716
|
+
source: listed.source,
|
|
701
717
|
});
|
|
702
718
|
}),
|
|
703
719
|
});
|
|
@@ -1217,7 +1233,7 @@ function collectCursorSlackTargets(runtimes) {
|
|
|
1217
1233
|
*/
|
|
1218
1234
|
function startCursorSlackRelay(input) {
|
|
1219
1235
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1220
|
-
var _a
|
|
1236
|
+
var _a;
|
|
1221
1237
|
const { options, runtimes, accountKey, logger } = input;
|
|
1222
1238
|
const targets = collectCursorSlackTargets(runtimes);
|
|
1223
1239
|
if (targets.length === 0) {
|
|
@@ -1226,8 +1242,10 @@ function startCursorSlackRelay(input) {
|
|
|
1226
1242
|
if (accountKey === undefined) {
|
|
1227
1243
|
throw new Error(`This project has Slack channels using the Cursor account connection (slackChannel({ cursorAccount: true })) but the host is not signed in to Cursor. ${SIGN_IN_HINT}`);
|
|
1228
1244
|
}
|
|
1229
|
-
|
|
1230
|
-
|
|
1245
|
+
// Same host split as scm-events: `/v0/slack-events/*` is on api.cursor.com,
|
|
1246
|
+
// not api2 (accountKey.backendUrl 404s these routes).
|
|
1247
|
+
const baseUrl = cursorExternalApiUrl();
|
|
1248
|
+
const baseStateRoot = (_a = options.stateRoot) !== null && _a !== void 0 ? _a : join(targets[0].runtime.project.rootDir, ".agent-serve");
|
|
1231
1249
|
const stateDir = join(baseStateRoot, "cursor-slack");
|
|
1232
1250
|
// Optional fields may be undefined — the relay JSON-serializes the
|
|
1233
1251
|
// registration body, which drops them.
|