@cursor/july 0.1.96 → 0.1.97
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/README.md +3 -2
- package/dist/bin/agent-serve.js +14 -3
- package/dist/channels/origin/api.d.ts +15 -4
- package/dist/channels/origin/api.d.ts.map +1 -1
- package/dist/channels/origin/api.js +19 -3
- package/dist/channels/origin/binding.d.ts +11 -0
- package/dist/channels/origin/binding.d.ts.map +1 -1
- package/dist/channels/origin/binding.js +41 -25
- package/dist/channels/origin/index.d.ts +1 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +1 -0
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +3 -0
- package/dist/channels/origin/reactions.d.ts +56 -0
- package/dist/channels/origin/reactions.d.ts.map +1 -0
- package/dist/channels/origin/reactions.js +67 -0
- package/dist/channels/origin/types.d.ts +11 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/approvals.d.ts +16 -0
- package/dist/channels/slack/approvals.d.ts.map +1 -1
- package/dist/channels/slack/approvals.js +86 -0
- package/dist/channels/slack/cli-project.d.ts +19 -0
- package/dist/channels/slack/cli-project.d.ts.map +1 -0
- package/dist/channels/slack/cli-project.js +234 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +97 -39
- package/dist/channels/slack/init.d.ts +3 -2
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +5 -5
- package/dist/channels/slack/interactive.d.ts +2 -1
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +15 -4
- package/dist/channels/slack/manifest.d.ts +1 -1
- package/dist/channels/slack/manifest.js +1 -1
- package/dist/channels/slack/setup.d.ts +1 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +10 -6
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +1 -0
- package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
- package/dist/channels/slack/tool-approval-events.js +91 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.jXleCmOc.js → app.B3rWNYE1.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BU9nHdnQ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.8LhyglIT.js → VPLocalSearchBox.C1lhqJJR.js} +1 -1
- package/dist/docs/assets/chunks/{theme.9ged-pr2.js → theme.B40_SXuv.js} +2 -2
- package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
- package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
- package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
- package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
- package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.CCnG-nJx.js → reference_cli.md.RyZf5OTE.js} +9 -6
- package/dist/docs/assets/{reference_cli.md.CCnG-nJx.lean.js → reference_cli.md.RyZf5OTE.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
- package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.5zOAbV86.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
- package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.B84gw9Ii.js} +1 -1
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
- package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/deployment.md +5 -4
- package/dist/docs/evals.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 +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +8 -8
- package/dist/docs/guides/mcp-oauth.md +26 -8
- package/dist/docs/guides/opentelemetry.html +4 -4
- package/dist/docs/guides/slack.html +17 -33
- package/dist/docs/guides/slack.md +92 -201
- 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/index.md +5 -3
- package/dist/docs/llms-full.txt +299 -653
- package/dist/docs/llms.txt +2 -2
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +6 -6
- package/dist/docs/reference/agent-config.md +2 -2
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +13 -10
- package/dist/docs/reference/cli.md +38 -16
- package/dist/docs/reference/connections.html +9 -8
- package/dist/docs/reference/connections.md +6 -3
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +2 -1
- 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 +5 -5
- package/dist/docs/reference/sessions.md +4 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +6 -6
- package/dist/docs/reference/tools.md +9 -2
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +28 -0
- package/dist/docs/templates/agents-md.md +105 -0
- package/dist/docs/templates/code-wiki.html +5 -5
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +5 -5
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +2 -2
- package/dist/evals/run-facts.d.ts.map +1 -1
- package/dist/evals/run-facts.js +27 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +15 -9
- package/dist/internal/approval-gate.d.ts +12 -13
- package/dist/internal/approval-gate.d.ts.map +1 -1
- package/dist/internal/approval-gate.js +16 -21
- package/dist/internal/chat-client.js +10 -0
- package/dist/internal/cli-deploy.d.ts +5 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +50 -17
- package/dist/internal/cli-mcp-oauth.js +8 -18
- package/dist/internal/cli-slack-manual.d.ts +24 -2
- package/dist/internal/cli-slack-manual.d.ts.map +1 -1
- package/dist/internal/cli-slack-manual.js +251 -20
- package/dist/internal/cli-slack.d.ts +9 -2
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +29 -82
- package/dist/internal/cursor/account-mcp.d.ts +1 -0
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +17 -0
- package/dist/internal/cursor-agent-template.d.ts +1 -1
- package/dist/internal/cursor-agent-template.d.ts.map +1 -1
- package/dist/internal/cursor-agent-template.js +1 -0
- package/dist/internal/deploy-client.d.ts +17 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +31 -10
- package/dist/internal/env-file.d.ts +19 -0
- package/dist/internal/env-file.d.ts.map +1 -0
- package/dist/internal/env-file.js +90 -0
- package/dist/internal/framework-file-storage.d.ts +1 -1
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +6 -0
- package/dist/internal/hosted-delivery-protocol.d.ts +7 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +7 -0
- package/dist/internal/hosted-delivery.d.ts +6 -0
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +63 -22
- package/dist/internal/hosted-execution-diag.d.ts +48 -0
- package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
- package/dist/internal/hosted-execution-diag.js +150 -0
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +81 -1
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +2 -0
- package/dist/internal/logs-client.d.ts +5 -0
- package/dist/internal/logs-client.d.ts.map +1 -1
- package/dist/internal/logs-client.js +5 -0
- package/dist/internal/mcp-endpoint.js +2 -3
- package/dist/internal/mcp-host.d.ts +10 -0
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +57 -8
- package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
- package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-on-demand.js +287 -0
- package/dist/internal/mcp-oauth-persist.d.ts +42 -0
- package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
- package/dist/internal/mcp-oauth-persist.js +92 -0
- package/dist/internal/mcp-oauth.d.ts +1 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -1
- package/dist/internal/mcp-oauth.js +10 -2
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +22 -9
- package/dist/internal/server.d.ts +3 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +49 -22
- package/dist/internal/session-engine.d.ts +88 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +515 -43
- package/dist/internal/sessions-client.d.ts +9 -7
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +3 -1
- package/dist/internal/storage-coordinator.d.ts +7 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +28 -5
- package/dist/internal/storage-roles.d.ts +5 -0
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +10 -0
- package/dist/internal/tool-policy.d.ts +9 -1
- package/dist/internal/tool-policy.d.ts.map +1 -1
- package/dist/internal/tool-policy.js +13 -0
- package/dist/internal/trajectory.d.ts.map +1 -1
- package/dist/internal/trajectory.js +10 -0
- package/dist/internal/turn-outbox.d.ts +24 -0
- package/dist/internal/turn-outbox.d.ts.map +1 -0
- package/dist/internal/turn-outbox.js +80 -0
- package/dist/playground/assets/{index-Cx9CclK_.js → index-DrkI6y5O.js} +45 -45
- package/dist/playground/assets/index-DzNGwm7q.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +1 -1
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +12 -0
- package/dist/storage.d.ts +8 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/types.d.ts +63 -7
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +5 -3
- package/docs/deployment.md +5 -4
- package/docs/guides/mcp-oauth.md +26 -8
- package/docs/guides/slack.md +93 -202
- package/docs/reference/agent-config.md +2 -2
- package/docs/reference/cli.md +38 -16
- package/docs/reference/connections.md +6 -3
- package/docs/reference/http-api.md +2 -1
- package/docs/reference/sessions.md +4 -2
- package/docs/reference/tools.md +9 -2
- package/docs/templates/agents-md.md +110 -0
- package/docs/troubleshooting.md +2 -2
- package/package.json +1 -1
- package/skills/create-agent/SKILL.md +2 -1
- package/skills/mcp-auth/SKILL.md +6 -3
- package/skills/setup-slack/SKILL.md +23 -13
- package/src/bin/agent-serve.ts +13 -1
- package/src/channels/origin/api.ts +24 -5
- package/src/channels/origin/binding.ts +55 -26
- package/src/channels/origin/index.ts +1 -0
- package/src/channels/origin/origin-channel.ts +4 -0
- package/src/channels/origin/reactions.ts +82 -0
- package/src/channels/origin/types.ts +11 -0
- package/src/channels/slack/approvals.ts +105 -0
- package/src/channels/slack/cli-project.ts +267 -0
- package/src/channels/slack/defaults.ts +109 -46
- package/src/channels/slack/init.ts +10 -5
- package/src/channels/slack/interactive.ts +35 -9
- package/src/channels/slack/manifest.ts +1 -1
- package/src/channels/slack/setup.ts +10 -6
- package/src/channels/slack/slack-channel.ts +1 -0
- package/src/channels/slack/tool-approval-events.ts +93 -0
- package/src/evals/run-facts.ts +32 -0
- package/src/internal/advertise-tools.ts +31 -10
- package/src/internal/approval-gate.ts +20 -29
- package/src/internal/chat-client.ts +19 -0
- package/src/internal/cli-deploy.ts +79 -9
- package/src/internal/cli-mcp-oauth.ts +7 -21
- package/src/internal/cli-slack-manual.ts +350 -18
- package/src/internal/cli-slack.ts +40 -84
- package/src/internal/cursor/account-mcp.ts +21 -0
- package/src/internal/cursor-agent-template.ts +1 -0
- package/src/internal/deploy-client.ts +43 -0
- package/src/internal/env-file.ts +84 -0
- package/src/internal/framework-file-storage.ts +7 -1
- package/src/internal/hosted-delivery-protocol.ts +7 -0
- package/src/internal/hosted-delivery.ts +100 -27
- package/src/internal/hosted-execution-diag.ts +207 -0
- package/src/internal/http-channel.ts +99 -0
- package/src/internal/init-project.ts +2 -0
- package/src/internal/logs-client.ts +5 -0
- package/src/internal/mcp-endpoint.ts +13 -4
- package/src/internal/mcp-host.ts +77 -11
- package/src/internal/mcp-oauth-on-demand.ts +352 -0
- package/src/internal/mcp-oauth-persist.ts +127 -0
- package/src/internal/mcp-oauth.ts +17 -1
- package/src/internal/otel/collector.ts +30 -0
- package/src/internal/server.ts +59 -9
- package/src/internal/session-engine.ts +659 -56
- package/src/internal/sessions-client.ts +17 -8
- package/src/internal/storage-coordinator.ts +38 -8
- package/src/internal/storage-roles.ts +7 -0
- package/src/internal/stream-progress.ts +19 -0
- package/src/internal/tool-policy.ts +18 -0
- package/src/internal/trajectory.ts +10 -0
- package/src/internal/turn-outbox.ts +85 -0
- package/src/storage-backends/cursor-hosted.ts +13 -1
- package/src/storage.ts +12 -0
- package/src/types.ts +68 -8
- package/templates/agents-md/README.md +39 -0
- package/templates/agents-md/agent/agent.ts +8 -0
- package/templates/agents-md/agent/channels/github.ts +10 -0
- package/templates/agents-md/agent/channels/queue.ts +28 -0
- package/templates/agents-md/agent/channels/slack.ts +9 -0
- package/templates/agents-md/agent/instructions.md +39 -0
- package/templates/agents-md/agent/lib/collect.ts +439 -0
- package/templates/agents-md/agent/lib/config.ts +8 -0
- package/templates/agents-md/agent/lib/paths.ts +51 -0
- package/templates/agents-md/agent/schedules/weekly.ts +17 -0
- package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
- package/templates/agents-md/evals/agents.eval.ts +135 -0
- package/templates/agents-md/evals/evals.config.ts +5 -0
- package/templates/agents-md/init.json +38 -0
- package/templates/agents-md/package.json +18 -0
- package/templates/agents-md/tsconfig.json +12 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.DFoGuETX.js +0 -1
- package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
- package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
- package/dist/docs/assets/index.md.CI93Ltlb.js +0 -5
- package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
- package/dist/docs/design/agsh.md +0 -406
- package/dist/playground/assets/index-B1DDvBeC.css +0 -1
- package/docs/design/agsh.md +0 -406
- /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
- /package/dist/docs/assets/{index.md.CI93Ltlb.lean.js → index.md.CVeRUOeZ.lean.js} +0 -0
- /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.5zOAbV86.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.B84gw9Ii.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
|
@@ -222,7 +222,7 @@ export function buildSlackManifestPair(
|
|
|
222
222
|
};
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
/**
|
|
225
|
+
/** Manifest filenames written under `.slack/`. */
|
|
226
226
|
export function slackManifestFileEntries(
|
|
227
227
|
pair: { dev: SlackAppManifest; prod: SlackAppManifest },
|
|
228
228
|
env: "dev" | "prod" | "both" = "both"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Slack setup guide printed by `agent-serve slack setup`.
|
|
3
3
|
*
|
|
4
4
|
* Dedicated Socket Mode app via `slack create` (dashboard wizard).
|
|
5
|
-
* `slack init --manual` is the unmanaged paste
|
|
5
|
+
* `slack init --manual` is the unmanaged Slack CLI / paste path.
|
|
6
6
|
* {@link SLACK_SETUP_PHASES} is that checklist; its ids key
|
|
7
7
|
* `.agent-serve/slack/setup-status.json`.
|
|
8
8
|
*/
|
|
@@ -21,6 +21,7 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
21
21
|
title: "Generate channel + manifests",
|
|
22
22
|
steps: [
|
|
23
23
|
"agent-serve slack init --manual --dir . --name My Agent",
|
|
24
|
+
"Installs the Slack app when Slack CLI is logged in. Otherwise next asks the user to install it.",
|
|
24
25
|
"Manifests default to Socket Mode (no public Request URL).",
|
|
25
26
|
],
|
|
26
27
|
},
|
|
@@ -29,9 +30,11 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
29
30
|
actor: "human",
|
|
30
31
|
title: "Create two Slack apps from manifests",
|
|
31
32
|
steps: [
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
33
|
+
"Preferred: Slack CLI at ~/.slack/bin/slack. slack login --no-prompt, then slack app install --environment local --team <T> --force",
|
|
34
|
+
"Prod: SLACK_ENV=deployed slack app install --environment deployed --team <T> --force",
|
|
35
|
+
"Do not slack deploy; Agent SDK serve owns Socket Mode",
|
|
36
|
+
"Fallback: https://api.slack.com/apps -> Create New App from a manifest",
|
|
37
|
+
"Paste .slack/manifest.dev.json, then manifest.prod.json",
|
|
35
38
|
],
|
|
36
39
|
},
|
|
37
40
|
{
|
|
@@ -39,8 +42,9 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
|
|
|
39
42
|
actor: "human",
|
|
40
43
|
title: "Install + mint App-Level Token",
|
|
41
44
|
steps: [
|
|
42
|
-
"
|
|
45
|
+
"Slack CLI install leaves tokens in that process only. Copy xoxb from OAuth & Permissions at https://api.slack.com/apps/<appId>",
|
|
43
46
|
"App-Level Tokens: create token with connections:write; copy xapp-...",
|
|
47
|
+
"If Slack CLI wrote SLACK_* to .env, copy them into .env.local using env.example names",
|
|
44
48
|
],
|
|
45
49
|
},
|
|
46
50
|
{
|
|
@@ -106,7 +110,7 @@ export function formatSlackSetupGuide(): string {
|
|
|
106
110
|
" Finish Slack consent and the bot name there. The CLI writes",
|
|
107
111
|
" tokens into .env.local.",
|
|
108
112
|
"",
|
|
109
|
-
"Manual Slack app: `slack init --manual
|
|
113
|
+
"Manual Slack app: `slack init --manual` (Slack CLI, or paste at api.slack.com).",
|
|
110
114
|
"Goal: importable dev + prod Slack apps over Socket Mode (no public URL).",
|
|
111
115
|
"App-Level Token (xapp-...) + Bot Token (xoxb-...) required.",
|
|
112
116
|
"",
|
|
@@ -21,8 +21,11 @@
|
|
|
21
21
|
import type { ChannelEventHandlers } from "../../types.js";
|
|
22
22
|
import { postMessage, setThreadStatus, updateMessage } from "./api.js";
|
|
23
23
|
import {
|
|
24
|
+
authThreadStatus,
|
|
24
25
|
buildApprovalBlocks,
|
|
26
|
+
buildAuthBlocks,
|
|
25
27
|
buildResolvedApprovalBlocks,
|
|
28
|
+
buildResolvedAuthBlocks,
|
|
26
29
|
} from "./approvals.js";
|
|
27
30
|
import { SLACK_DEFAULT_LOADING_MESSAGES } from "./constants.js";
|
|
28
31
|
import { defaultSlackLog, type SlackLog } from "./log.js";
|
|
@@ -132,5 +135,95 @@ export function buildToolApprovalEvents(
|
|
|
132
135
|
decision: event.data.decision,
|
|
133
136
|
});
|
|
134
137
|
},
|
|
138
|
+
|
|
139
|
+
async "action.auth_requested"(event, channel, ctx) {
|
|
140
|
+
const log = getLog();
|
|
141
|
+
const state = channel.state;
|
|
142
|
+
if (state.channelId === null || state.threadTs === null) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const blocks = buildAuthBlocks({
|
|
146
|
+
sessionId: ctx.session.id,
|
|
147
|
+
callId: event.data.callId,
|
|
148
|
+
toolName: event.data.toolName,
|
|
149
|
+
connection: event.data.connection,
|
|
150
|
+
authUrl: event.data.authUrl,
|
|
151
|
+
});
|
|
152
|
+
try {
|
|
153
|
+
const posted = await postMessage({
|
|
154
|
+
botToken,
|
|
155
|
+
channel: state.channelId,
|
|
156
|
+
threadTs: state.threadTs,
|
|
157
|
+
text: `Authorization required for \`${event.data.connection}\``,
|
|
158
|
+
blocks,
|
|
159
|
+
});
|
|
160
|
+
channel.state.approvalMessageByCallId = {
|
|
161
|
+
...(state.approvalMessageByCallId ?? {}),
|
|
162
|
+
[event.data.callId]: posted.ts,
|
|
163
|
+
};
|
|
164
|
+
await setThreadStatus({
|
|
165
|
+
botToken,
|
|
166
|
+
channelId: state.channelId,
|
|
167
|
+
threadTs: state.threadTs,
|
|
168
|
+
status: authThreadStatus(event.data.connection),
|
|
169
|
+
loadingMessages: [
|
|
170
|
+
authThreadStatus(event.data.connection),
|
|
171
|
+
...SLACK_DEFAULT_LOADING_MESSAGES,
|
|
172
|
+
],
|
|
173
|
+
});
|
|
174
|
+
log.info("auth card posted", {
|
|
175
|
+
call_id: event.data.callId,
|
|
176
|
+
connection: event.data.connection,
|
|
177
|
+
message_ts: posted.ts,
|
|
178
|
+
});
|
|
179
|
+
} catch (error) {
|
|
180
|
+
log.warn("auth card post failed", {
|
|
181
|
+
call_id: event.data.callId,
|
|
182
|
+
error: error instanceof Error ? error.message : String(error),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
async "action.auth_resolved"(event, channel) {
|
|
188
|
+
const log = getLog();
|
|
189
|
+
const state = channel.state;
|
|
190
|
+
const messageTs = state.approvalMessageByCallId?.[event.data.callId];
|
|
191
|
+
if (
|
|
192
|
+
state.channelId !== null &&
|
|
193
|
+
messageTs !== undefined &&
|
|
194
|
+
messageTs !== ""
|
|
195
|
+
) {
|
|
196
|
+
const blocks = buildResolvedAuthBlocks({
|
|
197
|
+
connection: event.data.connection,
|
|
198
|
+
decision: event.data.decision,
|
|
199
|
+
byUserId: event.data.by,
|
|
200
|
+
});
|
|
201
|
+
const verb =
|
|
202
|
+
event.data.decision === "approve" ? "Connected" : "Cancelled";
|
|
203
|
+
await updateMessage({
|
|
204
|
+
botToken,
|
|
205
|
+
channel: state.channelId,
|
|
206
|
+
ts: messageTs,
|
|
207
|
+
text: `${verb} — ${event.data.connection}`,
|
|
208
|
+
blocks,
|
|
209
|
+
});
|
|
210
|
+
const next = { ...(state.approvalMessageByCallId ?? {}) };
|
|
211
|
+
delete next[event.data.callId];
|
|
212
|
+
channel.state.approvalMessageByCallId = next;
|
|
213
|
+
}
|
|
214
|
+
if (state.channelId !== null && state.threadTs !== null) {
|
|
215
|
+
await setThreadStatus({
|
|
216
|
+
botToken,
|
|
217
|
+
channelId: state.channelId,
|
|
218
|
+
threadTs: state.threadTs,
|
|
219
|
+
status: "Working…",
|
|
220
|
+
loadingMessages: [...SLACK_DEFAULT_LOADING_MESSAGES],
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
log.info("auth resolved in slack", {
|
|
224
|
+
call_id: event.data.callId,
|
|
225
|
+
decision: event.data.decision,
|
|
226
|
+
});
|
|
227
|
+
},
|
|
135
228
|
};
|
|
136
229
|
}
|
package/src/evals/run-facts.ts
CHANGED
|
@@ -182,6 +182,38 @@ export function deriveRunFacts(events: readonly SessionEvent[]): EvalRunFacts {
|
|
|
182
182
|
}
|
|
183
183
|
break;
|
|
184
184
|
}
|
|
185
|
+
case "action.auth_requested": {
|
|
186
|
+
const request: EvalInputRequestFact = {
|
|
187
|
+
callId: event.data.callId,
|
|
188
|
+
toolName: event.data.toolName,
|
|
189
|
+
args: {
|
|
190
|
+
connection: event.data.connection,
|
|
191
|
+
authUrl: event.data.authUrl,
|
|
192
|
+
},
|
|
193
|
+
resolved: false,
|
|
194
|
+
};
|
|
195
|
+
inputRequests.push(request);
|
|
196
|
+
inputRequestsByCallId.set(event.data.callId, request);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case "action.auth_resolved": {
|
|
200
|
+
const request = inputRequestsByCallId.get(event.data.callId);
|
|
201
|
+
if (request !== undefined) {
|
|
202
|
+
request.resolved = true;
|
|
203
|
+
request.decision = event.data.decision;
|
|
204
|
+
}
|
|
205
|
+
const fact = ensureCall(
|
|
206
|
+
event.data.callId,
|
|
207
|
+
event.data.toolName,
|
|
208
|
+
event.turnId,
|
|
209
|
+
event.data.parentCallId
|
|
210
|
+
);
|
|
211
|
+
fact.approvalDecision = event.data.decision;
|
|
212
|
+
if (event.data.decision === "deny") {
|
|
213
|
+
fact.status = "rejected";
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
185
217
|
case "subagent.called": {
|
|
186
218
|
const existing = subagentsByCallId.get(event.data.callId);
|
|
187
219
|
if (existing === undefined) {
|
|
@@ -118,24 +118,45 @@ export async function resolveAdvertisedTools(args: {
|
|
|
118
118
|
return [];
|
|
119
119
|
}
|
|
120
120
|
const sourceFor = args.sourceFor ?? sourceForConnection;
|
|
121
|
+
// Each connection's listing is a network round trip against a distinct
|
|
122
|
+
// server (auth callback, MCP initialize, tools/list), so they run
|
|
123
|
+
// concurrently; the fan-out is bounded by the agent's declared
|
|
124
|
+
// connections. Name assignment below stays in declaration order so
|
|
125
|
+
// collision suffixes do not depend on which server answered first.
|
|
126
|
+
type Listing =
|
|
127
|
+
| {
|
|
128
|
+
connection: DiscoveredConnection;
|
|
129
|
+
ok: true;
|
|
130
|
+
source: AdvertisedToolSource;
|
|
131
|
+
listed: HostMcpToolInfo[];
|
|
132
|
+
}
|
|
133
|
+
| { connection: DiscoveredConnection; ok: false; error: unknown };
|
|
134
|
+
const listings = await Promise.all(
|
|
135
|
+
advertising.map(async (connection): Promise<Listing> => {
|
|
136
|
+
try {
|
|
137
|
+
const source = await sourceFor(connection, args.session, args.hostMcp);
|
|
138
|
+
const listed = await source.listTools();
|
|
139
|
+
return { connection, ok: true, source, listed };
|
|
140
|
+
} catch (error) {
|
|
141
|
+
return { connection, ok: false, error };
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
);
|
|
121
145
|
const claimed = new Set(args.agent.tools.map((tool) => tool.name));
|
|
122
146
|
const resolved: DiscoveredTool[] = [];
|
|
123
|
-
for (const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
source = await sourceFor(connection, args.session, args.hostMcp);
|
|
128
|
-
listed = await source.listTools();
|
|
129
|
-
} catch (error) {
|
|
147
|
+
for (const listing of listings) {
|
|
148
|
+
const { connection } = listing;
|
|
149
|
+
if (!listing.ok) {
|
|
130
150
|
if (args.onConnectionError !== undefined) {
|
|
131
|
-
args.onConnectionError(connection.name, error);
|
|
151
|
+
args.onConnectionError(connection.name, listing.error);
|
|
132
152
|
continue;
|
|
133
153
|
}
|
|
134
154
|
throw new Error(
|
|
135
|
-
`Failed to list tools on advertised connection "${connection.name}": ${describeError(error)}`,
|
|
136
|
-
{ cause: error }
|
|
155
|
+
`Failed to list tools on advertised connection "${connection.name}": ${describeError(listing.error)}`,
|
|
156
|
+
{ cause: listing.error }
|
|
137
157
|
);
|
|
138
158
|
}
|
|
159
|
+
const { source, listed } = listing;
|
|
139
160
|
const intended = listed.filter(
|
|
140
161
|
(info) =>
|
|
141
162
|
!isDoNotCallTool(info.annotations) &&
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* In-memory gate for human-in-the-loop
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* {@link ApprovalGate.resolve}.
|
|
2
|
+
* In-memory gate for human-in-the-loop parks. The session engine parks
|
|
3
|
+
* inside a server-tool `execute` by awaiting {@link ApprovalGate.wait};
|
|
4
|
+
* HTTP (or the playground) unblocks via {@link ApprovalGate.resolve}.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
* durability of the *list* across
|
|
9
|
-
* in-flight SDK tool callback is gone,
|
|
10
|
-
* the host treats the
|
|
6
|
+
* Used for `needsApproval` and MCP on-demand auth. Pending rows are also
|
|
7
|
+
* mirrored onto {@link SessionRecord} for durability of the *list* across
|
|
8
|
+
* reloads. After a process restart the in-flight SDK tool callback is gone,
|
|
9
|
+
* so resolve returns false and the host treats the park as interrupted.
|
|
11
10
|
*/
|
|
12
11
|
|
|
13
12
|
import type { ApprovalDecision, PendingApproval } from "../types.js";
|
|
@@ -21,33 +20,25 @@ export interface ApprovalResolution {
|
|
|
21
20
|
by?: string;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
interface Waiter {
|
|
25
|
-
meta:
|
|
23
|
+
interface Waiter<T> {
|
|
24
|
+
meta: T;
|
|
26
25
|
resolve: (resolution: ApprovalResolution) => void;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
export class ApprovalGate {
|
|
30
|
-
private readonly waiters = new Map<string, Waiter
|
|
28
|
+
export class ApprovalGate<T extends { callId: string } = PendingApproval> {
|
|
29
|
+
private readonly waiters = new Map<string, Waiter<T>>();
|
|
31
30
|
|
|
32
|
-
wait(
|
|
33
|
-
|
|
34
|
-
): Promise<ApprovalResolution> {
|
|
35
|
-
const key = approvalKey(meta.sessionId, meta.callId);
|
|
31
|
+
wait(sessionId: string, meta: T): Promise<ApprovalResolution> {
|
|
32
|
+
const key = approvalKey(sessionId, meta.callId);
|
|
36
33
|
const existing = this.waiters.get(key);
|
|
37
34
|
if (existing !== undefined) {
|
|
38
35
|
throw new Error(
|
|
39
|
-
`Approval already pending for session ${
|
|
36
|
+
`Approval already pending for session ${sessionId} call ${meta.callId}`
|
|
40
37
|
);
|
|
41
38
|
}
|
|
42
39
|
return new Promise<ApprovalResolution>((resolveDecision) => {
|
|
43
40
|
this.waiters.set(key, {
|
|
44
|
-
meta
|
|
45
|
-
callId: meta.callId,
|
|
46
|
-
turnId: meta.turnId,
|
|
47
|
-
toolName: meta.toolName,
|
|
48
|
-
args: meta.args,
|
|
49
|
-
requestedAt: meta.requestedAt,
|
|
50
|
-
},
|
|
41
|
+
meta,
|
|
51
42
|
resolve: resolveDecision,
|
|
52
43
|
});
|
|
53
44
|
});
|
|
@@ -69,11 +60,11 @@ export class ApprovalGate {
|
|
|
69
60
|
return false;
|
|
70
61
|
}
|
|
71
62
|
this.waiters.delete(key);
|
|
63
|
+
const by =
|
|
64
|
+
resolvedBy === undefined || resolvedBy === "" ? undefined : resolvedBy;
|
|
72
65
|
waiter.resolve({
|
|
73
66
|
decision,
|
|
74
|
-
|
|
75
|
-
? {}
|
|
76
|
-
: { by: resolvedBy }),
|
|
67
|
+
by,
|
|
77
68
|
});
|
|
78
69
|
return true;
|
|
79
70
|
}
|
|
@@ -82,9 +73,9 @@ export class ApprovalGate {
|
|
|
82
73
|
return this.waiters.has(approvalKey(sessionId, callId));
|
|
83
74
|
}
|
|
84
75
|
|
|
85
|
-
list(sessionId: string):
|
|
76
|
+
list(sessionId: string): T[] {
|
|
86
77
|
const prefix = `${sessionId}\0`;
|
|
87
|
-
const out:
|
|
78
|
+
const out: T[] = [];
|
|
88
79
|
for (const [key, waiter] of this.waiters) {
|
|
89
80
|
if (key.startsWith(prefix)) {
|
|
90
81
|
out.push(waiter.meta);
|
|
@@ -483,6 +483,25 @@ async function streamTurn(args: StreamTurnArgs): Promise<number> {
|
|
|
483
483
|
);
|
|
484
484
|
continue;
|
|
485
485
|
}
|
|
486
|
+
if (event.type === "action.auth_requested") {
|
|
487
|
+
closeAssistant();
|
|
488
|
+
write(
|
|
489
|
+
` ${c.yellow("⏸")} ${c.bold(event.data.connection)} ${c.dim(
|
|
490
|
+
"awaiting MCP authorization"
|
|
491
|
+
)}\n`
|
|
492
|
+
);
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
if (event.type === "action.auth_resolved") {
|
|
496
|
+
const mark =
|
|
497
|
+
event.data.decision === "approve" ? c.green("✓") : c.red("✗");
|
|
498
|
+
write(
|
|
499
|
+
` ${mark} ${c.bold(event.data.connection)} ${c.dim(
|
|
500
|
+
event.data.decision === "approve" ? "connected" : "denied"
|
|
501
|
+
)}\n`
|
|
502
|
+
);
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
486
505
|
if (event.type === "action.result") {
|
|
487
506
|
if (
|
|
488
507
|
event.data.toolName === "task" &&
|
|
@@ -112,6 +112,11 @@ export interface DeployCliOptions {
|
|
|
112
112
|
cursorEventsRepos?: string[];
|
|
113
113
|
/** deploy `--allow-domain <domain>` (repeatable; unioned with the manifest). */
|
|
114
114
|
allowDomains?: string[];
|
|
115
|
+
/**
|
|
116
|
+
* deploy `--multi-tenant`: add a release to an existing Cursor-managed
|
|
117
|
+
* (multi-tenant) product. Cannot create a new multi-tenant application.
|
|
118
|
+
*/
|
|
119
|
+
multiTenant?: boolean;
|
|
115
120
|
/** Test seams. */
|
|
116
121
|
fetchImpl?: typeof fetch;
|
|
117
122
|
/** Inject the connector-auth browser opener (tests; also forces interactive). */
|
|
@@ -311,7 +316,9 @@ export async function cmdDeploy(options: DeployCliOptions): Promise<number> {
|
|
|
311
316
|
manifests.push(await readDeployManifest(target.dir));
|
|
312
317
|
}
|
|
313
318
|
if (manifests.every((manifest) => manifest.architecture === "v2")) {
|
|
314
|
-
return deployAgentsdkApplication(ctx, options, targets
|
|
319
|
+
return deployAgentsdkApplication(ctx, options, targets, {
|
|
320
|
+
hasScmChannels: manifests.some((manifest) => manifest.hasScmChannels),
|
|
321
|
+
});
|
|
315
322
|
}
|
|
316
323
|
if (
|
|
317
324
|
!ctx.json &&
|
|
@@ -722,9 +729,18 @@ async function deployOne(
|
|
|
722
729
|
gitRef,
|
|
723
730
|
agentPath,
|
|
724
731
|
repositories: options.cursorEventsRepos,
|
|
732
|
+
hasScmChannels: manifest.hasScmChannels,
|
|
733
|
+
multiTenant: options.multiTenant === true,
|
|
725
734
|
});
|
|
726
735
|
}
|
|
727
736
|
|
|
737
|
+
if (options.multiTenant === true) {
|
|
738
|
+
ctx.err(
|
|
739
|
+
"--multi-tenant is only valid for architecture: v2 deploys (Cursor-managed products).\n"
|
|
740
|
+
);
|
|
741
|
+
return 1;
|
|
742
|
+
}
|
|
743
|
+
|
|
728
744
|
// Today's only source shape: the control plane builds from a git ref.
|
|
729
745
|
// See DeploySource for the artifact seam.
|
|
730
746
|
const source: DeploySource = {
|
|
@@ -804,11 +820,9 @@ async function deployOne(
|
|
|
804
820
|
}
|
|
805
821
|
|
|
806
822
|
if (detail.status !== "running") {
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
: `: ${sanitizeCustomerError(detail.lastError)}`;
|
|
811
|
-
ctx.err(`Deployment ${slug} ended ${detail.status}${errorDetail}\n`);
|
|
823
|
+
ctx.err(
|
|
824
|
+
`Deployment ${slug} ended ${detail.status}${deployFailureDetail(detail.lastError)}\n`
|
|
825
|
+
);
|
|
812
826
|
return 1;
|
|
813
827
|
}
|
|
814
828
|
const deployedPublicRoutes = detail.publicRoutePaths ?? [];
|
|
@@ -845,7 +859,8 @@ async function deployOne(
|
|
|
845
859
|
async function deployAgentsdkApplication(
|
|
846
860
|
ctx: DeployCliContext,
|
|
847
861
|
options: DeployCliOptions,
|
|
848
|
-
targets: readonly DeployTarget[]
|
|
862
|
+
targets: readonly DeployTarget[],
|
|
863
|
+
declarations: { hasScmChannels: boolean }
|
|
849
864
|
): Promise<number> {
|
|
850
865
|
const parentDir = resolve(options.dir ?? ".");
|
|
851
866
|
const slug = slugFromDirectoryName(basename(parentDir));
|
|
@@ -926,6 +941,8 @@ async function deployAgentsdkApplication(
|
|
|
926
941
|
agentPath: undefined,
|
|
927
942
|
components,
|
|
928
943
|
repositories: options.cursorEventsRepos,
|
|
944
|
+
hasScmChannels: declarations.hasScmChannels,
|
|
945
|
+
multiTenant: options.multiTenant === true,
|
|
929
946
|
});
|
|
930
947
|
}
|
|
931
948
|
|
|
@@ -944,6 +961,10 @@ async function deployOneAgentsdk(
|
|
|
944
961
|
agentPath: string | undefined;
|
|
945
962
|
components?: AgentkitDeployComponent[];
|
|
946
963
|
repositories: string[] | undefined;
|
|
964
|
+
/** Any component declares a GitHub/Origin channel. */
|
|
965
|
+
hasScmChannels: boolean;
|
|
966
|
+
/** Redeploy an existing Cursor-managed product. */
|
|
967
|
+
multiTenant: boolean;
|
|
947
968
|
}
|
|
948
969
|
): Promise<number> {
|
|
949
970
|
const { slug } = args;
|
|
@@ -953,6 +974,9 @@ async function deployOneAgentsdk(
|
|
|
953
974
|
: ` components: ${args.components
|
|
954
975
|
.map((component) => component.componentKey)
|
|
955
976
|
.join(", ")}\n`;
|
|
977
|
+
if (args.multiTenant && !ctx.json) {
|
|
978
|
+
ctx.err(" multi-tenant: existing product\n");
|
|
979
|
+
}
|
|
956
980
|
let accepted: AgentkitDeployAccepted;
|
|
957
981
|
try {
|
|
958
982
|
accepted = await ctx.client.deployAgentkit({
|
|
@@ -963,6 +987,7 @@ async function deployOneAgentsdk(
|
|
|
963
987
|
agentPath: args.agentPath,
|
|
964
988
|
components: args.components,
|
|
965
989
|
repositories: args.repositories,
|
|
990
|
+
...(args.multiTenant ? { multiTenant: true } : {}),
|
|
966
991
|
});
|
|
967
992
|
} catch (error) {
|
|
968
993
|
return renderApiError(error, ctx.err);
|
|
@@ -1004,7 +1029,9 @@ async function deployOneAgentsdk(
|
|
|
1004
1029
|
}
|
|
1005
1030
|
|
|
1006
1031
|
if (detail.status !== "running") {
|
|
1007
|
-
ctx.err(
|
|
1032
|
+
ctx.err(
|
|
1033
|
+
`Deployment ${slug} ended ${detail.status}${deployFailureDetail(detail.lastError)}\n`
|
|
1034
|
+
);
|
|
1008
1035
|
return 1;
|
|
1009
1036
|
}
|
|
1010
1037
|
ctx.out(
|
|
@@ -1017,8 +1044,19 @@ async function deployOneAgentsdk(
|
|
|
1017
1044
|
? ""
|
|
1018
1045
|
: ` components: ${args.components
|
|
1019
1046
|
.map((component) => component.componentKey)
|
|
1020
|
-
.join(", ")}\n`)
|
|
1047
|
+
.join(", ")}\n`) +
|
|
1048
|
+
(detail.repositories === undefined || !args.hasScmChannels
|
|
1049
|
+
? ""
|
|
1050
|
+
: ` watching: ${detail.repositories.length === 0 ? "(nothing)" : detail.repositories.join(", ")}\n`)
|
|
1021
1051
|
);
|
|
1052
|
+
// An agent with GitHub/Origin channels bound to no repository scope gets
|
|
1053
|
+
// no deliveries at all, which is otherwise invisible in this output.
|
|
1054
|
+
if (args.hasScmChannels && detail.repositories?.length === 0) {
|
|
1055
|
+
ctx.err(
|
|
1056
|
+
`warning: ${slug} watches no repositories, so its GitHub/Origin channels receive no events.\n` +
|
|
1057
|
+
` Redeploy with --cursor-events-repo <owner>/<name> to set the scope.\n`
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1022
1060
|
return 0;
|
|
1023
1061
|
}
|
|
1024
1062
|
|
|
@@ -1128,6 +1166,11 @@ interface DeployManifest {
|
|
|
1128
1166
|
* (only `/v1/channels/…` subtrees can be public); surfaced as a warning.
|
|
1129
1167
|
*/
|
|
1130
1168
|
httpChannelPublicEndpoint: boolean;
|
|
1169
|
+
/**
|
|
1170
|
+
* The agent has GitHub/Origin channels, so it only receives deliveries
|
|
1171
|
+
* while the deployment is bound to at least one `owner/name` scope.
|
|
1172
|
+
*/
|
|
1173
|
+
hasScmChannels: boolean;
|
|
1131
1174
|
}
|
|
1132
1175
|
|
|
1133
1176
|
/**
|
|
@@ -1163,6 +1206,10 @@ async function readDeployManifest(dir: string): Promise<DeployManifest> {
|
|
|
1163
1206
|
httpChannelPublicEndpoint: (project.httpChannel.auth ?? []).some(
|
|
1164
1207
|
isPublicEndpointPolicy
|
|
1165
1208
|
),
|
|
1209
|
+
hasScmChannels: project.channels.some((channel) => {
|
|
1210
|
+
const kind = channel.definition.meta?.kind;
|
|
1211
|
+
return kind === "github" || kind === "origin";
|
|
1212
|
+
}),
|
|
1166
1213
|
};
|
|
1167
1214
|
}
|
|
1168
1215
|
|
|
@@ -1938,9 +1985,32 @@ function aliasTokenBlock(aliasToken: string): string {
|
|
|
1938
1985
|
);
|
|
1939
1986
|
}
|
|
1940
1987
|
|
|
1988
|
+
/**
|
|
1989
|
+
* `: <reason>` suffix for a deploy that ended in a non-running state, or
|
|
1990
|
+
* empty when the control plane recorded no reason.
|
|
1991
|
+
*/
|
|
1992
|
+
function deployFailureDetail(lastError: string | null | undefined): string {
|
|
1993
|
+
if (
|
|
1994
|
+
lastError === null ||
|
|
1995
|
+
lastError === undefined ||
|
|
1996
|
+
lastError.trim() === ""
|
|
1997
|
+
) {
|
|
1998
|
+
return "";
|
|
1999
|
+
}
|
|
2000
|
+
return `: ${sanitizeCustomerError(lastError.trim())}`;
|
|
2001
|
+
}
|
|
2002
|
+
|
|
1941
2003
|
function renderApiError(error: unknown, err: (text: string) => void): number {
|
|
1942
2004
|
if (error instanceof DeployApiError) {
|
|
1943
2005
|
err(`${error.message}\n`);
|
|
2006
|
+
if (
|
|
2007
|
+
error.status === 409 &&
|
|
2008
|
+
error.message.includes("application multiTenant does not match")
|
|
2009
|
+
) {
|
|
2010
|
+
err(
|
|
2011
|
+
"This slug is a Cursor-managed (multi-tenant) product. Redeploy it with --multi-tenant.\n"
|
|
2012
|
+
);
|
|
2013
|
+
}
|
|
1944
2014
|
return 1;
|
|
1945
2015
|
}
|
|
1946
2016
|
throw error;
|
|
@@ -23,10 +23,10 @@ import { CLI_COMMAND_NAME as CLI, LOG_PREFIX } from "./distribution.js";
|
|
|
23
23
|
import {
|
|
24
24
|
createHostMcpOAuthProvider,
|
|
25
25
|
MCP_OAUTH_CALLBACK_URL,
|
|
26
|
-
mcpOauthSecretNames,
|
|
27
26
|
openBrowser,
|
|
28
27
|
waitForMcpOAuthCallback,
|
|
29
28
|
} from "./mcp-oauth.js";
|
|
29
|
+
import { upsertHostMcpOauthSecrets } from "./mcp-oauth-persist.js";
|
|
30
30
|
import { resolveProdSlug } from "./resolve-prod-target.js";
|
|
31
31
|
|
|
32
32
|
export type McpOauthCliOptions = {
|
|
@@ -381,29 +381,15 @@ async function storeOauthSecrets(args: {
|
|
|
381
381
|
return auth;
|
|
382
382
|
}
|
|
383
383
|
|
|
384
|
-
const names = mcpOauthSecretNames(args.connection);
|
|
385
|
-
const secrets: Array<{ name: string; value: string }> = [
|
|
386
|
-
{ name: names.accessToken, value: tokens.access_token },
|
|
387
|
-
];
|
|
388
|
-
if (
|
|
389
|
-
tokens.refresh_token !== undefined &&
|
|
390
|
-
tokens.refresh_token.trim() !== ""
|
|
391
|
-
) {
|
|
392
|
-
secrets.push({ name: names.refreshToken, value: tokens.refresh_token });
|
|
393
|
-
}
|
|
394
|
-
if (args.clientId !== undefined && args.clientId.trim() !== "") {
|
|
395
|
-
secrets.push({ name: names.clientId, value: args.clientId });
|
|
396
|
-
}
|
|
397
|
-
|
|
398
384
|
try {
|
|
399
|
-
const secretNames = await
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
385
|
+
const secretNames = await upsertHostMcpOauthSecrets({
|
|
386
|
+
connection: args.connection,
|
|
387
|
+
tokens,
|
|
388
|
+
clientId: args.clientId,
|
|
389
|
+
target: { client: auth.client, teamId: auth.teamId, slug },
|
|
403
390
|
});
|
|
404
391
|
args.out(
|
|
405
|
-
`${LOG_PREFIX} Stored on ${slug}: ${
|
|
406
|
-
`${LOG_PREFIX} Secrets now: ${secretNames.join(", ")}. Next deploy picks them up.\n`
|
|
392
|
+
`${LOG_PREFIX} Stored on ${slug}. Secrets now: ${secretNames.join(", ")}. Next deploy picks them up.\n`
|
|
407
393
|
);
|
|
408
394
|
return 0;
|
|
409
395
|
} catch (error) {
|