@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
@@ -29,17 +29,17 @@ var __rest = (this && this.__rest) || function (s, e) {
29
29
  };
30
30
  import { CursorRelayCore } from "./cursor-relay-core.js";
31
31
  const DEFAULT_EVENTS = ["deployment.succeeded"];
32
- /** Normalize the channel's `repos` option into concrete subscriptions. */
32
+ /** Normalize the channel's `deploySourceUris` option into concrete subscriptions. */
33
33
  export function resolveDeploymentSubscriptions(options) {
34
34
  var _a, _b, _c, _d;
35
- const byRepo = new Map();
36
- for (const entry of options.repos) {
37
- const subscription = typeof entry === "string" ? { repo: entry } : entry;
38
- // Case-folded only: `Deployment.repository` has no documented format, and
39
- // the server keys subscriptions the same way.
40
- const repo = subscription.repo.trim().toLowerCase();
41
- if (repo === "") {
42
- throw new Error(`deploymentsChannel: invalid repo "${subscription.repo}".`);
35
+ const bySource = new Map();
36
+ for (const entry of options.deploySourceUris) {
37
+ const subscription = typeof entry === "string" ? { deploySourceUri: entry } : entry;
38
+ // Case-folded only: `Deployment.deploy_source_uri` has no documented
39
+ // format, and the server keys subscriptions the same way.
40
+ const deploySourceUri = subscription.deploySourceUri.trim().toLowerCase();
41
+ if (deploySourceUri === "") {
42
+ throw new Error(`deploymentsChannel: invalid deploy source "${subscription.deploySourceUri}".`);
43
43
  }
44
44
  const environments = [
45
45
  ...new Set(((_b = (_a = subscription.environments) !== null && _a !== void 0 ? _a : options.environments) !== null && _b !== void 0 ? _b : [])
@@ -48,13 +48,13 @@ export function resolveDeploymentSubscriptions(options) {
48
48
  ];
49
49
  const events = new Set((_d = (_c = subscription.events) !== null && _c !== void 0 ? _c : options.events) !== null && _d !== void 0 ? _d : DEFAULT_EVENTS);
50
50
  if (events.size === 0) {
51
- throw new Error(`deploymentsChannel: repo "${repo}" subscribes to no events.`);
51
+ throw new Error(`deploymentsChannel: deploy source "${deploySourceUri}" subscribes to no events.`);
52
52
  }
53
- // Later entries for the same repo widen the earlier one rather than
54
- // silently replacing it.
55
- const existing = byRepo.get(repo);
53
+ // Later entries for the same deploy source widen the earlier one rather
54
+ // than silently replacing it.
55
+ const existing = bySource.get(deploySourceUri);
56
56
  if (existing === undefined) {
57
- byRepo.set(repo, { repo, environments, events });
57
+ bySource.set(deploySourceUri, { deploySourceUri, environments, events });
58
58
  continue;
59
59
  }
60
60
  for (const event of events)
@@ -65,9 +65,10 @@ export function resolveDeploymentSubscriptions(options) {
65
65
  : [...new Set([...existing.environments, ...environments])];
66
66
  }
67
67
  // Empty is legal here and means "this channel wants nothing", which is how
68
- // an env-configured channel stays inert without a repo list. The wire-level
69
- // empty list means deregister, so the host simply never registers it.
70
- return [...byRepo.values()];
68
+ // an env-configured channel stays inert without a deploy-source list. The
69
+ // wire-level empty list means deregister, so the host simply never
70
+ // registers it.
71
+ return [...bySource.values()];
71
72
  }
72
73
  /** Whether one confirmed subscription wants this event. */
73
74
  export function deploymentEventMatches(subscription, envelope) {
@@ -89,7 +90,7 @@ export function deploymentEventMatches(subscription, envelope) {
89
90
  export function fanOutDeploymentEvent(input) {
90
91
  return __awaiter(this, void 0, void 0, function* () {
91
92
  const { event, logger } = input;
92
- const matched = input.targets.filter((target) => target.subscriptions.some((subscription) => subscription.repo === event.repo &&
93
+ const matched = input.targets.filter((target) => target.subscriptions.some((subscription) => subscription.deploySourceUri === event.deploySourceUri &&
93
94
  deploymentEventMatches(subscription, event)));
94
95
  const failures = [];
95
96
  for (const target of matched) {
@@ -101,7 +102,7 @@ export function fanOutDeploymentEvent(input) {
101
102
  logger(`[agent-sdk] deployment-events: ${target.name} failed on ${event.eventId}: ${error instanceof Error ? error.message : String(error)}`);
102
103
  }
103
104
  }
104
- logger(`[agent-sdk] deployment-events: ${event.eventType} ${event.repo}@${event.sha} (${event.environment}) → ${matched.length - failures.length}/${matched.length} channel(s)`);
105
+ logger(`[agent-sdk] deployment-events: ${event.eventType} ${event.deploySourceUri}@${event.deployVersion} (${event.environment}) → ${matched.length - failures.length}/${matched.length} channel(s)`);
105
106
  if (failures.length > 0 && failures.length === matched.length) {
106
107
  throw new Error(`deployment-events: every subscribed channel failed on ${event.eventId} (${failures.join(", ")})`);
107
108
  }
@@ -111,7 +112,7 @@ export class DeploymentEventRelay {
111
112
  constructor(options) {
112
113
  this.options = options;
113
114
  this.subscribed = new Map();
114
- this.loggedSkippedRepos = new Set();
115
+ this.loggedSkippedSources = new Set();
115
116
  const adapter = {
116
117
  logPrefix: "deployment-events",
117
118
  subscribePath: "/v0/deployment-events/subscriptions",
@@ -119,7 +120,7 @@ export class DeploymentEventRelay {
119
120
  buildRegistrationBody: (consumerId) => ({
120
121
  consumerId,
121
122
  subscriptions: options.subscriptions.map((subscription) => ({
122
- repo: subscription.repo,
123
+ deploySourceUri: subscription.deploySourceUri,
123
124
  environments: subscription.environments,
124
125
  events: [...subscription.events],
125
126
  })),
@@ -134,17 +135,17 @@ export class DeploymentEventRelay {
134
135
  var _a, _b;
135
136
  const result = json;
136
137
  this.subscribed = new Map();
137
- this.loggedSkippedRepos.clear();
138
+ this.loggedSkippedSources.clear();
138
139
  const lines = [];
139
140
  const confirmed = [];
140
- for (const status of (_a = result.repos) !== null && _a !== void 0 ? _a : []) {
141
- const wanted = options.subscriptions.find((subscription) => subscription.repo === status.repo);
141
+ for (const status of (_a = result.deploySourceUris) !== null && _a !== void 0 ? _a : []) {
142
+ const wanted = options.subscriptions.find((subscription) => subscription.deploySourceUri === status.deploySourceUri);
142
143
  if (!status.isSubscribed || wanted === undefined) {
143
- lines.push(`not subscribed to ${status.repo}: ${(_b = status.detail) !== null && _b !== void 0 ? _b : "unknown reason"}`);
144
+ lines.push(`not subscribed to ${status.deploySourceUri}: ${(_b = status.detail) !== null && _b !== void 0 ? _b : "unknown reason"}`);
144
145
  continue;
145
146
  }
146
- this.subscribed.set(status.repo, wanted);
147
- confirmed.push(status.repo);
147
+ this.subscribed.set(status.deploySourceUri, wanted);
148
+ confirmed.push(status.deploySourceUri);
148
149
  }
149
150
  if (confirmed.length > 0) {
150
151
  const kinds = [
@@ -177,14 +178,14 @@ export class DeploymentEventRelay {
177
178
  const envelope = event;
178
179
  if (envelope === null ||
179
180
  typeof envelope !== "object" ||
180
- typeof envelope.repo !== "string") {
181
+ typeof envelope.deploySourceUri !== "string") {
181
182
  return false;
182
183
  }
183
- const subscription = this.subscribed.get(envelope.repo);
184
+ const subscription = this.subscribed.get(envelope.deploySourceUri);
184
185
  if (subscription === undefined) {
185
- if (!this.loggedSkippedRepos.has(envelope.repo)) {
186
- this.loggedSkippedRepos.add(envelope.repo);
187
- this.options.logger(`[agent-sdk] deployment-events: skipping events for ${envelope.repo}: not in this host's subscription (another consumer of this API key likely subscribed it)`);
186
+ if (!this.loggedSkippedSources.has(envelope.deploySourceUri)) {
187
+ this.loggedSkippedSources.add(envelope.deploySourceUri);
188
+ this.options.logger(`[agent-sdk] deployment-events: skipping events for ${envelope.deploySourceUri}: not in this host's subscription (another consumer of this API key likely subscribed it)`);
188
189
  }
189
190
  return false;
190
191
  }
@@ -13,6 +13,7 @@
13
13
  import type { GitHubChannelOptions } from "../channels/github/types.js";
14
14
  import type { OriginChannelOptions } from "../channels/origin/types.js";
15
15
  import type { ChannelHandlerArgs } from "../types.js";
16
+ import { type RouteLocalIngressContinuation } from "./local-ingress.js";
16
17
  export interface AgentServeGitHubTriggerTarget {
17
18
  /** Agent mount slug (empty string in single-agent mode). */
18
19
  slug: string;
@@ -28,6 +29,8 @@ export interface AgentServeGitHubTriggerEvent {
28
29
  eventName: string | null;
29
30
  deliveryId?: string;
30
31
  targets: AgentServeGitHubTriggerTarget[];
32
+ /** Local CP ingest. Defaults to {@link routeLocalIngressContinuation}. */
33
+ routeContinuation?: RouteLocalIngressContinuation;
31
34
  }
32
35
  export interface AgentServeOriginTriggerTarget {
33
36
  slug: string;
@@ -39,6 +42,8 @@ export interface AgentServeOriginTriggerEvent {
39
42
  /** Origin envelope JSON (signature already verified by the caller). */
40
43
  bodyText: string;
41
44
  targets: AgentServeOriginTriggerTarget[];
45
+ /** Local CP ingest. Defaults to {@link routeLocalIngressContinuation}. */
46
+ routeContinuation?: RouteLocalIngressContinuation;
42
47
  }
43
48
  export type AgentServeTriggerEvent = AgentServeGitHubTriggerEvent | AgentServeOriginTriggerEvent;
44
49
  export interface AgentServeTriggerTargetResult {
@@ -1 +1 @@
1
- {"version":3,"file":"handleAgentServeTrigger.d.ts","sourceRoot":"","sources":["../../src/internal/handleAgentServeTrigger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAMxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,6BAA6B;IAC5C,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,uEAAuE;IACvE,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,QAAQ,CAAC;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,QAAQ,CAAC;IACf,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,sBAAsB,GAC9B,4BAA4B,GAC5B,4BAA4B,CAAC;AAEjC,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpD,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,kBAAkB,CAAC;KAC7D,CAAC,CAAC;CACJ,GAAG,6BAA6B,EAAE,CAgBlC;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpD,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,kBAAkB,CAAC;KAC7D,CAAC,CAAC;CACJ,GAAG,6BAA6B,EAAE,CAgBlC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CAalC"}
1
+ {"version":3,"file":"handleAgentServeTrigger.d.ts","sourceRoot":"","sources":["../../src/internal/handleAgentServeTrigger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAOxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,6BAA6B;IAC5C,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,uEAAuE;IACvE,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,QAAQ,CAAC;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,6BAA6B,EAAE,CAAC;IACzC,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,6BAA6B,CAAC;CACnD;AAED,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,QAAQ,CAAC;IACf,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,6BAA6B,EAAE,CAAC;IACzC,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,6BAA6B,CAAC;CACnD;AAED,MAAM,MAAM,sBAAsB,GAC9B,4BAA4B,GAC5B,4BAA4B,CAAC;AAEjC,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpD,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,kBAAkB,CAAC;KAC7D,CAAC,CAAC;CACJ,GAAG,6BAA6B,EAAE,CAgBlC;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpD,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,kBAAkB,CAAC;KAC7D,CAAC,CAAC;CACJ,GAAG,6BAA6B,EAAE,CAgBlC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CAalC"}
@@ -20,7 +20,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
20
20
  });
21
21
  };
22
22
  import { dispatchGitHubWebhook, getGitHubChannelOptions, } from "../channels/github/github-channel.js";
23
- import { dispatchOriginWebhook, getOriginChannelOptions, parseOriginWebhookEnvelope, } from "../channels/origin/origin-channel.js";
23
+ import { dispatchOriginWebhook, getOriginChannelOptions, originIngressExtractPayload, parseOriginWebhookEnvelope, } from "../channels/origin/origin-channel.js";
24
+ import { bindLocalIngressSend, } from "./local-ingress.js";
24
25
  /**
25
26
  * Build fan-out targets from mounted agent projects that export a github
26
27
  * channel created via {@link githubChannel}.
@@ -108,12 +109,17 @@ function handleAgentServeGitHubTrigger(event) {
108
109
  }
109
110
  const targets = [];
110
111
  for (const target of event.targets) {
112
+ const args = event.eventName === null
113
+ ? target.args
114
+ : bindLocalIngressSend(target.args, Object.assign({ identity: target.options.continuation, kind: "github", eventType: event.eventName, payload }, (event.routeContinuation === undefined
115
+ ? {}
116
+ : { routeContinuation: event.routeContinuation })));
111
117
  const response = yield dispatchGitHubWebhook({
112
118
  options: target.options,
113
119
  eventName: event.eventName,
114
120
  payload,
115
121
  deliveryId: event.deliveryId,
116
- args: target.args,
122
+ args,
117
123
  });
118
124
  targets.push(yield triggerTargetResult(target.slug, response));
119
125
  }
@@ -162,7 +168,9 @@ function handleAgentServeOriginTrigger(event) {
162
168
  const response = yield dispatchOriginWebhook({
163
169
  options: target.options,
164
170
  envelope,
165
- args: target.args,
171
+ args: bindLocalIngressSend(target.args, Object.assign({ identity: target.options.continuation, kind: "origin", eventType: envelope.event.type, payload: originIngressExtractPayload(envelope) }, (event.routeContinuation === undefined
172
+ ? {}
173
+ : { routeContinuation: event.routeContinuation }))),
166
174
  });
167
175
  targets.push(yield triggerTargetResult(target.slug, response));
168
176
  }
@@ -2,9 +2,28 @@
2
2
  * In-process control plane started with local `serve`. Owns schedule clocks
3
3
  * and reminder documents + clocks, then fires into the kit the same way the
4
4
  * Cursor backend does over HTTP when `--no-control-plane` is set.
5
+ *
6
+ * v2 ingest lives here: `routeContinuation` stamps the mailbox (July twin
7
+ * of hosted `routeVerifiedIngressContinuation`), and `attachScmEvents`
8
+ * owns the `/v0/scm-events` long poll. v1 keeps engine-side scm-events.
9
+ * Hosted `--no-control-plane` v2 skips that poll — the hosted CP delivers.
5
10
  */
11
+ import { type LocalIngressContinuation, type RouteLocalIngressContinuationInput } from "./local-ingress.js";
6
12
  import type { PlatformTimers } from "./platform-timers.js";
7
13
  export interface LocalControlPlane extends PlatformTimers {
14
+ /**
15
+ * Stamp a v2 mailbox from the channel selector + live payload. Same
16
+ * contract as hosted verified ingress. `/v1` is a no-op.
17
+ */
18
+ routeContinuation(input: RouteLocalIngressContinuationInput): LocalIngressContinuation;
19
+ /**
20
+ * Take ownership of the v2 `/v0/scm-events` long poll. Starts the relay.
21
+ * v1 scm-events stay on the engine serve path.
22
+ */
23
+ attachScmEvents(relay: {
24
+ start(): void;
25
+ stop(): Promise<void>;
26
+ }): void;
8
27
  /** Arm persisted reminder clocks after the kit fire callback is live. */
9
28
  startClocks(): void;
10
29
  stop(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"local-control-plane.d.ts","sourceRoot":"","sources":["../../src/internal/local-control-plane.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,yEAAyE;IACzE,WAAW,IAAI,IAAI,CAAC;IACpB,IAAI,IAAI,IAAI,CAAC;CACd;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA6J7B"}
1
+ {"version":3,"file":"local-control-plane.d.ts","sourceRoot":"","sources":["../../src/internal/local-control-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,kCAAkC,EAExC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;;OAGG;IACH,iBAAiB,CACf,KAAK,EAAE,kCAAkC,GACxC,wBAAwB,CAAC;IAC5B;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE;QAAE,KAAK,IAAI,IAAI,CAAC;QAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE,yEAAyE;IACzE,WAAW,IAAI,IAAI,CAAC;IACpB,IAAI,IAAI,IAAI,CAAC;CACd;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwK7B"}
@@ -2,6 +2,11 @@
2
2
  * In-process control plane started with local `serve`. Owns schedule clocks
3
3
  * and reminder documents + clocks, then fires into the kit the same way the
4
4
  * Cursor backend does over HTTP when `--no-control-plane` is set.
5
+ *
6
+ * v2 ingest lives here: `routeContinuation` stamps the mailbox (July twin
7
+ * of hosted `routeVerifiedIngressContinuation`), and `attachScmEvents`
8
+ * owns the `/v0/scm-events` long poll. v1 keeps engine-side scm-events.
9
+ * Hosted `--no-control-plane` v2 skips that poll — the hosted CP delivers.
5
10
  */
6
11
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
7
12
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -14,6 +19,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
14
19
  };
15
20
  import { dirname, join } from "node:path";
16
21
  import { parseCron } from "./cron.js";
22
+ import { routeLocalIngressContinuation, } from "./local-ingress.js";
17
23
  import { MAX_TIMER_MS } from "./reminder-schedule.js";
18
24
  import { ReminderStore } from "./reminder-store.js";
19
25
  export function createLocalControlPlane(opts) {
@@ -29,6 +35,7 @@ export function createLocalControlPlane(opts) {
29
35
  const reminders = new Map();
30
36
  let scheduleTimer;
31
37
  let lastFiredMinute = -1;
38
+ let scmRelay;
32
39
  if (store !== undefined) {
33
40
  for (const record of yield store.list()) {
34
41
  reminders.set(record.id, record);
@@ -109,6 +116,12 @@ export function createLocalControlPlane(opts) {
109
116
  reminderTimers.set(record.id, timer);
110
117
  }
111
118
  return {
119
+ routeContinuation: routeLocalIngressContinuation,
120
+ attachScmEvents(relay) {
121
+ scmRelay = relay;
122
+ relay.start();
123
+ logger("[agent-sdk] cursor-events: control-plane ingest started");
124
+ },
112
125
  upsertSchedule(input) {
113
126
  return __awaiter(this, void 0, void 0, function* () {
114
127
  schedules.set(input.name, parseCron(input.cron));
@@ -166,6 +179,10 @@ export function createLocalControlPlane(opts) {
166
179
  for (const id of [...reminderTimers.keys()]) {
167
180
  clearReminderTimer(id);
168
181
  }
182
+ if (scmRelay !== undefined) {
183
+ void scmRelay.stop();
184
+ scmRelay = undefined;
185
+ }
169
186
  },
170
187
  };
171
188
  });
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Local control-plane ingest for v2 continuation.
3
+ *
4
+ * Twin of backend `routeVerifiedIngressContinuation`. Hosted Cursor runs
5
+ * that copy after the webhook is verified. Self-hosted / `july serve`
6
+ * runs this copy on the in-process local CP before the channel adapter
7
+ * `send()`s. Channel adapters do not extract.
8
+ */
9
+ import type { ChannelHandlerArgs } from "../types.js";
10
+ import { type ContinuationIdentity, type MailboxContinuation } from "./continuation-identity.js";
11
+ export type LocalIngressContinuation = {
12
+ explicitContinuationKey?: string;
13
+ mailboxContinuation?: MailboxContinuation;
14
+ };
15
+ export type RouteLocalIngressContinuation = (input: RouteLocalIngressContinuationInput) => LocalIngressContinuation;
16
+ export type RouteLocalIngressContinuationInput = {
17
+ identity?: ContinuationIdentity;
18
+ kind?: string;
19
+ eventType: string;
20
+ payload: unknown;
21
+ deterministicContinuationKey?: string;
22
+ };
23
+ /**
24
+ * Selector + live payload → mailbox stamp. `/v1` and omitted identity
25
+ * keep the caller-supplied deterministic key and do not stamp a mailbox.
26
+ */
27
+ export declare function routeLocalIngressContinuation(input: RouteLocalIngressContinuationInput): LocalIngressContinuation;
28
+ /**
29
+ * Bind a CP mailbox stamp onto `args.send` so the channel adapter only
30
+ * calls `send()` — it does not extract. No-op for `/v1`.
31
+ */
32
+ export declare function bindLocalIngressSend(args: ChannelHandlerArgs, input: RouteLocalIngressContinuationInput & {
33
+ routeContinuation?: RouteLocalIngressContinuation;
34
+ }): ChannelHandlerArgs;
35
+ //# sourceMappingURL=local-ingress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-ingress.d.ts","sourceRoot":"","sources":["../../src/internal/local-ingress.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAEL,KAAK,oBAAoB,EAEzB,KAAK,mBAAmB,EAGzB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,wBAAwB,GAAG;IACrC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG,CAC1C,KAAK,EAAE,kCAAkC,KACtC,wBAAwB,CAAC;AAE9B,MAAM,MAAM,kCAAkC,GAAG;IAC/C,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B,CAAC,EAAE,MAAM,CAAC;CACvC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,kCAAkC,GACxC,wBAAwB,CA6B1B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,kBAAkB,EACxB,KAAK,EAAE,kCAAkC,GAAG;IAC1C,iBAAiB,CAAC,EAAE,6BAA6B,CAAC;CACnD,GACA,kBAAkB,CAOpB"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Local control-plane ingest for v2 continuation.
3
+ *
4
+ * Twin of backend `routeVerifiedIngressContinuation`. Hosted Cursor runs
5
+ * that copy after the webhook is verified. Self-hosted / `july serve`
6
+ * runs this copy on the in-process local CP before the channel adapter
7
+ * `send()`s. Channel adapters do not extract.
8
+ */
9
+ import { bindMailboxContinuationSend, continuationSource, normalizeIdentity, stampMailboxContinuation, } from "./continuation-identity.js";
10
+ /**
11
+ * Selector + live payload → mailbox stamp. `/v1` and omitted identity
12
+ * keep the caller-supplied deterministic key and do not stamp a mailbox.
13
+ */
14
+ export function routeLocalIngressContinuation(input) {
15
+ if (input.identity === undefined) {
16
+ return Object.assign({}, (input.deterministicContinuationKey === undefined
17
+ ? {}
18
+ : { explicitContinuationKey: input.deterministicContinuationKey }));
19
+ }
20
+ const identity = normalizeIdentity(input.identity, input.kind);
21
+ if (continuationSource(identity, input.kind) !== "control-plane") {
22
+ return Object.assign({}, (input.deterministicContinuationKey === undefined
23
+ ? {}
24
+ : { explicitContinuationKey: input.deterministicContinuationKey }));
25
+ }
26
+ const mailboxContinuation = stampMailboxContinuation(identity, input.eventType, input.payload, input.kind);
27
+ if (mailboxContinuation.key.startsWith("cont:")) {
28
+ return {
29
+ explicitContinuationKey: mailboxContinuation.key,
30
+ mailboxContinuation,
31
+ };
32
+ }
33
+ return { mailboxContinuation };
34
+ }
35
+ /**
36
+ * Bind a CP mailbox stamp onto `args.send` so the channel adapter only
37
+ * calls `send()` — it does not extract. No-op for `/v1`.
38
+ */
39
+ export function bindLocalIngressSend(args, input) {
40
+ var _a;
41
+ const route = (_a = input.routeContinuation) !== null && _a !== void 0 ? _a : routeLocalIngressContinuation;
42
+ const routed = route(input);
43
+ return Object.assign(Object.assign({}, args), { send: bindMailboxContinuationSend(args.send, routed.mailboxContinuation) });
44
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0CH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAwHrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAwBpE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAaD,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,CAo0B3B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0CH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAyHrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAwBpE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAmCD,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,CAy3B3B"}