@cursor/july 0.1.93 → 0.1.95
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/AGENTS.md +8 -20
- package/README.md +4 -26
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +14 -2
- package/dist/channels/github/types.d.ts +18 -3
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +11 -3
- package/dist/channels/origin/origin-webhook.d.ts +11 -1
- package/dist/channels/origin/origin-webhook.d.ts.map +1 -1
- package/dist/channels/origin/origin-webhook.js +23 -3
- package/dist/channels/origin/types.d.ts +8 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels/slack/attachments.js +2 -2
- package/dist/channels/slack/dispatch.d.ts +0 -7
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +4 -7
- package/dist/channels/slack/eval-directive.d.ts +5 -12
- package/dist/channels/slack/eval-directive.d.ts.map +1 -1
- package/dist/channels/slack/eval-directive.js +8 -19
- package/dist/channels/slack/index.d.ts +0 -6
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +0 -6
- package/dist/channels/slack/pr-ref.d.ts +7 -1
- package/dist/channels/slack/pr-ref.d.ts.map +1 -1
- package/dist/channels/slack/pr-ref.js +42 -23
- package/dist/channels/slack/setup.d.ts +4 -4
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +8 -15
- package/dist/channels/slack/slack-channel.d.ts +6 -13
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +15 -101
- package/dist/channels/slack/types.d.ts +12 -79
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels/slack/types.js +1 -15
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +12 -0
- package/dist/connections.d.ts +18 -9
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +17 -8
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.CjWU-x0z.js → app.BBj0klBO.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.oqPawjiD.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.Cxy8ySFQ.js → VPLocalSearchBox.CUEXpL78.js} +1 -1
- package/dist/docs/assets/chunks/{theme.Dvq1Bktu.js → theme.DabmQnia.js} +2 -2
- package/dist/docs/assets/concepts.md.lwAgBIMI.js +1 -0
- package/dist/docs/assets/{deployment.md.DoLFAzfm.js → deployment.md.D9msOFOW.js} +3 -8
- package/dist/docs/assets/{deployment.md.DoLFAzfm.lean.js → deployment.md.D9msOFOW.lean.js} +1 -1
- package/dist/docs/assets/{guides_agent-to-agent.md.B3JIaAqz.js → guides_agent-to-agent.md.BDb0t1QV.js} +1 -1
- package/dist/docs/assets/guides_cloud-runtime.md.CkYbjnAX.js +9 -0
- package/dist/docs/assets/guides_cloud-runtime.md.CkYbjnAX.lean.js +1 -0
- package/dist/docs/assets/{guides_convert-automation.md.Bboisykk.js → guides_convert-automation.md.B4sjlodG.js} +1 -1
- package/dist/docs/assets/{guides_github.md.DqJhuaN1.js → guides_github.md.Cnh2mL4a.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.CJvrXtkN.js → guides_mcp-oauth.md.DPYmBCbV.js} +7 -9
- package/dist/docs/assets/{guides_mcp-oauth.md.CJvrXtkN.lean.js → guides_mcp-oauth.md.DPYmBCbV.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.mqeNKs84.js → guides_slack.md.C32HsdKk.js} +5 -11
- package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +1 -0
- package/dist/docs/assets/index.md.BoHaMdeZ.js +5 -0
- package/dist/docs/assets/{index.md.B-lVR4wT.lean.js → index.md.BoHaMdeZ.lean.js} +1 -1
- package/dist/docs/assets/{quickstart.md.BrmfrrIr.js → quickstart.md.Nj_LjW_a.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.D9KESDsD.js → reference_cli.md.BsMOxDvh.js} +4 -3
- package/dist/docs/assets/{reference_cli.md.D9KESDsD.lean.js → reference_cli.md.BsMOxDvh.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.DB6SsN6U.js → reference_connections.md.BH8Oc0D0.js} +5 -5
- package/dist/docs/assets/{reference_connections.md.DB6SsN6U.lean.js → reference_connections.md.BH8Oc0D0.lean.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BxN87gCw.js → reference_hooks.md.a8BJxMR5.js} +1 -1
- package/dist/docs/assets/reference_http-api.md.D89k1mdm.js +11 -0
- package/dist/docs/assets/reference_http-api.md.D89k1mdm.lean.js +1 -0
- package/dist/docs/assets/reference_project-layout.md.Bv4KOtlB.js +19 -0
- package/dist/docs/assets/{reference_subagents.md.Xoav0AII.js → reference_subagents.md.CfsIloPm.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.DuKvkYWG.js → reference_tools.md.BHeXn2id.js} +3 -3
- package/dist/docs/assets/{reference_tools.md.DuKvkYWG.lean.js → reference_tools.md.BHeXn2id.lean.js} +1 -1
- package/dist/docs/assets/{templates_agentic-owners.md.DqtPdm6f.js → templates_agentic-owners.md.BZSH4N9z.js} +1 -1
- package/dist/docs/assets/{templates_demo.md.DhFcWN6j.js → templates_demo.md.BeQX9V3H.js} +1 -1
- package/dist/docs/assets/{templates_pr-autofixer.md.R4K_qytS.js → templates_pr-autofixer.md.x5zl6-GT.js} +2 -2
- package/dist/docs/assets/{templates_pr-autofixer.md.R4K_qytS.lean.js → templates_pr-autofixer.md.x5zl6-GT.lean.js} +1 -1
- package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.js +4 -0
- package/dist/docs/assets/templates_security-help.md.C3Ny_Qr2.lean.js +1 -0
- package/dist/docs/assets/{templates_security-reviewer.md.ByFyRta2.js → templates_security-reviewer.md.lshxbCLK.js} +2 -2
- package/dist/docs/assets/{templates_security-reviewer.md.ByFyRta2.lean.js → templates_security-reviewer.md.lshxbCLK.lean.js} +1 -1
- package/dist/docs/assets/{templates_triage.md.CVlpctKS.js → templates_triage.md.Co4UNzkZ.js} +3 -3
- package/dist/docs/assets/{templates_triage.md.CVlpctKS.lean.js → templates_triage.md.Co4UNzkZ.lean.js} +1 -1
- package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/concepts.md +1 -0
- package/dist/docs/deployment.html +7 -12
- package/dist/docs/deployment.md +1 -20
- package/dist/docs/design/agsh.md +406 -0
- package/dist/docs/evals.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +6 -6
- package/dist/docs/guides/agent-to-agent.md +2 -2
- package/dist/docs/guides/cloud-runtime.html +6 -6
- package/dist/docs/guides/cloud-runtime.md +1 -0
- package/dist/docs/guides/convert-automation.html +6 -6
- package/dist/docs/guides/convert-automation.md +1 -1
- package/dist/docs/guides/github.html +6 -6
- package/dist/docs/guides/github.md +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +11 -13
- package/dist/docs/guides/mcp-oauth.md +10 -18
- package/dist/docs/guides/opentelemetry.html +5 -5
- package/dist/docs/guides/slack.html +9 -15
- package/dist/docs/guides/slack.md +9 -46
- 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 +3 -29
- package/dist/docs/llms-full.txt +756 -2810
- package/dist/docs/llms.txt +3 -16
- package/dist/docs/quickstart.html +6 -6
- package/dist/docs/quickstart.md +2 -3
- 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 +8 -7
- package/dist/docs/reference/cli.md +5 -2
- package/dist/docs/reference/connections.html +9 -9
- package/dist/docs/reference/connections.md +15 -11
- package/dist/docs/reference/hooks.html +6 -6
- package/dist/docs/reference/hooks.md +2 -3
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +8 -0
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +8 -6
- package/dist/docs/reference/project-layout.md +5 -1
- 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 +6 -6
- package/dist/docs/reference/subagents.md +2 -2
- package/dist/docs/reference/tools.html +7 -7
- package/dist/docs/reference/tools.md +19 -3
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/templates/agentic-owners.html +7 -7
- package/dist/docs/templates/agentic-owners.md +1 -1
- package/dist/docs/templates/demo.html +6 -6
- package/dist/docs/templates/demo.md +3 -2
- package/dist/docs/templates/pr-autofixer.html +6 -6
- package/dist/docs/templates/pr-autofixer.md +8 -13
- package/dist/docs/templates/security-help.html +30 -0
- package/dist/docs/templates/security-help.md +65 -0
- package/dist/docs/templates/security-reviewer.html +6 -6
- package/dist/docs/templates/security-reviewer.md +1 -3
- package/dist/docs/templates/triage.html +7 -7
- package/dist/docs/templates/triage.md +2 -6
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/docs/troubleshooting.md +2 -2
- package/dist/files-backends/cursor-hosted.d.ts +6 -2
- package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/files-backends/cursor-hosted.js +2 -2
- package/dist/files.d.ts +2 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +5 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/advertise-tools.d.ts +11 -0
- package/dist/internal/advertise-tools.d.ts.map +1 -1
- package/dist/internal/advertise-tools.js +47 -9
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +135 -6
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +7 -4
- package/dist/internal/conversation-mirror.d.ts +82 -0
- package/dist/internal/conversation-mirror.d.ts.map +1 -0
- package/dist/internal/conversation-mirror.js +251 -0
- package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -1
- package/dist/internal/convert-automation/convert-workflow.js +26 -15
- package/dist/internal/convert-automation/slug.d.ts +0 -2
- package/dist/internal/convert-automation/slug.d.ts.map +1 -1
- package/dist/internal/convert-automation/slug.js +0 -8
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +5 -1
- package/dist/internal/deferred-channel-session.d.ts +20 -0
- package/dist/internal/deferred-channel-session.d.ts.map +1 -0
- package/dist/internal/deferred-channel-session.js +62 -0
- package/dist/internal/deploy-client.d.ts +13 -1
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +11 -1
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +11 -5
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +110 -15
- package/dist/internal/framework-storage-selection.d.ts +32 -16
- package/dist/internal/framework-storage-selection.d.ts.map +1 -1
- package/dist/internal/framework-storage-selection.js +51 -17
- package/dist/internal/hosted-admission-context.d.ts +20 -0
- package/dist/internal/hosted-admission-context.d.ts.map +1 -0
- package/dist/internal/hosted-admission-context.js +31 -0
- package/dist/internal/hosted-delivery-protocol.d.ts +5 -0
- package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-delivery-protocol.js +33 -1
- package/dist/internal/hosted-delivery.d.ts +4 -2
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +97 -44
- package/dist/internal/hosted-managed-automation.d.ts +30 -0
- package/dist/internal/hosted-managed-automation.d.ts.map +1 -0
- package/dist/internal/hosted-managed-automation.js +58 -0
- package/dist/internal/mcp-endpoint.js +3 -3
- package/dist/internal/mcp-host.d.ts +8 -7
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +8 -7
- package/dist/internal/peer-connections.d.ts.map +1 -1
- package/dist/internal/peer-connections.js +5 -1
- package/dist/internal/playground/static.d.ts +0 -3
- package/dist/internal/playground/static.d.ts.map +1 -1
- package/dist/internal/resolved-connections.d.ts.map +1 -1
- package/dist/internal/resolved-connections.js +5 -7
- package/dist/internal/review-comments.d.ts.map +1 -1
- package/dist/internal/review-comments.js +10 -98
- package/dist/internal/scm/pr-url.d.ts +14 -0
- package/dist/internal/scm/pr-url.d.ts.map +1 -0
- package/dist/internal/scm/pr-url.js +65 -0
- package/dist/internal/sdk-runner.d.ts +14 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +41 -2
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +123 -174
- package/dist/internal/session-engine.d.ts +45 -10
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +217 -65
- package/dist/internal/tool-catalog.d.ts +31 -0
- package/dist/internal/tool-catalog.d.ts.map +1 -0
- package/dist/internal/tool-catalog.js +67 -0
- package/dist/playground/assets/index-CF7hUDnQ.css +1 -0
- package/dist/playground/assets/{index-D9MFzhNE.js → index-CZA1uEWA.js} +48 -48
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +7 -2
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +2 -2
- package/dist/types.d.ts +72 -23
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +19 -0
- package/docs/README.md +3 -29
- package/docs/concepts.md +1 -0
- package/docs/deployment.md +1 -20
- package/docs/design/agsh.md +406 -0
- package/docs/guides/agent-to-agent.md +2 -2
- package/docs/guides/cloud-runtime.md +1 -0
- package/docs/guides/convert-automation.md +1 -1
- package/docs/guides/github.md +4 -4
- package/docs/guides/mcp-oauth.md +10 -18
- package/docs/guides/slack.md +10 -47
- package/docs/quickstart.md +2 -3
- package/docs/reference/cli.md +5 -2
- package/docs/reference/connections.md +15 -11
- package/docs/reference/hooks.md +2 -3
- package/docs/reference/http-api.md +8 -0
- package/docs/reference/project-layout.md +5 -1
- package/docs/reference/subagents.md +2 -2
- package/docs/reference/tools.md +19 -3
- package/docs/templates/agentic-owners.md +1 -1
- package/docs/templates/demo.md +3 -2
- package/docs/templates/pr-autofixer.md +8 -13
- package/docs/templates/security-help.md +70 -0
- package/docs/templates/security-reviewer.md +1 -3
- package/docs/templates/triage.md +2 -6
- package/docs/troubleshooting.md +2 -2
- package/package.json +9 -2
- package/skills/create-agent/SKILL.md +6 -13
- package/skills/debug/SKILL.md +2 -4
- package/skills/evals/SKILL.md +1 -1
- package/skills/framework-map/SKILL.md +3 -2
- package/skills/mcp-auth/SKILL.md +10 -13
- package/skills/setup-slack/SKILL.md +21 -137
- package/src/channels/github/github-channel.ts +23 -8
- package/src/channels/github/types.ts +19 -2
- package/src/channels/origin/origin-channel.ts +13 -1
- package/src/channels/origin/origin-webhook.ts +27 -3
- package/src/channels/origin/types.ts +8 -0
- package/src/channels/slack/attachments.ts +2 -2
- package/src/channels/slack/dispatch.ts +2 -16
- package/src/channels/slack/eval-directive.ts +8 -27
- package/src/channels/slack/index.ts +0 -6
- package/src/channels/slack/pr-ref.ts +56 -25
- package/src/channels/slack/setup.ts +8 -15
- package/src/channels/slack/slack-channel.ts +14 -125
- package/src/channels/slack/types.ts +12 -96
- package/src/client.ts +23 -0
- package/src/connections.ts +20 -7
- package/src/files-backends/cursor-hosted.ts +9 -3
- package/src/files.ts +11 -0
- package/src/index.ts +2 -0
- package/src/internal/advertise-tools.ts +45 -7
- package/src/internal/cli-deploy.ts +171 -7
- package/src/internal/cli-mcp-oauth.ts +6 -4
- package/src/internal/conversation-mirror.ts +330 -0
- package/src/internal/convert-automation/convert-workflow.ts +29 -17
- package/src/internal/convert-automation/slug.ts +0 -9
- package/src/internal/cursor/account-mcp.ts +4 -1
- package/src/internal/deferred-channel-session.ts +61 -0
- package/src/internal/deploy-client.ts +24 -1
- package/src/internal/deploy-manifest.ts +10 -5
- package/src/internal/discovery.ts +129 -15
- package/src/internal/fixtures/units-server.ts +52 -0
- package/src/internal/framework-storage-selection.ts +61 -19
- package/src/internal/hosted-admission-context.ts +37 -0
- package/src/internal/hosted-delivery-protocol.ts +44 -1
- package/src/internal/hosted-delivery.ts +155 -68
- package/src/internal/hosted-managed-automation.ts +72 -0
- package/src/internal/mcp-endpoint.ts +3 -3
- package/src/internal/mcp-host.ts +8 -7
- package/src/internal/peer-connections.ts +4 -1
- package/src/internal/playground/static.ts +1 -3
- package/src/internal/resolved-connections.ts +8 -10
- package/src/internal/review-comments.ts +10 -113
- package/src/internal/scm/pr-url.ts +95 -0
- package/src/internal/sdk-runner.ts +57 -2
- package/src/internal/server.ts +161 -251
- package/src/internal/session-engine.ts +266 -69
- package/src/internal/tool-catalog.ts +106 -0
- package/src/storage-backends/cursor-hosted.ts +10 -3
- package/src/types.ts +90 -23
- package/templates/agentic-owners/README.md +1 -1
- package/templates/agentic-owners/agent/agent.ts +0 -10
- package/templates/agentic-owners/agent/channels/github.ts +5 -14
- package/templates/agentic-owners/agent/lib/config.ts +0 -8
- package/templates/agentic-owners/agent/lib/review.ts +2 -15
- package/templates/agentic-owners/agent/tools/record_review.ts +2 -4
- package/templates/demo/agent/agent.ts +0 -10
- package/templates/pr-autofixer/README.md +0 -2
- package/templates/pr-autofixer/agent/agent.ts +0 -11
- package/templates/pr-autofixer/agent/channels/slack.ts +1 -2
- package/templates/pr-autofixer/agent/lib/pr-state.ts +5 -17
- package/templates/pr-autofixer/agent/lib/repos.ts +0 -1
- package/templates/security-help/README.md +2 -2
- package/templates/security-help/agent/agent.ts +1 -2
- package/templates/security-help/agent/channels/slack.ts +0 -3
- package/templates/security-help/agent/instructions.md +9 -10
- package/templates/security-help/agent/skills/access-request.md +1 -1
- package/templates/security-help/agent/skills/faq.md +31 -0
- package/templates/security-help/agent/skills/security-playbooks.md +1 -1
- package/templates/security-help/package.json +1 -2
- package/templates/security-reviewer/agent/agent.ts +0 -10
- package/templates/triage/README.md +2 -1
- package/templates/triage/agent/agent.ts +0 -10
- package/templates/triage/agent/channels/queue.ts +1 -1
- package/templates/triage/agent/channels/webhook.ts +1 -3
- package/templates/triage/overlays/jira/agent/mcp-connections/tracker.ts +0 -1
- package/templates/triage/overlays/linear/agent/mcp-connections/tracker.ts +0 -1
- package/dist/channels/slack/cursor-account.d.ts +0 -87
- package/dist/channels/slack/cursor-account.d.ts.map +0 -1
- package/dist/channels/slack/cursor-account.js +0 -100
- package/dist/docs/assets/chunks/@localSearchIndexroot.ChpIC3Zy.js +0 -1
- package/dist/docs/assets/concepts.md.F6AiPorA.js +0 -1
- package/dist/docs/assets/example-agents_approval-buddy.md.DmezILPg.js +0 -10
- package/dist/docs/assets/example-agents_approval-buddy.md.DmezILPg.lean.js +0 -1
- package/dist/docs/assets/example-agents_benny.md.B0kwY7D_.js +0 -5
- package/dist/docs/assets/example-agents_benny.md.B0kwY7D_.lean.js +0 -1
- package/dist/docs/assets/example-agents_bugbot.md.BRGMi9O2.js +0 -11
- package/dist/docs/assets/example-agents_bugbot.md.BRGMi9O2.lean.js +0 -1
- package/dist/docs/assets/example-agents_codebase-wiki.md.BBNw9Ekr.js +0 -8
- package/dist/docs/assets/example-agents_codebase-wiki.md.BBNw9Ekr.lean.js +0 -1
- package/dist/docs/assets/example-agents_codeowners-review.md.Bfta-lBU.js +0 -8
- package/dist/docs/assets/example-agents_codeowners-review.md.Bfta-lBU.lean.js +0 -1
- package/dist/docs/assets/example-agents_concierge.md.BzB2b20R.js +0 -22
- package/dist/docs/assets/example-agents_concierge.md.BzB2b20R.lean.js +0 -1
- package/dist/docs/assets/example-agents_index.md.ChBp0AX6.js +0 -2
- package/dist/docs/assets/example-agents_index.md.ChBp0AX6.lean.js +0 -1
- package/dist/docs/assets/example-agents_knowledge-base.md.CrA85ig-.js +0 -11
- package/dist/docs/assets/example-agents_knowledge-base.md.CrA85ig-.lean.js +0 -1
- package/dist/docs/assets/example-agents_oncall.md.DK4XkYTd.js +0 -10
- package/dist/docs/assets/example-agents_oncall.md.DK4XkYTd.lean.js +0 -1
- package/dist/docs/assets/example-agents_security-reviewer.md.74pPpWYj.js +0 -19
- package/dist/docs/assets/example-agents_security-reviewer.md.74pPpWYj.lean.js +0 -1
- package/dist/docs/assets/example-agents_slack-agent.md.D7Kdj5BV.js +0 -5
- package/dist/docs/assets/example-agents_slack-agent.md.D7Kdj5BV.lean.js +0 -1
- package/dist/docs/assets/example-agents_weather-agent.md.CaGpmw3Y.js +0 -25
- package/dist/docs/assets/example-agents_weather-agent.md.CaGpmw3Y.lean.js +0 -1
- package/dist/docs/assets/guides_cloud-runtime.md.BnvjPiia.js +0 -9
- package/dist/docs/assets/guides_cloud-runtime.md.BnvjPiia.lean.js +0 -1
- package/dist/docs/assets/guides_slack.md.mqeNKs84.lean.js +0 -1
- package/dist/docs/assets/index.md.B-lVR4wT.js +0 -5
- package/dist/docs/assets/reference_http-api.md.C68BERYr.js +0 -11
- package/dist/docs/assets/reference_http-api.md.C68BERYr.lean.js +0 -1
- package/dist/docs/assets/reference_project-layout.md.WN9nwJht.js +0 -17
- package/dist/docs/assets/troubleshooting.md.vCWwvqcJ.js +0 -1
- package/dist/docs/example-agents/approval-buddy.html +0 -36
- package/dist/docs/example-agents/approval-buddy.md +0 -266
- package/dist/docs/example-agents/benny.html +0 -31
- package/dist/docs/example-agents/benny.md +0 -173
- package/dist/docs/example-agents/bugbot.html +0 -37
- package/dist/docs/example-agents/bugbot.md +0 -229
- package/dist/docs/example-agents/codebase-wiki.html +0 -34
- package/dist/docs/example-agents/codebase-wiki.md +0 -167
- package/dist/docs/example-agents/codeowners-review.html +0 -34
- package/dist/docs/example-agents/codeowners-review.md +0 -192
- package/dist/docs/example-agents/concierge.html +0 -48
- package/dist/docs/example-agents/concierge.md +0 -200
- package/dist/docs/example-agents/index.html +0 -28
- package/dist/docs/example-agents/index.md +0 -99
- package/dist/docs/example-agents/knowledge-base.html +0 -37
- package/dist/docs/example-agents/knowledge-base.md +0 -168
- package/dist/docs/example-agents/oncall.html +0 -36
- package/dist/docs/example-agents/oncall.md +0 -212
- package/dist/docs/example-agents/security-reviewer.html +0 -45
- package/dist/docs/example-agents/security-reviewer.md +0 -265
- package/dist/docs/example-agents/slack-agent.html +0 -31
- package/dist/docs/example-agents/slack-agent.md +0 -142
- package/dist/docs/example-agents/weather-agent.html +0 -51
- package/dist/docs/example-agents/weather-agent.md +0 -297
- package/dist/internal/cursor-slack-relay.d.ts +0 -96
- package/dist/internal/cursor-slack-relay.d.ts.map +0 -1
- package/dist/internal/cursor-slack-relay.js +0 -176
- package/dist/playground/assets/index-D9N7-q97.css +0 -1
- package/docs/example-agents/approval-buddy.md +0 -271
- package/docs/example-agents/benny.md +0 -178
- package/docs/example-agents/bugbot.md +0 -234
- package/docs/example-agents/codebase-wiki.md +0 -172
- package/docs/example-agents/codeowners-review.md +0 -197
- package/docs/example-agents/concierge.md +0 -205
- package/docs/example-agents/index.md +0 -104
- package/docs/example-agents/knowledge-base.md +0 -173
- package/docs/example-agents/oncall.md +0 -217
- package/docs/example-agents/security-reviewer.md +0 -270
- package/docs/example-agents/slack-agent.md +0 -147
- package/docs/example-agents/weather-agent.md +0 -302
- package/src/channels/slack/cursor-account.ts +0 -202
- package/src/internal/cursor-slack-relay.ts +0 -249
- package/templates/security-help/agent/knowledge/faq/approvals.md +0 -5
- package/templates/security-help/agent/knowledge/faq/channels.md +0 -6
- package/templates/security-help/agent/knowledge/faq/phishing.md +0 -10
- package/templates/security-help/agent/skills/security-first-pass.md +0 -15
- /package/dist/docs/assets/{concepts.md.F6AiPorA.lean.js → concepts.md.lwAgBIMI.lean.js} +0 -0
- /package/dist/docs/assets/{guides_agent-to-agent.md.B3JIaAqz.lean.js → guides_agent-to-agent.md.BDb0t1QV.lean.js} +0 -0
- /package/dist/docs/assets/{guides_convert-automation.md.Bboisykk.lean.js → guides_convert-automation.md.B4sjlodG.lean.js} +0 -0
- /package/dist/docs/assets/{guides_github.md.DqJhuaN1.lean.js → guides_github.md.Cnh2mL4a.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.BrmfrrIr.lean.js → quickstart.md.Nj_LjW_a.lean.js} +0 -0
- /package/dist/docs/assets/{reference_hooks.md.BxN87gCw.lean.js → reference_hooks.md.a8BJxMR5.lean.js} +0 -0
- /package/dist/docs/assets/{reference_project-layout.md.WN9nwJht.lean.js → reference_project-layout.md.Bv4KOtlB.lean.js} +0 -0
- /package/dist/docs/assets/{reference_subagents.md.Xoav0AII.lean.js → reference_subagents.md.CfsIloPm.lean.js} +0 -0
- /package/dist/docs/assets/{templates_agentic-owners.md.DqtPdm6f.lean.js → templates_agentic-owners.md.BZSH4N9z.lean.js} +0 -0
- /package/dist/docs/assets/{templates_demo.md.DhFcWN6j.lean.js → templates_demo.md.BeQX9V3H.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.vCWwvqcJ.lean.js → troubleshooting.md.Ctv3T8C2.lean.js} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agentsdk-setup-slack
|
|
3
3
|
description: >-
|
|
4
|
-
Wire Slack to an Agent SDK agent.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
Wire Slack to an Agent SDK agent. Mint a dedicated Socket Mode app with
|
|
5
|
+
slack create (dashboard wizard), then doctor and smoke. Use the manual
|
|
6
|
+
manifest path only when the user owns the Slack app. Use when adding
|
|
7
|
+
Slack to an agent.
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Setup Slack for the Agent SDK
|
|
@@ -14,132 +14,19 @@ host serves the same index at `/docs/llms.txt`.
|
|
|
14
14
|
|
|
15
15
|
Use this skill when a human asks to wire Slack to an Agent SDK agent.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
integration already installed in the workspace. No Slack app, no
|
|
22
|
-
tokens, no Slack admin. Live in minutes.
|
|
23
|
-
- **Path B — Dedicated Slack app** (Socket Mode): the agent's own bot
|
|
24
|
-
user. `agent-sdk slack create` opens a signed-in Cursor dashboard
|
|
25
|
-
wizard; Slack consent and the bot name happen there. Tokens land in
|
|
26
|
-
`.env.local` and as deployment secrets. Required for channel watching,
|
|
27
|
-
approval buttons, or a distinct bot handle.
|
|
17
|
+
`slackChannel()` is a dedicated Socket Mode Slack app: the agent's own
|
|
18
|
+
bot user. `agent-sdk slack create` opens a signed-in Cursor dashboard
|
|
19
|
+
wizard; Slack consent and the bot name happen there. Tokens land in
|
|
20
|
+
`.env.local` and as deployment secrets.
|
|
28
21
|
|
|
29
22
|
Do not generate manifests or ask anyone to paste tokens unless they
|
|
30
|
-
asked for a custom Slack app (`slack init --manual`).
|
|
31
|
-
Path B buries the user in Slack admin work they may not need.
|
|
23
|
+
asked for a custom Slack app (`slack init --manual`).
|
|
32
24
|
|
|
33
25
|
Existing bots that already have `<PREFIX>_SLACK_BOT_TOKEN` and
|
|
34
26
|
`_SLACK_APP_TOKEN` in `.env.local` keep working. Do not force them onto
|
|
35
27
|
the wizard.
|
|
36
28
|
|
|
37
|
-
##
|
|
38
|
-
|
|
39
|
-
Walk the user through the tradeoffs before touching files:
|
|
40
|
-
|
|
41
|
-
| | A: Cursor-hosted | B: Dedicated Slack app |
|
|
42
|
-
| --- | --- | --- |
|
|
43
|
-
| Setup | Zero Slack admin: sign the host in (`agent-sdk login` / `CURSOR_API_KEY`) and serve | One `agent-sdk slack create` per env. Finish in the dashboard wizard (Slack consent + bot name). Tokens are never shown. |
|
|
44
|
-
| Prereq | Cursor Slack integration installed in the workspace and linked to the Cursor account | Agent Serve access (`agent-sdk login`) and permission to approve a Slack app |
|
|
45
|
-
| How users reach it | `@Cursor <AgentName> …`, DMs to @Cursor, replies in claimed threads | Its own bot user: @mention, DM, channel invites |
|
|
46
|
-
| Identity | Posts as the Cursor app under the agent's name + icon | Own app name, avatar, and handle |
|
|
47
|
-
| Channel watching (dispatch without a mention) | Not available | `engagement.channelPosts` allowlist |
|
|
48
|
-
| Tool approvals / Block Kit interactivity | Not available (construction throws) | `toolApprovals: true` Approve/Deny cards |
|
|
49
|
-
| Reply delivery | Status while working, then one final post (no streaming edits) | Streaming replies with postMessage fallback |
|
|
50
|
-
| Multi-agent hosts | Any number of agents, unique `agentName` each, no extra Slack apps | One Slack app + token pair **per agent** |
|
|
51
|
-
|
|
52
|
-
Decision shortcuts; skip the question when the request already decides:
|
|
53
|
-
|
|
54
|
-
- Needs channel watching, Approve/Deny buttons, `onBlockAction`, or its
|
|
55
|
-
own bot user / handle → **Path B**. Say which requirement forced it.
|
|
56
|
-
- Workspace has no Cursor Slack integration and won't install it →
|
|
57
|
-
**Path B**.
|
|
58
|
-
- Asked for a custom Slack app they own at api.slack.com, or to paste a
|
|
59
|
-
manifest → **Path C** (`slack init --manual`).
|
|
60
|
-
- "Just get it into Slack", a first bring-up, or the user already said
|
|
61
|
-
to use the Cursor Slack integration, with none of the above → **Path A**.
|
|
62
|
-
|
|
63
|
-
### Collect the decision with AskQuestion
|
|
64
|
-
|
|
65
|
-
Otherwise ask. One single-select question via the `AskQuestion` tool,
|
|
66
|
-
recommended option first so one click accepts it:
|
|
67
|
-
|
|
68
|
-
- **Cursor-hosted Slack connection (recommended)** — zero Slack setup;
|
|
69
|
-
sign in and mention `@Cursor <AgentName>`. No channel watching or
|
|
70
|
-
approval buttons.
|
|
71
|
-
- **Dedicated Slack app (Socket Mode)** — own bot user, channel
|
|
72
|
-
watching, approval buttons. `agent-sdk slack create` opens the
|
|
73
|
-
dashboard wizard.
|
|
74
|
-
|
|
75
|
-
If `AskQuestion` is unavailable in your environment, or the user does
|
|
76
|
-
not answer, **default to Path A (Cursor-hosted)**: state the assumption
|
|
77
|
-
in one line and proceed. It is the reversible choice. A dedicated app
|
|
78
|
-
can be added later as a *second* channel file without losing anything.
|
|
79
|
-
Never mix both in one channel definition: `cursorAccount: true` rejects
|
|
80
|
-
`credentials` / `envPrefix` at construction.
|
|
81
|
-
|
|
82
|
-
## Path A — Cursor-hosted connection
|
|
83
|
-
|
|
84
|
-
Goal: mention `@Cursor <AgentName>` in the linked workspace and get a
|
|
85
|
-
threaded reply. No Slack app, no tokens, no manifests.
|
|
86
|
-
|
|
87
|
-
### A1 — Author the channel (agent)
|
|
88
|
-
|
|
89
|
-
Write `agent/channels/slack.ts` by hand. Do not run `slack create` for
|
|
90
|
-
this path:
|
|
91
|
-
|
|
92
|
-
```ts
|
|
93
|
-
import { slackChannel } from "@cursor/july/channels/slack";
|
|
94
|
-
|
|
95
|
-
export default slackChannel({
|
|
96
|
-
cursorAccount: true,
|
|
97
|
-
agentName: "MyAgent", // single token, no whitespace; prefer PascalCase
|
|
98
|
-
agentIcon: { emoji: ":robot_face:" },
|
|
99
|
-
});
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
`agentName` defaults from the mount slug (PascalCase) and must be a
|
|
103
|
-
single token. String literals with spaces fail typecheck; runtime
|
|
104
|
-
values throw at construction/serve. Names must be unique on the host;
|
|
105
|
-
an unmatched `@Cursor <name>` stays with Cursor's normal Slack agent.
|
|
106
|
-
External senders (Slack Connect / guests / other workspaces) are
|
|
107
|
-
blocked by default; see `policy.blockExternals` in
|
|
108
|
-
[docs/guides/slack.md](../../docs/guides/slack.md).
|
|
109
|
-
|
|
110
|
-
### A2 — Sign in + serve (agent)
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
agent-sdk login # or export CURSOR_API_KEY
|
|
114
|
-
agent-sdk dev .
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Confirm log: `[agent-sdk] cursor-slack: relaying Slack for <AgentName> …`.
|
|
118
|
-
An unsigned host fails `serve` with a sign-in hint naming the channel.
|
|
119
|
-
|
|
120
|
-
### A3 — Smoke (human)
|
|
121
|
-
|
|
122
|
-
1. In the Slack workspace linked to the Cursor account, post
|
|
123
|
-
`@Cursor MyAgent <question>` (or DM @Cursor)
|
|
124
|
-
2. Confirm a working status while the turn runs, then a threaded reply
|
|
125
|
-
posted under the agent's name and icon
|
|
126
|
-
3. Reply in the thread without re-mentioning; it stays with the agent
|
|
127
|
-
|
|
128
|
-
### Path A limits (enforced at construction)
|
|
129
|
-
|
|
130
|
-
- `credentials` / `envPrefix` → throw (author a second channel file for
|
|
131
|
-
a dedicated app instead)
|
|
132
|
-
- `engagement.channelPosts`, `toolApprovals`, `interactivity`,
|
|
133
|
-
`onBlockAction` → throw (Socket Mode only)
|
|
134
|
-
- `engagement.mentions: false` / `directMessages: false` → throw (the
|
|
135
|
-
relay always delivers those)
|
|
136
|
-
- Streaming is forced off: rotating status while thinking, one final
|
|
137
|
-
reply post
|
|
138
|
-
|
|
139
|
-
When one of these limits becomes a real requirement, keep the
|
|
140
|
-
cursor-account channel and add a Path B channel file beside it.
|
|
141
|
-
|
|
142
|
-
## Path B — Dedicated Slack app (Socket Mode)
|
|
29
|
+
## Dedicated Slack app (Socket Mode)
|
|
143
30
|
|
|
144
31
|
Goal: one dedicated bot per agent, tokens in `.env.local`, local serve
|
|
145
32
|
without a cloud deploy. The dashboard wizard is the only first-run.
|
|
@@ -167,7 +54,8 @@ install does not file the request. After an admin approves, click
|
|
|
167
54
|
|
|
168
55
|
`create` scaffolds `agent/channels/slack.ts` when missing. Do not paste
|
|
169
56
|
a manifest at api.slack.com for this path. `slack init` without
|
|
170
|
-
`--manual` hard-errors; see
|
|
57
|
+
`--manual` hard-errors; see the manual path below for a hand-imported
|
|
58
|
+
app.
|
|
171
59
|
|
|
172
60
|
Existing tokens in `.env.local` keep working. Skip the wizard for those
|
|
173
61
|
agents unless you want a Cursor-managed app.
|
|
@@ -203,7 +91,7 @@ app. It keeps the Slack app id and replaces the manifest and tokens.
|
|
|
203
91
|
`agent-sdk slack destroy` deletes the provisioned app. Tokens left in
|
|
204
92
|
`.env.local` simply stop working.
|
|
205
93
|
|
|
206
|
-
##
|
|
94
|
+
## Manual Slack app (`slack init --manual`)
|
|
207
95
|
|
|
208
96
|
Use this when the user wants a Slack app they own at api.slack.com, not
|
|
209
97
|
a Cursor-managed app. Not the default. Do not offer it unless they
|
|
@@ -287,7 +175,7 @@ Human:
|
|
|
287
175
|
|
|
288
176
|
## Features (defaults ON)
|
|
289
177
|
|
|
290
|
-
- Chat streaming (`chat.startStream` / `appendStream` / `stopStream`) with postMessage fallback
|
|
178
|
+
- Chat streaming (`chat.startStream` / `appendStream` / `stopStream`) with postMessage fallback
|
|
291
179
|
- Thinking / task cards for tool calls
|
|
292
180
|
- `assistant.threads.setStatus` with rotating `loading_messages`
|
|
293
181
|
- Thread title + suggested prompts
|
|
@@ -296,7 +184,7 @@ Human:
|
|
|
296
184
|
|
|
297
185
|
If a Slack API is unavailable (`method_not_found` / `missing_scope`), the pack falls back to postMessage + setStatus.
|
|
298
186
|
|
|
299
|
-
## Engagement: mentions by default, channel watch opt-in
|
|
187
|
+
## Engagement: mentions by default, channel watch opt-in
|
|
300
188
|
|
|
301
189
|
The pack dispatches only on `app_mention` + DMs unless told otherwise:
|
|
302
190
|
summoned, never proactive. To watch channels (dispatch on new posts without
|
|
@@ -323,7 +211,7 @@ each watched channel. Posts mentioning the bot stay on the
|
|
|
323
211
|
thread. `engagement.mentions` / `engagement.directMessages` can be set to
|
|
324
212
|
`false` to turn those surfaces off.
|
|
325
213
|
|
|
326
|
-
## Tool approvals over Slack (opt-in HITL
|
|
214
|
+
## Tool approvals over Slack (opt-in HITL)
|
|
327
215
|
|
|
328
216
|
Tools with `needsApproval` park until a human approves or denies. To route
|
|
329
217
|
that through Slack, set `toolApprovals: true` on `slackChannel`. It posts
|
|
@@ -357,20 +245,16 @@ Requirements and caveats:
|
|
|
357
245
|
|
|
358
246
|
## Notes
|
|
359
247
|
|
|
360
|
-
- Dev and prod are **separate Slack apps** (separate tokens)
|
|
361
|
-
|
|
362
|
-
where it relays.
|
|
363
|
-
- Socket Mode / the Cursor relay are outbound only. No Events HTTP /
|
|
364
|
-
Request URL path on either connection.
|
|
248
|
+
- Dev and prod are **separate Slack apps** (separate tokens).
|
|
249
|
+
- Socket Mode is outbound only. No Events HTTP / Request URL path.
|
|
365
250
|
- Do not `await waitForCompletion()` inside Slack dispatch handlers. The pack uses `waitUntil`.
|
|
366
251
|
- Do not share one token pair across multiple agents in the same process.
|
|
367
252
|
|
|
368
253
|
## CLI reference
|
|
369
254
|
|
|
370
|
-
|
|
371
|
-
`init --manual` / `manifest` / `doctor`.
|
|
372
|
-
|
|
373
|
-
`--manual`.
|
|
255
|
+
Wizard tooling is `create` / `destroy` / `icon` / `doctor`. Manual is
|
|
256
|
+
`init --manual` / `manifest` / `doctor`. `slack setup` prints this
|
|
257
|
+
guide. `slack init` hard-errors unless `--manual`.
|
|
374
258
|
|
|
375
259
|
```bash
|
|
376
260
|
agent-sdk slack setup
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
continuationSource,
|
|
12
12
|
normalizeIdentity,
|
|
13
13
|
} from "../../internal/continuation-identity.js";
|
|
14
|
+
import { isDeferredChannelSession } from "../../internal/deferred-channel-session.js";
|
|
14
15
|
import { isDevMode } from "../../internal/dev-mode.js";
|
|
15
16
|
import { bindLocalIngressSend } from "../../internal/local-ingress.js";
|
|
16
17
|
import type {
|
|
@@ -1622,16 +1623,15 @@ async function startTurn(input: {
|
|
|
1622
1623
|
scheduleAfterAck(input.args, async () => {
|
|
1623
1624
|
await sendTurn();
|
|
1624
1625
|
});
|
|
1625
|
-
return
|
|
1626
|
-
Response.json(
|
|
1627
|
-
{ ok: true, dispatched: true, mode: "turn" },
|
|
1628
|
-
{ status: 202 }
|
|
1629
|
-
),
|
|
1630
|
-
"send"
|
|
1631
|
-
);
|
|
1626
|
+
return acknowledgeTurn();
|
|
1632
1627
|
}
|
|
1633
1628
|
|
|
1634
1629
|
const session = await sendTurn();
|
|
1630
|
+
if (isDeferredChannelSession(session)) {
|
|
1631
|
+
// Hosted admission captured the send; the control plane allocates the
|
|
1632
|
+
// session after acknowledgement, so there is nothing to report yet.
|
|
1633
|
+
return acknowledgeTurn();
|
|
1634
|
+
}
|
|
1635
1635
|
return withDispatchOutcome(
|
|
1636
1636
|
Response.json({
|
|
1637
1637
|
ok: true,
|
|
@@ -1677,12 +1677,27 @@ function scheduleAfterAck(
|
|
|
1677
1677
|
);
|
|
1678
1678
|
}
|
|
1679
1679
|
|
|
1680
|
+
/** 202 ack for a turn whose send completes after the response flushes. */
|
|
1681
|
+
function acknowledgeTurn(): Response {
|
|
1682
|
+
return withDispatchOutcome(
|
|
1683
|
+
Response.json(
|
|
1684
|
+
{ ok: true, dispatched: true, mode: "turn" },
|
|
1685
|
+
{ status: 202 }
|
|
1686
|
+
),
|
|
1687
|
+
"send"
|
|
1688
|
+
);
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1680
1691
|
function acknowledgeTask(
|
|
1681
1692
|
args: ChannelHandlerArgs,
|
|
1682
1693
|
dispatch: GitHubTaskDispatch,
|
|
1683
1694
|
extra: Record<string, unknown>
|
|
1684
1695
|
): Response {
|
|
1685
|
-
|
|
1696
|
+
// Hand the task the per-delivery send/waitUntil so hosted admission can
|
|
1697
|
+
// capture task-initiated sends; startup-captured sends bypass capture.
|
|
1698
|
+
scheduleAfterAck(args, () =>
|
|
1699
|
+
dispatch.task({ send: args.send, waitUntil: args.waitUntil })
|
|
1700
|
+
);
|
|
1686
1701
|
return withDispatchOutcome(
|
|
1687
1702
|
Response.json(
|
|
1688
1703
|
{ ok: true, dispatched: true, mode: "task", ...extra },
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
ChannelEventHandlers,
|
|
8
8
|
ChannelStartArgs,
|
|
9
9
|
HostContext,
|
|
10
|
+
SendMessageFn,
|
|
10
11
|
SendMessageOptions,
|
|
11
12
|
} from "../../types.js";
|
|
12
13
|
import type { GitHubApiOptions } from "./api.js";
|
|
@@ -370,13 +371,29 @@ export interface GitHubTurnDispatch {
|
|
|
370
371
|
| Promise<GitHubWorkspaceFiles | undefined>);
|
|
371
372
|
}
|
|
372
373
|
|
|
374
|
+
/** Bound per-delivery helpers passed to a {@link GitHubTaskDispatch.task}. */
|
|
375
|
+
export interface GitHubTaskArgs {
|
|
376
|
+
/**
|
|
377
|
+
* Start (or resume) a session for this delivery. Locally this runs a real
|
|
378
|
+
* turn and returns the live session. In hosted admission it captures the
|
|
379
|
+
* send for the control plane to execute after `ses_…` is allocated and
|
|
380
|
+
* returns an inert deferred handle, so the task body keeps running.
|
|
381
|
+
* Always use this over a send captured at `onStart` — a startup-captured
|
|
382
|
+
* send bypasses hosted capture and is rejected during hosted admission.
|
|
383
|
+
*/
|
|
384
|
+
send: SendMessageFn;
|
|
385
|
+
/** Extend the delivery's background window past the task promise. */
|
|
386
|
+
waitUntil: (promise: Promise<unknown>) => void;
|
|
387
|
+
}
|
|
388
|
+
|
|
373
389
|
/**
|
|
374
390
|
* Run a host-side handler for the event instead of a model turn. The task
|
|
375
391
|
* runs in the background (`waitUntil`) after the webhook is acknowledged
|
|
376
|
-
* with a 202, so it can outlive GitHub's ~10s delivery timeout.
|
|
392
|
+
* with a 202, so it can outlive GitHub's ~10s delivery timeout. The callback
|
|
393
|
+
* receives {@link GitHubTaskArgs}; zero-argument tasks remain valid.
|
|
377
394
|
*/
|
|
378
395
|
export interface GitHubTaskDispatch {
|
|
379
|
-
task: () => void | Promise<void>;
|
|
396
|
+
task: (args: GitHubTaskArgs) => void | Promise<void>;
|
|
380
397
|
}
|
|
381
398
|
|
|
382
399
|
export type GitHubDispatchResult =
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
import { deriveOriginWebhookEvents, ORIGIN_CHANNEL_KIND } from "./events.js";
|
|
27
27
|
import {
|
|
28
28
|
DEFAULT_ORIGIN_API_BASE_URL,
|
|
29
|
+
OriginJwksUnavailableError,
|
|
29
30
|
type OriginWebhookHeaders,
|
|
30
31
|
verifyOriginWebhook,
|
|
31
32
|
} from "./origin-webhook.js";
|
|
@@ -300,10 +301,12 @@ export function parseOriginPullRequestEvent(input: {
|
|
|
300
301
|
ctx: {
|
|
301
302
|
deliveryId: input.envelope.deliveryId,
|
|
302
303
|
eventType,
|
|
304
|
+
eventTime: input.envelope.event.eventTime,
|
|
303
305
|
installationId: input.envelope.installationId,
|
|
304
306
|
repository,
|
|
305
307
|
pullRequestNumber: number,
|
|
306
308
|
pullRequestUrl: url,
|
|
309
|
+
payload,
|
|
307
310
|
sender: originSender(input.envelope, payload),
|
|
308
311
|
},
|
|
309
312
|
pullRequest: {
|
|
@@ -687,7 +690,16 @@ export async function handleOriginWebhookRequest(input: {
|
|
|
687
690
|
await verifyOriginWebhook(bodyText, originHeaders(input.request), {
|
|
688
691
|
apiBaseUrl: resolveApiBaseUrl(input.options),
|
|
689
692
|
});
|
|
690
|
-
} catch {
|
|
693
|
+
} catch (error) {
|
|
694
|
+
// A JWKS outage means the delivery was never checked: answer 503 so
|
|
695
|
+
// Origin's delivery worker retries. Only a real signature mismatch
|
|
696
|
+
// is the terminal 401.
|
|
697
|
+
if (error instanceof OriginJwksUnavailableError) {
|
|
698
|
+
return Response.json(
|
|
699
|
+
{ ok: false, error: "signature_verification_unavailable" },
|
|
700
|
+
{ status: 503 }
|
|
701
|
+
);
|
|
702
|
+
}
|
|
691
703
|
return Response.json(
|
|
692
704
|
{ ok: false, error: "invalid_signature" },
|
|
693
705
|
{ status: 401 }
|
|
@@ -247,7 +247,31 @@ export interface VerifyOriginWebhookOptions {
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
/**
|
|
250
|
-
*
|
|
250
|
+
* The signing JWKS could not be fetched (and no cached copy applies), so
|
|
251
|
+
* the delivery was never actually checked. Callers must answer retryably
|
|
252
|
+
* (5xx) — a 401 would make Origin's delivery worker drop the wake as
|
|
253
|
+
* terminal on what is only a transient outage.
|
|
254
|
+
*/
|
|
255
|
+
export class OriginJwksUnavailableError extends Error {}
|
|
256
|
+
|
|
257
|
+
async function fetchJwksOrUnavailable(
|
|
258
|
+
apiBaseUrl: string,
|
|
259
|
+
fetchImpl: typeof fetch,
|
|
260
|
+
options?: FetchOriginJwksOptions
|
|
261
|
+
): Promise<readonly OriginJwk[]> {
|
|
262
|
+
try {
|
|
263
|
+
return await fetchOriginJwks(apiBaseUrl, fetchImpl, options);
|
|
264
|
+
} catch (error) {
|
|
265
|
+
throw new OriginJwksUnavailableError(
|
|
266
|
+
`Origin JWKS unavailable: ${error instanceof Error ? error.message : String(error)}`
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Verify a Standard-Webhooks v1ed Origin payload. Throws
|
|
273
|
+
* {@link OriginJwksUnavailableError} when the keys cannot be fetched, and a
|
|
274
|
+
* plain error when the signature does not verify against them.
|
|
251
275
|
*/
|
|
252
276
|
export async function verifyOriginWebhook(
|
|
253
277
|
body: string | Buffer,
|
|
@@ -256,7 +280,7 @@ export async function verifyOriginWebhook(
|
|
|
256
280
|
): Promise<void> {
|
|
257
281
|
const apiBaseUrl = options?.apiBaseUrl ?? DEFAULT_ORIGIN_API_BASE_URL;
|
|
258
282
|
const fetchImpl = options?.fetchImpl ?? fetch;
|
|
259
|
-
const keys = await
|
|
283
|
+
const keys = await fetchJwksOrUnavailable(apiBaseUrl, fetchImpl);
|
|
260
284
|
if (
|
|
261
285
|
verifyV1edWebhookPayload({
|
|
262
286
|
publicJwks: keys,
|
|
@@ -267,7 +291,7 @@ export async function verifyOriginWebhook(
|
|
|
267
291
|
) {
|
|
268
292
|
return;
|
|
269
293
|
}
|
|
270
|
-
const refreshed = await
|
|
294
|
+
const refreshed = await fetchJwksOrUnavailable(apiBaseUrl, fetchImpl, {
|
|
271
295
|
force: true,
|
|
272
296
|
});
|
|
273
297
|
if (
|
|
@@ -51,11 +51,19 @@ export interface OriginReview {
|
|
|
51
51
|
export interface OriginEventContext {
|
|
52
52
|
deliveryId?: string;
|
|
53
53
|
eventType: string;
|
|
54
|
+
/** Delivery envelope `event.eventTime`, when present. */
|
|
55
|
+
eventTime?: string;
|
|
54
56
|
/** Origin app installation id from the delivery envelope, when present. */
|
|
55
57
|
installationId?: string;
|
|
56
58
|
repository: OriginRepositoryRef;
|
|
57
59
|
pullRequestNumber: number;
|
|
58
60
|
pullRequestUrl: string;
|
|
61
|
+
/**
|
|
62
|
+
* Raw parsed `event.payload` record (`{}` when absent), for consumers
|
|
63
|
+
* whose normalization needs more than the typed event — the GitHub
|
|
64
|
+
* channel's hook ctx exposes the same.
|
|
65
|
+
*/
|
|
66
|
+
payload: Record<string, unknown>;
|
|
59
67
|
sender?: OriginActor;
|
|
60
68
|
host: HostContext;
|
|
61
69
|
artifacts: ArtifactsApi;
|
|
@@ -381,8 +381,8 @@ async function downloadSlackFileBytes(args: {
|
|
|
381
381
|
maxBytes: number;
|
|
382
382
|
downloadTimeoutMs: number;
|
|
383
383
|
}): Promise<{ data: Uint8Array; mimeType: string; filename: string } | null> {
|
|
384
|
-
//
|
|
385
|
-
//
|
|
384
|
+
// Transport callers cannot mint a Bearer for files.slack.com; they
|
|
385
|
+
// must pre-attach `dataBase64` on the file ref instead.
|
|
386
386
|
if (isSlackApiTransport(args.botToken)) {
|
|
387
387
|
return null;
|
|
388
388
|
}
|
|
@@ -162,8 +162,6 @@ export interface SlackInboundDispatchDeps extends SlackContinuationProbes {
|
|
|
162
162
|
* `host.evals` is present.
|
|
163
163
|
*/
|
|
164
164
|
evalCommandsEnabled?: boolean;
|
|
165
|
-
/** cursorAccount agent name stripped before `eval` directive parsing. */
|
|
166
|
-
cursorAgentName?: string;
|
|
167
165
|
/**
|
|
168
166
|
* Drop external senders before the handler. Defaults to `true`; pass
|
|
169
167
|
* `false` to admit them (or when an upstream gate already refused them).
|
|
@@ -245,11 +243,6 @@ export async function dispatchInboundMessage(args: {
|
|
|
245
243
|
evalCommandsEnabled?: boolean;
|
|
246
244
|
/** See {@link SlackInboundDispatchDeps.followUpStatus}. Defaults to `true`. */
|
|
247
245
|
followUpStatus?: boolean;
|
|
248
|
-
/**
|
|
249
|
-
* cursorAccount agent display name — stripped before parsing `eval …`
|
|
250
|
-
* (`OncallBuddy eval list`).
|
|
251
|
-
*/
|
|
252
|
-
cursorAgentName?: string;
|
|
253
246
|
blockExternals?: boolean;
|
|
254
247
|
continuation?: ContinuationIdentity;
|
|
255
248
|
}): Promise<void> {
|
|
@@ -342,14 +335,10 @@ export async function dispatchInboundMessage(args: {
|
|
|
342
335
|
|
|
343
336
|
// Built-in eval directive: run playground batches without an agent turn.
|
|
344
337
|
const evalCommandsEnabled = args.evalCommandsEnabled !== false;
|
|
345
|
-
const evalParseOptions =
|
|
346
|
-
args.cursorAgentName === undefined || args.cursorAgentName === ""
|
|
347
|
-
? undefined
|
|
348
|
-
: { agentName: args.cursorAgentName };
|
|
349
338
|
const evalDirective =
|
|
350
339
|
evalCommandsEnabled && args.host.evals !== undefined
|
|
351
|
-
? (parseSlackEvalDirective(message.text
|
|
352
|
-
parseSlackEvalDirective(message.markdown
|
|
340
|
+
? (parseSlackEvalDirective(message.text) ??
|
|
341
|
+
parseSlackEvalDirective(message.markdown))
|
|
353
342
|
: null;
|
|
354
343
|
if (evalDirective !== null && args.host.evals !== undefined) {
|
|
355
344
|
log.info("eval directive", {
|
|
@@ -657,7 +646,6 @@ export function dispatchInboundFromEventBody(
|
|
|
657
646
|
artifacts: deps.artifacts,
|
|
658
647
|
log,
|
|
659
648
|
evalCommandsEnabled: deps.evalCommandsEnabled,
|
|
660
|
-
cursorAgentName: deps.cursorAgentName,
|
|
661
649
|
followUpStatus: deps.followUpStatus,
|
|
662
650
|
blockExternals: deps.blockExternals,
|
|
663
651
|
...continuationArg(deps.continuation),
|
|
@@ -701,7 +689,6 @@ export function dispatchInboundFromEventBody(
|
|
|
701
689
|
artifacts: deps.artifacts,
|
|
702
690
|
log,
|
|
703
691
|
evalCommandsEnabled: deps.evalCommandsEnabled,
|
|
704
|
-
cursorAgentName: deps.cursorAgentName,
|
|
705
692
|
followUpStatus: deps.followUpStatus,
|
|
706
693
|
blockExternals: deps.blockExternals,
|
|
707
694
|
...continuationArg(deps.continuation),
|
|
@@ -739,7 +726,6 @@ export function dispatchInboundFromEventBody(
|
|
|
739
726
|
artifacts: deps.artifacts,
|
|
740
727
|
log,
|
|
741
728
|
evalCommandsEnabled: false,
|
|
742
|
-
cursorAgentName: deps.cursorAgentName,
|
|
743
729
|
followUpStatus: deps.followUpStatus,
|
|
744
730
|
blockExternals: deps.blockExternals,
|
|
745
731
|
...continuationArg(deps.continuation),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Built-in Slack `eval` directive — run playground evals from a mention/DM
|
|
3
3
|
* without per-agent custom handlers (parity with CLI / playground runs).
|
|
4
4
|
*
|
|
5
|
-
* Examples (after stripping @mentions
|
|
5
|
+
* Examples (after stripping @mentions):
|
|
6
6
|
* eval
|
|
7
7
|
* eval triage/open-incidents smoke
|
|
8
8
|
* eval --tag oncall
|
|
@@ -29,29 +29,15 @@ export type SlackEvalDirective =
|
|
|
29
29
|
| { kind: "cancel"; runId: string }
|
|
30
30
|
| { kind: "run"; filterIds?: string[]; tags?: string[] };
|
|
31
31
|
|
|
32
|
-
function escapeRegExp(value: string): string {
|
|
33
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
32
|
/**
|
|
37
33
|
* Normalize inbound Slack text for directive parsing: strip leading
|
|
38
|
-
* `<@U…>` mentions
|
|
39
|
-
* cursorAccount agentName prefix (`OncallBuddy eval …`).
|
|
34
|
+
* `<@U…>` mentions and leading `@U…` markdown mentions.
|
|
40
35
|
*/
|
|
41
|
-
export function normalizeSlackEvalDirectiveBody(
|
|
42
|
-
text: string,
|
|
43
|
-
options?: { agentName?: string }
|
|
44
|
-
): string {
|
|
36
|
+
export function normalizeSlackEvalDirectiveBody(text: string): string {
|
|
45
37
|
let body = stripLeadingSlackMentions(text);
|
|
46
|
-
// markdown form from slackTextToMarkdown / cursorAccount envelopes
|
|
47
38
|
while (/^@[A-Za-z0-9._-]+\s+/.test(body)) {
|
|
48
39
|
body = body.replace(/^@[A-Za-z0-9._-]+\s+/, "").trim();
|
|
49
40
|
}
|
|
50
|
-
const agentName = options?.agentName?.trim();
|
|
51
|
-
if (agentName !== undefined && agentName.length > 0) {
|
|
52
|
-
const prefix = new RegExp(`^${escapeRegExp(agentName)}\\s+`, "i");
|
|
53
|
-
body = body.replace(prefix, "").trim();
|
|
54
|
-
}
|
|
55
41
|
return body;
|
|
56
42
|
}
|
|
57
43
|
|
|
@@ -60,10 +46,9 @@ export function normalizeSlackEvalDirectiveBody(
|
|
|
60
46
|
* eval command (falls through to the normal agent handler).
|
|
61
47
|
*/
|
|
62
48
|
export function parseSlackEvalDirective(
|
|
63
|
-
text: string
|
|
64
|
-
options?: { agentName?: string }
|
|
49
|
+
text: string
|
|
65
50
|
): SlackEvalDirective | null {
|
|
66
|
-
const body = normalizeSlackEvalDirectiveBody(text
|
|
51
|
+
const body = normalizeSlackEvalDirectiveBody(text);
|
|
67
52
|
if (body.length === 0) {
|
|
68
53
|
return null;
|
|
69
54
|
}
|
|
@@ -141,14 +126,10 @@ export function parseSlackEvalDirective(
|
|
|
141
126
|
}
|
|
142
127
|
|
|
143
128
|
/** True when either raw Slack text or markdown form is an eval directive. */
|
|
144
|
-
export function isSlackEvalDirective(
|
|
145
|
-
text: string,
|
|
146
|
-
markdown: string,
|
|
147
|
-
options?: { agentName?: string }
|
|
148
|
-
): boolean {
|
|
129
|
+
export function isSlackEvalDirective(text: string, markdown: string): boolean {
|
|
149
130
|
return (
|
|
150
|
-
parseSlackEvalDirective(text
|
|
151
|
-
parseSlackEvalDirective(markdown
|
|
131
|
+
parseSlackEvalDirective(text) !== null ||
|
|
132
|
+
parseSlackEvalDirective(markdown) !== null
|
|
152
133
|
);
|
|
153
134
|
}
|
|
154
135
|
|
|
@@ -10,11 +10,6 @@
|
|
|
10
10
|
* // Multi-agent serve: one Slack app per agent
|
|
11
11
|
* export default slackChannel({ envPrefix: "MY_AGENT" });
|
|
12
12
|
* // → MY_AGENT_SLACK_BOT_TOKEN + MY_AGENT_SLACK_APP_TOKEN
|
|
13
|
-
*
|
|
14
|
-
* // No Slack app at all: ride the signed-in Cursor account's Slack
|
|
15
|
-
* // connection (`@Cursor <agent name> …` routes here; replies post as
|
|
16
|
-
* // this agent through the Cursor Slack app)
|
|
17
|
-
* export default slackChannel({ cursorAccount: true });
|
|
18
13
|
* ```
|
|
19
14
|
*/
|
|
20
15
|
|
|
@@ -28,7 +23,6 @@ export * from "./bot-mentions.js";
|
|
|
28
23
|
export * from "./channel-watch.js";
|
|
29
24
|
export * from "./constants.js";
|
|
30
25
|
export * from "./credentials.js";
|
|
31
|
-
export * from "./cursor-account.js";
|
|
32
26
|
export * from "./defaults.js";
|
|
33
27
|
export * from "./dispatch.js";
|
|
34
28
|
export * from "./doctor.js";
|