@cursor/bdk 0.2.9 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifacts.js +3 -5
- package/dist/bin/agent-serve.js +803 -812
- package/dist/channels/bitbucket/api.js +305 -321
- package/dist/channels/bitbucket/binding.js +97 -61
- package/dist/channels/bitbucket/bitbucket-channel.d.ts +15 -1
- package/dist/channels/bitbucket/bitbucket-channel.d.ts.map +1 -1
- package/dist/channels/bitbucket/bitbucket-channel.js +95 -42
- package/dist/channels/bitbucket/bitbucket-webhook.d.ts +11 -0
- package/dist/channels/bitbucket/bitbucket-webhook.d.ts.map +1 -1
- package/dist/channels/bitbucket/bitbucket-webhook.js +214 -204
- package/dist/channels/bitbucket/checks.js +9 -21
- package/dist/channels/bitbucket/cursor-account.js +1 -1
- package/dist/channels/bitbucket/defaults.js +14 -4
- package/dist/channels/bitbucket/events.js +1 -2
- package/dist/channels/bitbucket/index.d.ts +6 -2
- package/dist/channels/bitbucket/index.d.ts.map +1 -1
- package/dist/channels/bitbucket/index.js +6 -2
- package/dist/channels/bitbucket/replay.js +80 -56
- package/dist/channels/bitbucket/state.js +16 -7
- package/dist/channels/bitbucket/types.d.ts +11 -2
- package/dist/channels/bitbucket/types.d.ts.map +1 -1
- package/dist/channels/checks.js +18 -28
- package/dist/channels/deployments/deployments-channel.js +26 -34
- package/dist/channels/github/api.js +216 -210
- package/dist/channels/github/auth.d.ts +5 -1
- package/dist/channels/github/auth.d.ts.map +1 -1
- package/dist/channels/github/auth.js +157 -174
- package/dist/channels/github/binding.js +48 -39
- package/dist/channels/github/checks.js +9 -14
- package/dist/channels/github/cursor-account.js +6 -11
- package/dist/channels/github/defaults.js +105 -130
- package/dist/channels/github/forward.js +13 -17
- package/dist/channels/github/github-channel.d.ts +43 -2
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +1228 -958
- package/dist/channels/github/progress.js +145 -146
- package/dist/channels/github/replay.js +30 -39
- package/dist/channels/github/state.js +40 -16
- package/dist/channels/github/types.d.ts +30 -6
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/gitlab/api.js +100 -114
- package/dist/channels/gitlab/binding.js +52 -33
- package/dist/channels/gitlab/checks.js +28 -29
- package/dist/channels/gitlab/cursor-account.js +1 -1
- package/dist/channels/gitlab/defaults.js +9 -3
- package/dist/channels/gitlab/gitlab-channel.d.ts +16 -1
- package/dist/channels/gitlab/gitlab-channel.d.ts.map +1 -1
- package/dist/channels/gitlab/gitlab-channel.js +95 -42
- package/dist/channels/gitlab/gitlab-webhook.d.ts +10 -1
- package/dist/channels/gitlab/gitlab-webhook.d.ts.map +1 -1
- package/dist/channels/gitlab/gitlab-webhook.js +282 -249
- package/dist/channels/gitlab/index.d.ts +6 -2
- package/dist/channels/gitlab/index.d.ts.map +1 -1
- package/dist/channels/gitlab/index.js +6 -2
- package/dist/channels/gitlab/replay.js +50 -27
- package/dist/channels/gitlab/state.js +14 -6
- package/dist/channels/gitlab/types.d.ts +13 -2
- package/dist/channels/gitlab/types.d.ts.map +1 -1
- package/dist/channels/origin/api.js +100 -116
- package/dist/channels/origin/binding.js +15 -16
- package/dist/channels/origin/checks.js +30 -28
- package/dist/channels/origin/defaults.js +50 -65
- package/dist/channels/origin/origin-channel.js +266 -272
- package/dist/channels/origin/origin-webhook.js +70 -88
- package/dist/channels/origin/reactions.js +9 -21
- package/dist/channels/origin/state.js +13 -5
- package/dist/channels/slack/agentic-delivery.js +426 -478
- package/dist/channels/slack/agentic-posted.js +9 -10
- package/dist/channels/slack/agentic-signals.js +2 -3
- package/dist/channels/slack/api.js +417 -427
- package/dist/channels/slack/approvals.js +1 -1
- package/dist/channels/slack/assistant.js +37 -47
- package/dist/channels/slack/attachments.js +188 -206
- package/dist/channels/slack/auth.js +8 -6
- package/dist/channels/slack/bot-mentions.js +31 -45
- package/dist/channels/slack/channel-watch.js +42 -48
- package/dist/channels/slack/cli-project.js +112 -137
- package/dist/channels/slack/code-fences.js +3 -5
- package/dist/channels/slack/constants.js +2 -2
- package/dist/channels/slack/credentials.js +23 -38
- package/dist/channels/slack/defaults.js +292 -331
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +533 -460
- package/dist/channels/slack/doctor.js +200 -214
- package/dist/channels/slack/eval-directive.js +79 -96
- package/dist/channels/slack/event-id-dedupe.js +1 -1
- package/dist/channels/slack/external-policy.js +26 -39
- package/dist/channels/slack/footer.js +28 -41
- package/dist/channels/slack/inbound.d.ts +1 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +50 -31
- package/dist/channels/slack/init.d.ts +1 -5
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +42 -59
- package/dist/channels/slack/interactive.d.ts +9 -3
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +160 -162
- package/dist/channels/slack/links.js +1 -2
- package/dist/channels/slack/live-delivery.js +172 -190
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +44 -23
- package/dist/channels/slack/message-body.js +2 -2
- package/dist/channels/slack/nudge-carrier.js +30 -42
- package/dist/channels/slack/nudge-store.js +164 -191
- package/dist/channels/slack/paint-start.js +66 -81
- package/dist/channels/slack/placeholder.js +123 -152
- package/dist/channels/slack/pr-ref.js +1 -1
- package/dist/channels/slack/progress-delivery.js +65 -78
- package/dist/channels/slack/reasoning-card.js +36 -49
- package/dist/channels/slack/recording-sink.js +12 -24
- package/dist/channels/slack/reply-options.js +7 -12
- package/dist/channels/slack/self-identity.js +27 -35
- package/dist/channels/slack/sender-name.d.ts +12 -3
- package/dist/channels/slack/sender-name.d.ts.map +1 -1
- package/dist/channels/slack/sender-name.js +57 -61
- package/dist/channels/slack/setup.js +2 -4
- package/dist/channels/slack/slack-channel.d.ts +6 -4
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +441 -308
- package/dist/channels/slack/socket-mode.js +38 -52
- package/dist/channels/slack/thread-context.js +143 -160
- package/dist/channels/slack/tool-approval-events.js +149 -166
- package/dist/channels/slack/tool-cards.js +6 -11
- package/dist/channels/slack/tool-chip.js +1 -2
- package/dist/channels/slack/types.d.ts +15 -17
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels/slack/upload.js +84 -97
- package/dist/channels/slack/user-info.js +27 -41
- package/dist/channels.js +9 -20
- package/dist/dashboard-session-url.js +3 -4
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.BNhEdGa8.js → app.DXI7bwox.js} +4 -4
- package/dist/docs/assets/{building-with-agents.md.BPjPFxFg.js → building-with-agents.md.Df87rAe1.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CtLtpWcx.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DIdUV1Ph.js → VPLocalSearchBox.BrbO5mEe.js} +1 -1
- package/dist/docs/assets/chunks/{arc.lELI4_SR.js → arc.BOG1yms8.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.iCMdvuoM.js → architectureDiagram-Q4EWVU46.C0hsMZnZ.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.C1-nDJBf.js → baseUniq.H044KjKs.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.ClemzBox.js → blockDiagram-DXYQGD6D.BsRW6GoB.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.BqTak6cR.js → c4Diagram-AHTNJAMY.B9HV5PFR.js} +1 -1
- package/dist/docs/assets/chunks/channel.CBwrU9rP.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.CUS3qs_R.js → chunk-4BX2VUAB.CPoT_ajl.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.dz5fdHcl.js → chunk-4TB4RGXK.DZBwWuCL.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.D6BEBmve.js → chunk-55IACEB6.CZ3yTiyq.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.B5uK4ID9.js → chunk-EDXVE4YY.6DfvHSd8.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.PgOJgNQs.js → chunk-FMBD7UC4.CpBj8HfK.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.CvkTrCii.js → chunk-OYMX7WX6.BdKo8YqS.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BnSfKYsB.js → chunk-QZHKN3VN.BnXNyxJx.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.MZH6v5UC.js → chunk-YZCP3GAM.Cg1OcF8G.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CbC_mrvB.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CbC_mrvB.js +1 -0
- package/dist/docs/assets/chunks/clone.BTvFyY1a.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.BBbw_YZi.js → cose-bilkent-S5V4N54A.1SP8al9c.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.CNJB2l7E.js → dagre-KV5264BT.DS1L6hJt.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.BQzlnFfq.js → diagram-5BDNPKRD.ChsausbG.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.DkgqqZMz.js → diagram-G4DWMVQ6.3XsptNWj.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.DIT8L7H_.js → diagram-MMDJMWI5.DPA9Dk_P.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.3xLPZWGJ.js → diagram-TYMM5635.BVswXWrB.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.5_IHz8jF.js → erDiagram-SMLLAGMA.BSak5OSP.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.BGUCXz8A.js → flowDiagram-DWJPFMVM.CQgN4TTz.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.DbfFavS1.js → ganttDiagram-T4ZO3ILL.GrT0kA4a.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.D2yKdeNW.js → gitGraphDiagram-UUTBAWPF.CdS7Ucll.js} +1 -1
- package/dist/docs/assets/chunks/{graph.CSCxwHba.js → graph.BVqKRmRo.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.FDeb6xHY.js → infoDiagram-42DDH7IO.C3C9FRto.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DbeYs9VL.js → ishikawaDiagram-UXIWVN3A.2FuAh_Zj.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CWjKINpx.js → journeyDiagram-VCZTEJTY.CaHMfK4b.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.B4FrAlwz.js → kanban-definition-6JOO6SKY.CjhIUwcA.js} +1 -1
- package/dist/docs/assets/chunks/{layout.DFGxQ9ab.js → layout.CGU3gfSf.js} +1 -1
- package/dist/docs/assets/chunks/{linear.BmjZ-G59.js → linear.DaihpW_n.js} +1 -1
- package/dist/docs/assets/chunks/{min.DZSxulMW.js → min.BS-j8kHQ.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.CHLi3-aN.js → mindmap-definition-QFDTVHPH.BVJ1Bbnk.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DteG-CkU.js → pieDiagram-DEJITSTG.Cz1WIv9r.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.D458ipN3.js → quadrantDiagram-34T5L4WZ.DKLFxcjy.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.DcFgUxst.js → requirementDiagram-MS252O5E.BHegiK7x.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.BwQAMmSA.js → sankeyDiagram-XADWPNL6.DYkY6yPc.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.B_Xdsrh9.js → sequenceDiagram-FGHM5R23.DYQ1QUrI.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.CdfDW6-C.js → stateDiagram-FHFEXIEX.Iru8BsFo.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.BYXl4LW6.js +1 -0
- package/dist/docs/assets/chunks/{theme.sfdL3srp.js → theme.DaplWQhQ.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.56-4hXaC.js → timeline-definition-GMOUNBTQ.BwFA8hiX.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CvZSQBO7.js → vennDiagram-DHZGUBPP.CZ60W1C_.js} +1 -1
- package/dist/docs/assets/chunks/{wardley-RL74JXVD.C9qc8k39.js → wardley-RL74JXVD.iXazD3Z7.js} +1 -1
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.D9s0nihi.js → wardleyDiagram-NUSXRM2D.B69D2r8-.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.BVJSpYrC.js → xychartDiagram-5P7HB3ND.CLPZEIU9.js} +1 -1
- package/dist/docs/assets/{deployment.md.BdqTiGdc.js → deployment.md.BYuEcDBv.js} +2 -2
- package/dist/docs/assets/{guides_bitbucket.md.BB6fqD-M.js → guides_bitbucket.md.CKUayYtD.js} +3 -3
- package/dist/docs/assets/{guides_bitbucket.md.BB6fqD-M.lean.js → guides_bitbucket.md.CKUayYtD.lean.js} +1 -1
- package/dist/docs/assets/{guides_github.md.Cr1Xlf-m.js → guides_github.md.TuNiZAOQ.js} +4 -4
- package/dist/docs/assets/{guides_github.md.Cr1Xlf-m.lean.js → guides_github.md.TuNiZAOQ.lean.js} +1 -1
- package/dist/docs/assets/{guides_gitlab.md.CMpmFi4M.js → guides_gitlab.md.CtNI4fSH.js} +4 -4
- package/dist/docs/assets/{guides_gitlab.md.CMpmFi4M.lean.js → guides_gitlab.md.CtNI4fSH.lean.js} +1 -1
- package/dist/docs/assets/guides_migrate.md.sCAvvlC6.js +7 -0
- package/dist/docs/assets/guides_migrate.md.sCAvvlC6.lean.js +1 -0
- package/dist/docs/assets/{reference_cli.md.GwugN3n-.js → reference_cli.md.dYCAL2lB.js} +4 -3
- package/dist/docs/assets/reference_cli.md.dYCAL2lB.lean.js +1 -0
- package/dist/docs/assets/troubleshooting.md.x-GBa7wN.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.Bscj6ODe.lean.js → troubleshooting.md.x-GBa7wN.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +37 -37
- package/dist/docs/building-with-agents.md +2 -0
- package/dist/docs/deployment.html +38 -38
- package/dist/docs/deployment.md +7 -0
- package/dist/docs/evals.html +36 -36
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +38 -38
- package/dist/docs/guides/bitbucket.md +9 -1
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/github.html +39 -39
- package/dist/docs/guides/github.md +20 -4
- package/dist/docs/guides/gitlab.html +38 -38
- package/dist/docs/guides/gitlab.md +9 -1
- package/dist/docs/guides/grokbot-agents.html +35 -35
- package/dist/docs/guides/hooks.html +35 -35
- package/dist/docs/guides/improve.html +35 -35
- package/dist/docs/guides/jev.html +35 -35
- package/dist/docs/guides/mcp-oauth.html +35 -35
- package/dist/docs/guides/migrate.html +66 -0
- package/dist/docs/guides/migrate.md +122 -0
- package/dist/docs/guides/opentelemetry.html +35 -35
- package/dist/docs/guides/slack.html +35 -35
- package/dist/docs/guides/webhooks.html +35 -35
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +35 -35
- package/dist/docs/index.html +35 -35
- package/dist/docs/llms-full.txt +214 -6
- package/dist/docs/llms.txt +1 -0
- package/dist/docs/quickstart.html +35 -35
- package/dist/docs/reference/agent-config.html +35 -35
- package/dist/docs/reference/artifacts.html +35 -35
- package/dist/docs/reference/channels.html +35 -35
- package/dist/docs/reference/cli.html +39 -38
- package/dist/docs/reference/cli.md +39 -0
- package/dist/docs/reference/connections.html +35 -35
- package/dist/docs/reference/evals.html +35 -35
- package/dist/docs/reference/extensions.html +35 -35
- package/dist/docs/reference/hooks.html +35 -35
- package/dist/docs/reference/http-api.html +35 -35
- package/dist/docs/reference/instructions.html +35 -35
- package/dist/docs/reference/playground.html +35 -35
- package/dist/docs/reference/project-layout.html +35 -35
- package/dist/docs/reference/prompt.html +35 -35
- package/dist/docs/reference/schedules.html +35 -35
- package/dist/docs/reference/sessions.html +35 -35
- package/dist/docs/reference/skills.html +35 -35
- package/dist/docs/reference/subagents.html +35 -35
- package/dist/docs/reference/tools.html +35 -35
- package/dist/docs/templates/agentic-owners.html +35 -35
- package/dist/docs/templates/grokbot-agents.html +35 -35
- package/dist/docs/templates/security-reviewer.html +35 -35
- package/dist/docs/templates/thermo-quality-review.html +35 -35
- package/dist/docs/templates/thermo-review.html +35 -35
- package/dist/docs/templates/triage.html +35 -35
- package/dist/docs/troubleshooting.html +36 -36
- package/dist/docs/troubleshooting.md +1 -0
- package/dist/evals/assertions.js +20 -34
- package/dist/evals/expect.js +3 -6
- package/dist/evals/judge.js +5 -8
- package/dist/evals/loaders.js +45 -62
- package/dist/evals/matchers.js +2 -3
- package/dist/evals/reporters.js +43 -67
- package/dist/evals/results.js +1 -1
- package/dist/evals/run-facts.js +5 -6
- package/dist/evals.js +27 -15
- package/dist/extensions/cursor-cloud-agents/extension.js +4 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +100 -126
- package/dist/extensions/cursor-cloud-agents/lib/fleet.js +22 -38
- package/dist/extensions/cursor-cloud-agents/lib/repos.js +8 -10
- package/dist/extensions/cursor-cloud-agents/lib/transcript.js +2 -3
- package/dist/extensions/cursor-cloud-agents/lib/watch.js +52 -66
- package/dist/extensions/cursor-cloud-agents/reminders/cloud-agent-stop-watch.js +29 -40
- package/dist/extensions/cursor-cloud-agents/tools/cancel.js +6 -17
- package/dist/extensions/cursor-cloud-agents/tools/dump.js +25 -36
- package/dist/extensions/cursor-cloud-agents/tools/get.js +3 -14
- package/dist/extensions/cursor-cloud-agents/tools/launch.js +13 -21
- package/dist/extensions/cursor-cloud-agents/tools/list.js +8 -19
- package/dist/extensions/cursor-cloud-agents/tools/reply.js +5 -16
- package/dist/extensions/cursor-grokbot-agents/extension.js +4 -1
- package/dist/extensions/cursor-grokbot-agents/lib/agents.js +3 -3
- package/dist/extensions/cursor-grokbot-agents/lib/backend.js +53 -73
- package/dist/extensions/cursor-grokbot-agents/lib/contacts.js +10 -23
- package/dist/extensions/cursor-grokbot-agents/lib/conversation.js +112 -132
- package/dist/extensions/cursor-grokbot-agents/lib/lock.js +1 -2
- package/dist/extensions/cursor-grokbot-agents/tools/ask.js +5 -16
- package/dist/extensions/cursor-grokbot-agents/tools/check.js +4 -15
- package/dist/extensions/cursor-grokbot-agents/tools/interrupt.js +2 -13
- package/dist/extensions/cursor-grokbot-agents/tools/list.js +11 -23
- package/dist/extensions/jev/extension.js +3 -3
- package/dist/extensions/jev/lib/evaluate.js +43 -60
- package/dist/extensions/jev/tools/evaluate.js +6 -17
- package/dist/extensions/slack-communication/tools/post-file.js +1 -1
- package/dist/extensions.js +3 -5
- package/dist/files-backends/cursor-hosted.js +504 -523
- package/dist/files-backends/local-fs.js +72 -134
- package/dist/files.js +3 -3
- package/dist/filesystem.js +562 -861
- package/dist/index.js +16 -35
- package/dist/internal/advertise-tools.js +74 -86
- package/dist/internal/artifacts-store.js +298 -361
- package/dist/internal/as-of.js +2 -4
- package/dist/internal/authored-alias-hooks.js +6 -4
- package/dist/internal/authored-loaders.js +37 -52
- package/dist/internal/bounded-int.js +1 -2
- package/dist/internal/bounded.js +13 -24
- package/dist/internal/brand.js +1 -1
- package/dist/internal/browser-origin-guard.js +4 -4
- package/dist/internal/builtin-tools/artifacts.js +15 -27
- package/dist/internal/builtin-tools/index.js +2 -3
- package/dist/internal/builtin-tools/reminders.js +33 -52
- package/dist/internal/channel-architecture.d.ts +21 -0
- package/dist/internal/channel-architecture.d.ts.map +1 -0
- package/dist/internal/channel-architecture.js +41 -0
- package/dist/internal/channel-dispatch.js +3 -4
- package/dist/internal/channel-route-dispatch.js +40 -51
- package/dist/internal/channel-state.js +1 -1
- package/dist/internal/chat-client.js +319 -340
- package/dist/internal/cli-ax.js +1262 -1294
- package/dist/internal/cli-bitbucket.js +244 -272
- package/dist/internal/cli-convert-automation.js +137 -151
- package/dist/internal/cli-cursor.js +126 -147
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +1457 -1507
- package/dist/internal/cli-docs.js +130 -147
- package/dist/internal/cli-github.js +437 -476
- package/dist/internal/cli-gitlab.js +259 -288
- package/dist/internal/cli-images.js +266 -334
- package/dist/internal/cli-manifest.js +25 -37
- package/dist/internal/cli-mcp-oauth.js +228 -247
- package/dist/internal/cli-mcp.js +358 -383
- package/dist/internal/cli-migrate.js +73 -90
- package/dist/internal/cli-skills.js +35 -47
- package/dist/internal/cli-slack-manual.d.ts +0 -1
- package/dist/internal/cli-slack-manual.d.ts.map +1 -1
- package/dist/internal/cli-slack-manual.js +175 -204
- package/dist/internal/cli-slack.d.ts +1 -1
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +416 -456
- package/dist/internal/cloud-merge.js +7 -3
- package/dist/internal/cloud-turn-cost.js +8 -1
- package/dist/internal/connection-env.js +5 -6
- package/dist/internal/continuation-channel.js +10 -7
- package/dist/internal/continuation-identity.js +85 -67
- package/dist/internal/conversation-mirror.js +112 -131
- package/dist/internal/convert-automation/convert-workflow.js +21 -31
- package/dist/internal/cron.js +3 -3
- package/dist/internal/cursor/account-mcp.js +147 -146
- package/dist/internal/cursor/backend-client.js +290 -320
- package/dist/internal/cursor/bound-secret-file.js +3 -3
- package/dist/internal/cursor/credentials.js +127 -142
- package/dist/internal/cursor/cursor-api-transport.js +4 -8
- package/dist/internal/cursor/github-credentials.js +91 -108
- package/dist/internal/cursor/hosted-bound-secrets.js +3 -4
- package/dist/internal/cursor/hosted-deployment-secrets.js +1 -1
- package/dist/internal/cursor/hosted-store-secrets.js +5 -9
- package/dist/internal/cursor/session-token.js +36 -48
- package/dist/internal/cursor/store-api-client.js +77 -92
- package/dist/internal/cursor-account-mcp-auth.js +132 -149
- package/dist/internal/cursor-agent-template.js +1 -1
- package/dist/internal/cursor-deployment-relay.js +33 -54
- package/dist/internal/cursor-event-relay.js +65 -59
- package/dist/internal/cursor-relay-core.js +258 -286
- package/dist/internal/deferred-channel-session.js +3 -12
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +413 -475
- package/dist/internal/deploy-manifest.d.ts +17 -0
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +71 -21
- package/dist/internal/deploy-source.js +31 -43
- package/dist/internal/discovery/agent-config.js +45 -59
- package/dist/internal/discovery/agent.js +276 -280
- package/dist/internal/discovery/channels.js +67 -80
- package/dist/internal/discovery/connections.js +286 -296
- package/dist/internal/discovery/context.js +2 -13
- package/dist/internal/discovery/cursor-plugin.js +223 -259
- package/dist/internal/discovery/extension-overlay.js +104 -131
- package/dist/internal/discovery/extensions.js +276 -281
- package/dist/internal/discovery/fs.js +56 -79
- package/dist/internal/discovery/hooks.js +39 -50
- package/dist/internal/discovery/info.js +17 -19
- package/dist/internal/discovery/instructions.js +58 -71
- package/dist/internal/discovery/modules.js +45 -58
- package/dist/internal/discovery/project.d.ts.map +1 -1
- package/dist/internal/discovery/project.js +192 -215
- package/dist/internal/discovery/reminders.js +41 -52
- package/dist/internal/discovery/runtime.js +1 -1
- package/dist/internal/discovery/schedules.js +71 -82
- package/dist/internal/discovery/seed-files.js +21 -32
- package/dist/internal/discovery/services.js +74 -96
- package/dist/internal/discovery/skills.js +77 -94
- package/dist/internal/discovery/subagent.js +79 -95
- package/dist/internal/discovery/tools.js +12 -23
- package/dist/internal/distribution.js +2 -2
- package/dist/internal/docs-site.js +30 -45
- package/dist/internal/duration.js +1 -1
- package/dist/internal/env-file.js +48 -64
- package/dist/internal/eval-judge-model.js +17 -28
- package/dist/internal/eval-run-store.js +265 -254
- package/dist/internal/eval-runner.d.ts +8 -0
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +406 -408
- package/dist/internal/eval-transport.d.ts +24 -0
- package/dist/internal/eval-transport.d.ts.map +1 -0
- package/dist/internal/eval-transport.js +22 -0
- package/dist/internal/evals-client.js +242 -246
- package/dist/internal/event-log.js +72 -120
- package/dist/internal/event-mapper.js +30 -31
- package/dist/internal/factory-resource-channel.js +16 -30
- package/dist/internal/filesystem/errors.js +6 -6
- package/dist/internal/filesystem/format.js +10 -13
- package/dist/internal/filesystem/merge.js +52 -94
- package/dist/internal/filesystem/nearest.js +15 -27
- package/dist/internal/filesystem/scratch.js +65 -85
- package/dist/internal/filesystem/tools.js +221 -241
- package/dist/internal/filesystem/walk.js +76 -143
- package/dist/internal/framework-file-storage.js +118 -139
- package/dist/internal/framework-storage-selection.js +21 -13
- package/dist/internal/frontmatter.js +4 -6
- package/dist/internal/github-fanout.js +50 -64
- package/dist/internal/guest-network.js +96 -109
- package/dist/internal/handleAgentServeTrigger.js +121 -126
- package/dist/internal/host-files.js +73 -88
- package/dist/internal/host-kv.js +21 -36
- package/dist/internal/host-otel.js +22 -19
- package/dist/internal/host-platforms.js +49 -63
- package/dist/internal/hosted-catch-protocol.d.ts +1 -0
- package/dist/internal/hosted-catch-protocol.d.ts.map +1 -1
- package/dist/internal/hosted-catch-protocol.js +1 -0
- package/dist/internal/hosted-catch.d.ts +5 -3
- package/dist/internal/hosted-catch.d.ts.map +1 -1
- package/dist/internal/hosted-catch.js +84 -93
- package/dist/internal/hosted-delivery-protocol.js +32 -8
- package/dist/internal/hosted-delivery.d.ts +13 -1
- package/dist/internal/hosted-delivery.d.ts.map +1 -1
- package/dist/internal/hosted-delivery.js +614 -584
- package/dist/internal/hosted-eval-cases.d.ts +21 -0
- package/dist/internal/hosted-eval-cases.d.ts.map +1 -0
- package/dist/internal/hosted-eval-cases.js +162 -0
- package/dist/internal/hosted-execution-diag.js +38 -30
- package/dist/internal/hosted-execution-flush.js +75 -66
- package/dist/internal/hosted-execution-latency.js +16 -8
- package/dist/internal/hosted-managed-automation.js +2 -2
- package/dist/internal/hosting.js +2 -3
- package/dist/internal/http-channel-define.js +4 -1
- package/dist/internal/http-channel.js +101 -112
- package/dist/internal/http-control-plane-session.d.ts +18 -1
- package/dist/internal/http-control-plane-session.d.ts.map +1 -1
- package/dist/internal/http-control-plane-session.js +66 -32
- package/dist/internal/incoming-headers-to-fetch.js +1 -2
- package/dist/internal/init-interview.js +73 -93
- package/dist/internal/init-project.js +182 -214
- package/dist/internal/init-scaffold.js +10 -21
- package/dist/internal/inline-stdio-mcp.js +80 -86
- package/dist/internal/install-cursor-skills.js +231 -273
- package/dist/internal/legacy-command-guard.js +18 -31
- package/dist/internal/listen-port.js +34 -45
- package/dist/internal/local-control-plane.js +293 -307
- package/dist/internal/local-env.js +1 -1
- package/dist/internal/local-ingress.js +15 -9
- package/dist/internal/log-ring.js +1 -2
- package/dist/internal/logs-client.js +207 -227
- package/dist/internal/map-pool.js +24 -38
- package/dist/internal/mcp-endpoint.js +204 -180
- package/dist/internal/mcp-host.js +165 -168
- package/dist/internal/mcp-oauth-on-demand.js +170 -207
- package/dist/internal/mcp-oauth-persist.js +15 -29
- package/dist/internal/mcp-oauth.js +209 -266
- package/dist/internal/named-webhook-secret.d.ts +39 -0
- package/dist/internal/named-webhook-secret.d.ts.map +1 -0
- package/dist/internal/named-webhook-secret.js +47 -0
- package/dist/internal/open-browser.js +2 -3
- package/dist/internal/otel/collector.js +104 -68
- package/dist/internal/otel/config.js +24 -37
- package/dist/internal/otel/http.js +5 -7
- package/dist/internal/otel/mcp.js +3 -12
- package/dist/internal/otel/runtime.js +69 -83
- package/dist/internal/package-inline-stdio.js +57 -65
- package/dist/internal/peer-connections.js +9 -5
- package/dist/internal/platform-schedule-sync.js +39 -54
- package/dist/internal/platform-timers.js +176 -210
- package/dist/internal/playground/static.js +1 -2
- package/dist/internal/playground/toolchain.js +37 -53
- package/dist/internal/playground-proxy.js +230 -270
- package/dist/internal/process-memory-telemetry.js +33 -51
- package/dist/internal/prompt-context.js +3 -6
- package/dist/internal/reminder-control-plane-protocol.js +46 -13
- package/dist/internal/reminder-runner.js +770 -785
- package/dist/internal/reminder-schedule.js +1 -1
- package/dist/internal/reminder-store.js +57 -78
- package/dist/internal/request-error-status.js +1 -3
- package/dist/internal/request-headers.js +2 -2
- package/dist/internal/resolve-prod-target.js +119 -135
- package/dist/internal/resolved-connections.js +16 -6
- package/dist/internal/run-client.js +221 -229
- package/dist/internal/runtime-dispatch-runner.js +18 -43
- package/dist/internal/schedule-runner.js +49 -58
- package/dist/internal/scm/pr-url.js +7 -6
- package/dist/internal/sdk-runner.js +388 -363
- package/dist/internal/serve-restart.js +26 -39
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +1283 -1244
- package/dist/internal/session-cost.js +7 -9
- package/dist/internal/session-engine.d.ts +3 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +2801 -2777
- package/dist/internal/session-links.js +12 -16
- package/dist/internal/session-run-log.js +134 -82
- package/dist/internal/session-store.js +133 -164
- package/dist/internal/sessions-client.js +97 -118
- package/dist/internal/skill-catalog.js +18 -23
- package/dist/internal/skills-sync.js +16 -30
- package/dist/internal/slack-provision-client.js +90 -116
- package/dist/internal/start-log-store.js +48 -67
- package/dist/internal/steering.js +1 -2
- package/dist/internal/storage-coordinator.js +160 -196
- package/dist/internal/store-mirror.js +16 -30
- package/dist/internal/stream-progress.js +6 -8
- package/dist/internal/terminal-style.js +3 -4
- package/dist/internal/testing/scm-continuation-fixtures.js +6 -2
- package/dist/internal/testing/slack-continuation-fixtures.d.ts +26 -0
- package/dist/internal/testing/slack-continuation-fixtures.d.ts.map +1 -0
- package/dist/internal/testing/slack-continuation-fixtures.js +136 -0
- package/dist/internal/tool-catalog.js +11 -5
- package/dist/internal/tool-result.js +1 -1
- package/dist/internal/trajectory.js +19 -22
- package/dist/internal/turn-cost.js +52 -62
- package/dist/internal/turn-governor.js +5 -8
- package/dist/internal/turn-lease-store.js +85 -105
- package/dist/internal/turn-outbox.js +28 -43
- package/dist/internal/update-check.js +231 -259
- package/dist/internal/v2-hosting.js +1 -2
- package/dist/internal/workspace-sync.js +25 -41
- package/dist/internal/workspace.js +111 -139
- package/dist/kv/memory-kv.js +27 -51
- package/dist/memory.js +106 -148
- package/dist/otel.js +5 -8
- package/dist/playground/assets/{index-Co4CUVTQ.js → index-Be0-1hw2.js} +45 -45
- package/dist/playground/assets/index-Clz6uHj9.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/prompt.js +2 -4
- package/dist/storage-backends/cursor-hosted-v2.js +53 -83
- package/dist/storage-backends/cursor-hosted.js +105 -145
- package/dist/storage-backends/file-kv.js +100 -128
- package/dist/storage-protocol.js +3 -5
- package/dist/storage.js +17 -26
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +20 -18
- package/docs/building-with-agents.md +2 -0
- package/docs/deployment.md +7 -0
- package/docs/guides/bitbucket.md +9 -1
- package/docs/guides/github.md +20 -4
- package/docs/guides/gitlab.md +9 -1
- package/docs/guides/migrate.md +127 -0
- package/docs/reference/cli.md +39 -0
- package/docs/troubleshooting.md +1 -0
- package/package.json +1 -1
- package/skills/debug/SKILL.md +1 -0
- package/skills/github/SKILL.md +23 -0
- package/skills/migrate-v2/SKILL.md +51 -10
- package/dist/docs/assets/chunks/@localSearchIndexroot.BJ8UZggu.js +0 -1
- package/dist/docs/assets/chunks/channel.BTJ5J9FI.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.D4BZ3cVV.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.D4BZ3cVV.js +0 -1
- package/dist/docs/assets/chunks/clone.62tX-O-1.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.DkTs1aEU.js +0 -1
- package/dist/docs/assets/reference_cli.md.GwugN3n-.lean.js +0 -1
- package/dist/docs/assets/troubleshooting.md.Bscj6ODe.js +0 -1
- package/dist/playground/assets/index-C1g_PTTZ.css +0 -1
- /package/dist/docs/assets/{building-with-agents.md.BPjPFxFg.lean.js → building-with-agents.md.Df87rAe1.lean.js} +0 -0
- /package/dist/docs/assets/{deployment.md.BdqTiGdc.lean.js → deployment.md.BYuEcDBv.lean.js} +0 -0
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
11
2
|
import { z } from "zod";
|
|
12
|
-
import { allowAll, defineChannel, localDevStrict, loopbackGitHubDev, POST, } from "../../channels.js";
|
|
3
|
+
import { allowAll, defineChannel, hmacSignatureAuth, localDevStrict, loopbackGitHubDev, POST, } from "../../channels.js";
|
|
13
4
|
import { acknowledgeTask, acknowledgeTurn, isTaskDispatch, scheduleAfterAck, skipped, turnStarted, withPropagatingBackgroundErrors, } from "../../internal/channel-dispatch.js";
|
|
14
5
|
import { continuationSource, normalizeIdentity } from "../../internal/continuation-identity.js";
|
|
15
6
|
import { isDevMode } from "../../internal/dev-mode.js";
|
|
@@ -17,9 +8,11 @@ import { attachHostedAdmissionAdapter } from "../../internal/hosted-admission-ad
|
|
|
17
8
|
import { CATCH_DELIVERY_ID_HEADER, replayCatchRequest } from "../../internal/hosted-catch.js";
|
|
18
9
|
import { AGENT_SDK_CATCH_EVENT_TYPE } from "../../internal/hosted-catch-protocol.js";
|
|
19
10
|
import { bindLocalIngressSend } from "../../internal/local-ingress.js";
|
|
11
|
+
import { envSecretRef, namedWebhookSecretArchitectureError, } from "../../internal/named-webhook-secret.js";
|
|
12
|
+
import { isSecretRef, } from "../../types.js";
|
|
20
13
|
import { resolveCredentialValue } from "./auth.js";
|
|
21
14
|
import { buildGitHubBinding, } from "./binding.js";
|
|
22
|
-
import { createCursorAccountGithubTokenResolver, createPendingCursorGithubCredentials, cursorGithubPermissionsForChannel, parseCursorGithubRepoScope, registerGithubCursorAccountRuntime, } from "./cursor-account.js";
|
|
15
|
+
import { createCursorAccountGithubTokenResolver, createPendingCursorGithubCredentials, cursorGithubPermissionsForChannel, isCursorAccountGithubTokenResolver, parseCursorGithubRepoScope, registerGithubCursorAccountRuntime, } from "./cursor-account.js";
|
|
23
16
|
import { buildDefaultGitHubEvents } from "./defaults.js";
|
|
24
17
|
import { deriveGitHubWebhookEvents, GITHUB_CHANNEL_KIND } from "./events.js";
|
|
25
18
|
import { emptyGitHubChannelState, githubBindingStateForEvent, } from "./state.js";
|
|
@@ -105,14 +98,22 @@ const githubPullRequestPayloadSchema = z.object({
|
|
|
105
98
|
* standard `{ auth: defaultGitHubAuth(ctx) }` dispatch from an inbound hook.
|
|
106
99
|
*/
|
|
107
100
|
export function defaultGitHubAuth(ctx) {
|
|
108
|
-
|
|
109
|
-
var _d;
|
|
110
|
-
const senderId = (_a = ctx.sender) === null || _a === void 0 ? void 0 : _a.id;
|
|
101
|
+
const senderId = ctx.sender?.id;
|
|
111
102
|
return {
|
|
112
103
|
authenticator: "github-webhook",
|
|
113
|
-
principalId: senderId !== undefined ? `github:${senderId}` : (
|
|
114
|
-
principalType:
|
|
115
|
-
attributes:
|
|
104
|
+
principalId: senderId !== undefined ? `github:${senderId}` : (ctx.senderLogin ?? "github"),
|
|
105
|
+
principalType: ctx.sender?.type === "Bot" ? "service" : "user",
|
|
106
|
+
attributes: {
|
|
107
|
+
conversation_kind: ctx.conversation.kind,
|
|
108
|
+
...(ctx.deliveryId === undefined ? {} : { delivery_id: ctx.deliveryId }),
|
|
109
|
+
...(ctx.installationId === undefined ? {} : { installation_id: String(ctx.installationId) }),
|
|
110
|
+
repository: ctx.repository.fullName,
|
|
111
|
+
...(ctx.repository.id === undefined ? {} : { repository_id: String(ctx.repository.id) }),
|
|
112
|
+
...(ctx.senderLogin === undefined ? {} : { user_login: ctx.senderLogin }),
|
|
113
|
+
...(ctx.sender?.type === undefined ? {} : { user_type: ctx.sender.type }),
|
|
114
|
+
...(ctx.repository.owner === "" ? {} : { issuer: `github:${ctx.repository.owner}` }),
|
|
115
|
+
...(ctx.senderLogin === undefined ? {} : { subject: ctx.senderLogin }),
|
|
116
|
+
},
|
|
116
117
|
};
|
|
117
118
|
}
|
|
118
119
|
export function githubContinuationKey(ctx) {
|
|
@@ -181,8 +182,7 @@ export function defaultOnComment(ctx, comment, options) {
|
|
|
181
182
|
return { auth: defaultGitHubAuth(ctx) };
|
|
182
183
|
}
|
|
183
184
|
export function shouldDispatchGitHubComment(args) {
|
|
184
|
-
|
|
185
|
-
const botName = (_a = args.botName) === null || _a === void 0 ? void 0 : _a.trim();
|
|
185
|
+
const botName = args.botName?.trim();
|
|
186
186
|
if (botName === undefined || botName === "") {
|
|
187
187
|
return false;
|
|
188
188
|
}
|
|
@@ -193,8 +193,7 @@ export function shouldDispatchGitHubComment(args) {
|
|
|
193
193
|
return mention.test(args.body);
|
|
194
194
|
}
|
|
195
195
|
export function extractGitHubCommentTrigger(args) {
|
|
196
|
-
|
|
197
|
-
const botName = (_a = args.botName) === null || _a === void 0 ? void 0 : _a.trim();
|
|
196
|
+
const botName = args.botName?.trim();
|
|
198
197
|
if (botName === undefined || botName === "") {
|
|
199
198
|
const trimmed = args.body.trim();
|
|
200
199
|
return trimmed === "" ? undefined : { message: trimmed };
|
|
@@ -207,8 +206,6 @@ export function extractGitHubCommentTrigger(args) {
|
|
|
207
206
|
return { message: stripped };
|
|
208
207
|
}
|
|
209
208
|
export function parseGitHubPullRequestEvent(args) {
|
|
210
|
-
var _a, _b, _c, _d, _e, _f;
|
|
211
|
-
var _g;
|
|
212
209
|
const parsed = githubPullRequestPayloadSchema.safeParse(args.payload);
|
|
213
210
|
if (!parsed.success) {
|
|
214
211
|
return null;
|
|
@@ -216,46 +213,65 @@ export function parseGitHubPullRequestEvent(args) {
|
|
|
216
213
|
const payload = parsed.data;
|
|
217
214
|
const repository = toRepositoryRef(payload.repository);
|
|
218
215
|
const sender = toUser(payload.sender);
|
|
219
|
-
const installationId =
|
|
220
|
-
const ctx =
|
|
216
|
+
const installationId = payload.installation?.id;
|
|
217
|
+
const ctx = {
|
|
218
|
+
...(args.deliveryId === undefined ? {} : { deliveryId: args.deliveryId }),
|
|
219
|
+
eventName: "pull_request",
|
|
220
|
+
repository,
|
|
221
|
+
conversation: {
|
|
221
222
|
kind: "pull_request",
|
|
222
223
|
number: payload.pull_request.number,
|
|
223
224
|
url: payload.pull_request.html_url,
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
? {}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
:
|
|
230
|
-
|
|
231
|
-
:
|
|
232
|
-
|
|
233
|
-
|
|
225
|
+
},
|
|
226
|
+
...(sender === undefined ? {} : { sender, senderLogin: sender.login }),
|
|
227
|
+
...(installationId === undefined ? {} : { installationId }),
|
|
228
|
+
};
|
|
229
|
+
const pullRequest = {
|
|
230
|
+
action: payload.action,
|
|
231
|
+
number: payload.pull_request.number,
|
|
232
|
+
url: payload.pull_request.html_url,
|
|
233
|
+
title: payload.pull_request.title,
|
|
234
|
+
...(payload.pull_request.body === undefined || payload.pull_request.body === null
|
|
235
|
+
? {}
|
|
236
|
+
: { body: payload.pull_request.body }),
|
|
237
|
+
headRef: payload.pull_request.head.ref,
|
|
238
|
+
headSha: payload.pull_request.head.sha,
|
|
239
|
+
baseRef: payload.pull_request.base.ref,
|
|
240
|
+
...(payload.pull_request.base.sha === undefined
|
|
241
|
+
? {}
|
|
242
|
+
: { baseSha: payload.pull_request.base.sha }),
|
|
243
|
+
...(payload.changes?.base?.ref?.from === undefined
|
|
244
|
+
? {}
|
|
245
|
+
: { baseRefChangedFrom: payload.changes.base.ref.from }),
|
|
246
|
+
draft: payload.pull_request.draft ?? false,
|
|
247
|
+
merged: payload.pull_request.merged === true,
|
|
248
|
+
...(payload.pull_request.user?.login === undefined
|
|
249
|
+
? {}
|
|
250
|
+
: { authorLogin: payload.pull_request.user.login }),
|
|
251
|
+
...(payload.label?.name === undefined ? {} : { label: { name: payload.label.name } }),
|
|
252
|
+
};
|
|
234
253
|
return { ctx, pullRequest };
|
|
235
254
|
}
|
|
236
|
-
export function verifyGitHubWebhookSignature(args) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
signatureHeader: args.signatureHeader,
|
|
249
|
-
});
|
|
250
|
-
return isVerified ? "verified" : "mismatch";
|
|
255
|
+
export async function verifyGitHubWebhookSignature(args) {
|
|
256
|
+
const secret = await resolveCredentialValue(args.secret);
|
|
257
|
+
if (secret === undefined || secret === "") {
|
|
258
|
+
return "missing_secret";
|
|
259
|
+
}
|
|
260
|
+
if (args.signatureHeader === null) {
|
|
261
|
+
return "missing_signature";
|
|
262
|
+
}
|
|
263
|
+
const isVerified = verifyWebhookSha256Signature({
|
|
264
|
+
secret,
|
|
265
|
+
body: args.body,
|
|
266
|
+
signatureHeader: args.signatureHeader,
|
|
251
267
|
});
|
|
268
|
+
return isVerified ? "verified" : "mismatch";
|
|
252
269
|
}
|
|
253
270
|
function verifyWebhookSha256Signature(args) {
|
|
254
|
-
|
|
255
|
-
if (!args.signatureHeader.startsWith(prefix)) {
|
|
271
|
+
if (!args.signatureHeader.startsWith(GITHUB_SIGNATURE_PREFIX)) {
|
|
256
272
|
return false;
|
|
257
273
|
}
|
|
258
|
-
const receivedHex = args.signatureHeader.slice(
|
|
274
|
+
const receivedHex = args.signatureHeader.slice(GITHUB_SIGNATURE_PREFIX.length);
|
|
259
275
|
if (!/^[0-9a-f]+$/i.test(receivedHex) || receivedHex.length % 2 !== 0) {
|
|
260
276
|
return false;
|
|
261
277
|
}
|
|
@@ -269,149 +285,142 @@ function verifyWebhookSha256Signature(args) {
|
|
|
269
285
|
* fan-out and hosted admission arrive verified. The v2 mailbox is stamped
|
|
270
286
|
* upstream (local CP or hosted ingress), never here.
|
|
271
287
|
*/
|
|
272
|
-
export function dispatchGitHubWebhook(input) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
288
|
+
export async function dispatchGitHubWebhook(input) {
|
|
289
|
+
const { options, eventName, payload, deliveryId, args } = input;
|
|
290
|
+
const botName = options.botName ?? process.env.GITHUB_APP_SLUG;
|
|
291
|
+
const bindingConfig = {
|
|
292
|
+
api: options.api,
|
|
293
|
+
credentials: options.credentials,
|
|
294
|
+
};
|
|
295
|
+
if (eventName === "ping") {
|
|
296
|
+
return Response.json({ ok: true, event: "ping" });
|
|
297
|
+
}
|
|
298
|
+
switch (eventName) {
|
|
299
|
+
case "pull_request":
|
|
300
|
+
return handlePullRequest({
|
|
301
|
+
options,
|
|
302
|
+
bindingConfig,
|
|
303
|
+
payload,
|
|
304
|
+
deliveryId,
|
|
305
|
+
args,
|
|
306
|
+
});
|
|
307
|
+
case "issue_comment":
|
|
308
|
+
return handleIssueComment({
|
|
309
|
+
options,
|
|
310
|
+
bindingConfig,
|
|
311
|
+
botName,
|
|
312
|
+
payload,
|
|
313
|
+
deliveryId,
|
|
314
|
+
args,
|
|
315
|
+
});
|
|
316
|
+
case "pull_request_review_comment":
|
|
317
|
+
return handleReviewComment({
|
|
318
|
+
options,
|
|
319
|
+
bindingConfig,
|
|
320
|
+
botName,
|
|
321
|
+
payload,
|
|
322
|
+
deliveryId,
|
|
323
|
+
args,
|
|
324
|
+
});
|
|
325
|
+
case "issues":
|
|
326
|
+
return handleIssue({
|
|
327
|
+
options,
|
|
328
|
+
bindingConfig,
|
|
329
|
+
payload,
|
|
330
|
+
deliveryId,
|
|
331
|
+
args,
|
|
332
|
+
});
|
|
333
|
+
case "check_suite":
|
|
334
|
+
return handleCheckSuite({
|
|
335
|
+
options,
|
|
336
|
+
bindingConfig,
|
|
337
|
+
payload,
|
|
338
|
+
deliveryId,
|
|
339
|
+
args,
|
|
340
|
+
});
|
|
341
|
+
case "check_run":
|
|
342
|
+
return handleCheckRun({
|
|
343
|
+
options,
|
|
344
|
+
bindingConfig,
|
|
345
|
+
payload,
|
|
346
|
+
deliveryId,
|
|
347
|
+
args,
|
|
348
|
+
});
|
|
349
|
+
case "workflow_run":
|
|
350
|
+
return handleWorkflowRun({
|
|
351
|
+
options,
|
|
352
|
+
bindingConfig,
|
|
353
|
+
payload,
|
|
354
|
+
deliveryId,
|
|
355
|
+
args,
|
|
356
|
+
});
|
|
357
|
+
case "status":
|
|
358
|
+
return handleStatus({
|
|
359
|
+
options,
|
|
360
|
+
bindingConfig,
|
|
361
|
+
payload,
|
|
362
|
+
deliveryId,
|
|
363
|
+
args,
|
|
364
|
+
});
|
|
365
|
+
default:
|
|
366
|
+
if (options.onEvent !== undefined && eventName !== null) {
|
|
367
|
+
return handleGenericEvent({
|
|
345
368
|
options,
|
|
346
369
|
bindingConfig,
|
|
370
|
+
eventName,
|
|
347
371
|
payload,
|
|
348
372
|
deliveryId,
|
|
349
373
|
args,
|
|
350
374
|
});
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
options,
|
|
355
|
-
bindingConfig,
|
|
356
|
-
eventName,
|
|
357
|
-
payload,
|
|
358
|
-
deliveryId,
|
|
359
|
-
args,
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
return skipped("unsupported_event", { event: eventName });
|
|
363
|
-
}
|
|
364
|
-
});
|
|
375
|
+
}
|
|
376
|
+
return skipped("unsupported_event", { event: eventName });
|
|
377
|
+
}
|
|
365
378
|
}
|
|
366
379
|
/**
|
|
367
380
|
* HTTP entry for a single agent's GitHub channel: optional HMAC verify, then
|
|
368
381
|
* {@link dispatchGitHubWebhook}.
|
|
369
382
|
*/
|
|
370
|
-
export function handleGitHubWebhookRequest(input) {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
});
|
|
388
|
-
if (signatureResult !== "verified") {
|
|
389
|
-
return Response.json({ ok: false, error: signatureResult }, { status: 401 });
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
let payload;
|
|
393
|
-
try {
|
|
394
|
-
payload = JSON.parse(bodyText);
|
|
395
|
-
}
|
|
396
|
-
catch (_d) {
|
|
397
|
-
return Response.json({ ok: false, error: "invalid_json" }, { status: 400 });
|
|
383
|
+
export async function handleGitHubWebhookRequest(input) {
|
|
384
|
+
const bodyText = await input.request.text();
|
|
385
|
+
const webhookSecret = input.options.credentials?.webhookSecret ?? envWebhookSecret();
|
|
386
|
+
// A hosted public catch is reachable without an alias token. Require a
|
|
387
|
+
// verified Hub signature there even when no secret is configured, so a
|
|
388
|
+
// missing secret is a rejection rather than an unsigned accept. Local
|
|
389
|
+
// routes keep the existing rule: verify only when a secret is set.
|
|
390
|
+
const requireSignature = input.skipSignatureVerification !== true &&
|
|
391
|
+
(webhookSecret !== undefined || input.request.headers.has(CATCH_DELIVERY_ID_HEADER));
|
|
392
|
+
if (requireSignature) {
|
|
393
|
+
const signatureResult = await verifyGitHubWebhookSignature({
|
|
394
|
+
body: bodyText,
|
|
395
|
+
signatureHeader: input.request.headers.get(GITHUB_SIGNATURE_HEADER),
|
|
396
|
+
secret: webhookSecret,
|
|
397
|
+
});
|
|
398
|
+
if (signatureResult !== "verified") {
|
|
399
|
+
return Response.json({ ok: false, error: signatureResult }, { status: 401 });
|
|
398
400
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
401
|
+
}
|
|
402
|
+
let payload;
|
|
403
|
+
try {
|
|
404
|
+
payload = JSON.parse(bodyText);
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
return Response.json({ ok: false, error: "invalid_json" }, { status: 400 });
|
|
408
|
+
}
|
|
409
|
+
const eventName = input.request.headers.get("x-github-event");
|
|
410
|
+
const args = eventName === null
|
|
411
|
+
? input.args
|
|
412
|
+
: bindLocalIngressSend(input.args, {
|
|
413
|
+
identity: input.options.continuation,
|
|
414
|
+
kind: "github",
|
|
415
|
+
eventType: eventName,
|
|
411
416
|
payload,
|
|
412
|
-
deliveryId: (_c = input.request.headers.get("x-github-delivery")) !== null && _c !== void 0 ? _c : undefined,
|
|
413
|
-
args,
|
|
414
417
|
});
|
|
418
|
+
return dispatchGitHubWebhook({
|
|
419
|
+
options: input.options,
|
|
420
|
+
eventName,
|
|
421
|
+
payload,
|
|
422
|
+
deliveryId: input.request.headers.get("x-github-delivery") ?? undefined,
|
|
423
|
+
args,
|
|
415
424
|
});
|
|
416
425
|
}
|
|
417
426
|
/** Options used to construct a github channel — for host-level fan-out. */
|
|
@@ -433,7 +442,9 @@ export function getGitHubChannelOptions(definition) {
|
|
|
433
442
|
*
|
|
434
443
|
* export default githubChannel({
|
|
435
444
|
* botName: "my-agent",
|
|
436
|
-
*
|
|
445
|
+
* // Named, not read: locally `process.env.GITHUB_WEBHOOK_SECRET`; hosted,
|
|
446
|
+
* // the deployment secret, which the control plane checks at ingestion.
|
|
447
|
+
* credentials: { webhookSecret: { secretName: "GITHUB_WEBHOOK_SECRET" } },
|
|
437
448
|
* // Replaces the @mention gate. Prefer typed Octokit via getOctokit().
|
|
438
449
|
* onComment: (ctx, comment) => ({ auth: defaultGitHubAuth(ctx) }),
|
|
439
450
|
* onPullRequest: (ctx, pr) => {
|
|
@@ -469,7 +480,6 @@ export function getGitHubChannelOptions(definition) {
|
|
|
469
480
|
* ```
|
|
470
481
|
*/
|
|
471
482
|
export function githubChannel(options = {}) {
|
|
472
|
-
var _a, _b, _c;
|
|
473
483
|
const usesCursorAccount = options.cursorAccount === true || typeof options.cursorAccount === "object";
|
|
474
484
|
// Normalized scope lives on the private runtime — never rewrite authored
|
|
475
485
|
// `cursorAccount` on the options object the author passed in.
|
|
@@ -484,29 +494,24 @@ export function githubChannel(options = {}) {
|
|
|
484
494
|
}
|
|
485
495
|
const pending = createPendingCursorGithubCredentials();
|
|
486
496
|
cursorCredentials = pending;
|
|
487
|
-
credentials =
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
// Evaluate `isDevMode()` per request (not at channel construction): channel
|
|
499
|
-
// modules call `githubChannel()` at import, and discovery may cache the
|
|
500
|
-
// definition across serve() calls. `serve()` sets the flag before discovery,
|
|
501
|
-
// but request-time lookup stays correct if that ordering ever drifts.
|
|
502
|
-
const auth = (_c = options.auth) !== null && _c !== void 0 ? _c : (webhookSecret !== undefined
|
|
503
|
-
? [allowAll()]
|
|
504
|
-
: [(request, info) => (isDevMode() ? loopbackGitHubDev() : localDevStrict())(request, info)]);
|
|
505
|
-
const channelOptions = Object.assign(Object.assign({}, options), { credentials });
|
|
497
|
+
credentials = {
|
|
498
|
+
...options.credentials,
|
|
499
|
+
token: createCursorAccountGithubTokenResolver(() => pending.getToken(), pending),
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
const routePath = options.path ?? "/";
|
|
503
|
+
const auth = options.auth ?? defaultGitHubRouteAuth(credentials?.webhookSecret ?? envWebhookSecret());
|
|
504
|
+
const channelOptions = {
|
|
505
|
+
...options,
|
|
506
|
+
credentials,
|
|
507
|
+
};
|
|
506
508
|
if (channelOptions.continuation !== undefined) {
|
|
507
509
|
channelOptions.continuation = normalizeIdentity(channelOptions.continuation, "github");
|
|
508
510
|
}
|
|
509
|
-
const events =
|
|
511
|
+
const events = {
|
|
512
|
+
...buildDefaultGitHubEvents({ ...channelOptions }),
|
|
513
|
+
...options.events,
|
|
514
|
+
};
|
|
510
515
|
const definition = defineChannel({
|
|
511
516
|
auth,
|
|
512
517
|
state: emptyGitHubChannelState(),
|
|
@@ -524,12 +529,10 @@ export function githubChannel(options = {}) {
|
|
|
524
529
|
// route boundary so /v1/info + Try always have something to show.
|
|
525
530
|
bodySchema: z.unknown(),
|
|
526
531
|
description: "GitHub webhook ingress",
|
|
527
|
-
handler: (request, args) =>
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
args,
|
|
532
|
-
});
|
|
532
|
+
handler: async (request, args) => handleGitHubWebhookRequest({
|
|
533
|
+
options: channelOptions,
|
|
534
|
+
request,
|
|
535
|
+
args,
|
|
533
536
|
}),
|
|
534
537
|
}),
|
|
535
538
|
],
|
|
@@ -539,16 +542,17 @@ export function githubChannel(options = {}) {
|
|
|
539
542
|
kind: GITHUB_CHANNEL_KIND,
|
|
540
543
|
prepareArgs: withPropagatingBackgroundErrors,
|
|
541
544
|
dispatch: ({ channelId, eventType, payload, deliveryId, args }) => {
|
|
542
|
-
|
|
543
|
-
//
|
|
544
|
-
//
|
|
545
|
-
//
|
|
545
|
+
// A catch (publicEndpoint() or a named webhook secret) is an
|
|
546
|
+
// http.request envelope. Replay it into the route handler, which
|
|
547
|
+
// verifies X-Hub-Signature-256 — the only check on a public catch,
|
|
548
|
+
// and a second one behind the control plane's on a named-secret
|
|
549
|
+
// catch. Forge deliveries carry a GitHub event name and stay on
|
|
546
550
|
// dispatchGitHubWebhook.
|
|
547
551
|
if (eventType === AGENT_SDK_CATCH_EVENT_TYPE) {
|
|
548
552
|
return replayCatchRequest({
|
|
549
|
-
channelId: channelId
|
|
553
|
+
channelId: channelId ?? "github",
|
|
550
554
|
deliveryId,
|
|
551
|
-
routes:
|
|
555
|
+
routes: definition.routes ?? [],
|
|
552
556
|
payload,
|
|
553
557
|
args,
|
|
554
558
|
});
|
|
@@ -571,698 +575,817 @@ export function githubChannel(options = {}) {
|
|
|
571
575
|
}
|
|
572
576
|
return definition;
|
|
573
577
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
578
|
+
/** Header GitHub signs deliveries with; `sha256=<hex hmac of the raw body>`. */
|
|
579
|
+
const GITHUB_SIGNATURE_HEADER = "x-hub-signature-256";
|
|
580
|
+
const GITHUB_SIGNATURE_PREFIX = "sha256=";
|
|
581
|
+
/** Env var / deployment secret an omitted `webhookSecret` falls back to. */
|
|
582
|
+
export const GITHUB_WEBHOOK_SECRET_ENV = "GITHUB_WEBHOOK_SECRET";
|
|
583
|
+
/**
|
|
584
|
+
* The secret name the v2 error suggests for each API credential: the env
|
|
585
|
+
* var the field falls back to when omitted, or for `installationToken`
|
|
586
|
+
* (which has no fallback) the conventional name.
|
|
587
|
+
*/
|
|
588
|
+
const GITHUB_API_CREDENTIAL_ENV = {
|
|
589
|
+
token: "GITHUB_TOKEN",
|
|
590
|
+
installationToken: "GITHUB_APP_INSTALLATION_TOKEN",
|
|
591
|
+
appId: "GITHUB_APP_ID",
|
|
592
|
+
privateKey: "GITHUB_APP_PRIVATE_KEY",
|
|
593
|
+
};
|
|
594
|
+
/**
|
|
595
|
+
* Why a `githubChannel` cannot deploy onto architecture v2 as authored, or
|
|
596
|
+
* `undefined` when it can.
|
|
597
|
+
*
|
|
598
|
+
* v2 terminates the Hub signature on the control plane, which can only do
|
|
599
|
+
* that for a secret it can name: a literal or getter `webhookSecret` never
|
|
600
|
+
* reaches the manifest, so the check would run inside the guest only —
|
|
601
|
+
* after compute was spent and after GitHub already got its 202.
|
|
602
|
+
*
|
|
603
|
+
* The API credentials (`token`, `installationToken`, `appId`,
|
|
604
|
+
* `privateKey`) follow the same rule on v2: a name is what lets `deploy`
|
|
605
|
+
* flag an unset deployment secret before the first API call fails inside
|
|
606
|
+
* the guest, and a getter is a hook that runs inside the guest with no
|
|
607
|
+
* declared input. A numeric `appId` is configuration, not a secret, and
|
|
608
|
+
* stays allowed. Omitting a field (its env fallback) and `publicEndpoint()`
|
|
609
|
+
* postures are both still allowed. Architecture `"v1"` accepts every shape.
|
|
610
|
+
*/
|
|
611
|
+
export function githubChannelArchitectureError(definition) {
|
|
612
|
+
const options = getGitHubChannelOptions(definition);
|
|
613
|
+
if (options === undefined) {
|
|
614
|
+
return undefined;
|
|
615
|
+
}
|
|
616
|
+
const webhookError = namedWebhookSecretArchitectureError({
|
|
617
|
+
option: "githubChannel credentials.webhookSecret",
|
|
618
|
+
webhookSecret: options.credentials?.webhookSecret,
|
|
619
|
+
envName: GITHUB_WEBHOOK_SECRET_ENV,
|
|
620
|
+
verifies: "X-Hub-Signature-256",
|
|
621
|
+
});
|
|
622
|
+
if (webhookError !== undefined) {
|
|
623
|
+
return webhookError;
|
|
624
|
+
}
|
|
625
|
+
for (const field of Object.keys(GITHUB_API_CREDENTIAL_ENV)) {
|
|
626
|
+
const value = options.credentials?.[field];
|
|
627
|
+
if (value === undefined ||
|
|
628
|
+
isSecretRef(value) ||
|
|
629
|
+
typeof value === "number" ||
|
|
630
|
+
// `cursorAccount: true` installs the SDK's own token resolver; it is
|
|
631
|
+
// not something the author wrote and the control plane mints it.
|
|
632
|
+
isCursorAccountGithubTokenResolver(value)) {
|
|
633
|
+
continue;
|
|
617
634
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
635
|
+
const envName = GITHUB_API_CREDENTIAL_ENV[field];
|
|
636
|
+
const authored = typeof value === "function" ? "a function" : "a literal value";
|
|
637
|
+
return (`githubChannel credentials.${field} is ${authored}; architecture "v2" requires a named secret: ` +
|
|
638
|
+
`{ secretName: "${envName}" }. The guest reads the deployment secret of that name from its ` +
|
|
639
|
+
`environment, and \`deploy\` warns when it is not set; a literal or function value is neither ` +
|
|
640
|
+
`declared nor checkable before the first API call. Set the value with ` +
|
|
641
|
+
`\`secrets set <slug> ${envName}\`.`);
|
|
642
|
+
}
|
|
643
|
+
return undefined;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Deployment secrets a `githubChannel`'s API credentials name
|
|
647
|
+
* (`{ secretName }` values of `token`, `installationToken`, `appId`, and
|
|
648
|
+
* `privateKey`). `deploy` declares them beside `hosting.secretNames` and the
|
|
649
|
+
* catch secrets so an unset one is flagged at deploy time rather than as a
|
|
650
|
+
* failed API call inside the guest. The webhook secret is not here: it is
|
|
651
|
+
* a catch secret and travels through the catch declaration.
|
|
652
|
+
*/
|
|
653
|
+
export function githubChannelCredentialSecretNames(definition) {
|
|
654
|
+
const credentials = getGitHubChannelOptions(definition)?.credentials;
|
|
655
|
+
if (credentials === undefined) {
|
|
656
|
+
return [];
|
|
657
|
+
}
|
|
658
|
+
const names = new Set();
|
|
659
|
+
for (const field of Object.keys(GITHUB_API_CREDENTIAL_ENV)) {
|
|
660
|
+
const value = credentials[field];
|
|
661
|
+
if (isSecretRef(value)) {
|
|
662
|
+
names.add(value.secretName);
|
|
624
663
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
});
|
|
664
|
+
}
|
|
665
|
+
return [...names];
|
|
666
|
+
}
|
|
667
|
+
/** True for a `githubChannel({ cursorAccount })` definition. */
|
|
668
|
+
export function isCursorAccountGitHubChannel(definition) {
|
|
669
|
+
const cursorAccount = getGitHubChannelOptions(definition)?.cursorAccount;
|
|
670
|
+
return cursorAccount === true || typeof cursorAccount === "object";
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* The route policy for a GitHub webhook whose secret is named: verify
|
|
674
|
+
* `X-Hub-Signature-256` under the env var / deployment secret `secretName`.
|
|
675
|
+
* Being an {@link hmacSignatureAuth} policy, `deploy` writes it into the
|
|
676
|
+
* manifest, so on Cursor hosting the control plane runs the same check
|
|
677
|
+
* at ingestion and refuses a bad signature before any compute starts.
|
|
678
|
+
*/
|
|
679
|
+
export function githubWebhookSignatureAuth(secretName) {
|
|
680
|
+
return hmacSignatureAuth({
|
|
681
|
+
header: GITHUB_SIGNATURE_HEADER,
|
|
682
|
+
secret: secretName,
|
|
683
|
+
prefix: GITHUB_SIGNATURE_PREFIX,
|
|
646
684
|
});
|
|
647
685
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
686
|
+
/**
|
|
687
|
+
* Default route auth for the resolved webhook secret:
|
|
688
|
+
*
|
|
689
|
+
* - A named secret makes the HMAC the route policy itself
|
|
690
|
+
* ({@link githubWebhookSignatureAuth}), which is also what makes the
|
|
691
|
+
* channel catchable on the control plane.
|
|
692
|
+
* - A literal or getter secret keeps the HMAC inside the handler, so the
|
|
693
|
+
* route admits everything (allowAll) and the handler is the request auth.
|
|
694
|
+
* - No secret: prod stays loopback-strict; dev admits unsigned deliveries
|
|
695
|
+
* from a loopback peer only (loopbackGitHubDev) — not the LAN. Admits
|
|
696
|
+
* `gh webhook forward` deliveries (loopback peer + GitHub forwarding /
|
|
697
|
+
* delivery headers) while rejecting loopback tunnels that relay unsigned
|
|
698
|
+
* traffic without `X-GitHub-Event`.
|
|
699
|
+
*
|
|
700
|
+
* `isDevMode()` is evaluated per request (not at channel construction):
|
|
701
|
+
* channel modules call `githubChannel()` at import, and discovery may cache
|
|
702
|
+
* the definition across serve() calls. `serve()` sets the flag before
|
|
703
|
+
* discovery, but request-time lookup stays correct if that ordering drifts.
|
|
704
|
+
*/
|
|
705
|
+
function defaultGitHubRouteAuth(webhookSecret) {
|
|
706
|
+
if (webhookSecret === undefined) {
|
|
707
|
+
return [
|
|
708
|
+
(request, info) => (isDevMode() ? loopbackGitHubDev() : localDevStrict())(request, info),
|
|
709
|
+
];
|
|
710
|
+
}
|
|
711
|
+
if (isSecretRef(webhookSecret)) {
|
|
712
|
+
return [githubWebhookSignatureAuth(webhookSecret.secretName)];
|
|
713
|
+
}
|
|
714
|
+
return [allowAll()];
|
|
715
|
+
}
|
|
716
|
+
function hasDedicatedGitHubApiCredentials(options) {
|
|
717
|
+
return (options.credentials?.token !== undefined ||
|
|
718
|
+
options.credentials?.installationToken !== undefined ||
|
|
719
|
+
options.credentials?.appId !== undefined ||
|
|
720
|
+
options.credentials?.privateKey !== undefined);
|
|
721
|
+
}
|
|
722
|
+
async function handlePullRequest(input) {
|
|
723
|
+
const parsed = parseGitHubPullRequestEvent({
|
|
724
|
+
payload: input.payload,
|
|
725
|
+
deliveryId: input.deliveryId,
|
|
726
|
+
});
|
|
727
|
+
if (parsed === null) {
|
|
728
|
+
return Response.json({ ok: false, error: "invalid_pull_request_payload" }, { status: 400 });
|
|
729
|
+
}
|
|
730
|
+
const { pullRequest } = parsed;
|
|
731
|
+
const installationId = readInstallationId(input.payload) ?? parsed.ctx.installationId;
|
|
732
|
+
const binding = githubBindingStateForEvent({
|
|
733
|
+
kind: parsed.ctx.conversation.kind,
|
|
734
|
+
owner: parsed.ctx.repository.owner,
|
|
735
|
+
repo: parsed.ctx.repository.name,
|
|
736
|
+
number: parsed.ctx.conversation.number,
|
|
737
|
+
repositoryId: parsed.ctx.repository.id,
|
|
738
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
739
|
+
installationId,
|
|
740
|
+
});
|
|
741
|
+
const ctx = enrichEventContext({
|
|
742
|
+
bindingConfig: input.bindingConfig,
|
|
743
|
+
ctx: parsed.ctx,
|
|
744
|
+
payload: input.payload,
|
|
745
|
+
bindingState: binding,
|
|
746
|
+
installationId,
|
|
747
|
+
host: input.args.host,
|
|
748
|
+
artifacts: input.args.artifacts,
|
|
749
|
+
send: input.args.send,
|
|
750
|
+
});
|
|
751
|
+
const dispatch = input.options.onPullRequest === undefined
|
|
752
|
+
? defaultGitHubPullRequestDispatch(ctx, pullRequest)
|
|
753
|
+
: await input.options.onPullRequest(ctx, pullRequest);
|
|
754
|
+
if (dispatch === null) {
|
|
755
|
+
return skipped("not_dispatched", { action: pullRequest.action });
|
|
756
|
+
}
|
|
757
|
+
if (isTaskDispatch(dispatch)) {
|
|
758
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
759
|
+
action: pullRequest.action,
|
|
760
|
+
prUrl: pullRequest.url,
|
|
761
|
+
headSha: pullRequest.headSha,
|
|
684
762
|
});
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
763
|
+
}
|
|
764
|
+
const message = [
|
|
765
|
+
dispatch.message ?? defaultGitHubPullRequestMessage(ctx, pullRequest),
|
|
766
|
+
...(dispatch.context ?? []),
|
|
767
|
+
].join("\n");
|
|
768
|
+
const cloud = dispatch.cloud ?? (await resolveCloudOptions(input.options.cloud, ctx, pullRequest));
|
|
769
|
+
return startTurn({
|
|
770
|
+
options: input.options,
|
|
771
|
+
args: input.args,
|
|
772
|
+
ctx,
|
|
773
|
+
message,
|
|
774
|
+
dispatch,
|
|
775
|
+
cloud,
|
|
776
|
+
state: sessionStateFromBinding({
|
|
777
|
+
binding,
|
|
778
|
+
deliveryId: ctx.deliveryId,
|
|
779
|
+
eventName: ctx.eventName,
|
|
780
|
+
headSha: pullRequest.headSha,
|
|
781
|
+
baseRef: pullRequest.baseRef,
|
|
782
|
+
headRef: pullRequest.headRef,
|
|
783
|
+
}),
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
async function handleIssueComment(input) {
|
|
787
|
+
const parsed = parseIssueCommentEvent({
|
|
788
|
+
payload: input.payload,
|
|
789
|
+
deliveryId: input.deliveryId,
|
|
790
|
+
});
|
|
791
|
+
if (parsed === null) {
|
|
792
|
+
return Response.json({ ok: false, error: "invalid_issue_comment_payload" }, { status: 400 });
|
|
793
|
+
}
|
|
794
|
+
if (parsed.action !== "created") {
|
|
795
|
+
return skipped("not_dispatched", { action: parsed.action });
|
|
796
|
+
}
|
|
797
|
+
if (isIgnoredInboundComment(parsed.comment.body, parsed.comment.author, input.botName)) {
|
|
798
|
+
return skipped("ignored_comment");
|
|
799
|
+
}
|
|
800
|
+
const installationId = readInstallationId(input.payload) ?? parsed.ctx.installationId;
|
|
801
|
+
const binding = githubBindingStateForEvent({
|
|
802
|
+
kind: parsed.ctx.conversation.kind,
|
|
803
|
+
owner: parsed.ctx.repository.owner,
|
|
804
|
+
repo: parsed.ctx.repository.name,
|
|
805
|
+
number: parsed.ctx.conversation.number,
|
|
806
|
+
repositoryId: parsed.ctx.repository.id,
|
|
807
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
808
|
+
installationId,
|
|
809
|
+
triggeringCommentId: parsed.comment.id,
|
|
810
|
+
});
|
|
811
|
+
const ctx = enrichEventContext({
|
|
812
|
+
bindingConfig: input.bindingConfig,
|
|
813
|
+
ctx: parsed.ctx,
|
|
814
|
+
payload: input.payload,
|
|
815
|
+
bindingState: binding,
|
|
816
|
+
installationId,
|
|
817
|
+
host: input.args.host,
|
|
818
|
+
artifacts: input.args.artifacts,
|
|
819
|
+
send: input.args.send,
|
|
820
|
+
});
|
|
821
|
+
const dispatch = input.options.onComment === undefined
|
|
822
|
+
? defaultOnComment(ctx, parsed.comment, {
|
|
701
823
|
botName: input.botName,
|
|
824
|
+
})
|
|
825
|
+
: await input.options.onComment(ctx, parsed.comment);
|
|
826
|
+
if (dispatch === null) {
|
|
827
|
+
return skipped("not_dispatched");
|
|
828
|
+
}
|
|
829
|
+
if (isTaskDispatch(dispatch)) {
|
|
830
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
831
|
+
event: "issue_comment",
|
|
832
|
+
action: parsed.action,
|
|
702
833
|
});
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
834
|
+
}
|
|
835
|
+
const trigger = extractGitHubCommentTrigger({
|
|
836
|
+
body: parsed.comment.body,
|
|
837
|
+
botName: input.botName,
|
|
838
|
+
});
|
|
839
|
+
const message = [
|
|
840
|
+
dispatch.message ?? trigger?.message ?? parsed.comment.body.trim(),
|
|
841
|
+
...(dispatch.context ?? []),
|
|
842
|
+
].join("\n");
|
|
843
|
+
return startTurn({
|
|
844
|
+
options: input.options,
|
|
845
|
+
args: input.args,
|
|
846
|
+
ctx,
|
|
847
|
+
message,
|
|
848
|
+
dispatch,
|
|
849
|
+
state: sessionStateFromBinding({
|
|
850
|
+
binding,
|
|
851
|
+
deliveryId: ctx.deliveryId,
|
|
852
|
+
eventName: ctx.eventName,
|
|
853
|
+
}),
|
|
719
854
|
});
|
|
720
855
|
}
|
|
721
|
-
function handleReviewComment(input) {
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
});
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
const dispatch = input.options.onComment === undefined
|
|
761
|
-
? defaultOnComment(ctx, parsed.comment, {
|
|
762
|
-
botName: input.botName,
|
|
763
|
-
})
|
|
764
|
-
: yield input.options.onComment(ctx, parsed.comment);
|
|
765
|
-
if (dispatch === null) {
|
|
766
|
-
return skipped("not_dispatched");
|
|
767
|
-
}
|
|
768
|
-
if (isTaskDispatch(dispatch)) {
|
|
769
|
-
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
770
|
-
event: "pull_request_review_comment",
|
|
771
|
-
action: parsed.action,
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
const trigger = extractGitHubCommentTrigger({
|
|
775
|
-
body: parsed.comment.body,
|
|
856
|
+
async function handleReviewComment(input) {
|
|
857
|
+
const parsed = parseReviewCommentEvent({
|
|
858
|
+
payload: input.payload,
|
|
859
|
+
deliveryId: input.deliveryId,
|
|
860
|
+
});
|
|
861
|
+
if (parsed === null) {
|
|
862
|
+
return Response.json({ ok: false, error: "invalid_review_comment_payload" }, { status: 400 });
|
|
863
|
+
}
|
|
864
|
+
if (parsed.action !== "created") {
|
|
865
|
+
return skipped("not_dispatched", { action: parsed.action });
|
|
866
|
+
}
|
|
867
|
+
if (isIgnoredInboundComment(parsed.comment.body, parsed.comment.author, input.botName)) {
|
|
868
|
+
return skipped("ignored_comment");
|
|
869
|
+
}
|
|
870
|
+
const installationId = readInstallationId(input.payload) ?? parsed.ctx.installationId;
|
|
871
|
+
const binding = githubBindingStateForEvent({
|
|
872
|
+
kind: parsed.ctx.conversation.kind,
|
|
873
|
+
owner: parsed.ctx.repository.owner,
|
|
874
|
+
repo: parsed.ctx.repository.name,
|
|
875
|
+
number: parsed.ctx.conversation.number,
|
|
876
|
+
repositoryId: parsed.ctx.repository.id,
|
|
877
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
878
|
+
installationId,
|
|
879
|
+
triggeringCommentId: parsed.comment.id,
|
|
880
|
+
reviewCommentId: parsed.comment.id,
|
|
881
|
+
reviewThreadRootCommentId: parsed.comment.inReplyToId ?? parsed.comment.id,
|
|
882
|
+
});
|
|
883
|
+
const ctx = enrichEventContext({
|
|
884
|
+
bindingConfig: input.bindingConfig,
|
|
885
|
+
ctx: parsed.ctx,
|
|
886
|
+
payload: input.payload,
|
|
887
|
+
bindingState: binding,
|
|
888
|
+
installationId,
|
|
889
|
+
host: input.args.host,
|
|
890
|
+
artifacts: input.args.artifacts,
|
|
891
|
+
send: input.args.send,
|
|
892
|
+
});
|
|
893
|
+
const dispatch = input.options.onComment === undefined
|
|
894
|
+
? defaultOnComment(ctx, parsed.comment, {
|
|
776
895
|
botName: input.botName,
|
|
896
|
+
})
|
|
897
|
+
: await input.options.onComment(ctx, parsed.comment);
|
|
898
|
+
if (dispatch === null) {
|
|
899
|
+
return skipped("not_dispatched");
|
|
900
|
+
}
|
|
901
|
+
if (isTaskDispatch(dispatch)) {
|
|
902
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
903
|
+
event: "pull_request_review_comment",
|
|
904
|
+
action: parsed.action,
|
|
777
905
|
});
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
906
|
+
}
|
|
907
|
+
const trigger = extractGitHubCommentTrigger({
|
|
908
|
+
body: parsed.comment.body,
|
|
909
|
+
botName: input.botName,
|
|
910
|
+
});
|
|
911
|
+
const message = [
|
|
912
|
+
dispatch.message ?? trigger?.message ?? parsed.comment.body.trim(),
|
|
913
|
+
...(dispatch.context ?? []),
|
|
914
|
+
].join("\n");
|
|
915
|
+
return startTurn({
|
|
916
|
+
options: input.options,
|
|
917
|
+
args: input.args,
|
|
918
|
+
ctx,
|
|
919
|
+
message,
|
|
920
|
+
dispatch,
|
|
921
|
+
state: sessionStateFromBinding({
|
|
922
|
+
binding,
|
|
923
|
+
deliveryId: ctx.deliveryId,
|
|
924
|
+
eventName: ctx.eventName,
|
|
925
|
+
headSha: parsed.headSha,
|
|
926
|
+
headRef: parsed.headRef,
|
|
927
|
+
baseRef: parsed.baseRef,
|
|
928
|
+
}),
|
|
797
929
|
});
|
|
798
930
|
}
|
|
799
|
-
function handleIssue(input) {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
});
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
action: parsed.issue.action,
|
|
840
|
-
issueNumber: parsed.issue.number,
|
|
841
|
-
});
|
|
842
|
-
}
|
|
843
|
-
const message = [
|
|
844
|
-
(_b = dispatch.message) !== null && _b !== void 0 ? _b : `Issue ${parsed.issue.action}: #${parsed.issue.number} ${parsed.issue.title}`,
|
|
845
|
-
...((_c = dispatch.context) !== null && _c !== void 0 ? _c : []),
|
|
846
|
-
].join("\n");
|
|
847
|
-
return startTurn({
|
|
848
|
-
options: input.options,
|
|
849
|
-
args: input.args,
|
|
850
|
-
ctx,
|
|
851
|
-
message,
|
|
852
|
-
dispatch,
|
|
853
|
-
state: sessionStateFromBinding({
|
|
854
|
-
binding,
|
|
855
|
-
deliveryId: ctx.deliveryId,
|
|
856
|
-
eventName: ctx.eventName,
|
|
857
|
-
}),
|
|
931
|
+
async function handleIssue(input) {
|
|
932
|
+
if (input.options.onIssue === undefined) {
|
|
933
|
+
return skipped("no_handler", { event: "issues" });
|
|
934
|
+
}
|
|
935
|
+
const parsed = parseIssueEvent({
|
|
936
|
+
payload: input.payload,
|
|
937
|
+
deliveryId: input.deliveryId,
|
|
938
|
+
});
|
|
939
|
+
if (parsed === null) {
|
|
940
|
+
return Response.json({ ok: false, error: "invalid_issues_payload" }, { status: 400 });
|
|
941
|
+
}
|
|
942
|
+
const installationId = readInstallationId(input.payload) ?? parsed.ctx.installationId;
|
|
943
|
+
const binding = githubBindingStateForEvent({
|
|
944
|
+
kind: parsed.ctx.conversation.kind,
|
|
945
|
+
owner: parsed.ctx.repository.owner,
|
|
946
|
+
repo: parsed.ctx.repository.name,
|
|
947
|
+
number: parsed.ctx.conversation.number,
|
|
948
|
+
repositoryId: parsed.ctx.repository.id,
|
|
949
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
950
|
+
installationId,
|
|
951
|
+
});
|
|
952
|
+
const ctx = enrichEventContext({
|
|
953
|
+
bindingConfig: input.bindingConfig,
|
|
954
|
+
ctx: parsed.ctx,
|
|
955
|
+
payload: input.payload,
|
|
956
|
+
bindingState: binding,
|
|
957
|
+
installationId,
|
|
958
|
+
host: input.args.host,
|
|
959
|
+
artifacts: input.args.artifacts,
|
|
960
|
+
send: input.args.send,
|
|
961
|
+
});
|
|
962
|
+
const dispatch = await input.options.onIssue(ctx, parsed.issue);
|
|
963
|
+
if (dispatch === null) {
|
|
964
|
+
return skipped("not_dispatched", { action: parsed.issue.action });
|
|
965
|
+
}
|
|
966
|
+
if (isTaskDispatch(dispatch)) {
|
|
967
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
968
|
+
event: "issues",
|
|
969
|
+
action: parsed.issue.action,
|
|
970
|
+
issueNumber: parsed.issue.number,
|
|
858
971
|
});
|
|
972
|
+
}
|
|
973
|
+
const message = [
|
|
974
|
+
dispatch.message ??
|
|
975
|
+
`Issue ${parsed.issue.action}: #${parsed.issue.number} ${parsed.issue.title}`,
|
|
976
|
+
...(dispatch.context ?? []),
|
|
977
|
+
].join("\n");
|
|
978
|
+
return startTurn({
|
|
979
|
+
options: input.options,
|
|
980
|
+
args: input.args,
|
|
981
|
+
ctx,
|
|
982
|
+
message,
|
|
983
|
+
dispatch,
|
|
984
|
+
state: sessionStateFromBinding({
|
|
985
|
+
binding,
|
|
986
|
+
deliveryId: ctx.deliveryId,
|
|
987
|
+
eventName: ctx.eventName,
|
|
988
|
+
}),
|
|
859
989
|
});
|
|
860
990
|
}
|
|
861
|
-
function handleCheckSuite(input) {
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
});
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
const
|
|
875
|
-
if (parsed.ctx === null) {
|
|
876
|
-
const dispatch = yield input.options.onCheckSuite(enrichCiContext({
|
|
877
|
-
bindingConfig: input.bindingConfig,
|
|
878
|
-
ctx: parsed.unanchoredCtx,
|
|
879
|
-
payload: input.payload,
|
|
880
|
-
installationId,
|
|
881
|
-
host: input.args.host,
|
|
882
|
-
artifacts: input.args.artifacts,
|
|
883
|
-
send: input.args.send,
|
|
884
|
-
}), parsed.checkSuite);
|
|
885
|
-
if (dispatch !== null && isTaskDispatch(dispatch)) {
|
|
886
|
-
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
887
|
-
event: "check_suite",
|
|
888
|
-
action: parsed.checkSuite.action,
|
|
889
|
-
checkSuiteId: parsed.checkSuite.checkSuiteId,
|
|
890
|
-
});
|
|
891
|
-
}
|
|
892
|
-
return skipped("no_pull_request", { event: "check_suite" });
|
|
893
|
-
}
|
|
894
|
-
const binding = githubBindingStateForEvent({
|
|
895
|
-
kind: parsed.ctx.conversation.kind,
|
|
896
|
-
owner: parsed.ctx.repository.owner,
|
|
897
|
-
repo: parsed.ctx.repository.name,
|
|
898
|
-
number: parsed.ctx.conversation.number,
|
|
899
|
-
repositoryId: parsed.ctx.repository.id,
|
|
900
|
-
repositoryUrl: parsed.ctx.repository.url,
|
|
901
|
-
installationId,
|
|
902
|
-
});
|
|
903
|
-
const ctx = enrichEventContext({
|
|
991
|
+
async function handleCheckSuite(input) {
|
|
992
|
+
if (input.options.onCheckSuite === undefined) {
|
|
993
|
+
return skipped("no_handler", { event: "check_suite" });
|
|
994
|
+
}
|
|
995
|
+
const parsed = parseCheckSuiteEvent({
|
|
996
|
+
payload: input.payload,
|
|
997
|
+
deliveryId: input.deliveryId,
|
|
998
|
+
});
|
|
999
|
+
if (parsed === null) {
|
|
1000
|
+
return Response.json({ ok: false, error: "invalid_check_suite_payload" }, { status: 400 });
|
|
1001
|
+
}
|
|
1002
|
+
const installationId = readInstallationId(input.payload) ?? parsed.unanchoredCtx.installationId;
|
|
1003
|
+
if (parsed.ctx === null) {
|
|
1004
|
+
const dispatch = await input.options.onCheckSuite(enrichCiContext({
|
|
904
1005
|
bindingConfig: input.bindingConfig,
|
|
905
|
-
ctx: parsed.
|
|
1006
|
+
ctx: parsed.unanchoredCtx,
|
|
906
1007
|
payload: input.payload,
|
|
907
|
-
bindingState: binding,
|
|
908
1008
|
installationId,
|
|
909
1009
|
host: input.args.host,
|
|
910
1010
|
artifacts: input.args.artifacts,
|
|
911
1011
|
send: input.args.send,
|
|
912
|
-
});
|
|
913
|
-
|
|
914
|
-
if (dispatch === null) {
|
|
915
|
-
return skipped("not_dispatched", { action: parsed.checkSuite.action });
|
|
916
|
-
}
|
|
917
|
-
if (isTaskDispatch(dispatch)) {
|
|
1012
|
+
}), parsed.checkSuite);
|
|
1013
|
+
if (dispatch !== null && isTaskDispatch(dispatch)) {
|
|
918
1014
|
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
919
1015
|
event: "check_suite",
|
|
920
1016
|
action: parsed.checkSuite.action,
|
|
921
1017
|
checkSuiteId: parsed.checkSuite.checkSuiteId,
|
|
922
1018
|
});
|
|
923
1019
|
}
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1020
|
+
return skipped("no_pull_request", { event: "check_suite" });
|
|
1021
|
+
}
|
|
1022
|
+
const binding = githubBindingStateForEvent({
|
|
1023
|
+
kind: parsed.ctx.conversation.kind,
|
|
1024
|
+
owner: parsed.ctx.repository.owner,
|
|
1025
|
+
repo: parsed.ctx.repository.name,
|
|
1026
|
+
number: parsed.ctx.conversation.number,
|
|
1027
|
+
repositoryId: parsed.ctx.repository.id,
|
|
1028
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
1029
|
+
installationId,
|
|
1030
|
+
});
|
|
1031
|
+
const ctx = enrichEventContext({
|
|
1032
|
+
bindingConfig: input.bindingConfig,
|
|
1033
|
+
ctx: parsed.ctx,
|
|
1034
|
+
payload: input.payload,
|
|
1035
|
+
bindingState: binding,
|
|
1036
|
+
installationId,
|
|
1037
|
+
host: input.args.host,
|
|
1038
|
+
artifacts: input.args.artifacts,
|
|
1039
|
+
send: input.args.send,
|
|
1040
|
+
});
|
|
1041
|
+
const dispatch = await input.options.onCheckSuite(ctx, parsed.checkSuite);
|
|
1042
|
+
if (dispatch === null) {
|
|
1043
|
+
return skipped("not_dispatched", { action: parsed.checkSuite.action });
|
|
1044
|
+
}
|
|
1045
|
+
if (isTaskDispatch(dispatch)) {
|
|
1046
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1047
|
+
event: "check_suite",
|
|
1048
|
+
action: parsed.checkSuite.action,
|
|
1049
|
+
checkSuiteId: parsed.checkSuite.checkSuiteId,
|
|
940
1050
|
});
|
|
1051
|
+
}
|
|
1052
|
+
const message = [
|
|
1053
|
+
dispatch.message ??
|
|
1054
|
+
formatCiMessage("Check suite", parsed.checkSuite.checkSuiteId, parsed.checkSuite),
|
|
1055
|
+
...(dispatch.context ?? []),
|
|
1056
|
+
].join("\n");
|
|
1057
|
+
return startTurn({
|
|
1058
|
+
options: input.options,
|
|
1059
|
+
args: input.args,
|
|
1060
|
+
ctx,
|
|
1061
|
+
message,
|
|
1062
|
+
dispatch,
|
|
1063
|
+
state: sessionStateFromBinding({
|
|
1064
|
+
binding,
|
|
1065
|
+
deliveryId: ctx.deliveryId,
|
|
1066
|
+
eventName: ctx.eventName,
|
|
1067
|
+
headSha: parsed.checkSuite.headSha,
|
|
1068
|
+
}),
|
|
941
1069
|
});
|
|
942
1070
|
}
|
|
943
|
-
function handleCheckRun(input) {
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
});
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
const
|
|
957
|
-
if (parsed.ctx === null) {
|
|
958
|
-
const dispatch = yield input.options.onCheckRun(enrichCiContext({
|
|
959
|
-
bindingConfig: input.bindingConfig,
|
|
960
|
-
ctx: parsed.unanchoredCtx,
|
|
961
|
-
payload: input.payload,
|
|
962
|
-
installationId,
|
|
963
|
-
host: input.args.host,
|
|
964
|
-
artifacts: input.args.artifacts,
|
|
965
|
-
send: input.args.send,
|
|
966
|
-
}), parsed.checkRun);
|
|
967
|
-
if (dispatch !== null && isTaskDispatch(dispatch)) {
|
|
968
|
-
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
969
|
-
event: "check_run",
|
|
970
|
-
action: parsed.checkRun.action,
|
|
971
|
-
checkRunId: parsed.checkRun.checkRunId,
|
|
972
|
-
});
|
|
973
|
-
}
|
|
974
|
-
return skipped("no_pull_request", { event: "check_run" });
|
|
975
|
-
}
|
|
976
|
-
const binding = githubBindingStateForEvent({
|
|
977
|
-
kind: parsed.ctx.conversation.kind,
|
|
978
|
-
owner: parsed.ctx.repository.owner,
|
|
979
|
-
repo: parsed.ctx.repository.name,
|
|
980
|
-
number: parsed.ctx.conversation.number,
|
|
981
|
-
repositoryId: parsed.ctx.repository.id,
|
|
982
|
-
repositoryUrl: parsed.ctx.repository.url,
|
|
983
|
-
installationId,
|
|
984
|
-
});
|
|
985
|
-
const ctx = enrichEventContext({
|
|
1071
|
+
async function handleCheckRun(input) {
|
|
1072
|
+
if (input.options.onCheckRun === undefined) {
|
|
1073
|
+
return skipped("no_handler", { event: "check_run" });
|
|
1074
|
+
}
|
|
1075
|
+
const parsed = parseCheckRunEvent({
|
|
1076
|
+
payload: input.payload,
|
|
1077
|
+
deliveryId: input.deliveryId,
|
|
1078
|
+
});
|
|
1079
|
+
if (parsed === null) {
|
|
1080
|
+
return Response.json({ ok: false, error: "invalid_check_run_payload" }, { status: 400 });
|
|
1081
|
+
}
|
|
1082
|
+
const installationId = readInstallationId(input.payload) ?? parsed.unanchoredCtx.installationId;
|
|
1083
|
+
if (parsed.ctx === null) {
|
|
1084
|
+
const dispatch = await input.options.onCheckRun(enrichCiContext({
|
|
986
1085
|
bindingConfig: input.bindingConfig,
|
|
987
|
-
ctx: parsed.
|
|
1086
|
+
ctx: parsed.unanchoredCtx,
|
|
988
1087
|
payload: input.payload,
|
|
989
|
-
bindingState: binding,
|
|
990
1088
|
installationId,
|
|
991
1089
|
host: input.args.host,
|
|
992
1090
|
artifacts: input.args.artifacts,
|
|
993
1091
|
send: input.args.send,
|
|
994
|
-
});
|
|
995
|
-
|
|
996
|
-
if (dispatch === null) {
|
|
997
|
-
return skipped("not_dispatched", { action: parsed.checkRun.action });
|
|
998
|
-
}
|
|
999
|
-
if (isTaskDispatch(dispatch)) {
|
|
1092
|
+
}), parsed.checkRun);
|
|
1093
|
+
if (dispatch !== null && isTaskDispatch(dispatch)) {
|
|
1000
1094
|
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1001
1095
|
event: "check_run",
|
|
1002
1096
|
action: parsed.checkRun.action,
|
|
1003
1097
|
checkRunId: parsed.checkRun.checkRunId,
|
|
1004
1098
|
});
|
|
1005
1099
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1100
|
+
return skipped("no_pull_request", { event: "check_run" });
|
|
1101
|
+
}
|
|
1102
|
+
const binding = githubBindingStateForEvent({
|
|
1103
|
+
kind: parsed.ctx.conversation.kind,
|
|
1104
|
+
owner: parsed.ctx.repository.owner,
|
|
1105
|
+
repo: parsed.ctx.repository.name,
|
|
1106
|
+
number: parsed.ctx.conversation.number,
|
|
1107
|
+
repositoryId: parsed.ctx.repository.id,
|
|
1108
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
1109
|
+
installationId,
|
|
1110
|
+
});
|
|
1111
|
+
const ctx = enrichEventContext({
|
|
1112
|
+
bindingConfig: input.bindingConfig,
|
|
1113
|
+
ctx: parsed.ctx,
|
|
1114
|
+
payload: input.payload,
|
|
1115
|
+
bindingState: binding,
|
|
1116
|
+
installationId,
|
|
1117
|
+
host: input.args.host,
|
|
1118
|
+
artifacts: input.args.artifacts,
|
|
1119
|
+
send: input.args.send,
|
|
1120
|
+
});
|
|
1121
|
+
const dispatch = await input.options.onCheckRun(ctx, parsed.checkRun);
|
|
1122
|
+
if (dispatch === null) {
|
|
1123
|
+
return skipped("not_dispatched", { action: parsed.checkRun.action });
|
|
1124
|
+
}
|
|
1125
|
+
if (isTaskDispatch(dispatch)) {
|
|
1126
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1127
|
+
event: "check_run",
|
|
1128
|
+
action: parsed.checkRun.action,
|
|
1129
|
+
checkRunId: parsed.checkRun.checkRunId,
|
|
1022
1130
|
});
|
|
1131
|
+
}
|
|
1132
|
+
const message = [
|
|
1133
|
+
dispatch.message ?? formatCiMessage("Check run", parsed.checkRun.checkRunId, parsed.checkRun),
|
|
1134
|
+
...(dispatch.context ?? []),
|
|
1135
|
+
].join("\n");
|
|
1136
|
+
return startTurn({
|
|
1137
|
+
options: input.options,
|
|
1138
|
+
args: input.args,
|
|
1139
|
+
ctx,
|
|
1140
|
+
message,
|
|
1141
|
+
dispatch,
|
|
1142
|
+
state: sessionStateFromBinding({
|
|
1143
|
+
binding,
|
|
1144
|
+
deliveryId: ctx.deliveryId,
|
|
1145
|
+
eventName: ctx.eventName,
|
|
1146
|
+
headSha: parsed.checkRun.headSha,
|
|
1147
|
+
}),
|
|
1023
1148
|
});
|
|
1024
1149
|
}
|
|
1025
|
-
function handleWorkflowRun(input) {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
});
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
const
|
|
1039
|
-
if (parsed.ctx === null) {
|
|
1040
|
-
const dispatch = yield input.options.onWorkflowRun(enrichCiContext({
|
|
1041
|
-
bindingConfig: input.bindingConfig,
|
|
1042
|
-
ctx: parsed.unanchoredCtx,
|
|
1043
|
-
payload: input.payload,
|
|
1044
|
-
installationId,
|
|
1045
|
-
host: input.args.host,
|
|
1046
|
-
artifacts: input.args.artifacts,
|
|
1047
|
-
send: input.args.send,
|
|
1048
|
-
}), parsed.workflowRun);
|
|
1049
|
-
if (dispatch !== null && isTaskDispatch(dispatch)) {
|
|
1050
|
-
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1051
|
-
event: "workflow_run",
|
|
1052
|
-
action: parsed.workflowRun.action,
|
|
1053
|
-
workflowRunId: parsed.workflowRun.workflowRunId,
|
|
1054
|
-
});
|
|
1055
|
-
}
|
|
1056
|
-
return skipped("no_pull_request", { event: "workflow_run" });
|
|
1057
|
-
}
|
|
1058
|
-
const binding = githubBindingStateForEvent({
|
|
1059
|
-
kind: parsed.ctx.conversation.kind,
|
|
1060
|
-
owner: parsed.ctx.repository.owner,
|
|
1061
|
-
repo: parsed.ctx.repository.name,
|
|
1062
|
-
number: parsed.ctx.conversation.number,
|
|
1063
|
-
repositoryId: parsed.ctx.repository.id,
|
|
1064
|
-
repositoryUrl: parsed.ctx.repository.url,
|
|
1065
|
-
installationId,
|
|
1066
|
-
});
|
|
1067
|
-
const ctx = enrichEventContext({
|
|
1150
|
+
async function handleWorkflowRun(input) {
|
|
1151
|
+
if (input.options.onWorkflowRun === undefined) {
|
|
1152
|
+
return skipped("no_handler", { event: "workflow_run" });
|
|
1153
|
+
}
|
|
1154
|
+
const parsed = parseWorkflowRunEvent({
|
|
1155
|
+
payload: input.payload,
|
|
1156
|
+
deliveryId: input.deliveryId,
|
|
1157
|
+
});
|
|
1158
|
+
if (parsed === null) {
|
|
1159
|
+
return Response.json({ ok: false, error: "invalid_workflow_run_payload" }, { status: 400 });
|
|
1160
|
+
}
|
|
1161
|
+
const installationId = readInstallationId(input.payload) ?? parsed.unanchoredCtx.installationId;
|
|
1162
|
+
if (parsed.ctx === null) {
|
|
1163
|
+
const dispatch = await input.options.onWorkflowRun(enrichCiContext({
|
|
1068
1164
|
bindingConfig: input.bindingConfig,
|
|
1069
|
-
ctx: parsed.
|
|
1165
|
+
ctx: parsed.unanchoredCtx,
|
|
1070
1166
|
payload: input.payload,
|
|
1071
|
-
bindingState: binding,
|
|
1072
1167
|
installationId,
|
|
1073
1168
|
host: input.args.host,
|
|
1074
1169
|
artifacts: input.args.artifacts,
|
|
1075
1170
|
send: input.args.send,
|
|
1076
|
-
});
|
|
1077
|
-
|
|
1078
|
-
if (dispatch === null) {
|
|
1079
|
-
return skipped("not_dispatched", { action: parsed.workflowRun.action });
|
|
1080
|
-
}
|
|
1081
|
-
if (isTaskDispatch(dispatch)) {
|
|
1171
|
+
}), parsed.workflowRun);
|
|
1172
|
+
if (dispatch !== null && isTaskDispatch(dispatch)) {
|
|
1082
1173
|
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1083
1174
|
event: "workflow_run",
|
|
1084
1175
|
action: parsed.workflowRun.action,
|
|
1085
1176
|
workflowRunId: parsed.workflowRun.workflowRunId,
|
|
1086
1177
|
});
|
|
1087
1178
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1179
|
+
return skipped("no_pull_request", { event: "workflow_run" });
|
|
1180
|
+
}
|
|
1181
|
+
const binding = githubBindingStateForEvent({
|
|
1182
|
+
kind: parsed.ctx.conversation.kind,
|
|
1183
|
+
owner: parsed.ctx.repository.owner,
|
|
1184
|
+
repo: parsed.ctx.repository.name,
|
|
1185
|
+
number: parsed.ctx.conversation.number,
|
|
1186
|
+
repositoryId: parsed.ctx.repository.id,
|
|
1187
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
1188
|
+
installationId,
|
|
1189
|
+
});
|
|
1190
|
+
const ctx = enrichEventContext({
|
|
1191
|
+
bindingConfig: input.bindingConfig,
|
|
1192
|
+
ctx: parsed.ctx,
|
|
1193
|
+
payload: input.payload,
|
|
1194
|
+
bindingState: binding,
|
|
1195
|
+
installationId,
|
|
1196
|
+
host: input.args.host,
|
|
1197
|
+
artifacts: input.args.artifacts,
|
|
1198
|
+
send: input.args.send,
|
|
1199
|
+
});
|
|
1200
|
+
const dispatch = await input.options.onWorkflowRun(ctx, parsed.workflowRun);
|
|
1201
|
+
if (dispatch === null) {
|
|
1202
|
+
return skipped("not_dispatched", { action: parsed.workflowRun.action });
|
|
1203
|
+
}
|
|
1204
|
+
if (isTaskDispatch(dispatch)) {
|
|
1205
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1206
|
+
event: "workflow_run",
|
|
1207
|
+
action: parsed.workflowRun.action,
|
|
1208
|
+
workflowRunId: parsed.workflowRun.workflowRunId,
|
|
1104
1209
|
});
|
|
1210
|
+
}
|
|
1211
|
+
const message = [
|
|
1212
|
+
dispatch.message ??
|
|
1213
|
+
formatCiMessage("Workflow run", parsed.workflowRun.workflowRunId, parsed.workflowRun),
|
|
1214
|
+
...(dispatch.context ?? []),
|
|
1215
|
+
].join("\n");
|
|
1216
|
+
return startTurn({
|
|
1217
|
+
options: input.options,
|
|
1218
|
+
args: input.args,
|
|
1219
|
+
ctx,
|
|
1220
|
+
message,
|
|
1221
|
+
dispatch,
|
|
1222
|
+
state: sessionStateFromBinding({
|
|
1223
|
+
binding,
|
|
1224
|
+
deliveryId: ctx.deliveryId,
|
|
1225
|
+
eventName: ctx.eventName,
|
|
1226
|
+
headSha: parsed.workflowRun.headSha,
|
|
1227
|
+
}),
|
|
1105
1228
|
});
|
|
1106
1229
|
}
|
|
1107
|
-
function handleStatus(input) {
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
});
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1230
|
+
async function handleStatus(input) {
|
|
1231
|
+
if (input.options.onStatus === undefined) {
|
|
1232
|
+
return skipped("no_handler", { event: "status" });
|
|
1233
|
+
}
|
|
1234
|
+
const parsed = parseStatusEvent({
|
|
1235
|
+
payload: input.payload,
|
|
1236
|
+
deliveryId: input.deliveryId,
|
|
1237
|
+
});
|
|
1238
|
+
if (parsed === null) {
|
|
1239
|
+
return Response.json({ ok: false, error: "invalid_status_payload" }, { status: 400 });
|
|
1240
|
+
}
|
|
1241
|
+
const installationId = readInstallationId(input.payload) ?? parsed.ctx.installationId;
|
|
1242
|
+
const binding = githubBindingStateForEvent({
|
|
1243
|
+
kind: parsed.ctx.conversation.kind,
|
|
1244
|
+
owner: parsed.ctx.repository.owner,
|
|
1245
|
+
repo: parsed.ctx.repository.name,
|
|
1246
|
+
number: parsed.ctx.conversation.number,
|
|
1247
|
+
repositoryId: parsed.ctx.repository.id,
|
|
1248
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
1249
|
+
installationId,
|
|
1250
|
+
});
|
|
1251
|
+
const ctx = enrichEventContext({
|
|
1252
|
+
bindingConfig: input.bindingConfig,
|
|
1253
|
+
ctx: parsed.ctx,
|
|
1254
|
+
payload: input.payload,
|
|
1255
|
+
bindingState: binding,
|
|
1256
|
+
installationId,
|
|
1257
|
+
host: input.args.host,
|
|
1258
|
+
artifacts: input.args.artifacts,
|
|
1259
|
+
send: input.args.send,
|
|
1260
|
+
});
|
|
1261
|
+
const dispatch = await input.options.onStatus(ctx, parsed.status);
|
|
1262
|
+
if (dispatch === null) {
|
|
1263
|
+
return skipped("not_dispatched", {
|
|
1264
|
+
event: "status",
|
|
1265
|
+
state: parsed.status.state,
|
|
1139
1266
|
});
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
}
|
|
1147
|
-
if (isTaskDispatch(dispatch)) {
|
|
1148
|
-
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1149
|
-
event: "status",
|
|
1150
|
-
state: parsed.status.state,
|
|
1151
|
-
sha: parsed.status.sha,
|
|
1152
|
-
});
|
|
1153
|
-
}
|
|
1154
|
-
// A turn needs a thread to anchor to; commit statuses often have no PR.
|
|
1155
|
-
if (ctx.conversation.number === 0) {
|
|
1156
|
-
return skipped("no_pull_request", { event: "status" });
|
|
1157
|
-
}
|
|
1158
|
-
const message = [
|
|
1159
|
-
(_b = dispatch.message) !== null && _b !== void 0 ? _b : `Commit status ${parsed.status.state} for ${parsed.status.context} at ${parsed.status.sha}`,
|
|
1160
|
-
...((_c = dispatch.context) !== null && _c !== void 0 ? _c : []),
|
|
1161
|
-
].join("\n");
|
|
1162
|
-
return startTurn({
|
|
1163
|
-
options: input.options,
|
|
1164
|
-
args: input.args,
|
|
1165
|
-
ctx,
|
|
1166
|
-
message,
|
|
1167
|
-
dispatch,
|
|
1168
|
-
state: sessionStateFromBinding({
|
|
1169
|
-
binding,
|
|
1170
|
-
deliveryId: ctx.deliveryId,
|
|
1171
|
-
eventName: ctx.eventName,
|
|
1172
|
-
headSha: parsed.status.sha,
|
|
1173
|
-
}),
|
|
1267
|
+
}
|
|
1268
|
+
if (isTaskDispatch(dispatch)) {
|
|
1269
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1270
|
+
event: "status",
|
|
1271
|
+
state: parsed.status.state,
|
|
1272
|
+
sha: parsed.status.sha,
|
|
1174
1273
|
});
|
|
1274
|
+
}
|
|
1275
|
+
// A turn needs a thread to anchor to; commit statuses often have no PR.
|
|
1276
|
+
if (ctx.conversation.number === 0) {
|
|
1277
|
+
return skipped("no_pull_request", { event: "status" });
|
|
1278
|
+
}
|
|
1279
|
+
const message = [
|
|
1280
|
+
dispatch.message ??
|
|
1281
|
+
`Commit status ${parsed.status.state} for ${parsed.status.context} at ${parsed.status.sha}`,
|
|
1282
|
+
...(dispatch.context ?? []),
|
|
1283
|
+
].join("\n");
|
|
1284
|
+
return startTurn({
|
|
1285
|
+
options: input.options,
|
|
1286
|
+
args: input.args,
|
|
1287
|
+
ctx,
|
|
1288
|
+
message,
|
|
1289
|
+
dispatch,
|
|
1290
|
+
state: sessionStateFromBinding({
|
|
1291
|
+
binding,
|
|
1292
|
+
deliveryId: ctx.deliveryId,
|
|
1293
|
+
eventName: ctx.eventName,
|
|
1294
|
+
headSha: parsed.status.sha,
|
|
1295
|
+
}),
|
|
1175
1296
|
});
|
|
1176
1297
|
}
|
|
1177
|
-
function handleGenericEvent(input) {
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
});
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
}
|
|
1218
|
-
if (ctx.conversation.number === 0) {
|
|
1219
|
-
return skipped("no_conversation", { event: input.eventName });
|
|
1220
|
-
}
|
|
1221
|
-
const message = [
|
|
1222
|
-
(_b = dispatch.message) !== null && _b !== void 0 ? _b : `GitHub ${input.eventName} event`,
|
|
1223
|
-
...((_c = dispatch.context) !== null && _c !== void 0 ? _c : []),
|
|
1224
|
-
].join("\n");
|
|
1225
|
-
return startTurn({
|
|
1226
|
-
options: input.options,
|
|
1227
|
-
args: input.args,
|
|
1228
|
-
ctx,
|
|
1229
|
-
message,
|
|
1230
|
-
dispatch,
|
|
1231
|
-
state: sessionStateFromBinding({
|
|
1232
|
-
binding,
|
|
1233
|
-
deliveryId: ctx.deliveryId,
|
|
1234
|
-
eventName: ctx.eventName,
|
|
1235
|
-
}),
|
|
1298
|
+
async function handleGenericEvent(input) {
|
|
1299
|
+
if (input.options.onEvent === undefined) {
|
|
1300
|
+
return skipped("no_handler", { event: input.eventName });
|
|
1301
|
+
}
|
|
1302
|
+
const parsed = parseGenericEvent({
|
|
1303
|
+
eventName: input.eventName,
|
|
1304
|
+
payload: input.payload,
|
|
1305
|
+
deliveryId: input.deliveryId,
|
|
1306
|
+
});
|
|
1307
|
+
if (parsed === null) {
|
|
1308
|
+
return skipped("unsupported_event", { event: input.eventName });
|
|
1309
|
+
}
|
|
1310
|
+
const installationId = readInstallationId(input.payload) ?? parsed.ctx.installationId;
|
|
1311
|
+
const binding = githubBindingStateForEvent({
|
|
1312
|
+
kind: parsed.ctx.conversation.kind,
|
|
1313
|
+
owner: parsed.ctx.repository.owner,
|
|
1314
|
+
repo: parsed.ctx.repository.name,
|
|
1315
|
+
number: parsed.ctx.conversation.number,
|
|
1316
|
+
repositoryId: parsed.ctx.repository.id,
|
|
1317
|
+
repositoryUrl: parsed.ctx.repository.url,
|
|
1318
|
+
installationId,
|
|
1319
|
+
});
|
|
1320
|
+
const ctx = enrichEventContext({
|
|
1321
|
+
bindingConfig: input.bindingConfig,
|
|
1322
|
+
ctx: parsed.ctx,
|
|
1323
|
+
payload: input.payload,
|
|
1324
|
+
bindingState: binding,
|
|
1325
|
+
installationId,
|
|
1326
|
+
host: input.args.host,
|
|
1327
|
+
artifacts: input.args.artifacts,
|
|
1328
|
+
send: input.args.send,
|
|
1329
|
+
});
|
|
1330
|
+
const dispatch = await input.options.onEvent(ctx, parsed.event);
|
|
1331
|
+
if (dispatch === null) {
|
|
1332
|
+
return skipped("not_dispatched", { event: input.eventName });
|
|
1333
|
+
}
|
|
1334
|
+
if (isTaskDispatch(dispatch)) {
|
|
1335
|
+
return acknowledgeTask(input.args, GITHUB_CHANNEL_KIND, dispatch, {
|
|
1336
|
+
event: input.eventName,
|
|
1337
|
+
...(parsed.event.action === undefined ? {} : { action: parsed.event.action }),
|
|
1236
1338
|
});
|
|
1339
|
+
}
|
|
1340
|
+
if (ctx.conversation.number === 0) {
|
|
1341
|
+
return skipped("no_conversation", { event: input.eventName });
|
|
1342
|
+
}
|
|
1343
|
+
const message = [
|
|
1344
|
+
dispatch.message ?? `GitHub ${input.eventName} event`,
|
|
1345
|
+
...(dispatch.context ?? []),
|
|
1346
|
+
].join("\n");
|
|
1347
|
+
return startTurn({
|
|
1348
|
+
options: input.options,
|
|
1349
|
+
args: input.args,
|
|
1350
|
+
ctx,
|
|
1351
|
+
message,
|
|
1352
|
+
dispatch,
|
|
1353
|
+
state: sessionStateFromBinding({
|
|
1354
|
+
binding,
|
|
1355
|
+
deliveryId: ctx.deliveryId,
|
|
1356
|
+
eventName: ctx.eventName,
|
|
1357
|
+
}),
|
|
1237
1358
|
});
|
|
1238
1359
|
}
|
|
1239
|
-
function startTurn(input) {
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
const
|
|
1246
|
-
const
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1360
|
+
async function startTurn(input) {
|
|
1361
|
+
const files = input.dispatch.workspaceFiles;
|
|
1362
|
+
const lazy = typeof files === "function";
|
|
1363
|
+
const cloud = input.dispatch.cloud ?? input.cloud;
|
|
1364
|
+
const state = { ...input.dispatch.state, ...input.state };
|
|
1365
|
+
const sendTurn = async () => {
|
|
1366
|
+
const workspaceFiles = lazy ? await files() : files;
|
|
1367
|
+
const source = continuationSource(input.options.continuation, "github");
|
|
1368
|
+
return input.args.send(input.message, {
|
|
1369
|
+
auth: input.dispatch.auth,
|
|
1370
|
+
...(source === "engine" ? { continuationToken: githubContinuationKey(input.ctx) } : {}),
|
|
1371
|
+
title: input.dispatch.title ?? defaultGitHubTitle(input.ctx),
|
|
1372
|
+
cloud,
|
|
1373
|
+
...(workspaceFiles === undefined ? {} : { workspaceFiles }),
|
|
1374
|
+
state: state,
|
|
1375
|
+
// Resume must refresh headSha / refs without wiping sticky banner id.
|
|
1376
|
+
refreshState: state,
|
|
1253
1377
|
});
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1378
|
+
};
|
|
1379
|
+
if (lazy) {
|
|
1380
|
+
scheduleAfterAck(input.args, GITHUB_CHANNEL_KIND, async () => {
|
|
1381
|
+
await sendTurn();
|
|
1382
|
+
});
|
|
1383
|
+
return acknowledgeTurn();
|
|
1384
|
+
}
|
|
1385
|
+
return turnStarted(await sendTurn());
|
|
1262
1386
|
}
|
|
1263
1387
|
function formatCiMessage(label, id, event) {
|
|
1264
|
-
|
|
1265
|
-
const outcome = (_a = event.conclusion) !== null && _a !== void 0 ? _a : event.status;
|
|
1388
|
+
const outcome = event.conclusion ?? event.status;
|
|
1266
1389
|
return `${label} ${event.action}: ${id}${outcome ? ` (${outcome})` : ""}`;
|
|
1267
1390
|
}
|
|
1268
1391
|
function isIgnoredInboundComment(body, author, botName) {
|
|
@@ -1276,11 +1399,11 @@ function isIgnoredInboundComment(body, author, botName) {
|
|
|
1276
1399
|
}
|
|
1277
1400
|
/** Match GitHub App bot actors (`slug` config vs `slug[bot]` login). */
|
|
1278
1401
|
export function isGitHubAppBotAuthor(author, botName) {
|
|
1279
|
-
const normalizedBot = botName
|
|
1402
|
+
const normalizedBot = botName?.trim();
|
|
1280
1403
|
if (normalizedBot === undefined || normalizedBot === "") {
|
|
1281
1404
|
return false;
|
|
1282
1405
|
}
|
|
1283
|
-
if (
|
|
1406
|
+
if (author?.type !== "Bot") {
|
|
1284
1407
|
return false;
|
|
1285
1408
|
}
|
|
1286
1409
|
const login = author.login;
|
|
@@ -1289,8 +1412,6 @@ export function isGitHubAppBotAuthor(author, botName) {
|
|
|
1289
1412
|
stripBotSuffix(login) === stripBotSuffix(normalizedBot));
|
|
1290
1413
|
}
|
|
1291
1414
|
function parseIssueCommentEvent(args) {
|
|
1292
|
-
var _a;
|
|
1293
|
-
var _b;
|
|
1294
1415
|
const schema = z.object({
|
|
1295
1416
|
action: z.string().min(1),
|
|
1296
1417
|
repository: repositorySchema,
|
|
@@ -1324,18 +1445,29 @@ function parseIssueCommentEvent(args) {
|
|
|
1324
1445
|
const repository = toRepositoryRef(payload.repository);
|
|
1325
1446
|
const sender = toUser(payload.sender);
|
|
1326
1447
|
const author = toUser(payload.comment.user);
|
|
1327
|
-
const installationId =
|
|
1328
|
-
const ctx =
|
|
1448
|
+
const installationId = payload.installation?.id;
|
|
1449
|
+
const ctx = {
|
|
1450
|
+
...(args.deliveryId === undefined ? {} : { deliveryId: args.deliveryId }),
|
|
1451
|
+
eventName: "issue_comment",
|
|
1452
|
+
repository,
|
|
1453
|
+
conversation: {
|
|
1329
1454
|
kind,
|
|
1330
1455
|
number: payload.issue.number,
|
|
1331
1456
|
url: payload.issue.html_url,
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1457
|
+
},
|
|
1458
|
+
...(sender === undefined ? {} : { sender, senderLogin: sender.login }),
|
|
1459
|
+
...(installationId === undefined ? {} : { installationId }),
|
|
1460
|
+
};
|
|
1461
|
+
const comment = {
|
|
1462
|
+
id: payload.comment.id,
|
|
1463
|
+
body: payload.comment.body,
|
|
1464
|
+
htmlUrl: payload.comment.html_url,
|
|
1465
|
+
url: payload.comment.url ?? payload.comment.html_url,
|
|
1466
|
+
...(author === undefined ? {} : { author }),
|
|
1467
|
+
};
|
|
1334
1468
|
return { action: payload.action, ctx, comment };
|
|
1335
1469
|
}
|
|
1336
1470
|
function parseReviewCommentEvent(args) {
|
|
1337
|
-
var _a, _b, _c, _d;
|
|
1338
|
-
var _e;
|
|
1339
1471
|
const schema = z.object({
|
|
1340
1472
|
action: z.string().min(1),
|
|
1341
1473
|
repository: repositorySchema,
|
|
@@ -1382,28 +1514,44 @@ function parseReviewCommentEvent(args) {
|
|
|
1382
1514
|
const repository = toRepositoryRef(payload.repository);
|
|
1383
1515
|
const sender = toUser(payload.sender);
|
|
1384
1516
|
const author = toUser(payload.comment.user);
|
|
1385
|
-
const installationId =
|
|
1386
|
-
const ctx =
|
|
1517
|
+
const installationId = payload.installation?.id;
|
|
1518
|
+
const ctx = {
|
|
1519
|
+
...(args.deliveryId === undefined ? {} : { deliveryId: args.deliveryId }),
|
|
1520
|
+
eventName: "pull_request_review_comment",
|
|
1521
|
+
repository,
|
|
1522
|
+
conversation: {
|
|
1387
1523
|
kind: "review_thread",
|
|
1388
1524
|
number: payload.pull_request.number,
|
|
1389
1525
|
url: payload.pull_request.html_url,
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
? {}
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
:
|
|
1526
|
+
},
|
|
1527
|
+
...(sender === undefined ? {} : { sender, senderLogin: sender.login }),
|
|
1528
|
+
...(installationId === undefined ? {} : { installationId }),
|
|
1529
|
+
};
|
|
1530
|
+
const comment = {
|
|
1531
|
+
id: payload.comment.id,
|
|
1532
|
+
body: payload.comment.body,
|
|
1533
|
+
htmlUrl: payload.comment.html_url,
|
|
1534
|
+
url: payload.comment.url ?? payload.comment.html_url,
|
|
1535
|
+
...(author === undefined ? {} : { author }),
|
|
1536
|
+
...(payload.comment.path === undefined ? {} : { path: payload.comment.path }),
|
|
1537
|
+
...(payload.comment.line === undefined ? {} : { line: payload.comment.line }),
|
|
1538
|
+
...(payload.comment.pull_request_review_id === undefined
|
|
1539
|
+
? {}
|
|
1540
|
+
: { pullRequestReviewId: payload.comment.pull_request_review_id }),
|
|
1541
|
+
...(payload.comment.in_reply_to_id === undefined
|
|
1542
|
+
? {}
|
|
1543
|
+
: { inReplyToId: payload.comment.in_reply_to_id }),
|
|
1544
|
+
};
|
|
1396
1545
|
return {
|
|
1397
1546
|
action: payload.action,
|
|
1398
1547
|
ctx,
|
|
1399
1548
|
comment,
|
|
1400
|
-
headSha:
|
|
1401
|
-
headRef:
|
|
1402
|
-
baseRef:
|
|
1549
|
+
headSha: payload.pull_request.head?.sha,
|
|
1550
|
+
headRef: payload.pull_request.head?.ref,
|
|
1551
|
+
baseRef: payload.pull_request.base?.ref,
|
|
1403
1552
|
};
|
|
1404
1553
|
}
|
|
1405
1554
|
function parseIssueEvent(args) {
|
|
1406
|
-
var _a, _b;
|
|
1407
1555
|
const schema = z.object({
|
|
1408
1556
|
action: z.string().min(1),
|
|
1409
1557
|
repository: repositorySchema,
|
|
@@ -1428,20 +1576,32 @@ function parseIssueEvent(args) {
|
|
|
1428
1576
|
const payload = parsed.data;
|
|
1429
1577
|
const repository = toRepositoryRef(payload.repository);
|
|
1430
1578
|
const sender = toUser(payload.sender);
|
|
1431
|
-
const installationId =
|
|
1432
|
-
const ctx =
|
|
1579
|
+
const installationId = payload.installation?.id;
|
|
1580
|
+
const ctx = {
|
|
1581
|
+
...(args.deliveryId === undefined ? {} : { deliveryId: args.deliveryId }),
|
|
1582
|
+
eventName: "issues",
|
|
1583
|
+
repository,
|
|
1584
|
+
conversation: {
|
|
1433
1585
|
kind: "issue",
|
|
1434
1586
|
number: payload.issue.number,
|
|
1435
1587
|
url: payload.issue.html_url,
|
|
1436
|
-
}
|
|
1437
|
-
|
|
1438
|
-
? {}
|
|
1439
|
-
|
|
1588
|
+
},
|
|
1589
|
+
...(sender === undefined ? {} : { sender, senderLogin: sender.login }),
|
|
1590
|
+
...(installationId === undefined ? {} : { installationId }),
|
|
1591
|
+
};
|
|
1592
|
+
const issue = {
|
|
1593
|
+
action: payload.action,
|
|
1594
|
+
number: payload.issue.number,
|
|
1595
|
+
url: payload.issue.html_url,
|
|
1596
|
+
title: payload.issue.title,
|
|
1597
|
+
...(payload.issue.body === undefined || payload.issue.body === null
|
|
1598
|
+
? {}
|
|
1599
|
+
: { body: payload.issue.body }),
|
|
1600
|
+
...(payload.issue.user?.login === undefined ? {} : { authorLogin: payload.issue.user.login }),
|
|
1601
|
+
};
|
|
1440
1602
|
return { ctx, issue };
|
|
1441
1603
|
}
|
|
1442
1604
|
function parseCheckSuiteEvent(args) {
|
|
1443
|
-
var _a;
|
|
1444
|
-
var _b, _c;
|
|
1445
1605
|
const schema = z.object({
|
|
1446
1606
|
action: z.string().min(1),
|
|
1447
1607
|
repository: repositorySchema,
|
|
@@ -1474,9 +1634,17 @@ function parseCheckSuiteEvent(args) {
|
|
|
1474
1634
|
const payload = parsed.data;
|
|
1475
1635
|
const repository = toRepositoryRef(payload.repository);
|
|
1476
1636
|
const sender = toUser(payload.sender);
|
|
1477
|
-
const installationId =
|
|
1637
|
+
const installationId = payload.installation?.id;
|
|
1478
1638
|
const pullRequests = toCiPullRequests(payload.check_suite.pull_requests);
|
|
1479
|
-
const checkSuite =
|
|
1639
|
+
const checkSuite = {
|
|
1640
|
+
action: payload.action,
|
|
1641
|
+
checkSuiteId: payload.check_suite.id,
|
|
1642
|
+
headSha: payload.check_suite.head_sha,
|
|
1643
|
+
...(payload.check_suite.status === undefined ? {} : { status: payload.check_suite.status }),
|
|
1644
|
+
conclusion: (payload.check_suite.conclusion ?? null),
|
|
1645
|
+
app: toCiApp(payload.check_suite.app),
|
|
1646
|
+
pullRequests,
|
|
1647
|
+
};
|
|
1480
1648
|
const unanchoredCtx = unanchoredEventContext({
|
|
1481
1649
|
deliveryId: args.deliveryId,
|
|
1482
1650
|
eventName: "check_suite",
|
|
@@ -1489,18 +1657,19 @@ function parseCheckSuiteEvent(args) {
|
|
|
1489
1657
|
return { ctx: null, unanchoredCtx, checkSuite };
|
|
1490
1658
|
}
|
|
1491
1659
|
return {
|
|
1492
|
-
ctx:
|
|
1660
|
+
ctx: {
|
|
1661
|
+
...unanchoredCtx,
|
|
1662
|
+
conversation: {
|
|
1493
1663
|
kind: "pull_request",
|
|
1494
1664
|
number: first.number,
|
|
1495
|
-
url:
|
|
1496
|
-
}
|
|
1665
|
+
url: first.url ?? `${repository.url}/pull/${first.number}`,
|
|
1666
|
+
},
|
|
1667
|
+
},
|
|
1497
1668
|
unanchoredCtx,
|
|
1498
1669
|
checkSuite,
|
|
1499
1670
|
};
|
|
1500
1671
|
}
|
|
1501
1672
|
function parseCheckRunEvent(args) {
|
|
1502
|
-
var _a, _b;
|
|
1503
|
-
var _c, _d;
|
|
1504
1673
|
const schema = z.object({
|
|
1505
1674
|
action: z.string().min(1),
|
|
1506
1675
|
repository: repositorySchema,
|
|
@@ -1540,11 +1709,21 @@ function parseCheckRunEvent(args) {
|
|
|
1540
1709
|
const payload = parsed.data;
|
|
1541
1710
|
const repository = toRepositoryRef(payload.repository);
|
|
1542
1711
|
const sender = toUser(payload.sender);
|
|
1543
|
-
const installationId =
|
|
1712
|
+
const installationId = payload.installation?.id;
|
|
1544
1713
|
const pullRequests = toCiPullRequests(payload.check_run.pull_requests);
|
|
1545
|
-
const checkRun =
|
|
1546
|
-
|
|
1547
|
-
:
|
|
1714
|
+
const checkRun = {
|
|
1715
|
+
action: payload.action,
|
|
1716
|
+
checkRunId: payload.check_run.id,
|
|
1717
|
+
headSha: payload.check_run.head_sha,
|
|
1718
|
+
...(payload.check_run.name === undefined ? {} : { name: payload.check_run.name }),
|
|
1719
|
+
...(payload.check_run.check_suite?.id === undefined
|
|
1720
|
+
? {}
|
|
1721
|
+
: { checkSuiteId: payload.check_run.check_suite.id }),
|
|
1722
|
+
...(payload.check_run.status === undefined ? {} : { status: payload.check_run.status }),
|
|
1723
|
+
conclusion: (payload.check_run.conclusion ?? null),
|
|
1724
|
+
app: toCiApp(payload.check_run.app),
|
|
1725
|
+
pullRequests,
|
|
1726
|
+
};
|
|
1548
1727
|
const unanchoredCtx = unanchoredEventContext({
|
|
1549
1728
|
deliveryId: args.deliveryId,
|
|
1550
1729
|
eventName: "check_run",
|
|
@@ -1557,18 +1736,19 @@ function parseCheckRunEvent(args) {
|
|
|
1557
1736
|
return { ctx: null, unanchoredCtx, checkRun };
|
|
1558
1737
|
}
|
|
1559
1738
|
return {
|
|
1560
|
-
ctx:
|
|
1739
|
+
ctx: {
|
|
1740
|
+
...unanchoredCtx,
|
|
1741
|
+
conversation: {
|
|
1561
1742
|
kind: "pull_request",
|
|
1562
1743
|
number: first.number,
|
|
1563
|
-
url:
|
|
1564
|
-
}
|
|
1744
|
+
url: first.url ?? `${repository.url}/pull/${first.number}`,
|
|
1745
|
+
},
|
|
1746
|
+
},
|
|
1565
1747
|
unanchoredCtx,
|
|
1566
1748
|
checkRun,
|
|
1567
1749
|
};
|
|
1568
1750
|
}
|
|
1569
1751
|
function parseWorkflowRunEvent(args) {
|
|
1570
|
-
var _a;
|
|
1571
|
-
var _b, _c;
|
|
1572
1752
|
const schema = z.object({
|
|
1573
1753
|
action: z.string().min(1),
|
|
1574
1754
|
repository: repositorySchema,
|
|
@@ -1597,17 +1777,27 @@ function parseWorkflowRunEvent(args) {
|
|
|
1597
1777
|
const payload = parsed.data;
|
|
1598
1778
|
const repository = toRepositoryRef(payload.repository);
|
|
1599
1779
|
const sender = toUser(payload.sender);
|
|
1600
|
-
const installationId =
|
|
1780
|
+
const installationId = payload.installation?.id;
|
|
1601
1781
|
const pullRequests = toCiPullRequests(payload.workflow_run.pull_requests);
|
|
1602
|
-
const workflowRun =
|
|
1603
|
-
|
|
1604
|
-
:
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1782
|
+
const workflowRun = {
|
|
1783
|
+
action: payload.action,
|
|
1784
|
+
workflowRunId: payload.workflow_run.id,
|
|
1785
|
+
headSha: payload.workflow_run.head_sha,
|
|
1786
|
+
...(payload.workflow_run.name === undefined || payload.workflow_run.name === null
|
|
1787
|
+
? {}
|
|
1788
|
+
: { name: payload.workflow_run.name }),
|
|
1789
|
+
...(payload.workflow_run.workflow_id === undefined
|
|
1790
|
+
? {}
|
|
1791
|
+
: { workflowId: payload.workflow_run.workflow_id }),
|
|
1792
|
+
...(payload.workflow_run.html_url === undefined
|
|
1793
|
+
? {}
|
|
1794
|
+
: { htmlUrl: payload.workflow_run.html_url }),
|
|
1795
|
+
...(payload.workflow_run.status === undefined ? {} : { status: payload.workflow_run.status }),
|
|
1796
|
+
conclusion: (payload.workflow_run.conclusion ?? null),
|
|
1609
1797
|
// workflow_run is GitHub Actions-only (Eve semantics).
|
|
1610
|
-
app: { slug: "github-actions", name: "GitHub Actions" },
|
|
1798
|
+
app: { slug: "github-actions", name: "GitHub Actions" },
|
|
1799
|
+
pullRequests,
|
|
1800
|
+
};
|
|
1611
1801
|
const unanchoredCtx = unanchoredEventContext({
|
|
1612
1802
|
deliveryId: args.deliveryId,
|
|
1613
1803
|
eventName: "workflow_run",
|
|
@@ -1620,18 +1810,19 @@ function parseWorkflowRunEvent(args) {
|
|
|
1620
1810
|
return { ctx: null, unanchoredCtx, workflowRun };
|
|
1621
1811
|
}
|
|
1622
1812
|
return {
|
|
1623
|
-
ctx:
|
|
1813
|
+
ctx: {
|
|
1814
|
+
...unanchoredCtx,
|
|
1815
|
+
conversation: {
|
|
1624
1816
|
kind: "pull_request",
|
|
1625
1817
|
number: first.number,
|
|
1626
|
-
url:
|
|
1627
|
-
}
|
|
1818
|
+
url: first.url ?? `${repository.url}/pull/${first.number}`,
|
|
1819
|
+
},
|
|
1820
|
+
},
|
|
1628
1821
|
unanchoredCtx,
|
|
1629
1822
|
workflowRun,
|
|
1630
1823
|
};
|
|
1631
1824
|
}
|
|
1632
1825
|
function parseStatusEvent(args) {
|
|
1633
|
-
var _a;
|
|
1634
|
-
var _b, _c, _d, _e;
|
|
1635
1826
|
const schema = z.object({
|
|
1636
1827
|
state: z.string().min(1),
|
|
1637
1828
|
sha: z.string().min(1),
|
|
@@ -1668,24 +1859,45 @@ function parseStatusEvent(args) {
|
|
|
1668
1859
|
const payload = parsed.data;
|
|
1669
1860
|
const repository = toRepositoryRef(payload.repository);
|
|
1670
1861
|
const sender = toUser(payload.sender);
|
|
1671
|
-
const installationId =
|
|
1862
|
+
const installationId = payload.installation?.id;
|
|
1672
1863
|
const pullRequests = toCiPullRequests(payload.pull_requests);
|
|
1673
1864
|
const first = pullRequests[0];
|
|
1674
|
-
const status =
|
|
1675
|
-
|
|
1676
|
-
:
|
|
1677
|
-
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1865
|
+
const status = {
|
|
1866
|
+
state: payload.state,
|
|
1867
|
+
context: payload.context ?? "",
|
|
1868
|
+
...(payload.description === undefined ? {} : { description: payload.description }),
|
|
1869
|
+
...(payload.target_url === undefined ? {} : { targetUrl: payload.target_url }),
|
|
1870
|
+
sha: payload.sha,
|
|
1871
|
+
...(payload.name === undefined ? {} : { name: payload.name }),
|
|
1872
|
+
branches: (payload.branches ?? []).map(branch => ({
|
|
1873
|
+
name: branch.name,
|
|
1874
|
+
...(branch.commit === undefined ? {} : { commit: branch.commit }),
|
|
1875
|
+
})),
|
|
1876
|
+
...(payload.commit === undefined
|
|
1877
|
+
? {}
|
|
1878
|
+
: {
|
|
1879
|
+
commit: {
|
|
1880
|
+
...(payload.commit.sha === undefined ? {} : { sha: payload.commit.sha }),
|
|
1881
|
+
...(payload.commit.html_url === undefined ? {} : { htmlUrl: payload.commit.html_url }),
|
|
1882
|
+
},
|
|
1883
|
+
}),
|
|
1884
|
+
raw: args.payload,
|
|
1885
|
+
};
|
|
1886
|
+
const ctx = {
|
|
1887
|
+
...(args.deliveryId === undefined ? {} : { deliveryId: args.deliveryId }),
|
|
1888
|
+
eventName: "status",
|
|
1889
|
+
repository,
|
|
1890
|
+
conversation: {
|
|
1680
1891
|
kind: "pull_request",
|
|
1681
|
-
number:
|
|
1682
|
-
url:
|
|
1683
|
-
}
|
|
1892
|
+
number: first?.number ?? 0,
|
|
1893
|
+
url: first?.url ?? repository.url,
|
|
1894
|
+
},
|
|
1895
|
+
...(sender === undefined ? {} : { sender, senderLogin: sender.login }),
|
|
1896
|
+
...(installationId === undefined ? {} : { installationId }),
|
|
1897
|
+
};
|
|
1684
1898
|
return { ctx, status };
|
|
1685
1899
|
}
|
|
1686
1900
|
function parseGenericEvent(args) {
|
|
1687
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1688
|
-
var _g, _h, _j, _k;
|
|
1689
1901
|
const schema = z.object({
|
|
1690
1902
|
action: z.string().optional(),
|
|
1691
1903
|
repository: repositorySchema.optional(),
|
|
@@ -1715,45 +1927,78 @@ function parseGenericEvent(args) {
|
|
|
1715
1927
|
}
|
|
1716
1928
|
const repository = toRepositoryRef(payload.repository);
|
|
1717
1929
|
const sender = toUser(payload.sender);
|
|
1718
|
-
const installationId =
|
|
1719
|
-
const kind =
|
|
1930
|
+
const installationId = payload.installation?.id;
|
|
1931
|
+
const kind = payload.issue?.pull_request !== undefined
|
|
1720
1932
|
? "pull_request"
|
|
1721
1933
|
: payload.issue !== undefined
|
|
1722
1934
|
? "issue"
|
|
1723
1935
|
: "pull_request";
|
|
1724
|
-
const number =
|
|
1725
|
-
const url =
|
|
1726
|
-
const event =
|
|
1727
|
-
|
|
1936
|
+
const number = payload.issue?.number ?? payload.pull_request?.number ?? 0;
|
|
1937
|
+
const url = payload.issue?.html_url ?? payload.pull_request?.html_url ?? repository.url;
|
|
1938
|
+
const event = {
|
|
1939
|
+
eventName: args.eventName,
|
|
1940
|
+
...(args.deliveryId === undefined ? {} : { deliveryId: args.deliveryId }),
|
|
1941
|
+
...(payload.action === undefined ? {} : { action: payload.action }),
|
|
1942
|
+
payload: args.payload,
|
|
1943
|
+
};
|
|
1944
|
+
const ctx = {
|
|
1945
|
+
...(args.deliveryId === undefined ? {} : { deliveryId: args.deliveryId }),
|
|
1946
|
+
eventName: args.eventName,
|
|
1947
|
+
repository,
|
|
1948
|
+
conversation: { kind, number, url },
|
|
1949
|
+
...(sender === undefined ? {} : { sender, senderLogin: sender.login }),
|
|
1950
|
+
...(installationId === undefined ? {} : { installationId }),
|
|
1951
|
+
};
|
|
1728
1952
|
return { ctx, event };
|
|
1729
1953
|
}
|
|
1730
1954
|
function unanchoredEventContext(args) {
|
|
1731
|
-
return
|
|
1955
|
+
return {
|
|
1956
|
+
...(args.deliveryId === undefined ? {} : { deliveryId: args.deliveryId }),
|
|
1957
|
+
eventName: args.eventName,
|
|
1958
|
+
repository: args.repository,
|
|
1959
|
+
conversation: {
|
|
1732
1960
|
kind: "pull_request",
|
|
1733
1961
|
number: 0,
|
|
1734
1962
|
url: args.repository.url,
|
|
1735
|
-
}
|
|
1963
|
+
},
|
|
1964
|
+
...(args.sender === undefined ? {} : { sender: args.sender, senderLogin: args.sender.login }),
|
|
1965
|
+
...(args.installationId === undefined ? {} : { installationId: args.installationId }),
|
|
1966
|
+
};
|
|
1736
1967
|
}
|
|
1737
1968
|
function toRepositoryRef(repo) {
|
|
1738
|
-
var _a;
|
|
1739
|
-
var _b, _c, _d, _e;
|
|
1740
1969
|
const [ownerFromName, nameFromFull] = repo.full_name.split("/");
|
|
1741
|
-
return
|
|
1970
|
+
return {
|
|
1971
|
+
fullName: repo.full_name,
|
|
1972
|
+
url: repo.html_url,
|
|
1973
|
+
owner: repo.owner?.login ?? ownerFromName ?? "",
|
|
1974
|
+
name: repo.name ?? nameFromFull ?? repo.full_name,
|
|
1975
|
+
...(repo.id === undefined ? {} : { id: repo.id }),
|
|
1976
|
+
};
|
|
1742
1977
|
}
|
|
1743
1978
|
function toUser(raw) {
|
|
1744
|
-
if (
|
|
1979
|
+
if (raw?.login === undefined || raw.login === "")
|
|
1745
1980
|
return undefined;
|
|
1746
|
-
return
|
|
1981
|
+
return {
|
|
1982
|
+
login: raw.login,
|
|
1983
|
+
...(raw.id === undefined ? {} : { id: raw.id }),
|
|
1984
|
+
...(raw.type === undefined ? {} : { type: raw.type }),
|
|
1985
|
+
};
|
|
1747
1986
|
}
|
|
1748
1987
|
function toCiPullRequests(raw) {
|
|
1749
|
-
return (raw
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
? { url: pr.
|
|
1753
|
-
:
|
|
1988
|
+
return (raw ?? []).map(pr => ({
|
|
1989
|
+
number: pr.number,
|
|
1990
|
+
...(pr.html_url !== undefined
|
|
1991
|
+
? { url: pr.html_url }
|
|
1992
|
+
: pr.url !== undefined
|
|
1993
|
+
? { url: pr.url }
|
|
1994
|
+
: {}),
|
|
1995
|
+
}));
|
|
1754
1996
|
}
|
|
1755
1997
|
function toCiApp(raw) {
|
|
1756
|
-
return
|
|
1998
|
+
return {
|
|
1999
|
+
...(raw?.slug === undefined ? {} : { slug: raw.slug }),
|
|
2000
|
+
...(raw?.name === undefined ? {} : { name: raw.name }),
|
|
2001
|
+
};
|
|
1757
2002
|
}
|
|
1758
2003
|
function escapeRegExp(value) {
|
|
1759
2004
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -1767,8 +2012,16 @@ function enrichEventContext(input) {
|
|
|
1767
2012
|
config: input.bindingConfig,
|
|
1768
2013
|
state: input.bindingState,
|
|
1769
2014
|
});
|
|
1770
|
-
return
|
|
1771
|
-
|
|
2015
|
+
return {
|
|
2016
|
+
...input.ctx,
|
|
2017
|
+
payload: input.payload,
|
|
2018
|
+
...(input.installationId === undefined ? {} : { installationId: input.installationId }),
|
|
2019
|
+
github,
|
|
2020
|
+
thread,
|
|
2021
|
+
host: input.host,
|
|
2022
|
+
artifacts: input.artifacts,
|
|
2023
|
+
...(input.send === undefined ? {} : { send: input.send }),
|
|
2024
|
+
};
|
|
1772
2025
|
}
|
|
1773
2026
|
/**
|
|
1774
2027
|
* Enrich an unanchored CI context (`conversation.number === 0`). The binding
|
|
@@ -1784,45 +2037,62 @@ function enrichCiContext(input) {
|
|
|
1784
2037
|
repositoryUrl: input.ctx.repository.url,
|
|
1785
2038
|
installationId: input.installationId,
|
|
1786
2039
|
});
|
|
1787
|
-
return enrichEventContext(
|
|
2040
|
+
return enrichEventContext({
|
|
2041
|
+
bindingConfig: input.bindingConfig,
|
|
2042
|
+
ctx: input.ctx,
|
|
2043
|
+
bindingState: binding,
|
|
2044
|
+
installationId: input.installationId,
|
|
2045
|
+
payload: input.payload,
|
|
2046
|
+
host: input.host,
|
|
2047
|
+
artifacts: input.artifacts,
|
|
2048
|
+
...(input.send === undefined ? {} : { send: input.send }),
|
|
2049
|
+
});
|
|
1788
2050
|
}
|
|
1789
2051
|
/** Build the durable per-session channel state stored with the turn. */
|
|
1790
2052
|
function sessionStateFromBinding(input) {
|
|
1791
|
-
|
|
1792
|
-
|
|
2053
|
+
return emptyGitHubChannelState({
|
|
2054
|
+
...input.binding,
|
|
2055
|
+
deliveryId: input.deliveryId ?? null,
|
|
2056
|
+
eventName: input.eventName,
|
|
2057
|
+
headSha: input.headSha ?? null,
|
|
2058
|
+
baseRef: input.baseRef ?? null,
|
|
2059
|
+
headRef: input.headRef ?? null,
|
|
2060
|
+
});
|
|
1793
2061
|
}
|
|
1794
2062
|
/** Read `installation.id` from a raw webhook payload when present. */
|
|
1795
2063
|
function readInstallationId(payload) {
|
|
1796
2064
|
if (typeof payload !== "object" || payload === null)
|
|
1797
2065
|
return undefined;
|
|
1798
2066
|
const installation = payload.installation;
|
|
1799
|
-
return typeof
|
|
2067
|
+
return typeof installation?.id === "number" ? installation.id : undefined;
|
|
1800
2068
|
}
|
|
2069
|
+
/**
|
|
2070
|
+
* The omitted-`webhookSecret` fallback: a {@link SecretRef} naming
|
|
2071
|
+
* `GITHUB_WEBHOOK_SECRET`, present only while that env var is set at
|
|
2072
|
+
* channel construction. Named rather than read so the fallback keeps the
|
|
2073
|
+
* same route policy (and the same control-plane catch declaration) as an
|
|
2074
|
+
* authored `{ secretName: "GITHUB_WEBHOOK_SECRET" }`.
|
|
2075
|
+
*/
|
|
1801
2076
|
function envWebhookSecret() {
|
|
1802
|
-
|
|
2077
|
+
return envSecretRef(GITHUB_WEBHOOK_SECRET_ENV);
|
|
2078
|
+
}
|
|
2079
|
+
async function resolveCloudOptions(cloud, ctx, pullRequest) {
|
|
2080
|
+
if (cloud === undefined || cloud === false) {
|
|
1803
2081
|
return undefined;
|
|
1804
2082
|
}
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
],
|
|
1821
|
-
};
|
|
1822
|
-
}
|
|
1823
|
-
if (typeof cloud === "function") {
|
|
1824
|
-
return yield cloud(ctx, pullRequest);
|
|
1825
|
-
}
|
|
1826
|
-
return cloud;
|
|
1827
|
-
});
|
|
2083
|
+
if (cloud === true) {
|
|
2084
|
+
return {
|
|
2085
|
+
repos: [
|
|
2086
|
+
{
|
|
2087
|
+
url: ctx.repository.url,
|
|
2088
|
+
prUrl: pullRequest.url,
|
|
2089
|
+
startingRef: pullRequest.headSha,
|
|
2090
|
+
},
|
|
2091
|
+
],
|
|
2092
|
+
};
|
|
2093
|
+
}
|
|
2094
|
+
if (typeof cloud === "function") {
|
|
2095
|
+
return await cloud(ctx, pullRequest);
|
|
2096
|
+
}
|
|
2097
|
+
return cloud;
|
|
1828
2098
|
}
|