@cursor/july 0.1.84 → 0.1.86

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.
Files changed (116) hide show
  1. package/dist/channels/deployments/deployments-channel.d.ts +2 -2
  2. package/dist/channels/deployments/deployments-channel.d.ts.map +1 -1
  3. package/dist/channels/deployments/deployments-channel.js +7 -6
  4. package/dist/channels/deployments/index.d.ts +2 -3
  5. package/dist/channels/deployments/index.d.ts.map +1 -1
  6. package/dist/channels/deployments/index.js +2 -3
  7. package/dist/channels/deployments/types.d.ts +14 -14
  8. package/dist/channels/deployments/types.d.ts.map +1 -1
  9. package/dist/channels/github/github-channel.d.ts +4 -0
  10. package/dist/channels/github/github-channel.d.ts.map +1 -1
  11. package/dist/channels/github/github-channel.js +18 -11
  12. package/dist/channels/origin/origin-channel.d.ts +6 -0
  13. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  14. package/dist/channels/origin/origin-channel.js +24 -11
  15. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  16. package/dist/channels/slack/dispatch.js +12 -2
  17. package/dist/docs/404.html +2 -2
  18. package/dist/docs/ab.html +3 -3
  19. package/dist/docs/assets/{app.kqdC1N7p.js → app.DUOPbN18.js} +1 -1
  20. package/dist/docs/assets/chunks/@localSearchIndexroot.CxCtxfDE.js +1 -0
  21. package/dist/docs/assets/chunks/{VPLocalSearchBox.DXDE2WgG.js → VPLocalSearchBox.CmWbGcGk.js} +1 -1
  22. package/dist/docs/assets/chunks/{theme.DFYqbyta.js → theme.S57OeOLA.js} +2 -2
  23. package/dist/docs/assets/{reference_channels.md.G5GysZ7e.js → reference_channels.md.CboFd5IH.js} +1 -1
  24. package/dist/docs/building-with-agents.html +3 -3
  25. package/dist/docs/concepts.html +3 -3
  26. package/dist/docs/deployment.html +3 -3
  27. package/dist/docs/evals.html +3 -3
  28. package/dist/docs/example-agents/approval-buddy.html +3 -3
  29. package/dist/docs/example-agents/benny.html +3 -3
  30. package/dist/docs/example-agents/bugbot.html +3 -3
  31. package/dist/docs/example-agents/codebase-wiki.html +3 -3
  32. package/dist/docs/example-agents/codeowners-review.html +3 -3
  33. package/dist/docs/example-agents/concierge.html +3 -3
  34. package/dist/docs/example-agents/fsd.html +3 -3
  35. package/dist/docs/example-agents/index.html +3 -3
  36. package/dist/docs/example-agents/knowledge-base.html +3 -3
  37. package/dist/docs/example-agents/oncall.html +3 -3
  38. package/dist/docs/example-agents/security-reviewer.html +3 -3
  39. package/dist/docs/example-agents/slack-agent.html +3 -3
  40. package/dist/docs/example-agents/weather-agent.html +3 -3
  41. package/dist/docs/guides/agent-to-agent.html +3 -3
  42. package/dist/docs/guides/cloud-runtime.html +3 -3
  43. package/dist/docs/guides/convert-automation.html +3 -3
  44. package/dist/docs/guides/github.html +3 -3
  45. package/dist/docs/guides/human-in-the-loop.html +3 -3
  46. package/dist/docs/guides/mcp-oauth.html +3 -3
  47. package/dist/docs/guides/opentelemetry.html +3 -3
  48. package/dist/docs/guides/slack.html +3 -3
  49. package/dist/docs/guides/webhooks.html +3 -3
  50. package/dist/docs/hashmap.json +1 -1
  51. package/dist/docs/hillclimbing.html +3 -3
  52. package/dist/docs/index.html +3 -3
  53. package/dist/docs/quickstart.html +3 -3
  54. package/dist/docs/reference/agent-config.html +3 -3
  55. package/dist/docs/reference/artifacts.html +3 -3
  56. package/dist/docs/reference/channels.html +5 -5
  57. package/dist/docs/reference/cli.html +3 -3
  58. package/dist/docs/reference/connections.html +3 -3
  59. package/dist/docs/reference/hooks.html +3 -3
  60. package/dist/docs/reference/http-api.html +3 -3
  61. package/dist/docs/reference/instructions.html +3 -3
  62. package/dist/docs/reference/playground.html +3 -3
  63. package/dist/docs/reference/project-layout.html +3 -3
  64. package/dist/docs/reference/prompt.html +3 -3
  65. package/dist/docs/reference/schedules.html +3 -3
  66. package/dist/docs/reference/sessions.html +3 -3
  67. package/dist/docs/reference/skills.html +3 -3
  68. package/dist/docs/reference/subagents.html +3 -3
  69. package/dist/docs/reference/tools.html +3 -3
  70. package/dist/docs/scaffolding-agents.html +3 -3
  71. package/dist/docs/storage.html +3 -3
  72. package/dist/docs/templates/agentic-owners.html +3 -3
  73. package/dist/docs/templates/demo.html +3 -3
  74. package/dist/docs/templates/pr-autofixer.html +3 -3
  75. package/dist/docs/templates/security-reviewer.html +3 -3
  76. package/dist/docs/templates/triage.html +3 -3
  77. package/dist/docs/troubleshooting.html +3 -3
  78. package/dist/internal/continuation-identity.d.ts +10 -0
  79. package/dist/internal/continuation-identity.d.ts.map +1 -1
  80. package/dist/internal/continuation-identity.js +10 -0
  81. package/dist/internal/cursor-deployment-relay.d.ts +4 -4
  82. package/dist/internal/cursor-deployment-relay.d.ts.map +1 -1
  83. package/dist/internal/cursor-deployment-relay.js +33 -32
  84. package/dist/internal/handleAgentServeTrigger.d.ts +5 -0
  85. package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
  86. package/dist/internal/handleAgentServeTrigger.js +11 -3
  87. package/dist/internal/local-control-plane.d.ts +19 -0
  88. package/dist/internal/local-control-plane.d.ts.map +1 -1
  89. package/dist/internal/local-control-plane.js +17 -0
  90. package/dist/internal/local-ingress.d.ts +35 -0
  91. package/dist/internal/local-ingress.d.ts.map +1 -0
  92. package/dist/internal/local-ingress.js +44 -0
  93. package/dist/internal/server.d.ts.map +1 -1
  94. package/dist/internal/server.js +151 -75
  95. package/dist/playground/assets/{index-Cspgk9jC.js → index-Bqn91tW4.js} +45 -45
  96. package/dist/playground/assets/index-C0_5hOsf.css +1 -0
  97. package/dist/playground/index.html +2 -2
  98. package/dist/types.d.ts +2 -2
  99. package/docs/reference/channels.md +13 -11
  100. package/package.json +1 -1
  101. package/src/channels/deployments/deployments-channel.ts +7 -6
  102. package/src/channels/deployments/index.ts +2 -3
  103. package/src/channels/deployments/types.ts +14 -14
  104. package/src/channels/github/github-channel.ts +18 -21
  105. package/src/channels/origin/origin-channel.ts +26 -15
  106. package/src/channels/slack/dispatch.ts +11 -7
  107. package/src/internal/continuation-identity.ts +10 -0
  108. package/src/internal/cursor-deployment-relay.ts +38 -36
  109. package/src/internal/handleAgentServeTrigger.ts +31 -2
  110. package/src/internal/local-control-plane.ts +33 -0
  111. package/src/internal/local-ingress.ts +90 -0
  112. package/src/internal/server.ts +194 -40
  113. package/src/types.ts +2 -2
  114. package/dist/docs/assets/chunks/@localSearchIndexroot.BqhvUA76.js +0 -1
  115. package/dist/playground/assets/index-ChETdG-_.css +0 -1
  116. /package/dist/docs/assets/{reference_channels.md.G5GysZ7e.lean.js → reference_channels.md.CboFd5IH.lean.js} +0 -0
@@ -91,6 +91,21 @@ const MAX_BODY_BYTES = 32 * 1024 * 1024;
91
91
  /** `GET /v1/artifacts` limit defaults / ceiling. */
92
92
  const ARTIFACTS_LIST_DEFAULT_LIMIT = 200;
93
93
  const ARTIFACTS_LIST_MAX_LIMIT = 1000;
94
+ function localControlPlaneRoute(runtimes) {
95
+ for (const runtime of runtimes) {
96
+ if (runtime.controlPlane !== undefined) {
97
+ return (input) => runtime.controlPlane.routeContinuation(input);
98
+ }
99
+ }
100
+ return undefined;
101
+ }
102
+ function firstLocalControlPlane(runtimes) {
103
+ var _a;
104
+ return (_a = runtimes.find((runtime) => runtime.controlPlane !== undefined)) === null || _a === void 0 ? void 0 : _a.controlPlane;
105
+ }
106
+ function isV2Project(project) {
107
+ return project.agent.architecture === "v2";
108
+ }
94
109
  /**
95
110
  * Start an HTTP server hosting one or more agents. A single agent with an
96
111
  * empty slug serves at `/v1/*` and `/playground`; multiple agents each serve
@@ -98,9 +113,9 @@ const ARTIFACTS_LIST_MAX_LIMIT = 1000;
98
113
  */
99
114
  export function startServer(mounts_1) {
100
115
  return __awaiter(this, arguments, void 0, function* (mounts, options = {}) {
101
- var _a, _b, _c, _d, _e;
102
- var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
103
- var _y;
116
+ var _a, _b, _c, _d, _e, _f;
117
+ var _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
118
+ var _1;
104
119
  if (mounts.length === 0) {
105
120
  throw new Error("startServer requires at least one agent mount");
106
121
  }
@@ -112,16 +127,16 @@ export function startServer(mounts_1) {
112
127
  }
113
128
  }
114
129
  const logRing = createLogRing({ capacity: 2000 });
115
- const logger = logRing.wrap((_f = options.logger) !== null && _f !== void 0 ? _f : ((line) => console.log(line)));
116
- const dev = (_g = options.dev) !== null && _g !== void 0 ? _g : false;
117
- const playground = (_h = options.playground) !== null && _h !== void 0 ? _h : true;
130
+ const logger = logRing.wrap((_g = options.logger) !== null && _g !== void 0 ? _g : ((line) => console.log(line)));
131
+ const dev = (_h = options.dev) !== null && _h !== void 0 ? _h : false;
132
+ const playground = (_j = options.playground) !== null && _j !== void 0 ? _j : true;
118
133
  const noControlPlane = options.noControlPlane === true;
119
- const runSchedules = (_j = options.schedules) !== null && _j !== void 0 ? _j : !dev;
120
- const runReminders = (_k = options.reminders) !== null && _k !== void 0 ? _k : !dev;
134
+ const runSchedules = (_k = options.schedules) !== null && _k !== void 0 ? _k : !dev;
135
+ const runReminders = (_l = options.reminders) !== null && _l !== void 0 ? _l : !dev;
121
136
  // Identify this process to the Cursor backend as agentkit (the SDK reads
122
137
  // this when building its client-version header) so the internal-only
123
138
  // agentkit_enabled gate applies to every turn.
124
- (_l = (_y = process.env).CURSOR_AGENTKIT_VERSION) !== null && _l !== void 0 ? _l : (_y.CURSOR_AGENTKIT_VERSION = packageVersion());
139
+ (_m = (_1 = process.env).CURSOR_AGENTKIT_VERSION) !== null && _m !== void 0 ? _m : (_1.CURSOR_AGENTKIT_VERSION = packageVersion());
125
140
  const authoredOtel = pickAuthoredOtel(mounts.map((m) => ({
126
141
  slug: m.slug,
127
142
  name: m.project.name,
@@ -143,10 +158,10 @@ export function startServer(mounts_1) {
143
158
  targets: cursorGithubTargets,
144
159
  });
145
160
  const cursorOriginScope = resolveCursorOriginRepoScope({
146
- explicitRepos: (_m = (_b = options.cursorEvents) === null || _b === void 0 ? void 0 : _b.repos) !== null && _m !== void 0 ? _m : [],
161
+ explicitRepos: (_o = (_b = options.cursorEvents) === null || _b === void 0 ? void 0 : _b.repos) !== null && _o !== void 0 ? _o : [],
147
162
  targets: cursorOriginTargets,
148
163
  });
149
- const effectiveCursorEvents = (_o = cursorGithubConfig.cursorEvents) !== null && _o !== void 0 ? _o : (cursorOriginScope === undefined
164
+ const effectiveCursorEvents = (_p = cursorGithubConfig.cursorEvents) !== null && _p !== void 0 ? _p : (cursorOriginScope === undefined
150
165
  ? undefined
151
166
  : { repos: [...cursorOriginScope.repos] });
152
167
  // One resolution for every Cursor credential consumer (SDK runner, account
@@ -159,6 +174,19 @@ export function startServer(mounts_1) {
159
174
  const cursorEventsAuth = effectiveCursorEvents === undefined
160
175
  ? undefined
161
176
  : requireCursorEventsAuth(effectiveCursorEvents, accountKey);
177
+ // Two architectures + local CP + cursor-events would register two
178
+ // /v0/scm-events consumers (engine offset vs control-plane offset).
179
+ // Fail before engines or relays start. `--no-control-plane` mixed is one
180
+ // July consumer (v1 engine); hosted CP owns v2.
181
+ assertSingleCursorEventsLane({
182
+ noControlPlane,
183
+ config: effectiveCursorEvents,
184
+ auth: cursorEventsAuth,
185
+ v1Mounts: mounts.filter((mount) => !isV2Project(mount.project)),
186
+ v2Mounts: mounts.filter((mount) => isV2Project(mount.project)),
187
+ githubRepos: (_q = (_c = cursorGithubConfig.cursorEvents) === null || _c === void 0 ? void 0 : _c.repos) !== null && _q !== void 0 ? _q : [],
188
+ originRepos: (_r = cursorOriginScope === null || cursorOriginScope === void 0 ? void 0 : cursorOriginScope.repos) !== null && _r !== void 0 ? _r : [],
189
+ });
162
190
  let cursorGithubCredentials;
163
191
  // Proxy-wired GitHub token resolver for `ctx.host.github` when no startup
164
192
  // token mint runs (empty repo scope): host Octokit calls must route
@@ -262,7 +290,7 @@ export function startServer(mounts_1) {
262
290
  // Published installs already ship the bundle; vite may be absent there.
263
291
  yield ensurePlaygroundBundle(logger);
264
292
  }
265
- const docsSite = (_p = options.docs) !== null && _p !== void 0 ? _p : true;
293
+ const docsSite = (_s = options.docs) !== null && _s !== void 0 ? _s : true;
266
294
  if (docsSite) {
267
295
  // Same pattern for the documentation site at /docs.
268
296
  yield ensureDocsSiteBundle(logger);
@@ -270,7 +298,7 @@ export function startServer(mounts_1) {
270
298
  if (options.allowAnonymous === true) {
271
299
  logger("[agent-sdk] 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");
272
300
  }
273
- const runner = (_q = options.runner) !== null && _q !== void 0 ? _q : new CursorSdkRunner(Object.assign(Object.assign({}, (accountKey === undefined ? {} : { apiKey: accountKey.apiKey })), { logger }));
301
+ const runner = (_t = options.runner) !== null && _t !== void 0 ? _t : new CursorSdkRunner(Object.assign(Object.assign({}, (accountKey === undefined ? {} : { apiKey: accountKey.apiKey })), { logger }));
274
302
  const router = new Router();
275
303
  const runtimes = [];
276
304
  const channelStopHooks = [];
@@ -313,7 +341,7 @@ export function startServer(mounts_1) {
313
341
  }
314
342
  for (const { slug, project } of mounts) {
315
343
  // Each agent gets an isolated state root so their sessions never mix.
316
- const baseStateRoot = (_r = options.stateRoot) !== null && _r !== void 0 ? _r : join(project.rootDir, ".agent-serve");
344
+ const baseStateRoot = (_u = options.stateRoot) !== null && _u !== void 0 ? _u : join(project.rootDir, ".agent-serve");
317
345
  const stateRoot = slug === "" ? baseStateRoot : join(baseStateRoot, slug);
318
346
  const otelCollector = otelRuntime === undefined
319
347
  ? undefined
@@ -360,7 +388,7 @@ export function startServer(mounts_1) {
360
388
  reminderRunner = new ReminderRunner(engine, logger, timerClient);
361
389
  const evalRuns = new EvalRunStore(project.rootDir, logger,
362
390
  // Playground eval history mirrors onto the defineStorage evals table.
363
- (_c = engine.storage) === null || _c === void 0 ? void 0 : _c.evalRuns());
391
+ (_d = engine.storage) === null || _d === void 0 ? void 0 : _d.evalRuns());
364
392
  // Eval history restores with the same startup step as sessions (reads
365
393
  // also hydrate lazily, but doing it here surfaces store problems at
366
394
  // boot and makes /v1/dev/evals complete from the first request).
@@ -429,7 +457,7 @@ export function startServer(mounts_1) {
429
457
  }
430
458
  catch (error) {
431
459
  logger(`[agent-sdk] channel "${channel.id}" onStart failed: ${error instanceof Error
432
- ? ((_s = error.stack) !== null && _s !== void 0 ? _s : error.message)
460
+ ? ((_v = error.stack) !== null && _v !== void 0 ? _v : error.message)
433
461
  : String(error)}`);
434
462
  }
435
463
  }
@@ -507,20 +535,26 @@ export function startServer(mounts_1) {
507
535
  // job (backend `/github_webhook` already verified); we only admit loopback
508
536
  // so this route is not a public unsigned endpoint. Agents decide whether
509
537
  // to run via their onPullRequest / onComment / … hooks.
510
- const collectGitHubTargets = () => collectGitHubTriggerTargets({
511
- mounts: runtimes.map((runtime) => ({
538
+ const collectGitHubTargetsFrom = (selected) => collectGitHubTriggerTargets({
539
+ mounts: selected.map((runtime) => ({
512
540
  slug: runtime.slug,
513
541
  channels: runtime.project.channels,
514
542
  buildHandlerArgs: (channelId) => buildChannelHandlerArgs({ runtime, channelId }),
515
543
  })),
516
544
  });
517
- const collectOriginTargets = () => collectOriginTriggerTargets({
518
- mounts: runtimes.map((runtime) => ({
545
+ const collectOriginTargetsFrom = (selected) => collectOriginTriggerTargets({
546
+ mounts: selected.map((runtime) => ({
519
547
  slug: runtime.slug,
520
548
  channels: runtime.project.channels,
521
549
  buildHandlerArgs: (channelId) => buildChannelHandlerArgs({ runtime, channelId }),
522
550
  })),
523
551
  });
552
+ const collectGitHubTargets = () => collectGitHubTargetsFrom(runtimes);
553
+ const collectOriginTargets = () => collectOriginTargetsFrom(runtimes);
554
+ const v1Runtimes = runtimes.filter((runtime) => !isV2Project(runtime.project));
555
+ const v2Runtimes = runtimes.filter((runtime) => isV2Project(runtime.project));
556
+ const v1Mounts = mounts.filter((mount) => !isV2Project(mount.project));
557
+ const v2Mounts = mounts.filter((mount) => isV2Project(mount.project));
524
558
  router.add({
525
559
  method: "POST",
526
560
  pattern: "/v1/webhooks/github",
@@ -529,13 +563,8 @@ export function startServer(mounts_1) {
529
563
  var _a;
530
564
  var _b, _c;
531
565
  const bodyText = yield request.text();
532
- const result = yield handleAgentServeTrigger({
533
- type: "github",
534
- bodyText,
535
- eventName: request.headers.get("x-github-event"),
536
- deliveryId: (_b = request.headers.get("x-github-delivery")) !== null && _b !== void 0 ? _b : undefined,
537
- targets: collectGitHubTargets(),
538
- });
566
+ const routeContinuation = localControlPlaneRoute(runtimes);
567
+ const result = yield handleAgentServeTrigger(Object.assign({ type: "github", bodyText, eventName: request.headers.get("x-github-event"), deliveryId: (_b = request.headers.get("x-github-delivery")) !== null && _b !== void 0 ? _b : undefined, targets: collectGitHubTargets() }, (routeContinuation === undefined ? {} : { routeContinuation })));
539
568
  const status = result.ok ? 202 : ((_c = (_a = result.targets[0]) === null || _a === void 0 ? void 0 : _a.status) !== null && _c !== void 0 ? _c : 500);
540
569
  return jsonResponse(result, { status });
541
570
  }),
@@ -563,20 +592,30 @@ export function startServer(mounts_1) {
563
592
  yield cursorSlackRelay === null || cursorSlackRelay === void 0 ? void 0 : cursorSlackRelay.stop();
564
593
  throw error;
565
594
  }
566
- // Cursor SCM events relay (opt-in: serve({ cursorEvents }) / --cursor-events).
567
- const cursorEventRelay = startCursorEventRelay({
595
+ // Cursor SCM events: v1 stays on the engine poll. v2 ingest is local-CP
596
+ // only hosted `--no-control-plane` skips the July poll (hosted CP wakes).
597
+ const routeContinuation = localControlPlaneRoute(runtimes);
598
+ const cursorEventsCommon = {
568
599
  config: effectiveCursorEvents,
569
- githubRepos: (_t = (_d = cursorGithubConfig.cursorEvents) === null || _d === void 0 ? void 0 : _d.repos) !== null && _t !== void 0 ? _t : [],
570
- originRepos: (_u = cursorOriginScope === null || cursorOriginScope === void 0 ? void 0 : cursorOriginScope.repos) !== null && _u !== void 0 ? _u : [],
600
+ githubRepos: (_w = (_e = cursorGithubConfig.cursorEvents) === null || _e === void 0 ? void 0 : _e.repos) !== null && _w !== void 0 ? _w : [],
601
+ originRepos: (_x = cursorOriginScope === null || cursorOriginScope === void 0 ? void 0 : cursorOriginScope.repos) !== null && _x !== void 0 ? _x : [],
571
602
  stateRoot: options.stateRoot,
572
- mounts,
573
603
  auth: cursorEventsAuth,
574
604
  logger,
575
- collectGitHubTargets,
576
- collectOriginTargets,
577
605
  cursorAccountOnly: options.cursorEvents === undefined &&
578
606
  (cursorGithubTargets.length > 0 || cursorOriginTargets.length > 0),
579
- });
607
+ };
608
+ const cursorEventRelay = startCursorEventRelay(Object.assign(Object.assign({}, cursorEventsCommon), { mounts: v1Mounts, collectGitHubTargets: () => collectGitHubTargetsFrom(v1Runtimes), collectOriginTargets: () => collectOriginTargetsFrom(v1Runtimes), lane: "engine", skippedV2: v2Mounts.length > 0 }));
609
+ const controlPlaneScmRelay = startCursorEventRelay(Object.assign(Object.assign(Object.assign(Object.assign({}, cursorEventsCommon), { mounts: v2Mounts, collectGitHubTargets: () => collectGitHubTargetsFrom(v2Runtimes), collectOriginTargets: () => collectOriginTargetsFrom(v2Runtimes) }), (routeContinuation === undefined ? {} : { routeContinuation })), { lane: "control-plane", start: false, stateDirName: join("control-plane", "cursor-events") }));
610
+ const localCp = firstLocalControlPlane(runtimes);
611
+ if (controlPlaneScmRelay !== undefined) {
612
+ if (localCp !== undefined) {
613
+ localCp.attachScmEvents(controlPlaneScmRelay);
614
+ }
615
+ else {
616
+ logger("[agent-sdk] cursor-events: skipping v2 scm-events poll (--no-control-plane); hosted CP owns ingest");
617
+ }
618
+ }
580
619
  // Cursor deployment-events relay: automatic when a mounted agent authored
581
620
  // `deploymentsChannel({ ... })`.
582
621
  const cursorDeploymentRelay = startCursorDeploymentRelay({
@@ -588,9 +627,9 @@ export function startServer(mounts_1) {
588
627
  const server = createServer((req, res) => {
589
628
  void instrumentHttp(otelRuntime, req, res, () => handleRequest(router, req, res, logger));
590
629
  });
591
- const host = (_v = options.host) !== null && _v !== void 0 ? _v : "127.0.0.1";
630
+ const host = (_y = options.host) !== null && _y !== void 0 ? _y : "127.0.0.1";
592
631
  const portWasExplicit = options.port !== undefined;
593
- const requestedPort = (_w = options.port) !== null && _w !== void 0 ? _w : DEFAULT_SERVE_PORT;
632
+ const requestedPort = (_z = options.port) !== null && _z !== void 0 ? _z : DEFAULT_SERVE_PORT;
594
633
  let boundPort;
595
634
  try {
596
635
  boundPort = yield listenHttpServer({
@@ -604,6 +643,7 @@ export function startServer(mounts_1) {
604
643
  catch (error) {
605
644
  yield cursorDeploymentRelay === null || cursorDeploymentRelay === void 0 ? void 0 : cursorDeploymentRelay.stop();
606
645
  yield cursorEventRelay === null || cursorEventRelay === void 0 ? void 0 : cursorEventRelay.stop();
646
+ yield controlPlaneScmRelay === null || controlPlaneScmRelay === void 0 ? void 0 : controlPlaneScmRelay.stop();
607
647
  yield cursorSlackRelay === null || cursorSlackRelay === void 0 ? void 0 : cursorSlackRelay.stop();
608
648
  cursorGithubCredentials === null || cursorGithubCredentials === void 0 ? void 0 : cursorGithubCredentials.stop();
609
649
  yield shutdownOtelRuntime(otelRuntime);
@@ -635,7 +675,7 @@ export function startServer(mounts_1) {
635
675
  runtime.project.agent.cloud !== undefined;
636
676
  if ((hasServerTools || bridgeableNames.length > 0) && cloudCapable) {
637
677
  const basePath = runtime.slug === "" ? "" : `/${runtime.slug}`;
638
- const publicToolsUrl = (_x = options.cloudToolsUrl) !== null && _x !== void 0 ? _x : (options.publicUrl === undefined
678
+ const publicToolsUrl = (_0 = options.cloudToolsUrl) !== null && _0 !== void 0 ? _0 : (options.publicUrl === undefined
639
679
  ? undefined
640
680
  : `${options.publicUrl.replace(/\/$/, "")}${basePath}${TOOL_MCP_ENDPOINT_PATH}`);
641
681
  if (publicToolsUrl === undefined) {
@@ -687,7 +727,7 @@ export function startServer(mounts_1) {
687
727
  const handle = {
688
728
  url,
689
729
  port: address.port,
690
- project: (_e = runtimes[0]) === null || _e === void 0 ? void 0 : _e.project,
730
+ project: (_f = runtimes[0]) === null || _f === void 0 ? void 0 : _f.project,
691
731
  agents,
692
732
  dispatchSchedule: (name, slug) => {
693
733
  var _a;
@@ -755,6 +795,7 @@ export function startServer(mounts_1) {
755
795
  playgroundDev === null || playgroundDev === void 0 ? void 0 : playgroundDev.stop();
756
796
  yield cursorDeploymentRelay === null || cursorDeploymentRelay === void 0 ? void 0 : cursorDeploymentRelay.stop();
757
797
  yield cursorEventRelay === null || cursorEventRelay === void 0 ? void 0 : cursorEventRelay.stop();
798
+ yield controlPlaneScmRelay === null || controlPlaneScmRelay === void 0 ? void 0 : controlPlaneScmRelay.stop();
758
799
  yield cursorSlackRelay === null || cursorSlackRelay === void 0 ? void 0 : cursorSlackRelay.stop();
759
800
  for (const runtime of runtimes) {
760
801
  (_a = runtime.controlPlane) === null || _a === void 0 ? void 0 : _a.stop();
@@ -1452,15 +1493,9 @@ function requireCursorEventsAuth(config, accountKey) {
1452
1493
  * channels; Origin is subscribed only when an `originChannel({ cursorAccount })`
1453
1494
  * opted in.
1454
1495
  */
1455
- function startCursorEventRelay(input) {
1456
- var _a;
1457
- var _b;
1458
- const { config, stateRoot, mounts, auth, logger } = input;
1459
- if (config === undefined || auth === undefined) {
1460
- return undefined;
1461
- }
1462
- const githubTargets = findGitHubChannelTargets(mounts);
1463
- const originTargets = findOriginChannelTargets(mounts);
1496
+ function collectCursorEventSubscriptions(input) {
1497
+ const githubTargets = findGitHubChannelTargets(input.mounts);
1498
+ const originTargets = findOriginChannelTargets(input.mounts);
1464
1499
  const githubEvents = [
1465
1500
  ...new Set(githubTargets.flatMap((target) => target.events)),
1466
1501
  ];
@@ -1492,8 +1527,52 @@ function startCursorEventRelay(input) {
1492
1527
  });
1493
1528
  }
1494
1529
  }
1530
+ return subscriptions;
1531
+ }
1532
+ /**
1533
+ * Local CP + `--cursor-events` + both architectures would start two
1534
+ * consumers (different offset dirs). Refuse that at serve start.
1535
+ * `--no-control-plane` is one July consumer — hosted CP owns v2.
1536
+ */
1537
+ function assertSingleCursorEventsLane(input) {
1538
+ if (input.noControlPlane ||
1539
+ input.config === undefined ||
1540
+ input.auth === undefined) {
1541
+ return;
1542
+ }
1543
+ const shared = {
1544
+ githubRepos: input.githubRepos,
1545
+ originRepos: input.originRepos,
1546
+ };
1547
+ if (collectCursorEventSubscriptions(Object.assign({ mounts: input.v1Mounts }, shared))
1548
+ .length === 0 ||
1549
+ collectCursorEventSubscriptions(Object.assign({ mounts: input.v2Mounts }, shared))
1550
+ .length === 0) {
1551
+ return;
1552
+ }
1553
+ throw new Error("[agent-sdk] cursor-events: refusing to serve v1 and v2 github/origin agents in one process — they would open two /v0/scm-events consumers. Serve one architecture per process.");
1554
+ }
1555
+ function startCursorEventRelay(input) {
1556
+ var _a;
1557
+ var _b, _c;
1558
+ const { config, stateRoot, mounts, auth, logger } = input;
1559
+ if (config === undefined || auth === undefined) {
1560
+ return undefined;
1561
+ }
1562
+ const subscriptions = collectCursorEventSubscriptions({
1563
+ mounts,
1564
+ githubRepos: input.githubRepos,
1565
+ originRepos: input.originRepos,
1566
+ });
1495
1567
  if (subscriptions.length === 0) {
1496
- if (githubRepos.length === 0 && originRepos.length === 0) {
1568
+ if (input.lane === "engine" && input.skippedV2 === true) {
1569
+ logger("[agent-sdk] cursor-events: no v1 github/origin targets; v2 ingest is control-plane only");
1570
+ }
1571
+ else if (input.lane === "control-plane") {
1572
+ return undefined;
1573
+ }
1574
+ else if (input.githubRepos.every((repo) => repo.trim() === "") &&
1575
+ input.originRepos.every((repo) => repo.trim() === "")) {
1497
1576
  logger("[agent-sdk] cursor-events: no repos configured (pass --repo owner/name); relay disabled");
1498
1577
  }
1499
1578
  else {
@@ -1506,7 +1585,7 @@ function startCursorEventRelay(input) {
1506
1585
  baseUrl: auth.baseUrl,
1507
1586
  apiKey: auth.apiKey,
1508
1587
  subscriptions,
1509
- stateDir: join(baseStateRoot, "cursor-events"),
1588
+ stateDir: join(baseStateRoot, (_c = input.stateDirName) !== null && _c !== void 0 ? _c : "cursor-events"),
1510
1589
  logger,
1511
1590
  dispatch: (event) => __awaiter(this, void 0, void 0, function* () {
1512
1591
  if (event.provider === "origin") {
@@ -1521,11 +1600,9 @@ function startCursorEventRelay(input) {
1521
1600
  ? true
1522
1601
  : cursorAccount.repos.some((repo) => repo.toLowerCase() === event.repo.toLowerCase());
1523
1602
  });
1524
- const result = yield handleAgentServeTrigger({
1525
- type: "origin",
1526
- bodyText: JSON.stringify(scmMetadataToOriginPayload(event)),
1527
- targets,
1528
- });
1603
+ const result = yield handleAgentServeTrigger(Object.assign({ type: "origin", bodyText: JSON.stringify(scmMetadataToOriginPayload(event)), targets }, (input.routeContinuation === undefined
1604
+ ? {}
1605
+ : { routeContinuation: input.routeContinuation })));
1529
1606
  logCursorScmDispatch(logger, event, result);
1530
1607
  return;
1531
1608
  }
@@ -1542,16 +1619,15 @@ function startCursorEventRelay(input) {
1542
1619
  ? true
1543
1620
  : cursorAccount.repos.some((repo) => repo.toLowerCase() === event.repo.toLowerCase());
1544
1621
  });
1545
- const result = yield handleAgentServeTrigger({
1546
- type: "github",
1547
- bodyText: JSON.stringify(scmEventToGitHubPayload(event)),
1548
- eventName: event.eventName,
1549
- deliveryId: event.deliveryId,
1550
- targets,
1551
- });
1622
+ const result = yield handleAgentServeTrigger(Object.assign({ type: "github", bodyText: JSON.stringify(scmEventToGitHubPayload(event)), eventName: event.eventName, deliveryId: event.deliveryId, targets }, (input.routeContinuation === undefined
1623
+ ? {}
1624
+ : { routeContinuation: input.routeContinuation })));
1552
1625
  logCursorScmDispatch(logger, event, result);
1553
1626
  }),
1554
1627
  });
1628
+ if (input.start === false) {
1629
+ return relay;
1630
+ }
1555
1631
  relay.start();
1556
1632
  logger(`[agent-sdk] cursor-events: relaying ${subscriptions.length} subscription(s) from ${auth.baseUrl}`);
1557
1633
  return relay;
@@ -1745,7 +1821,7 @@ function collectCursorDeploymentTargets(runtimes, skipped) {
1745
1821
  }
1746
1822
  const subscriptions = resolveDeploymentSubscriptions(options);
1747
1823
  if (subscriptions.length === 0) {
1748
- // Declared the channel but named no repositories — usually an unset
1824
+ // Declared the channel but named no deploy sources — usually an unset
1749
1825
  // env var. Say so rather than starting a relay that receives nothing.
1750
1826
  skipped.push(`${runtime.slug || runtime.project.name}/${channel.id}`);
1751
1827
  continue;
@@ -1758,7 +1834,7 @@ function collectCursorDeploymentTargets(runtimes, skipped) {
1758
1834
  /**
1759
1835
  * Cursor deployment-events relay: automatic when a mounted agent authored
1760
1836
  * `deploymentsChannel({ ... })`. One relay per process reads
1761
- * `/v0/deployment-events` for the union of every channel's repositories, and
1837
+ * `/v0/deployment-events` for the union of every channel's deploy sources, and
1762
1838
  * each event is routed to the channels that asked for it — the same ownership
1763
1839
  * `startCursorSlackRelay` and `startCursorEventRelay` have.
1764
1840
  */
@@ -1768,24 +1844,24 @@ function startCursorDeploymentRelay(input) {
1768
1844
  const skipped = [];
1769
1845
  const targets = collectCursorDeploymentTargets(runtimes, skipped);
1770
1846
  if (skipped.length > 0) {
1771
- logger(`[agent-sdk] deployment-events: no repositories declared on ${skipped.join(", ")}; those channels receive nothing`);
1847
+ logger(`[agent-sdk] deployment-events: no deploy sources declared on ${skipped.join(", ")}; those channels receive nothing`);
1772
1848
  }
1773
1849
  if (targets.length === 0) {
1774
1850
  return undefined;
1775
1851
  }
1776
1852
  if (accountKey === undefined) {
1777
- throw new Error(`This project has channels subscribed to deployment events (deploymentsChannel({ repos })) but the host is not signed in to Cursor. ${SIGN_IN_HINT}`);
1853
+ throw new Error(`This project has channels subscribed to deployment events (deploymentsChannel({ deploySourceUris })) but the host is not signed in to Cursor. ${SIGN_IN_HINT}`);
1778
1854
  }
1779
- // Union across channels: one registration per repo for the whole process,
1780
- // however many channels named it. Per-channel environment and event-type
1781
- // filtering happens at dispatch.
1782
- const byRepo = new Map();
1855
+ // Union across channels: one registration per deploy source for the whole
1856
+ // process, however many channels named it. Per-channel environment and
1857
+ // event-type filtering happens at dispatch.
1858
+ const bySource = new Map();
1783
1859
  for (const target of targets) {
1784
1860
  for (const subscription of target.subscriptions) {
1785
- const existing = byRepo.get(subscription.repo);
1861
+ const existing = bySource.get(subscription.deploySourceUri);
1786
1862
  if (existing === undefined) {
1787
- byRepo.set(subscription.repo, {
1788
- repo: subscription.repo,
1863
+ bySource.set(subscription.deploySourceUri, {
1864
+ deploySourceUri: subscription.deploySourceUri,
1789
1865
  environments: [...subscription.environments],
1790
1866
  events: new Set(subscription.events),
1791
1867
  });
@@ -1813,7 +1889,7 @@ function startCursorDeploymentRelay(input) {
1813
1889
  baseUrl: cursorExternalApiUrl(),
1814
1890
  apiKey: accountKey.apiKey,
1815
1891
  stateDir: join(baseStateRoot, "deployment-events"),
1816
- subscriptions: [...byRepo.values()],
1892
+ subscriptions: [...bySource.values()],
1817
1893
  logger,
1818
1894
  dispatch: (event) => __awaiter(this, void 0, void 0, function* () {
1819
1895
  return fanOutDeploymentEvent({
@@ -1835,7 +1911,7 @@ function startCursorDeploymentRelay(input) {
1835
1911
  }),
1836
1912
  });
1837
1913
  relay.start();
1838
- logger(`[agent-sdk] deployment-events: relaying ${byRepo.size} repository subscription(s) to ${targets.length} channel(s)`);
1914
+ logger(`[agent-sdk] deployment-events: relaying ${bySource.size} deploy-source subscription(s) to ${targets.length} channel(s)`);
1839
1915
  return relay;
1840
1916
  }
1841
1917
  function startCursorSlackRelay(input) {