@cursor/july 0.1.31 → 0.1.33
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/docs/404.html +1 -1
- package/dist/docs/ab.html +2 -2
- package/dist/docs/assets/{app.DigB_9cQ.js → app.CgZqLyWL.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.B1uHGxBZ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BCMX25Bv.js → VPLocalSearchBox.C4KigoQn.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BDDWeELx.js → theme.C_Ty4yT7.js} +2 -2
- package/dist/docs/building-with-agents.html +2 -2
- package/dist/docs/concepts.html +2 -2
- package/dist/docs/deployment.html +2 -2
- package/dist/docs/evals.html +2 -2
- package/dist/docs/example-agents/approval-buddy.html +2 -2
- package/dist/docs/example-agents/benny.html +2 -2
- package/dist/docs/example-agents/bugbot.html +2 -2
- package/dist/docs/example-agents/codebase-wiki.html +2 -2
- package/dist/docs/example-agents/codeowners-review.html +2 -2
- package/dist/docs/example-agents/concierge.html +2 -2
- package/dist/docs/example-agents/fsd.html +2 -2
- package/dist/docs/example-agents/index.html +2 -2
- package/dist/docs/example-agents/knowledge-base.html +2 -2
- package/dist/docs/example-agents/oncall.html +2 -2
- package/dist/docs/example-agents/security-reviewer.html +2 -2
- package/dist/docs/example-agents/slack-agent.html +2 -2
- package/dist/docs/example-agents/weather-agent.html +2 -2
- package/dist/docs/guides/agent-to-agent.html +2 -2
- package/dist/docs/guides/cloud-runtime.html +2 -2
- package/dist/docs/guides/github.html +2 -2
- package/dist/docs/guides/human-in-the-loop.html +2 -2
- package/dist/docs/guides/mcp-oauth.html +2 -2
- package/dist/docs/guides/slack.html +2 -2
- package/dist/docs/guides/webhooks.html +2 -2
- package/dist/docs/hillclimbing.html +2 -2
- package/dist/docs/index.html +2 -2
- package/dist/docs/quickstart.html +2 -2
- package/dist/docs/reference/agent-config.html +2 -2
- package/dist/docs/reference/channels.html +2 -2
- package/dist/docs/reference/cli.html +2 -2
- package/dist/docs/reference/connections.html +2 -2
- package/dist/docs/reference/hooks.html +2 -2
- package/dist/docs/reference/http-api.html +2 -2
- package/dist/docs/reference/instructions.html +2 -2
- package/dist/docs/reference/playground.html +2 -2
- package/dist/docs/reference/project-layout.html +2 -2
- package/dist/docs/reference/prompt.html +2 -2
- package/dist/docs/reference/schedules.html +2 -2
- package/dist/docs/reference/sessions.html +2 -2
- package/dist/docs/reference/skills.html +2 -2
- package/dist/docs/reference/subagents.html +2 -2
- package/dist/docs/reference/tools.html +2 -2
- package/dist/docs/scaffolding-agents.html +2 -2
- package/dist/docs/storage.html +2 -2
- package/dist/docs/troubleshooting.html +2 -2
- package/dist/files-backends/agent-store-presigned-url.d.ts +9 -98
- package/dist/files-backends/agent-store-presigned-url.d.ts.map +1 -1
- package/dist/files-backends/agent-store-presigned-url.js +199 -314
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +25 -2
- package/dist/internal/cursor-relay-core.d.ts +12 -0
- package/dist/internal/cursor-relay-core.d.ts.map +1 -1
- package/dist/internal/cursor-relay-core.js +42 -8
- package/dist/internal/review-comments.d.ts +9 -1
- package/dist/internal/review-comments.d.ts.map +1 -1
- package/dist/internal/review-comments.js +76 -0
- package/dist/internal/server.js +8 -1
- package/dist/playground/assets/index-BRhBbnd4.css +1 -0
- package/dist/playground/assets/index-CVlCAcUx.js +85 -0
- package/dist/playground/index.html +2 -2
- package/package.json +3 -23
- package/src/files-backends/agent-store-presigned-url.ts +9 -401
- package/src/files-backends/cursor-hosted.ts +32 -6
- package/src/internal/cursor-relay-core.ts +62 -3
- package/src/internal/review-comments.ts +102 -2
- package/src/internal/server.ts +9 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CnFFl07y.js +0 -1
- package/dist/playground/assets/index-50PKeJlG.css +0 -1
- package/dist/playground/assets/index-C0f2Wl1q.js +0 -85
|
@@ -92,6 +92,30 @@ function splitOffset(offset) {
|
|
|
92
92
|
export function describeRelayError(error) {
|
|
93
93
|
return error instanceof Error ? error.message : String(error);
|
|
94
94
|
}
|
|
95
|
+
/** Must match server-shared `AGENT_SERVE_GENERATION_HEADER`. */
|
|
96
|
+
export const AGENT_SERVE_GENERATION_HEADER = "x-agent-serve-generation";
|
|
97
|
+
/** Must match server-shared `AGENT_SERVE_GENERATION_ENV_VAR`. */
|
|
98
|
+
export const AGENT_SERVE_GENERATION_ENV_VAR = "AGENT_SERVE_GENERATION";
|
|
99
|
+
export function resolveAgentServeDeploymentGeneration(explicit) {
|
|
100
|
+
var _a;
|
|
101
|
+
if (explicit !== undefined &&
|
|
102
|
+
Number.isSafeInteger(explicit) &&
|
|
103
|
+
explicit > 0) {
|
|
104
|
+
return explicit;
|
|
105
|
+
}
|
|
106
|
+
const raw = (_a = process.env[AGENT_SERVE_GENERATION_ENV_VAR]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
107
|
+
if (raw === undefined || raw.length === 0) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
if (!/^\d+$/.test(raw)) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
const parsed = Number(raw);
|
|
114
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
return parsed;
|
|
118
|
+
}
|
|
95
119
|
export class CursorRelayCore {
|
|
96
120
|
constructor(options) {
|
|
97
121
|
var _a;
|
|
@@ -102,6 +126,7 @@ export class CursorRelayCore {
|
|
|
102
126
|
this.registeredOnce = false;
|
|
103
127
|
this.offsetStore = new RelayOffsetStore(options.stateDir);
|
|
104
128
|
this.fetchImpl = (_a = options.fetchImpl) !== null && _a !== void 0 ? _a : fetch;
|
|
129
|
+
this.deploymentGeneration = resolveAgentServeDeploymentGeneration(options.deploymentGeneration);
|
|
105
130
|
}
|
|
106
131
|
start() {
|
|
107
132
|
if (this.running)
|
|
@@ -216,10 +241,11 @@ export class CursorRelayCore {
|
|
|
216
241
|
try {
|
|
217
242
|
const response = yield this.fetchImpl(url, {
|
|
218
243
|
method: "PUT",
|
|
219
|
-
headers: {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
244
|
+
headers: Object.assign({ authorization: `Bearer ${this.options.apiKey}`, "content-type": "application/json" }, (this.deploymentGeneration === undefined
|
|
245
|
+
? {}
|
|
246
|
+
: {
|
|
247
|
+
[AGENT_SERVE_GENERATION_HEADER]: String(this.deploymentGeneration),
|
|
248
|
+
})),
|
|
223
249
|
body: JSON.stringify(adapter.buildDeregistrationBody(this.consumerId)),
|
|
224
250
|
signal: controller.signal,
|
|
225
251
|
});
|
|
@@ -244,7 +270,11 @@ export class CursorRelayCore {
|
|
|
244
270
|
request(method, path, body) {
|
|
245
271
|
return __awaiter(this, void 0, void 0, function* () {
|
|
246
272
|
const url = `${this.options.baseUrl.replace(/\/+$/, "")}${path}`;
|
|
247
|
-
return this.fetchImpl(url, Object.assign(Object.assign({ method, headers: Object.assign({ authorization: `Bearer ${this.options.apiKey}` }, (body === undefined ? {} : { "content-type": "application/json" }))
|
|
273
|
+
return this.fetchImpl(url, Object.assign(Object.assign({ method, headers: Object.assign(Object.assign({ authorization: `Bearer ${this.options.apiKey}` }, (body === undefined ? {} : { "content-type": "application/json" })), (this.deploymentGeneration === undefined
|
|
274
|
+
? {}
|
|
275
|
+
: {
|
|
276
|
+
[AGENT_SERVE_GENERATION_HEADER]: String(this.deploymentGeneration),
|
|
277
|
+
})) }, (body === undefined ? {} : { body: JSON.stringify(body) })), (this.abort === undefined ? {} : { signal: this.abort.signal })));
|
|
248
278
|
});
|
|
249
279
|
}
|
|
250
280
|
/** Retry registration with backoff until it succeeds or the relay stops. */
|
|
@@ -412,12 +442,16 @@ export class CursorRelayCore {
|
|
|
412
442
|
/** Log the failure, sleep, and return the backoff for the NEXT failure. */
|
|
413
443
|
backoffAfterHttpFailure(response, backoffMs) {
|
|
414
444
|
return __awaiter(this, void 0, void 0, function* () {
|
|
415
|
-
|
|
416
|
-
|
|
445
|
+
// 409 = generation fence (stale resident after redeploy). Same long
|
|
446
|
+
// backoff as auth: retrying every second cannot heal a wrong generation.
|
|
447
|
+
const isAuthOrFenceFailure = response.status === 401 ||
|
|
448
|
+
response.status === 403 ||
|
|
449
|
+
response.status === 409;
|
|
450
|
+
const sleepMs = isAuthOrFenceFailure ? AUTH_FAILURE_BACKOFF_MS : backoffMs;
|
|
417
451
|
const text = yield response.text().catch(() => "");
|
|
418
452
|
this.log(`poll failed: ${response.status} ${text.slice(0, 300)} (retrying in ${Math.round(sleepMs / 1000)}s)`);
|
|
419
453
|
yield this.sleep(sleepMs);
|
|
420
|
-
return
|
|
454
|
+
return isAuthOrFenceFailure
|
|
421
455
|
? AUTH_FAILURE_BACKOFF_MS
|
|
422
456
|
: Math.min(backoffMs * 2, MAX_BACKOFF_MS);
|
|
423
457
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { HostGitHubClient } from "../types.js";
|
|
2
|
+
export type ReviewCommentPublisher = "local_gh" | "host_github";
|
|
2
3
|
export type ReviewCommentPostResult = {
|
|
3
4
|
posted: boolean;
|
|
4
5
|
publisher: ReviewCommentPublisher;
|
|
@@ -47,4 +48,11 @@ export declare function prepareReviewCommentsRequest(args: ReviewCommentPostArgs
|
|
|
47
48
|
* GH_TOKEN). Does not use the security-bugbot comments service.
|
|
48
49
|
*/
|
|
49
50
|
export declare function createLocalGhReviewPublisher(): ReviewCommentPublisherImplementation;
|
|
51
|
+
/**
|
|
52
|
+
* Posts a PR review through the host GitHub client (Cursor account lease,
|
|
53
|
+
* App installation token, or PAT). Prefer this on Cursor-deployed agents —
|
|
54
|
+
* no separate GitHub write secret is required when `githubChannel({
|
|
55
|
+
* cursorAccount })` is bound.
|
|
56
|
+
*/
|
|
57
|
+
export declare function createHostGithubReviewPublisher(github: HostGitHubClient): ReviewCommentPublisherImplementation;
|
|
50
58
|
//# sourceMappingURL=review-comments.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-comments.d.ts","sourceRoot":"","sources":["../../src/internal/review-comments.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-comments.d.ts","sourceRoot":"","sources":["../../src/internal/review-comments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,aAAa,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,sBAAsB,CAAC;IAClC,IAAI,EAAE,6BAA6B,GAAG,kBAAkB,GAAG,SAAS,CAAC;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IACjD,UAAU,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC/E,CAAC;AAOF;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,qBAAqB,GAEzB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,CAkBvD;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,oCAAoC,CAMnF;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,gBAAgB,GACvB,oCAAoC,CAMtC"}
|
|
@@ -43,6 +43,70 @@ export function createLocalGhReviewPublisher() {
|
|
|
43
43
|
},
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Posts a PR review through the host GitHub client (Cursor account lease,
|
|
48
|
+
* App installation token, or PAT). Prefer this on Cursor-deployed agents —
|
|
49
|
+
* no separate GitHub write secret is required when `githubChannel({
|
|
50
|
+
* cursorAccount })` is bound.
|
|
51
|
+
*/
|
|
52
|
+
export function createHostGithubReviewPublisher(github) {
|
|
53
|
+
return {
|
|
54
|
+
postReview(args) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
return postReviewViaHostGithub(github, args);
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function postReviewViaHostGithub(github, args) {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
var _a, _b, _c;
|
|
64
|
+
const prepared = prepareReviewCommentsRequest(args);
|
|
65
|
+
if (prepared.kind === "skipped") {
|
|
66
|
+
return Object.assign(Object.assign({}, prepared.result), { publisher: "host_github" });
|
|
67
|
+
}
|
|
68
|
+
const { request } = prepared;
|
|
69
|
+
const [owner, repo] = request.repo.split("/", 2);
|
|
70
|
+
if (owner === undefined || repo === undefined || repo === "") {
|
|
71
|
+
return skippedHost("unparseable owner/repo from PR URL");
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
(_a = args.signal) === null || _a === void 0 ? void 0 : _a.throwIfAborted();
|
|
75
|
+
const octokit = yield github.getOctokit();
|
|
76
|
+
(_b = args.signal) === null || _b === void 0 ? void 0 : _b.throwIfAborted();
|
|
77
|
+
const response = yield octokit.rest.pulls.createReview({
|
|
78
|
+
owner,
|
|
79
|
+
repo,
|
|
80
|
+
pull_number: request.prNumber,
|
|
81
|
+
commit_id: request.headSha,
|
|
82
|
+
body: request.message,
|
|
83
|
+
event: "COMMENT",
|
|
84
|
+
comments: request.comments.map(toGithubPullRequestReviewComment),
|
|
85
|
+
});
|
|
86
|
+
const htmlUrl = typeof response.data.html_url === "string"
|
|
87
|
+
? response.data.html_url
|
|
88
|
+
: undefined;
|
|
89
|
+
const inlineCommentCount = request.comments.length;
|
|
90
|
+
return {
|
|
91
|
+
posted: true,
|
|
92
|
+
publisher: "host_github",
|
|
93
|
+
mode: inlineCommentCount > 0
|
|
94
|
+
? "review_with_inline_comments"
|
|
95
|
+
: "review_body_only",
|
|
96
|
+
inlineCommentCount,
|
|
97
|
+
detail: htmlUrl
|
|
98
|
+
? `posted via host GitHub: ${htmlUrl}`
|
|
99
|
+
: `posted via host GitHub with ${inlineCommentCount} inline comment(s)`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if ((_c = args.signal) === null || _c === void 0 ? void 0 : _c.aborted) {
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
return skippedHost(`host GitHub review post failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
46
110
|
function postReviewViaLocalGh(args) {
|
|
47
111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
112
|
var _a, _b;
|
|
@@ -84,6 +148,9 @@ function postReviewViaLocalGh(args) {
|
|
|
84
148
|
});
|
|
85
149
|
}
|
|
86
150
|
function toGithubReviewComment(comment) {
|
|
151
|
+
return toGithubPullRequestReviewComment(comment);
|
|
152
|
+
}
|
|
153
|
+
function toGithubPullRequestReviewComment(comment) {
|
|
87
154
|
const body = {
|
|
88
155
|
path: comment.file,
|
|
89
156
|
body: comment.body,
|
|
@@ -107,6 +174,15 @@ function skipped(detail) {
|
|
|
107
174
|
detail,
|
|
108
175
|
};
|
|
109
176
|
}
|
|
177
|
+
function skippedHost(detail) {
|
|
178
|
+
return {
|
|
179
|
+
posted: false,
|
|
180
|
+
publisher: "host_github",
|
|
181
|
+
mode: "skipped",
|
|
182
|
+
inlineCommentCount: 0,
|
|
183
|
+
detail,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
110
186
|
function parseGithubPrUrl(prUrl) {
|
|
111
187
|
let url;
|
|
112
188
|
try {
|
package/dist/internal/server.js
CHANGED
|
@@ -727,7 +727,14 @@ function mountAgentRoutes(router, runtime, args) {
|
|
|
727
727
|
method: "GET",
|
|
728
728
|
pattern: `${base}/v1/health`,
|
|
729
729
|
auth: "none",
|
|
730
|
-
|
|
730
|
+
// Temporal consumes this response before promoting a newly deployed pod.
|
|
731
|
+
// Include the framework build there so deploy observability gets the
|
|
732
|
+
// version from the process that will serve turns, with no second request.
|
|
733
|
+
handler: () => jsonResponse({
|
|
734
|
+
ok: true,
|
|
735
|
+
name: project.name,
|
|
736
|
+
version: packageVersion(),
|
|
737
|
+
}),
|
|
731
738
|
});
|
|
732
739
|
// Bootstrap the SPA can't derive from its own URL (agent name, dev mode, and
|
|
733
740
|
// — in multi-agent mode — where the agents index lives).
|