@cursor/july 0.1.55 → 0.1.61
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/bin/agent-serve.js +30 -23
- package/dist/channels/github/github-channel.d.ts +12 -0
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +67 -15
- package/dist/channels/github/types.d.ts +27 -1
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/origin/cursor-account.d.ts +22 -0
- package/dist/channels/origin/cursor-account.d.ts.map +1 -0
- package/dist/channels/origin/cursor-account.js +35 -0
- package/dist/channels/origin/events.d.ts +10 -0
- package/dist/channels/origin/events.d.ts.map +1 -0
- package/dist/channels/origin/events.js +27 -0
- package/dist/channels/origin/index.d.ts +29 -0
- package/dist/channels/origin/index.d.ts.map +1 -0
- package/dist/channels/origin/index.js +28 -0
- package/dist/channels/origin/origin-channel.d.ts +68 -0
- package/dist/channels/origin/origin-channel.d.ts.map +1 -0
- package/dist/channels/origin/origin-channel.js +567 -0
- package/dist/channels/origin/origin-webhook.d.ts +38 -0
- package/dist/channels/origin/origin-webhook.d.ts.map +1 -0
- package/dist/channels/origin/origin-webhook.js +151 -0
- package/dist/channels/origin/types.d.ts +152 -0
- package/dist/channels/origin/types.d.ts.map +1 -0
- package/dist/channels/origin/types.js +1 -0
- package/dist/channels/slack/doctor.d.ts +17 -1
- package/dist/channels/slack/doctor.d.ts.map +1 -1
- package/dist/channels/slack/doctor.js +186 -10
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.CVQxhV85.js → app.CW3KJh72.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BuymfBAo.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.QAPzJjql.js → VPLocalSearchBox.Bk6EWpPj.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CSxTCOFu.js → theme.Bz9AodBA.js} +2 -2
- package/dist/docs/assets/{example-agents_fsd.md.DPz9ezO4.js → example-agents_fsd.md.ZeGEpAw_.js} +2 -2
- package/dist/docs/assets/{example-agents_fsd.md.DPz9ezO4.lean.js → example-agents_fsd.md.ZeGEpAw_.lean.js} +1 -1
- package/dist/docs/assets/{example-agents_security-reviewer.md.Dkf1gyo6.js → example-agents_security-reviewer.md.DBL1TwtP.js} +2 -2
- package/dist/docs/assets/{example-agents_security-reviewer.md.Dkf1gyo6.lean.js → example-agents_security-reviewer.md.DBL1TwtP.lean.js} +1 -1
- package/dist/docs/assets/guides_convert-automation.md.BhMzTkE5.js +12 -0
- package/dist/docs/assets/guides_convert-automation.md.BhMzTkE5.lean.js +1 -0
- package/dist/docs/assets/{guides_github.md.B8QKtIpw.js → guides_github.md.CLLQJKRB.js} +4 -4
- package/dist/docs/assets/{guides_github.md.B8QKtIpw.lean.js → guides_github.md.CLLQJKRB.lean.js} +1 -1
- package/dist/docs/assets/index.md.DhRHS_-L.js +5 -0
- package/dist/docs/assets/{index.md.COeoSkcF.lean.js → index.md.DhRHS_-L.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.D_CCfG8R.js → reference_cli.md.Cl14Jfo3.js} +8 -2
- package/dist/docs/assets/{reference_cli.md.D_CCfG8R.lean.js → reference_cli.md.Cl14Jfo3.lean.js} +1 -1
- package/dist/docs/assets/scaffolding-agents.md.CrWSA0Ko.js +1 -0
- package/dist/docs/assets/{scaffolding-agents.md.mkc3B_ZW.lean.js → scaffolding-agents.md.CrWSA0Ko.lean.js} +1 -1
- package/dist/docs/assets/templates_agentic-owners.md.BkTLORaU.js +14 -0
- package/dist/docs/assets/templates_agentic-owners.md.BkTLORaU.lean.js +1 -0
- package/dist/docs/assets/templates_demo.md.Bgd6MBaZ.js +4 -0
- package/dist/docs/assets/templates_demo.md.Bgd6MBaZ.lean.js +1 -0
- package/dist/docs/assets/templates_pr-autofixer.md.DcmoeUNZ.js +8 -0
- package/dist/docs/assets/templates_pr-autofixer.md.DcmoeUNZ.lean.js +1 -0
- package/dist/docs/assets/templates_security-reviewer.md.C0yIUaYs.js +2 -0
- package/dist/docs/assets/templates_security-reviewer.md.C0yIUaYs.lean.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/deployment.html +4 -4
- 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 +5 -5
- 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 +5 -5
- 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/convert-automation.html +36 -0
- package/dist/docs/guides/github.html +7 -7
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +4 -4
- package/dist/docs/guides/opentelemetry.html +4 -4
- 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/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +12 -6
- package/dist/docs/reference/connections.html +4 -4
- 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 +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +4 -4
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +38 -0
- package/dist/docs/templates/demo.html +28 -0
- package/dist/docs/templates/pr-autofixer.html +32 -0
- package/dist/docs/templates/security-reviewer.html +26 -0
- package/dist/docs/templates/triage.html +5 -5
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/internal/cli-ax.d.ts +2 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +20 -0
- package/dist/internal/cli-slack.d.ts +2 -0
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +11 -2
- package/dist/internal/cursor-event-relay.d.ts +59 -11
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +133 -26
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +11 -2
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/handleAgentServeTrigger.d.ts +33 -6
- package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
- package/dist/internal/handleAgentServeTrigger.js +97 -19
- package/dist/internal/init-interview.d.ts +67 -0
- package/dist/internal/init-interview.d.ts.map +1 -0
- package/dist/internal/init-interview.js +300 -0
- package/dist/internal/init-project.d.ts +4 -0
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +40 -16
- package/dist/internal/mcp-endpoint.d.ts +7 -0
- package/dist/internal/mcp-endpoint.d.ts.map +1 -1
- package/dist/internal/mcp-endpoint.js +7 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +159 -57
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +20 -21
- package/dist/internal/session-links.d.ts +14 -0
- package/dist/internal/session-links.d.ts.map +1 -0
- package/dist/internal/session-links.js +69 -0
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +1 -0
- package/dist/playground/assets/index-ClbuaLpm.css +1 -0
- package/dist/playground/assets/{index-0oqXUkrR.js → index-SqkR13k_.js} +39 -39
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +19 -12
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +15 -0
- package/docs/example-agents/fsd.md +3 -0
- package/docs/example-agents/security-reviewer.md +3 -0
- package/docs/guides/convert-automation.md +176 -0
- package/docs/guides/github.md +6 -2
- package/docs/reference/cli.md +34 -10
- package/docs/scaffolding-agents.md +3 -0
- package/docs/templates/agentic-owners.md +97 -0
- package/docs/templates/demo.md +84 -0
- package/docs/templates/pr-autofixer.md +136 -0
- package/docs/templates/security-reviewer.md +89 -0
- package/package.json +9 -1
- package/skills/github/SKILL.md +4 -5
- package/src/bin/agent-serve.ts +13 -6
- package/src/channels/github/github-channel.ts +95 -18
- package/src/channels/github/types.ts +31 -0
- package/src/channels/origin/cursor-account.ts +64 -0
- package/src/channels/origin/events.ts +41 -0
- package/src/channels/origin/index.ts +29 -0
- package/src/channels/origin/origin-channel.ts +784 -0
- package/src/channels/origin/origin-webhook.ts +202 -0
- package/src/channels/origin/types.ts +186 -0
- package/src/channels/slack/doctor.ts +218 -5
- package/src/index.ts +3 -1
- package/src/internal/cli-ax.ts +23 -0
- package/src/internal/cli-slack.ts +11 -1
- package/src/internal/cursor-event-relay.ts +193 -31
- package/src/internal/discovery.ts +15 -5
- package/src/internal/distribution.ts +1 -0
- package/src/internal/handleAgentServeTrigger.ts +129 -19
- package/src/internal/init-interview.ts +384 -0
- package/src/internal/init-project.ts +70 -15
- package/src/internal/mcp-endpoint.ts +7 -0
- package/src/internal/server.ts +188 -58
- package/src/internal/session-engine.ts +5 -21
- package/src/internal/session-links.ts +88 -0
- package/src/internal/sessions-client.ts +1 -0
- package/src/types.ts +19 -12
- package/templates/agentic-owners/README.md +73 -0
- package/templates/agentic-owners/agent/agent.ts +15 -0
- package/templates/agentic-owners/agent/channels/github.ts +85 -0
- package/templates/agentic-owners/agent/instructions.md +34 -0
- package/templates/agentic-owners/agent/lib/config.ts +13 -0
- package/templates/agentic-owners/agent/lib/github.ts +241 -0
- package/templates/agentic-owners/agent/lib/owners/README.md +50 -0
- package/templates/agentic-owners/agent/lib/owners/constants.ts +22 -0
- package/templates/agentic-owners/agent/lib/owners/decision.ts +485 -0
- package/templates/agentic-owners/agent/lib/owners/handles.ts +54 -0
- package/templates/agentic-owners/agent/lib/owners/match.ts +177 -0
- package/templates/agentic-owners/agent/lib/owners/matching.ts +95 -0
- package/templates/agentic-owners/agent/lib/owners/parse.ts +589 -0
- package/templates/agentic-owners/agent/lib/owners/policyMode.ts +65 -0
- package/templates/agentic-owners/agent/lib/owners/prompt.ts +66 -0
- package/templates/agentic-owners/agent/lib/owners/prompts/base-review.md +105 -0
- package/templates/agentic-owners/agent/lib/owners/types.ts +45 -0
- package/templates/agentic-owners/agent/lib/review.ts +777 -0
- package/templates/agentic-owners/agent/tools/record_review.ts +69 -0
- package/templates/agentic-owners/evals/evals.config.ts +5 -0
- package/templates/agentic-owners/evals/owners.eval.ts +116 -0
- package/templates/agentic-owners/package.json +20 -0
- package/templates/agentic-owners/tsconfig.json +12 -0
- package/templates/demo/README.md +33 -0
- package/templates/demo/agent/agent.ts +15 -0
- package/templates/demo/agent/channels/github.ts +50 -0
- package/templates/demo/agent/channels/queue.ts +30 -0
- package/templates/demo/agent/instructions.md +8 -0
- package/templates/demo/agent/lib/collect.ts +78 -0
- package/templates/demo/agent/tools/record_demo.ts +40 -0
- package/templates/demo/evals/demo.eval.ts +33 -0
- package/templates/demo/evals/evals.config.ts +5 -0
- package/templates/demo/package.json +18 -0
- package/templates/demo/tsconfig.json +12 -0
- package/templates/pr-autofixer/README.md +44 -0
- package/templates/pr-autofixer/agent/agent.ts +22 -0
- package/templates/pr-autofixer/agent/channels/drive.ts +40 -0
- package/templates/pr-autofixer/agent/channels/github.ts +167 -0
- package/templates/pr-autofixer/agent/channels/slack.ts +17 -0
- package/templates/pr-autofixer/agent/hooks/bind-agent.ts +19 -0
- package/templates/pr-autofixer/agent/instructions.md +83 -0
- package/templates/pr-autofixer/agent/lib/affinity.ts +33 -0
- package/templates/pr-autofixer/agent/lib/drive-schemas.ts +15 -0
- package/templates/pr-autofixer/agent/lib/drive.ts +79 -0
- package/templates/pr-autofixer/agent/lib/merge-watch.ts +123 -0
- package/templates/pr-autofixer/agent/lib/pr-state.ts +54 -0
- package/templates/pr-autofixer/agent/lib/repos.ts +19 -0
- package/templates/pr-autofixer/agent/lib/start-drive.ts +122 -0
- package/templates/pr-autofixer/agent/lib/webhook-buffer.ts +225 -0
- package/templates/pr-autofixer/agent/lib/webhook-routing.ts +231 -0
- package/templates/pr-autofixer/agent/storage.ts +7 -0
- package/templates/pr-autofixer/agent/tools/drive_pr.ts +22 -0
- package/templates/pr-autofixer/evals/coordinator.eval.ts +16 -0
- package/templates/pr-autofixer/evals/evals.config.ts +5 -0
- package/templates/pr-autofixer/init.json +25 -0
- package/templates/pr-autofixer/package.json +18 -0
- package/templates/pr-autofixer/tsconfig.json +12 -0
- package/templates/security-reviewer/README.md +31 -0
- package/templates/security-reviewer/agent/agent.ts +15 -0
- package/templates/security-reviewer/agent/channels/github.ts +46 -0
- package/templates/security-reviewer/agent/instructions.md +22 -0
- package/templates/security-reviewer/agent/lib/repos.ts +5 -0
- package/templates/security-reviewer/agent/tools/post_findings.ts +72 -0
- package/templates/security-reviewer/evals/evals.config.ts +5 -0
- package/templates/security-reviewer/evals/review.eval.ts +53 -0
- package/templates/security-reviewer/init.json +25 -0
- package/templates/security-reviewer/package.json +18 -0
- package/templates/security-reviewer/tsconfig.json +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.BFpWSo6D.js +0 -1
- package/dist/docs/assets/index.md.COeoSkcF.js +0 -5
- package/dist/docs/assets/scaffolding-agents.md.mkc3B_ZW.js +0 -1
- package/dist/playground/assets/index-tHCjJxv4.css +0 -1
package/src/internal/server.ts
CHANGED
|
@@ -17,7 +17,6 @@ import { join } from "node:path";
|
|
|
17
17
|
import {
|
|
18
18
|
type CursorGithubRepoScope,
|
|
19
19
|
createCursorAccountGithubTokenResolver,
|
|
20
|
-
cursorGithubPermissionsForChannel,
|
|
21
20
|
type GithubCursorAccountRuntime,
|
|
22
21
|
getGithubCursorAccountRuntime,
|
|
23
22
|
parseCursorGithubRepoScope,
|
|
@@ -25,6 +24,12 @@ import {
|
|
|
25
24
|
resolveCursorGithubProxyUrl,
|
|
26
25
|
} from "../channels/github/cursor-account.js";
|
|
27
26
|
import { findGitHubChannelTargets } from "../channels/github/forward.js";
|
|
27
|
+
import {
|
|
28
|
+
getOriginCursorAccountRuntime,
|
|
29
|
+
type OriginCursorAccountRuntime,
|
|
30
|
+
parseCursorOriginRepoScope,
|
|
31
|
+
} from "../channels/origin/cursor-account.js";
|
|
32
|
+
import { findOriginChannelTargets } from "../channels/origin/origin-channel.js";
|
|
28
33
|
import {
|
|
29
34
|
dispatchCursorSlackEnvelope,
|
|
30
35
|
getSlackCursorAccountRuntime,
|
|
@@ -59,9 +64,11 @@ import {
|
|
|
59
64
|
import { CursorGithubCredentialProvider } from "./cursor/github-credentials.js";
|
|
60
65
|
import {
|
|
61
66
|
CursorEventRelay,
|
|
67
|
+
type CursorScmSubscription,
|
|
62
68
|
formatCursorScmDispatchOutcome,
|
|
63
69
|
formatCursorScmEventLog,
|
|
64
70
|
scmMetadataToGitHubPayload,
|
|
71
|
+
scmMetadataToOriginPayload,
|
|
65
72
|
} from "./cursor-event-relay.js";
|
|
66
73
|
import {
|
|
67
74
|
type CursorSlackAgentRegistration,
|
|
@@ -89,6 +96,7 @@ import {
|
|
|
89
96
|
} from "./eval-run-store.js";
|
|
90
97
|
import {
|
|
91
98
|
collectGitHubTriggerTargets,
|
|
99
|
+
collectOriginTriggerTargets,
|
|
92
100
|
handleAgentServeTrigger,
|
|
93
101
|
} from "./handleAgentServeTrigger.js";
|
|
94
102
|
import { createHostPlatforms, warmupHostGitHubAuth } from "./host-platforms.js";
|
|
@@ -151,11 +159,7 @@ import {
|
|
|
151
159
|
} from "./resolved-connections.js";
|
|
152
160
|
import { Router } from "./router.js";
|
|
153
161
|
import { ScheduleRunner, UnknownScheduleError } from "./schedule-runner.js";
|
|
154
|
-
import {
|
|
155
|
-
type AgentRunner,
|
|
156
|
-
CursorSdkRunner,
|
|
157
|
-
resolveServeWorkspaceScanCacheTtlMs,
|
|
158
|
-
} from "./sdk-runner.js";
|
|
162
|
+
import { type AgentRunner, CursorSdkRunner } from "./sdk-runner.js";
|
|
159
163
|
import {
|
|
160
164
|
SessionAuthError,
|
|
161
165
|
SessionBusyError,
|
|
@@ -267,11 +271,20 @@ export async function startServer(
|
|
|
267
271
|
}
|
|
268
272
|
|
|
269
273
|
const cursorGithubTargets = collectCursorGithubTargets(mounts);
|
|
274
|
+
const cursorOriginTargets = collectCursorOriginTargets(mounts);
|
|
270
275
|
const cursorGithubConfig = resolveCursorGithubEventConfig({
|
|
271
276
|
configured: options.cursorEvents,
|
|
272
277
|
targets: cursorGithubTargets,
|
|
273
278
|
});
|
|
274
|
-
const
|
|
279
|
+
const cursorOriginScope = resolveCursorOriginRepoScope({
|
|
280
|
+
explicitRepos: options.cursorEvents?.repos ?? [],
|
|
281
|
+
targets: cursorOriginTargets,
|
|
282
|
+
});
|
|
283
|
+
const effectiveCursorEvents =
|
|
284
|
+
cursorGithubConfig.cursorEvents ??
|
|
285
|
+
(cursorOriginScope === undefined
|
|
286
|
+
? undefined
|
|
287
|
+
: { repos: [...cursorOriginScope.repos] });
|
|
275
288
|
|
|
276
289
|
// One resolution for every Cursor credential consumer (SDK runner, account
|
|
277
290
|
// MCP bridge, SCM event relay, GitHub credentials): explicit option →
|
|
@@ -379,17 +392,11 @@ export async function startServer(
|
|
|
379
392
|
"[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"
|
|
380
393
|
);
|
|
381
394
|
}
|
|
382
|
-
const workspaceScanCacheTtlMs = resolveServeWorkspaceScanCacheTtlMs({
|
|
383
|
-
dev,
|
|
384
|
-
});
|
|
385
395
|
const runner =
|
|
386
396
|
options.runner ??
|
|
387
397
|
new CursorSdkRunner({
|
|
388
398
|
...(accountKey === undefined ? {} : { apiKey: accountKey.apiKey }),
|
|
389
399
|
logger,
|
|
390
|
-
...(workspaceScanCacheTtlMs === undefined
|
|
391
|
-
? {}
|
|
392
|
-
: { workspaceScanCacheTtlMs }),
|
|
393
400
|
});
|
|
394
401
|
|
|
395
402
|
const router = new Router();
|
|
@@ -684,7 +691,7 @@ export async function startServer(
|
|
|
684
691
|
// job (backend `/github_webhook` already verified); we only admit loopback
|
|
685
692
|
// so this route is not a public unsigned endpoint. Agents decide whether
|
|
686
693
|
// to run via their onPullRequest / onComment / … hooks.
|
|
687
|
-
const
|
|
694
|
+
const collectGitHubTargets = () =>
|
|
688
695
|
collectGitHubTriggerTargets({
|
|
689
696
|
mounts: runtimes.map((runtime) => ({
|
|
690
697
|
slug: runtime.slug,
|
|
@@ -693,6 +700,15 @@ export async function startServer(
|
|
|
693
700
|
buildChannelHandlerArgs({ runtime, channelId }),
|
|
694
701
|
})),
|
|
695
702
|
});
|
|
703
|
+
const collectOriginTargets = () =>
|
|
704
|
+
collectOriginTriggerTargets({
|
|
705
|
+
mounts: runtimes.map((runtime) => ({
|
|
706
|
+
slug: runtime.slug,
|
|
707
|
+
channels: runtime.project.channels,
|
|
708
|
+
buildHandlerArgs: (channelId) =>
|
|
709
|
+
buildChannelHandlerArgs({ runtime, channelId }),
|
|
710
|
+
})),
|
|
711
|
+
});
|
|
696
712
|
router.add({
|
|
697
713
|
method: "POST",
|
|
698
714
|
pattern: "/v1/webhooks/github",
|
|
@@ -704,7 +720,7 @@ export async function startServer(
|
|
|
704
720
|
bodyText,
|
|
705
721
|
eventName: request.headers.get("x-github-event"),
|
|
706
722
|
deliveryId: request.headers.get("x-github-delivery") ?? undefined,
|
|
707
|
-
targets:
|
|
723
|
+
targets: collectGitHubTargets(),
|
|
708
724
|
});
|
|
709
725
|
const status = result.ok ? 202 : (result.targets[0]?.status ?? 500);
|
|
710
726
|
return jsonResponse(result, { status });
|
|
@@ -743,13 +759,17 @@ export async function startServer(
|
|
|
743
759
|
// Cursor SCM events relay (opt-in: serve({ cursorEvents }) / --cursor-events).
|
|
744
760
|
const cursorEventRelay = startCursorEventRelay({
|
|
745
761
|
config: effectiveCursorEvents,
|
|
762
|
+
githubRepos: cursorGithubConfig.cursorEvents?.repos ?? [],
|
|
763
|
+
originRepos: cursorOriginScope?.repos ?? [],
|
|
746
764
|
stateRoot: options.stateRoot,
|
|
747
765
|
mounts,
|
|
748
766
|
auth: cursorEventsAuth,
|
|
749
767
|
logger,
|
|
750
|
-
|
|
768
|
+
collectGitHubTargets,
|
|
769
|
+
collectOriginTargets,
|
|
751
770
|
cursorAccountOnly:
|
|
752
|
-
options.cursorEvents === undefined &&
|
|
771
|
+
options.cursorEvents === undefined &&
|
|
772
|
+
(cursorGithubTargets.length > 0 || cursorOriginTargets.length > 0),
|
|
753
773
|
});
|
|
754
774
|
|
|
755
775
|
const server = createServer((req, res) => {
|
|
@@ -1759,37 +1779,73 @@ function requireCursorEventsAuth(
|
|
|
1759
1779
|
/**
|
|
1760
1780
|
* Opt-in Cursor SCM events relay. Credentials are already required by
|
|
1761
1781
|
* {@link requireCursorEventsAuth}; the remaining unusable configs (no repos,
|
|
1762
|
-
* no github channel) warn and leave the relay off — serve still starts.
|
|
1782
|
+
* no github/origin channel) warn and leave the relay off — serve still starts.
|
|
1783
|
+
*
|
|
1784
|
+
* GitHub and Origin subscriptions are registered independently so mirrored
|
|
1785
|
+
* `owner/name` slugs do not mix. `--cursor-events --repo` feeds GitHub
|
|
1786
|
+
* channels; Origin is subscribed only when an `originChannel({ cursorAccount })`
|
|
1787
|
+
* opted in.
|
|
1763
1788
|
*/
|
|
1764
1789
|
function startCursorEventRelay(input: {
|
|
1765
1790
|
config: ServeOptions["cursorEvents"];
|
|
1791
|
+
githubRepos: readonly string[];
|
|
1792
|
+
originRepos: readonly string[];
|
|
1766
1793
|
stateRoot: string | undefined;
|
|
1767
1794
|
mounts: AgentMount[];
|
|
1768
1795
|
auth: CursorEventsAuth | undefined;
|
|
1769
1796
|
logger: (line: string) => void;
|
|
1770
|
-
|
|
1797
|
+
collectGitHubTargets: () => ReturnType<typeof collectGitHubTriggerTargets>;
|
|
1798
|
+
collectOriginTargets: () => ReturnType<typeof collectOriginTriggerTargets>;
|
|
1771
1799
|
cursorAccountOnly: boolean;
|
|
1772
1800
|
}): CursorEventRelay | undefined {
|
|
1773
|
-
const { config, stateRoot, mounts, auth, logger
|
|
1774
|
-
input;
|
|
1801
|
+
const { config, stateRoot, mounts, auth, logger } = input;
|
|
1775
1802
|
if (config === undefined || auth === undefined) {
|
|
1776
1803
|
return undefined;
|
|
1777
1804
|
}
|
|
1778
|
-
const repos = [...new Set(config.repos.map((repo) => repo.trim()))].filter(
|
|
1779
|
-
(repo) => repo.length > 0
|
|
1780
|
-
);
|
|
1781
|
-
if (repos.length === 0) {
|
|
1782
|
-
logger(
|
|
1783
|
-
"[agent-sdk] cursor-events: no repos configured (pass --repo owner/name); relay disabled"
|
|
1784
|
-
);
|
|
1785
|
-
return undefined;
|
|
1786
|
-
}
|
|
1787
1805
|
const githubTargets = findGitHubChannelTargets(mounts);
|
|
1788
|
-
const
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1806
|
+
const originTargets = findOriginChannelTargets(mounts);
|
|
1807
|
+
const githubEvents = [
|
|
1808
|
+
...new Set(githubTargets.flatMap((target) => target.events)),
|
|
1809
|
+
];
|
|
1810
|
+
const originEvents = [
|
|
1811
|
+
...new Set(originTargets.flatMap((target) => target.events)),
|
|
1812
|
+
];
|
|
1813
|
+
const githubRepos = [
|
|
1814
|
+
...new Set(input.githubRepos.map((repo) => repo.trim().toLowerCase())),
|
|
1815
|
+
].filter((repo) => repo.length > 0);
|
|
1816
|
+
const originRepos = [
|
|
1817
|
+
...new Set(input.originRepos.map((repo) => repo.trim().toLowerCase())),
|
|
1818
|
+
].filter((repo) => repo.length > 0);
|
|
1819
|
+
|
|
1820
|
+
const subscriptions: CursorScmSubscription[] = [];
|
|
1821
|
+
if (githubEvents.length > 0 && githubRepos.length > 0) {
|
|
1822
|
+
for (const repo of githubRepos) {
|
|
1823
|
+
subscriptions.push({
|
|
1824
|
+
provider: "github",
|
|
1825
|
+
repo,
|
|
1826
|
+
events: githubEvents,
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
if (originEvents.length > 0 && originRepos.length > 0) {
|
|
1831
|
+
for (const repo of originRepos) {
|
|
1832
|
+
subscriptions.push({
|
|
1833
|
+
provider: "origin",
|
|
1834
|
+
repo,
|
|
1835
|
+
events: originEvents,
|
|
1836
|
+
});
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
if (subscriptions.length === 0) {
|
|
1840
|
+
if (githubRepos.length === 0 && originRepos.length === 0) {
|
|
1841
|
+
logger(
|
|
1842
|
+
"[agent-sdk] cursor-events: no repos configured (pass --repo owner/name); relay disabled"
|
|
1843
|
+
);
|
|
1844
|
+
} else {
|
|
1845
|
+
logger(
|
|
1846
|
+
"[agent-sdk] cursor-events: no mounted agent declares a github or origin channel; relay disabled"
|
|
1847
|
+
);
|
|
1848
|
+
}
|
|
1793
1849
|
return undefined;
|
|
1794
1850
|
}
|
|
1795
1851
|
const baseStateRoot =
|
|
@@ -1798,15 +1854,36 @@ function startCursorEventRelay(input: {
|
|
|
1798
1854
|
const relay = new CursorEventRelay({
|
|
1799
1855
|
baseUrl: auth.baseUrl,
|
|
1800
1856
|
apiKey: auth.apiKey,
|
|
1801
|
-
|
|
1802
|
-
events,
|
|
1857
|
+
subscriptions,
|
|
1803
1858
|
stateDir: join(baseStateRoot, "cursor-events"),
|
|
1804
1859
|
logger,
|
|
1805
|
-
// Stream is compact metadata (Sand-style); stub a GitHub body from the
|
|
1806
|
-
// envelope — rich pullRequest meta when present for onPullRequest Zod.
|
|
1807
1860
|
dispatch: async (event) => {
|
|
1861
|
+
if (event.provider === "origin") {
|
|
1862
|
+
const targets = input.collectOriginTargets().filter((target) => {
|
|
1863
|
+
const cursorAccount = target.options.cursorAccount;
|
|
1864
|
+
if (
|
|
1865
|
+
input.cursorAccountOnly &&
|
|
1866
|
+
cursorAccount !== true &&
|
|
1867
|
+
typeof cursorAccount !== "object"
|
|
1868
|
+
) {
|
|
1869
|
+
return false;
|
|
1870
|
+
}
|
|
1871
|
+
return typeof cursorAccount !== "object"
|
|
1872
|
+
? true
|
|
1873
|
+
: cursorAccount.repos.some(
|
|
1874
|
+
(repo) => repo.toLowerCase() === event.repo.toLowerCase()
|
|
1875
|
+
);
|
|
1876
|
+
});
|
|
1877
|
+
const result = await handleAgentServeTrigger({
|
|
1878
|
+
type: "origin",
|
|
1879
|
+
bodyText: JSON.stringify(scmMetadataToOriginPayload(event)),
|
|
1880
|
+
targets,
|
|
1881
|
+
});
|
|
1882
|
+
logCursorScmDispatch(logger, event, result);
|
|
1883
|
+
return;
|
|
1884
|
+
}
|
|
1808
1885
|
if (event.provider !== "github") return;
|
|
1809
|
-
const targets =
|
|
1886
|
+
const targets = input.collectGitHubTargets().filter((target) => {
|
|
1810
1887
|
const cursorAccount = target.options.cursorAccount;
|
|
1811
1888
|
if (
|
|
1812
1889
|
input.cursorAccountOnly &&
|
|
@@ -1828,27 +1905,35 @@ function startCursorEventRelay(input: {
|
|
|
1828
1905
|
deliveryId: event.deliveryId,
|
|
1829
1906
|
targets,
|
|
1830
1907
|
});
|
|
1831
|
-
|
|
1832
|
-
.map((target) => formatCursorScmDispatchOutcome(target))
|
|
1833
|
-
.join(", ");
|
|
1834
|
-
const rejected = result.targets.filter((target) => target.status >= 400);
|
|
1835
|
-
if (rejected.length > 0) {
|
|
1836
|
-
logger(
|
|
1837
|
-
`[agent-sdk] cursor-events: dropped ${formatCursorScmEventLog(event)} before hook: ${rejected.map(formatCursorScmDispatchOutcome).join(", ")}`
|
|
1838
|
-
);
|
|
1839
|
-
}
|
|
1840
|
-
logger(
|
|
1841
|
-
`[agent-sdk] cursor-events: dispatched ${formatCursorScmEventLog(event)}${outcomes === "" ? "" : ` → ${outcomes}`}`
|
|
1842
|
-
);
|
|
1908
|
+
logCursorScmDispatch(logger, event, result);
|
|
1843
1909
|
},
|
|
1844
1910
|
});
|
|
1845
1911
|
relay.start();
|
|
1846
1912
|
logger(
|
|
1847
|
-
`[agent-sdk] cursor-events: relaying ${
|
|
1913
|
+
`[agent-sdk] cursor-events: relaying ${subscriptions.length} subscription(s) from ${auth.baseUrl}`
|
|
1848
1914
|
);
|
|
1849
1915
|
return relay;
|
|
1850
1916
|
}
|
|
1851
1917
|
|
|
1918
|
+
function logCursorScmDispatch(
|
|
1919
|
+
logger: (line: string) => void,
|
|
1920
|
+
event: Parameters<typeof formatCursorScmEventLog>[0],
|
|
1921
|
+
result: Awaited<ReturnType<typeof handleAgentServeTrigger>>
|
|
1922
|
+
): void {
|
|
1923
|
+
const outcomes = result.targets
|
|
1924
|
+
.map((target) => formatCursorScmDispatchOutcome(target))
|
|
1925
|
+
.join(", ");
|
|
1926
|
+
const rejected = result.targets.filter((target) => target.status >= 400);
|
|
1927
|
+
if (rejected.length > 0) {
|
|
1928
|
+
logger(
|
|
1929
|
+
`[agent-sdk] cursor-events: dropped ${formatCursorScmEventLog(event)} before hook: ${rejected.map(formatCursorScmDispatchOutcome).join(", ")}`
|
|
1930
|
+
);
|
|
1931
|
+
}
|
|
1932
|
+
logger(
|
|
1933
|
+
`[agent-sdk] cursor-events: dispatched ${formatCursorScmEventLog(event)}${outcomes === "" ? "" : ` → ${outcomes}`}`
|
|
1934
|
+
);
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1852
1937
|
interface CursorGithubTarget {
|
|
1853
1938
|
slug: string;
|
|
1854
1939
|
channelId: string;
|
|
@@ -1893,11 +1978,8 @@ function resolveCursorGithubEventConfig(input: {
|
|
|
1893
1978
|
]),
|
|
1894
1979
|
];
|
|
1895
1980
|
const permissions = resolveCursorGithubPermissions(
|
|
1896
|
-
input.targets.map(
|
|
1897
|
-
|
|
1898
|
-
target.accountRuntime.options,
|
|
1899
|
-
target.accountRuntime.scope?.permissions
|
|
1900
|
-
)
|
|
1981
|
+
input.targets.map(
|
|
1982
|
+
(target) => target.accountRuntime.scope?.permissions ?? "pr-write"
|
|
1901
1983
|
)
|
|
1902
1984
|
);
|
|
1903
1985
|
const scope = parseCursorGithubRepoScope(repos, permissions);
|
|
@@ -1910,6 +1992,54 @@ function resolveCursorGithubEventConfig(input: {
|
|
|
1910
1992
|
};
|
|
1911
1993
|
}
|
|
1912
1994
|
|
|
1995
|
+
interface CursorOriginTarget {
|
|
1996
|
+
slug: string;
|
|
1997
|
+
channelId: string;
|
|
1998
|
+
accountRuntime: OriginCursorAccountRuntime;
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
function collectCursorOriginTargets(
|
|
2002
|
+
mounts: AgentMount[]
|
|
2003
|
+
): CursorOriginTarget[] {
|
|
2004
|
+
const targets: CursorOriginTarget[] = [];
|
|
2005
|
+
for (const mount of mounts) {
|
|
2006
|
+
for (const channel of mount.project.channels) {
|
|
2007
|
+
const accountRuntime = getOriginCursorAccountRuntime(channel.definition);
|
|
2008
|
+
if (accountRuntime !== undefined) {
|
|
2009
|
+
targets.push({
|
|
2010
|
+
slug: mount.slug,
|
|
2011
|
+
channelId: channel.id,
|
|
2012
|
+
accountRuntime,
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
return targets;
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
/**
|
|
2021
|
+
* Origin cursorAccount repos. `true` takes the host's explicit `--repo`
|
|
2022
|
+
* list (not GitHub channel-declared repos). `{ repos }` is self-contained.
|
|
2023
|
+
*/
|
|
2024
|
+
function resolveCursorOriginRepoScope(input: {
|
|
2025
|
+
explicitRepos: readonly string[];
|
|
2026
|
+
targets: CursorOriginTarget[];
|
|
2027
|
+
}): ReturnType<typeof parseCursorOriginRepoScope> | undefined {
|
|
2028
|
+
if (input.targets.length === 0) {
|
|
2029
|
+
return undefined;
|
|
2030
|
+
}
|
|
2031
|
+
const wantsHostRepos = input.targets.some(
|
|
2032
|
+
(target) => target.accountRuntime.options.cursorAccount === true
|
|
2033
|
+
);
|
|
2034
|
+
const repos = [
|
|
2035
|
+
...(wantsHostRepos ? input.explicitRepos : []),
|
|
2036
|
+
...input.targets.flatMap(
|
|
2037
|
+
(target) => target.accountRuntime.scope?.repos ?? []
|
|
2038
|
+
),
|
|
2039
|
+
];
|
|
2040
|
+
return parseCursorOriginRepoScope(repos);
|
|
2041
|
+
}
|
|
2042
|
+
|
|
1913
2043
|
interface CursorSlackTarget {
|
|
1914
2044
|
runtime: MountedRuntime;
|
|
1915
2045
|
channelId: string;
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
resolveABMaxPlaygroundSessions,
|
|
18
18
|
resolveABSplit,
|
|
19
19
|
} from "../ab.js";
|
|
20
|
-
import { slackThreadPermalink } from "../channels/slack/links.js";
|
|
21
20
|
import {
|
|
22
21
|
SlackAskDedupeStore,
|
|
23
22
|
SlackNudgeStore,
|
|
@@ -122,6 +121,7 @@ import {
|
|
|
122
121
|
} from "./prompt-context.js";
|
|
123
122
|
import { assertCloudCanHonorAccountServersFilters } from "./resolved-connections.js";
|
|
124
123
|
import type { AgentRunner } from "./sdk-runner.js";
|
|
124
|
+
import { sessionExternalLinks } from "./session-links.js";
|
|
125
125
|
import { SessionStore } from "./session-store.js";
|
|
126
126
|
import { StorageCoordinator } from "./storage-coordinator.js";
|
|
127
127
|
import type { FrameworkSessionStore } from "./storage-roles.js";
|
|
@@ -2759,12 +2759,12 @@ export class SessionEngine {
|
|
|
2759
2759
|
return records
|
|
2760
2760
|
.filter((record) => includeAll || samePrincipal(record.auth, caller))
|
|
2761
2761
|
.map((record) => {
|
|
2762
|
-
const
|
|
2762
|
+
const links = sessionExternalLinks(record);
|
|
2763
2763
|
return {
|
|
2764
2764
|
sessionId: record.sessionId,
|
|
2765
2765
|
channelId: record.channelId,
|
|
2766
2766
|
mode: record.mode,
|
|
2767
|
-
|
|
2767
|
+
title: record.title,
|
|
2768
2768
|
turnCount: record.turnCount,
|
|
2769
2769
|
running:
|
|
2770
2770
|
this.activeTurns.has(record.sessionId) ||
|
|
@@ -2781,7 +2781,8 @@ export class SessionEngine {
|
|
|
2781
2781
|
record.channelId,
|
|
2782
2782
|
record.continuationKey
|
|
2783
2783
|
),
|
|
2784
|
-
|
|
2784
|
+
externalUrl: links.slack ?? links.github,
|
|
2785
|
+
prUrl: links.github,
|
|
2785
2786
|
};
|
|
2786
2787
|
});
|
|
2787
2788
|
}
|
|
@@ -3643,23 +3644,6 @@ function approvalResolverLabel(auth: AuthContext | null): string | undefined {
|
|
|
3643
3644
|
return auth.principalId;
|
|
3644
3645
|
}
|
|
3645
3646
|
|
|
3646
|
-
/** Deep link to the external conversation (Slack thread today). */
|
|
3647
|
-
function externalUrlForSession(record: SessionRecord): string | undefined {
|
|
3648
|
-
const auth = record.auth;
|
|
3649
|
-
if (auth === null || auth.authenticator !== "slack") {
|
|
3650
|
-
return undefined;
|
|
3651
|
-
}
|
|
3652
|
-
const channelId = auth.attributes?.channel_id ?? "";
|
|
3653
|
-
const threadTs = auth.attributes?.thread_ts ?? "";
|
|
3654
|
-
const teamId = auth.attributes?.team_id;
|
|
3655
|
-
const url = slackThreadPermalink({
|
|
3656
|
-
channelId,
|
|
3657
|
-
threadTs,
|
|
3658
|
-
...(teamId === undefined ? {} : { teamId }),
|
|
3659
|
-
});
|
|
3660
|
-
return url ?? undefined;
|
|
3661
|
-
}
|
|
3662
|
-
|
|
3663
3647
|
/** Let the HTTP NDJSON writer flush before the next SDK update. */
|
|
3664
3648
|
function yieldEventLoop(): Promise<void> {
|
|
3665
3649
|
return new Promise((resolve) => {
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { parseGitHubPrRef } from "../channels/github/replay.js";
|
|
2
|
+
import { slackThreadPermalink } from "../channels/slack/links.js";
|
|
3
|
+
import { extractGithubPrRef } from "../channels/slack/pr-ref.js";
|
|
4
|
+
import type { AgentCloudOptions, AuthContext } from "../types.js";
|
|
5
|
+
|
|
6
|
+
export type SessionExternalLinks = {
|
|
7
|
+
slack: string | undefined;
|
|
8
|
+
github: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type SessionLinkSource = {
|
|
12
|
+
auth: AuthContext | null;
|
|
13
|
+
title?: string;
|
|
14
|
+
continuationKey: string | null;
|
|
15
|
+
cloudOverride?: AgentCloudOptions;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const SLACK_TITLE = /^slack:([CGD][A-Z0-9]+):(\d+\.\d+)$/i;
|
|
19
|
+
const SLACK_CONTINUATION = /^([CGD][A-Z0-9]+):(\d+\.\d+)$/i;
|
|
20
|
+
|
|
21
|
+
export function sessionExternalLinks(
|
|
22
|
+
record: SessionLinkSource
|
|
23
|
+
): SessionExternalLinks {
|
|
24
|
+
return {
|
|
25
|
+
slack: slackUrl(record),
|
|
26
|
+
github: githubUrl(record),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function slackUrl(record: SessionLinkSource): string | undefined {
|
|
31
|
+
const auth = record.auth;
|
|
32
|
+
if (auth !== null && auth.authenticator === "slack") {
|
|
33
|
+
const fromAuth = slackThreadPermalink({
|
|
34
|
+
channelId: auth.attributes?.channel_id ?? "",
|
|
35
|
+
threadTs: auth.attributes?.thread_ts ?? "",
|
|
36
|
+
teamId: auth.attributes?.team_id,
|
|
37
|
+
});
|
|
38
|
+
if (fromAuth !== null) {
|
|
39
|
+
return fromAuth;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const fromTitle = (record.title ?? "").trim().match(SLACK_TITLE);
|
|
43
|
+
if (fromTitle !== null) {
|
|
44
|
+
return (
|
|
45
|
+
slackThreadPermalink({
|
|
46
|
+
channelId: fromTitle[1] as string,
|
|
47
|
+
threadTs: fromTitle[2] as string,
|
|
48
|
+
}) ?? undefined
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const fromKey = (record.continuationKey ?? "")
|
|
52
|
+
.trim()
|
|
53
|
+
.match(SLACK_CONTINUATION);
|
|
54
|
+
if (fromKey === null) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return (
|
|
58
|
+
slackThreadPermalink({
|
|
59
|
+
channelId: fromKey[1] as string,
|
|
60
|
+
threadTs: fromKey[2] as string,
|
|
61
|
+
}) ?? undefined
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function githubUrl(record: SessionLinkSource): string | undefined {
|
|
66
|
+
const fromTitle = extractGithubPrRef(record.title ?? "");
|
|
67
|
+
if (fromTitle !== undefined) {
|
|
68
|
+
return fromTitle.url;
|
|
69
|
+
}
|
|
70
|
+
const key = record.continuationKey ?? "";
|
|
71
|
+
if (key.startsWith("github-pr:")) {
|
|
72
|
+
return parseGitHubPrRef(key.slice("github-pr:".length))?.url;
|
|
73
|
+
}
|
|
74
|
+
const repos = record.cloudOverride?.repos;
|
|
75
|
+
if (repos === undefined) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
for (const repo of repos) {
|
|
79
|
+
if (repo.prUrl === undefined) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const parsed = parseGitHubPrRef(repo.prUrl);
|
|
83
|
+
if (parsed !== undefined) {
|
|
84
|
+
return parsed.url;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
@@ -171,6 +171,7 @@ function parseSessionSummary(value: unknown): SessionSummary | undefined {
|
|
|
171
171
|
continuationToken,
|
|
172
172
|
externalUrl:
|
|
173
173
|
typeof row.externalUrl === "string" ? row.externalUrl : undefined,
|
|
174
|
+
prUrl: typeof row.prUrl === "string" ? row.prUrl : undefined,
|
|
174
175
|
};
|
|
175
176
|
}
|
|
176
177
|
|
package/src/types.ts
CHANGED
|
@@ -254,15 +254,14 @@ export interface AgentConfig {
|
|
|
254
254
|
* - `"resident"` (default): the in-process session engine owns delivery —
|
|
255
255
|
* today's behavior, unchanged.
|
|
256
256
|
* - `"ledger"`: every delivery coordinates through the KV session ledger
|
|
257
|
-
* before its turn runs:
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
* commit through a fenced sequence. A delivery that finds the lease
|
|
261
|
-
* held walks away; the holder drains the parked event, and the janitor
|
|
262
|
-
* recovers sessions whose holder died. Requires a store with
|
|
263
|
-
* conditional writes and prefix listing (the `cas` group on
|
|
257
|
+
* before its turn runs: session identity, a one-writer-per-session
|
|
258
|
+
* lease with generation fencing, and a fenced commit sequence.
|
|
259
|
+
* Requires a store with conditional writes (the `cas` group on
|
|
264
260
|
* `defineStorage`, or an explicit CAS-capable override); startup fails
|
|
265
|
-
* fast otherwise.
|
|
261
|
+
* fast otherwise. This stage is coordination only — there is no
|
|
262
|
+
* durable inbox yet, so an event arriving while the lease is held
|
|
263
|
+
* waits in-process and a crash loses it exactly as resident serving
|
|
264
|
+
* does. The durable mailbox lands in a follow-up.
|
|
266
265
|
*/
|
|
267
266
|
export type AgentServingMode = "resident" | "ledger";
|
|
268
267
|
|
|
@@ -1448,11 +1447,11 @@ export interface SessionSummary {
|
|
|
1448
1447
|
/** `<channelId>:<key>` wire token, or null when not addressable. */
|
|
1449
1448
|
continuationToken: string | null;
|
|
1450
1449
|
/**
|
|
1451
|
-
*
|
|
1452
|
-
* Populated for channel-driven sessions when the principal carries enough
|
|
1453
|
-
* attributes to build a permalink.
|
|
1450
|
+
* Conversation permalink (Slack thread, else GitHub PR).
|
|
1454
1451
|
*/
|
|
1455
1452
|
externalUrl?: string;
|
|
1453
|
+
/** GitHub PR when the session is about one. */
|
|
1454
|
+
prUrl?: string;
|
|
1456
1455
|
}
|
|
1457
1456
|
|
|
1458
1457
|
/**
|
|
@@ -1907,6 +1906,11 @@ export interface ChannelMeta {
|
|
|
1907
1906
|
* to dispatch on. Used to derive `gh webhook forward --events`.
|
|
1908
1907
|
*/
|
|
1909
1908
|
githubWebhookEvents?: readonly string[];
|
|
1909
|
+
/**
|
|
1910
|
+
* For Origin webhook packs: the Origin event types this channel is wired
|
|
1911
|
+
* to dispatch on. Used by `--cursor-events` to subscribe `provider: "origin"`.
|
|
1912
|
+
*/
|
|
1913
|
+
originWebhookEvents?: readonly string[];
|
|
1910
1914
|
/**
|
|
1911
1915
|
* For Slack packs with the opt-in channel watch: the allowlisted channels
|
|
1912
1916
|
* (ids or `#names`) this channel dispatches on without a mention. Surfaced
|
|
@@ -2549,6 +2553,8 @@ export interface AgentProjectInfo {
|
|
|
2549
2553
|
kind?: string;
|
|
2550
2554
|
/** GitHub webhook events the channel dispatches on, when declared. */
|
|
2551
2555
|
githubWebhookEvents?: readonly string[];
|
|
2556
|
+
/** Origin webhook event types the channel dispatches on, when declared. */
|
|
2557
|
+
originWebhookEvents?: readonly string[];
|
|
2552
2558
|
/** Slack channels watched for posts (opt-in channel watch), when declared. */
|
|
2553
2559
|
slackChannelPosts?: readonly string[];
|
|
2554
2560
|
}>;
|
|
@@ -2746,7 +2752,8 @@ export interface ServeOptions {
|
|
|
2746
2752
|
*/
|
|
2747
2753
|
cloudToolsUrl?: string;
|
|
2748
2754
|
/**
|
|
2749
|
-
* Pull
|
|
2755
|
+
* Pull SCM webhook metadata from `/v0/scm-events` (Cursor account auth).
|
|
2756
|
+
* GitHub and Origin subscriptions are registered independently.
|
|
2750
2757
|
* The stream is read as the host's Cursor user, so this requires a signed-in
|
|
2751
2758
|
* host: `serve` throws when no key resolves from `apiKey` here,
|
|
2752
2759
|
* {@link ServeOptions.apiKey}, `CURSOR_API_KEY`, or `agent-serve login`.
|