@cursor/bdk 0.2.24 → 0.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -0
- package/dist/bin/agent-serve.d.ts +1 -1
- package/dist/bin/agent-serve.js +48 -12
- package/dist/channels/bitbucket/bitbucket-webhook.d.ts +3 -2
- package/dist/channels/bitbucket/bitbucket-webhook.d.ts.map +1 -1
- package/dist/channels/bitbucket/bitbucket-webhook.js +14 -9
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +9 -18
- package/dist/channels/pagerduty/api.d.ts +74 -0
- package/dist/channels/pagerduty/api.d.ts.map +1 -0
- package/dist/channels/pagerduty/api.js +101 -0
- package/dist/channels/pagerduty/defaults.d.ts +42 -0
- package/dist/channels/pagerduty/defaults.d.ts.map +1 -0
- package/dist/channels/pagerduty/defaults.js +132 -0
- package/dist/channels/pagerduty/events.d.ts +24 -0
- package/dist/channels/pagerduty/events.d.ts.map +1 -0
- package/dist/channels/pagerduty/events.js +38 -0
- package/dist/channels/pagerduty/index.d.ts +31 -0
- package/dist/channels/pagerduty/index.d.ts.map +1 -0
- package/dist/channels/pagerduty/index.js +30 -0
- package/dist/channels/pagerduty/pagerduty-channel.d.ts +64 -0
- package/dist/channels/pagerduty/pagerduty-channel.d.ts.map +1 -0
- package/dist/channels/pagerduty/pagerduty-channel.js +195 -0
- package/dist/channels/pagerduty/pagerduty-webhook.d.ts +70 -0
- package/dist/channels/pagerduty/pagerduty-webhook.d.ts.map +1 -0
- package/dist/channels/pagerduty/pagerduty-webhook.js +280 -0
- package/dist/channels/pagerduty/payload.d.ts +33 -0
- package/dist/channels/pagerduty/payload.d.ts.map +1 -0
- package/dist/channels/pagerduty/payload.js +150 -0
- package/dist/channels/pagerduty/replay.d.ts +35 -0
- package/dist/channels/pagerduty/replay.d.ts.map +1 -0
- package/dist/channels/pagerduty/replay.js +115 -0
- package/dist/channels/pagerduty/secrets.d.ts +16 -0
- package/dist/channels/pagerduty/secrets.d.ts.map +1 -0
- package/dist/channels/pagerduty/secrets.js +23 -0
- package/dist/channels/pagerduty/self-user.d.ts +51 -0
- package/dist/channels/pagerduty/self-user.d.ts.map +1 -0
- package/dist/channels/pagerduty/self-user.js +157 -0
- package/dist/channels/pagerduty/state.d.ts +31 -0
- package/dist/channels/pagerduty/state.d.ts.map +1 -0
- package/dist/channels/pagerduty/state.js +30 -0
- package/dist/channels/pagerduty/types.d.ts +217 -0
- package/dist/channels/pagerduty/types.d.ts.map +1 -0
- package/dist/channels/pagerduty/types.js +1 -0
- package/dist/channels.d.ts +6 -0
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +11 -23
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.DTIg0uKK.js → app.BjS1QEI4.js} +4 -4
- package/dist/docs/assets/chunks/@localSearchIndexroot.oGqZumnJ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BpJoSaxi.js → VPLocalSearchBox.BOuvjb5Y.js} +1 -1
- package/dist/docs/assets/chunks/{arc.ylgNvRNq.js → arc.3WR6Jf-y.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.BMrNJqYk.js → architectureDiagram-Q4EWVU46.Dtb6Dqh6.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.BBWUEqf9.js → baseUniq.BUyrgrZE.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.DFMu-Vza.js → blockDiagram-DXYQGD6D.BVLV_voZ.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.8nkAAxWv.js → c4Diagram-AHTNJAMY.jXJ1q70M.js} +1 -1
- package/dist/docs/assets/chunks/channel.Dt4aweTm.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.sO-z2Bag.js → chunk-4BX2VUAB.zz1SMBvK.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.BMROzTMq.js → chunk-4TB4RGXK.CzYKuv3I.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.X81urwg7.js → chunk-55IACEB6.C7_tcJZD.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.eaZVFLZM.js → chunk-EDXVE4YY.DeTwQPVO.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.CmZhzstR.js → chunk-FMBD7UC4.DhMTl7ut.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.CTezt9Lc.js → chunk-OYMX7WX6.Me7f5hEp.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.s-T8zukB.js → chunk-QZHKN3VN.D0E0Bb6g.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.DN4Nhy-D.js → chunk-YZCP3GAM.CdOOBFYL.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.DGUHZs6j.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.DGUHZs6j.js +1 -0
- package/dist/docs/assets/chunks/clone.DWf3k0Z0.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.Cqyp4BUH.js → cose-bilkent-S5V4N54A.BNbGESzN.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.BIECOiqR.js → dagre-KV5264BT.zU7Lu_xJ.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.1tLyWoTg.js → diagram-5BDNPKRD.B9qOdE5h.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.BVY_6VMO.js → diagram-G4DWMVQ6.D8X-sf77.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BSZ7xiBB.js → diagram-MMDJMWI5.CW7MvMlE.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.Bho6GmLh.js → diagram-TYMM5635.J489G0Nd.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.A0yVIANn.js → erDiagram-SMLLAGMA.BkW7tGfs.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.ZMgbllH6.js → flowDiagram-DWJPFMVM.jc9iWORD.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.BCCPBhXo.js → ganttDiagram-T4ZO3ILL.B-UQfd9E.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.BOkL0BbA.js → gitGraphDiagram-UUTBAWPF.DFzrTSlJ.js} +1 -1
- package/dist/docs/assets/chunks/{graph.DMyZPu86.js → graph.C5IB6_e_.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.CjG1IiEw.js → infoDiagram-42DDH7IO.DwF0-c8L.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.UCe-kq9g.js → ishikawaDiagram-UXIWVN3A.fBaTqzE7.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.3WyOK_eY.js → journeyDiagram-VCZTEJTY.CM8gDVJy.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.WoRG2qY1.js → kanban-definition-6JOO6SKY.YiD1p0LB.js} +1 -1
- package/dist/docs/assets/chunks/{layout.DV07xDd5.js → layout.6Um-DVJT.js} +1 -1
- package/dist/docs/assets/chunks/{linear.CTO8mN6o.js → linear.DcTeg4Hn.js} +1 -1
- package/dist/docs/assets/chunks/{min.SvTtcKuZ.js → min.CIxkY8Fe.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.DMGgQ-HB.js → mindmap-definition-QFDTVHPH.D4QM_voR.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.B7851apI.js → pieDiagram-DEJITSTG.nmB309G1.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CEqyypIX.js → quadrantDiagram-34T5L4WZ.D1HtZR3C.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.C3Mwsw-H.js → requirementDiagram-MS252O5E.CZgQWob-.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.DyYK0XxY.js → sankeyDiagram-XADWPNL6.DtiBfU-P.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.SiQPH-XM.js → sequenceDiagram-FGHM5R23.Cld4gDSt.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.CTJMsP4p.js → stateDiagram-FHFEXIEX.DatP823_.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.C0571l4D.js +1 -0
- package/dist/docs/assets/chunks/{theme.DJo4my9R.js → theme.D5jbBys7.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.CxSNRlQ6.js → timeline-definition-GMOUNBTQ.DwQLI2be.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.BdoJskyD.js → vennDiagram-DHZGUBPP.a5yMfnsa.js} +1 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.B-FXivgT.js +162 -0
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.IjIbFn_F.js → wardleyDiagram-NUSXRM2D.Dz--Opy3.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.CPUxDZLH.js → xychartDiagram-5P7HB3ND.Dl8w8TeT.js} +1 -1
- package/dist/docs/assets/{guides_opentelemetry.md.Ck1o2frw.js → guides_opentelemetry.md.DBQtp7_V.js} +4 -4
- package/dist/docs/assets/{guides_opentelemetry.md.Ck1o2frw.lean.js → guides_opentelemetry.md.DBQtp7_V.lean.js} +1 -1
- package/dist/docs/assets/guides_pagerduty.md.BHXMcMtx.js +60 -0
- package/dist/docs/assets/guides_pagerduty.md.BHXMcMtx.lean.js +1 -0
- package/dist/docs/assets/{reference_channels.md.DYg0CLud.js → reference_channels.md.Bxaa020x.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.DB7Llw3T.js → reference_cli.md.1o_TqKdt.js} +7 -2
- package/dist/docs/assets/{reference_cli.md.DB7Llw3T.lean.js → reference_cli.md.1o_TqKdt.lean.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.08XR7lIl.js → reference_tools.md.-6pypsWt.js} +1 -1
- package/dist/docs/building-with-agents.html +35 -35
- package/dist/docs/deployment.html +35 -35
- package/dist/docs/evals.html +35 -35
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +36 -36
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/export-grokbot.html +35 -35
- package/dist/docs/guides/github.html +35 -35
- package/dist/docs/guides/gitlab.html +35 -35
- 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 +35 -35
- package/dist/docs/guides/opentelemetry.html +39 -39
- package/dist/docs/guides/opentelemetry.md +10 -5
- package/dist/docs/guides/pagerduty.html +119 -0
- package/dist/docs/guides/pagerduty.md +336 -0
- 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 +381 -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 +37 -37
- package/dist/docs/reference/channels.md +2 -1
- package/dist/docs/reference/cli.html +42 -37
- package/dist/docs/reference/cli.md +27 -0
- package/dist/docs/reference/connections.html +35 -35
- package/dist/docs/reference/evals.html +35 -35
- package/dist/docs/reference/extensions.html +36 -36
- 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/memory.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 +37 -37
- package/dist/docs/reference/tools.md +1 -0
- 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 +35 -35
- package/dist/internal/approval-gate.d.ts +4 -2
- package/dist/internal/approval-gate.d.ts.map +1 -1
- package/dist/internal/approval-gate.js +2 -1
- package/dist/internal/builtin-tools/artifacts.d.ts.map +1 -1
- package/dist/internal/builtin-tools/artifacts.js +45 -12
- package/dist/internal/channel-architecture.d.ts +1 -1
- package/dist/internal/channel-architecture.d.ts.map +1 -1
- package/dist/internal/channel-architecture.js +4 -2
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +21 -12
- package/dist/internal/cli-pagerduty.d.ts +32 -0
- package/dist/internal/cli-pagerduty.d.ts.map +1 -0
- package/dist/internal/cli-pagerduty.js +242 -0
- package/dist/internal/continuation-channel.d.ts.map +1 -1
- package/dist/internal/continuation-channel.js +7 -0
- package/dist/internal/continuation-identity.d.ts +11 -3
- package/dist/internal/continuation-identity.d.ts.map +1 -1
- package/dist/internal/continuation-identity.js +83 -0
- package/dist/internal/deploy-manifest.d.ts +11 -4
- package/dist/internal/deploy-manifest.d.ts.map +1 -1
- package/dist/internal/deploy-manifest.js +17 -5
- package/dist/internal/discovery/agent-config.d.ts.map +1 -1
- package/dist/internal/discovery/agent-config.js +10 -10
- package/dist/internal/discovery/agent.d.ts.map +1 -1
- package/dist/internal/discovery/agent.js +10 -10
- package/dist/internal/discovery/channels.d.ts.map +1 -1
- package/dist/internal/discovery/channels.js +20 -16
- package/dist/internal/discovery/context.d.ts +16 -0
- package/dist/internal/discovery/context.d.ts.map +1 -1
- package/dist/internal/discovery/context.js +66 -0
- package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
- package/dist/internal/discovery/extension-overlay.js +2 -6
- package/dist/internal/discovery/info.d.ts.map +1 -1
- package/dist/internal/discovery/info.js +3 -0
- package/dist/internal/discovery/instructions.d.ts.map +1 -1
- package/dist/internal/discovery/instructions.js +3 -6
- package/dist/internal/discovery/modules.d.ts.map +1 -1
- package/dist/internal/discovery/modules.js +3 -6
- package/dist/internal/discovery/project.d.ts +6 -0
- package/dist/internal/discovery/project.d.ts.map +1 -1
- package/dist/internal/discovery/project.js +27 -5
- package/dist/internal/discovery/runtime.d.ts.map +1 -1
- package/dist/internal/discovery/runtime.js +8 -8
- package/dist/internal/discovery.d.ts +1 -1
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +1 -1
- package/dist/internal/expected-delivery-failure.d.ts.map +1 -1
- package/dist/internal/expected-delivery-failure.js +6 -0
- package/dist/internal/filesystem/sdk-schemas.d.ts.map +1 -1
- package/dist/internal/filesystem/sdk-schemas.js +4 -3
- package/dist/internal/hmac-secret-values.d.ts +48 -0
- package/dist/internal/hmac-secret-values.d.ts.map +1 -0
- package/dist/internal/hmac-secret-values.js +68 -0
- package/dist/internal/host-platforms.d.ts.map +1 -1
- package/dist/internal/host-platforms.js +8 -2
- package/dist/internal/json-schema.d.ts +7 -7
- package/dist/internal/json-schema.d.ts.map +1 -1
- package/dist/internal/json-schema.js +13 -16
- package/dist/internal/otel/collector.d.ts.map +1 -1
- package/dist/internal/otel/collector.js +3 -1
- package/dist/internal/otel/config.d.ts +6 -1
- package/dist/internal/otel/config.d.ts.map +1 -1
- package/dist/internal/otel/config.js +27 -1
- package/dist/internal/otel/runtime.d.ts.map +1 -1
- package/dist/internal/otel/runtime.js +26 -3
- package/dist/internal/package-inline-stdio.d.ts.map +1 -1
- package/dist/internal/package-inline-stdio.js +21 -6
- package/dist/internal/sdk-runner.d.ts +2 -3
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +8 -4
- package/dist/internal/secret-alternatives.d.ts +11 -0
- package/dist/internal/secret-alternatives.d.ts.map +1 -0
- package/dist/internal/secret-alternatives.js +13 -0
- package/dist/internal/server.js +2 -2
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +5 -4
- package/dist/internal/sqlite-experimental-warning.d.ts +2 -0
- package/dist/internal/sqlite-experimental-warning.d.ts.map +1 -0
- package/dist/internal/sqlite-experimental-warning.js +22 -0
- package/dist/internal/testing/conversation-identity-vectors.d.ts +6 -1
- package/dist/internal/testing/conversation-identity-vectors.d.ts.map +1 -1
- package/dist/internal/testing/conversation-identity-vectors.js +34 -0
- package/dist/internal/testing/hmac-secret-vectors.d.ts +38 -0
- package/dist/internal/testing/hmac-secret-vectors.d.ts.map +1 -0
- package/dist/internal/testing/hmac-secret-vectors.js +89 -0
- package/dist/internal/testing/pagerduty-continuation-fixtures.d.ts +42 -0
- package/dist/internal/testing/pagerduty-continuation-fixtures.d.ts.map +1 -0
- package/dist/internal/testing/pagerduty-continuation-fixtures.js +175 -0
- package/dist/internal/zod-schema.d.ts +14 -0
- package/dist/internal/zod-schema.d.ts.map +1 -0
- package/dist/internal/zod-schema.js +22 -0
- package/dist/playground/assets/cursor-icons-16-DmHBTm1-.woff2 +0 -0
- package/dist/playground/assets/index-BdMwybMt.css +1 -0
- package/dist/playground/assets/{index-DKKdkF29.js → index-CHk6O92d.js} +38 -38
- package/dist/playground/index.html +2 -2
- package/dist/tools.d.ts +13 -10
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +3 -2
- package/dist/types.d.ts +67 -16
- package/dist/types.d.ts.map +1 -1
- package/docs/guides/opentelemetry.md +10 -5
- package/docs/guides/pagerduty.md +341 -0
- package/docs/reference/channels.md +2 -1
- package/docs/reference/cli.md +27 -0
- package/docs/reference/tools.md +1 -0
- package/package.json +10 -3
- package/skills/migrate-v2/SKILL.md +1 -1
- package/skills/otel/SKILL.md +7 -3
- package/templates/agentic-owners/README.md +6 -1
- package/templates/agentic-owners/bot/lib/owners/decision.ts +31 -5
- package/templates/agentic-owners/bot/lib/owners/globalOverride.ts +60 -0
- package/templates/agentic-owners/bot/lib/owners/match.ts +85 -19
- package/templates/agentic-owners/bot/lib/owners/parse.ts +133 -2
- package/templates/agentic-owners/bot/lib/owners/types.ts +23 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.3ebvCWKy.js +0 -1
- package/dist/docs/assets/chunks/channel.BOebySCN.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.C55IaN-T.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.C55IaN-T.js +0 -1
- package/dist/docs/assets/chunks/clone.D06pA7ML.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.DddRVjeq.js +0 -1
- package/dist/docs/assets/chunks/wardley-RL74JXVD.CVCRSuQK.js +0 -162
- package/dist/playground/assets/cursor-icons-16-gwXtdAvu.woff2 +0 -0
- package/dist/playground/assets/index-DpKinTMs.css +0 -1
- /package/dist/docs/assets/{reference_channels.md.DYg0CLud.lean.js → reference_channels.md.Bxaa020x.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.08XR7lIl.lean.js → reference_tools.md.-6pypsWt.lean.js} +0 -0
package/AGENTS.md
CHANGED
|
@@ -336,6 +336,7 @@ Fixtures still work for offline replay: `POST` a saved payload with an
|
|
|
336
336
|
- Expect `bot/evals/` to be loaded — evals live at the **project root** `evals/`.
|
|
337
337
|
- Build optional object fields with a conditional empty-object spread.
|
|
338
338
|
Assign the property directly; `undefined` is fine on optional keys.
|
|
339
|
+
`bdk/no-conditional-empty-spread` enforces this.
|
|
339
340
|
|
|
340
341
|
```ts
|
|
341
342
|
// ❌ BAD
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* agent-sdk convert-automation <url> [--dir <path>] [--json]
|
|
14
14
|
* agent-sdk migrate [--dir .] [--no-wait] [--json]
|
|
15
15
|
* agent-sdk eval [--dir .] [evalId...]
|
|
16
|
-
* agent-sdk validate [--dir .]
|
|
16
|
+
* agent-sdk validate [--dir .] [--json]
|
|
17
17
|
* agent-sdk slack <subcommand>
|
|
18
18
|
*/
|
|
19
19
|
export {};
|
package/dist/bin/agent-serve.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* agent-sdk convert-automation <url> [--dir <path>] [--json]
|
|
14
14
|
* agent-sdk migrate [--dir .] [--no-wait] [--json]
|
|
15
15
|
* agent-sdk eval [--dir .] [evalId...]
|
|
16
|
-
* agent-sdk validate [--dir .]
|
|
16
|
+
* agent-sdk validate [--dir .] [--json]
|
|
17
17
|
* agent-sdk slack <subcommand>
|
|
18
18
|
*/
|
|
19
19
|
import { spawn } from "node:child_process";
|
|
@@ -22,6 +22,7 @@ import { resolve } from "node:path";
|
|
|
22
22
|
import { parseArgs } from "node:util";
|
|
23
23
|
import { formatDiagnostics, projectInfo, resolveAgentMounts, serve } from "../index.js";
|
|
24
24
|
import { registerAuthoredModuleLoaders } from "../internal/authored-loaders.js";
|
|
25
|
+
import { formatValidateJson } from "../internal/discovery.js";
|
|
25
26
|
import { cmdCall, cmdChat, cmdCost, cmdEval, cmdEvalCancel, cmdEvalStatus, cmdInit, cmdLogs, cmdPlayground, cmdResume, cmdRun, cmdSession, cmdSessions, cmdSkill, cmdTrajectory, } from "../internal/cli-ax.js";
|
|
26
27
|
import { cmdCancelRuns, cmdDelete, cmdDeploy, cmdDeploymentStatus, cmdDeployments, cmdEventRepos, cmdKill, cmdRollback, cmdRotateToken, cmdSecretsList, cmdSecretsSet, cmdSecretsUnset, cmdStart, cmdStop, cmdUnlockDeploys, cmdUpgrade, } from "../internal/cli-deploy.js";
|
|
27
28
|
import { cmdImagesList, cmdImagesPush, cmdImagesRm } from "../internal/cli-images.js";
|
|
@@ -99,7 +100,7 @@ Usage:
|
|
|
99
100
|
[--out <file.json>]
|
|
100
101
|
${CLI} eval cancel <runId> --url <baseUrl> [--dir <path>] [--json]
|
|
101
102
|
${CLI} info [--dir <path>] [--json]
|
|
102
|
-
${CLI} validate [--dir <path>]
|
|
103
|
+
${CLI} validate [--dir <path>] [--json]
|
|
103
104
|
${CLI} login [--api-key <key>] [--key-name <name>]
|
|
104
105
|
${CLI} logout
|
|
105
106
|
${CLI} whoami [--json]
|
|
@@ -308,6 +309,8 @@ Commands:
|
|
|
308
309
|
recipe (see gitlab help).
|
|
309
310
|
bitbucket Bitbucket webhook pack (Cloud + Data Center): replay a pull
|
|
310
311
|
request, events, forward recipe (see bitbucket help).
|
|
312
|
+
pagerduty PagerDuty webhook pack: replay synthesized incident events,
|
|
313
|
+
events (see pagerduty help).
|
|
311
314
|
|
|
312
315
|
Agent loop:
|
|
313
316
|
${CLI} validate --dir .
|
|
@@ -442,7 +445,7 @@ Options:
|
|
|
442
445
|
--skip-report eval: ignore reporters from evals.config.ts / eval files.
|
|
443
446
|
--no-stream run/eval: silence live progress on stderr (JSON still prints).
|
|
444
447
|
--json JSON output (init/convert-automation/install-skills/
|
|
445
|
-
info/chat/eval/logs/version/
|
|
448
|
+
info/validate/chat/eval/logs/version/
|
|
446
449
|
sessions/session/github; run defaults to JSON). logs:
|
|
447
450
|
NDJSON progress/log events (v2: {sessionId, line}).
|
|
448
451
|
session: trajectory JSON
|
|
@@ -487,7 +490,7 @@ Options:
|
|
|
487
490
|
--action github/gitlab replay: event action (e.g. opened, open).
|
|
488
491
|
--conclusion github replay: CI conclusion (check_run/suite/status).
|
|
489
492
|
gitlab replay: pipeline status (success, failed, …).
|
|
490
|
-
--comment github/gitlab/bitbucket replay: comment / note body.
|
|
493
|
+
--comment github/gitlab/bitbucket/pagerduty replay: comment / note body.
|
|
491
494
|
--context github replay: commit-status context.
|
|
492
495
|
--dry-run github replay: print synthesized payloads, don't POST.
|
|
493
496
|
--out eval / eval status <runId>: also write the full results
|
|
@@ -726,6 +729,29 @@ async function main(argv) {
|
|
|
726
729
|
out: values.out,
|
|
727
730
|
});
|
|
728
731
|
}
|
|
732
|
+
case "pagerduty": {
|
|
733
|
+
const port = values.port === undefined ? undefined : Number.parseInt(values.port, 10);
|
|
734
|
+
if (port !== undefined && (Number.isNaN(port) || port < 0 || port > 65535)) {
|
|
735
|
+
process.stderr.write(`invalid --port: ${values.port}\n`);
|
|
736
|
+
return 1;
|
|
737
|
+
}
|
|
738
|
+
const { cmdPagerDuty } = await import("../internal/cli-pagerduty.js");
|
|
739
|
+
return cmdPagerDuty(positionals[0], {
|
|
740
|
+
dir,
|
|
741
|
+
slug: values.slug,
|
|
742
|
+
channel: values.channel?.at(-1),
|
|
743
|
+
host: values.host,
|
|
744
|
+
port,
|
|
745
|
+
url: values.url,
|
|
746
|
+
events: values.events,
|
|
747
|
+
secret: values.secret,
|
|
748
|
+
json: values.json,
|
|
749
|
+
incidentId: positionals[1],
|
|
750
|
+
comment: values.comment,
|
|
751
|
+
dryRun: values["dry-run"],
|
|
752
|
+
out: values.out,
|
|
753
|
+
});
|
|
754
|
+
}
|
|
729
755
|
case "bitbucket": {
|
|
730
756
|
const port = values.port === undefined ? undefined : Number.parseInt(values.port, 10);
|
|
731
757
|
if (port !== undefined && (Number.isNaN(port) || port < 0 || port > 65535)) {
|
|
@@ -1172,16 +1198,20 @@ async function main(argv) {
|
|
|
1172
1198
|
}
|
|
1173
1199
|
case "validate": {
|
|
1174
1200
|
const mounts = await loadMounts(dir);
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1201
|
+
if (values.json === true) {
|
|
1202
|
+
process.stdout.write(formatValidateJson(mounts));
|
|
1203
|
+
}
|
|
1204
|
+
else {
|
|
1205
|
+
for (const { slug, project } of mounts) {
|
|
1206
|
+
const label = slug === "" ? project.name : `${slug} (${project.name})`;
|
|
1207
|
+
if (project.diagnostics.length === 0) {
|
|
1208
|
+
process.stdout.write(`ok: ${label} has no diagnostics\n`);
|
|
1209
|
+
continue;
|
|
1210
|
+
}
|
|
1211
|
+
process.stdout.write(`${label}:\n${formatDiagnostics(project.diagnostics)}\n`);
|
|
1181
1212
|
}
|
|
1182
|
-
process.stdout.write(`${label}:\n${formatDiagnostics(project.diagnostics)}\n`);
|
|
1183
|
-
hasError ||= project.diagnostics.some((d) => d.severity === "error");
|
|
1184
1213
|
}
|
|
1214
|
+
const hasError = mounts.some((mount) => mount.project.diagnostics.some((diagnostic) => diagnostic.severity === "error"));
|
|
1185
1215
|
return hasError ? 1 : 0;
|
|
1186
1216
|
}
|
|
1187
1217
|
case "info": {
|
|
@@ -1570,6 +1600,12 @@ function printServeBanner(handle, opts) {
|
|
|
1570
1600
|
handle.agents.some((agent) => projectInfo(agent.project).channels.some((c) => c.kind === "bitbucket"))) {
|
|
1571
1601
|
process.stdout.write(c.dim(` bitbucket: dev accepts unsigned loopback deliveries (${CLI} bitbucket replay works without a secret; set BITBUCKET_WEBHOOK_SECRET to verify X-Hub-Signature)\n`));
|
|
1572
1602
|
}
|
|
1603
|
+
if (opts.dev &&
|
|
1604
|
+
(process.env.PAGERDUTY_WEBHOOK_SECRET === undefined ||
|
|
1605
|
+
process.env.PAGERDUTY_WEBHOOK_SECRET === "") &&
|
|
1606
|
+
handle.agents.some((agent) => projectInfo(agent.project).channels.some((c) => c.kind === "pagerduty"))) {
|
|
1607
|
+
process.stdout.write(c.dim(` pagerduty: dev accepts unsigned loopback deliveries (${CLI} pagerduty replay works without a secret; set PAGERDUTY_WEBHOOK_SECRET to verify X-PagerDuty-Signature)\n`));
|
|
1608
|
+
}
|
|
1573
1609
|
}
|
|
1574
1610
|
/** Prefer the Vite playground URL in --dev; otherwise the static SPA path. */
|
|
1575
1611
|
function resolvePlaygroundBannerUrl(handle, noPlayground) {
|
|
@@ -19,8 +19,9 @@ export declare function resolveBitbucketWebhookSecret(options: Pick<BitbucketCha
|
|
|
19
19
|
export declare function signBitbucketWebhookBody(rawBody: string | Buffer, secret: string): string;
|
|
20
20
|
/**
|
|
21
21
|
* Both dialects sign the raw body with HMAC-SHA256 in `X-Hub-Signature`
|
|
22
|
-
* (`sha256=<hex>`, GitHub-shaped).
|
|
23
|
-
*
|
|
22
|
+
* (`sha256=<hex>`, GitHub-shaped). `secret` is the named secret's value,
|
|
23
|
+
* which may hold several signing secrets one per line; any verifies.
|
|
24
|
+
* Constant-time compare; a missing or malformed header is a plain `false`.
|
|
24
25
|
*/
|
|
25
26
|
export declare function verifyBitbucketWebhookSignature(rawBody: string | Buffer, signatureHeader: string | null | undefined, secret: string): boolean;
|
|
26
27
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bitbucket-webhook.d.ts","sourceRoot":"","sources":["../../../src/channels/bitbucket/bitbucket-webhook.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bitbucket-webhook.d.ts","sourceRoot":"","sources":["../../../src/channels/bitbucket/bitbucket-webhook.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAqB,kBAAkB,EAAa,MAAM,gBAAgB,CAAC;AACvF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAyBxD,OAAO,KAAK,EACV,uBAAuB,EAEvB,qBAAqB,EAGrB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB,4EAA4E;AAC5E,eAAO,MAAM,4BAA4B,6BAA6B,CAAC;AACvE,sFAAsF;AACtF,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,0BAA0B,YAAY,CAAC;AAEpD,6FAA6F;AAC7F,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,SAAS,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,eAAe,CAAC,GACtD,MAAM,GAAG,SAAS,CAEpB;AAID,kEAAkE;AAClE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzF;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC1C,MAAM,EAAE,MAAM,GACb,OAAO,CAYT;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,wBAAwB,GAAG,IAAI,CA2BjC;AAyED,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,wBAAwB,GACjC,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC,GAAG,IAAI,CAyBjF;AAwGD;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,KAAK,EAAE;IACpD,OAAO,EAAE,uBAAuB,CAAC;IACjC,QAAQ,EAAE,wBAAwB,CAAC;IACnC,IAAI,EAAE,kBAAkB,CAAC;IACzB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,uBAAuB,GAAG,SAAS,CAAC;CACnD,GAAG,OAAO,CAAC,QAAQ,CAAC,CAgHpB;AAED;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,KAAK,EAAE;IACzD,OAAO,EAAE,uBAAuB,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,kBAAkB,CAAC;IACzB,qEAAqE;IACrE,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,uBAAuB,GAAG,SAAS,CAAC;CACnD,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwCpB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { createHmac
|
|
1
|
+
import { createHmac } from "node:crypto";
|
|
2
2
|
import { acknowledgeTask, isTaskDispatch, skipped, turnStarted, } from "../../internal/channel-dispatch.js";
|
|
3
3
|
import { continuationSource } from "../../internal/continuation-identity.js";
|
|
4
|
+
import { hmacSignatureMatchesAny, parseHmacSecrets } from "../../internal/hmac-secret-values.js";
|
|
4
5
|
import { bindLocalIngressSend } from "../../internal/local-ingress.js";
|
|
5
6
|
import { resolveWebhookSecretValue } from "../../internal/named-webhook-secret.js";
|
|
6
7
|
import { asNonEmptyString, asPositiveInt, asRecord, bitbucketCommentFromPayload, bitbucketPullRequestFromPayload, bitbucketPullRequestRecord, bitbucketPullRequestUrl, bitbucketPushFromPayload, bitbucketRepositoryFromPayload, bitbucketUser, buildBitbucketBinding, } from "./binding.js";
|
|
@@ -33,18 +34,22 @@ export function signBitbucketWebhookBody(rawBody, secret) {
|
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
35
36
|
* Both dialects sign the raw body with HMAC-SHA256 in `X-Hub-Signature`
|
|
36
|
-
* (`sha256=<hex>`, GitHub-shaped).
|
|
37
|
-
*
|
|
37
|
+
* (`sha256=<hex>`, GitHub-shaped). `secret` is the named secret's value,
|
|
38
|
+
* which may hold several signing secrets one per line; any verifies.
|
|
39
|
+
* Constant-time compare; a missing or malformed header is a plain `false`.
|
|
38
40
|
*/
|
|
39
41
|
export function verifyBitbucketWebhookSignature(rawBody, signatureHeader, secret) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
!signatureHeader.startsWith(SIGNATURE_PREFIX)) {
|
|
42
|
+
const parsed = parseHmacSecrets(secret);
|
|
43
|
+
if (signatureHeader === null || signatureHeader === undefined || !parsed.ok) {
|
|
43
44
|
return false;
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
return hmacSignatureMatchesAny({
|
|
47
|
+
body: rawBody,
|
|
48
|
+
presented: signatureHeader,
|
|
49
|
+
secrets: parsed.secrets,
|
|
50
|
+
prefix: SIGNATURE_PREFIX,
|
|
51
|
+
separator: undefined,
|
|
52
|
+
});
|
|
48
53
|
}
|
|
49
54
|
/**
|
|
50
55
|
* Accept a raw Bitbucket payload plus the event key. The key comes from
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-channel.d.ts","sourceRoot":"","sources":["../../../src/channels/github/github-channel.ts"],"names":[],"mappings":"AA6BA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,iBAAiB,EAEtB,KAAK,kBAAkB,EAMxB,MAAM,gBAAgB,CAAC;AAkBxB,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAEV,oBAAoB,EAKpB,aAAa,EAEb,qBAAqB,EACrB,kBAAkB,EAGlB,sBAAsB,EAKtB,kBAAkB,EAClB,UAAU,EAEX,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,KAAK,mBAAmB,GAAG,IAAI,CAC7B,kBAAkB,EAClB,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CACvD,CAAC;AAoFF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB,GAAG,WAAW,CAkBvE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAGtE;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAU1F;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAEnE;AAED,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,mBAAmB,EACxB,WAAW,EAAE,sBAAsB,GAClC,MAAM,CAaR;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,mBAAmB,EACxB,WAAW,EAAE,sBAAsB,GAClC,kBAAkB,GAAG,IAAI,CAK3B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,mBAAmB,EACxB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5B,kBAAkB,GAAG,IAAI,CAW3B;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAUV;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAYlC;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG;IAAE,GAAG,EAAE,mBAAmB,CAAC;IAAC,WAAW,EAAE,sBAAsB,CAAA;CAAE,GAAG,IAAI,CA8C3E;AAED,wBAAsB,4BAA4B,CAAC,IAAI,EAAE;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,qBAAqB,GAAG,SAAS,CAAC;CAC3C,GAAG,OAAO,CAAC,UAAU,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"github-channel.d.ts","sourceRoot":"","sources":["../../../src/channels/github/github-channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
1
|
import { z } from "zod/v3";
|
|
3
2
|
import { allowAll, defineChannel, hmacSignatureAuth, localDevStrict, loopbackGitHubDev, POST, } from "../../channels.js";
|
|
4
3
|
import { acknowledgeTask, acknowledgeTurn, isTaskDispatch, scheduleAfterAck, skipped, turnStarted, withPropagatingBackgroundErrors, } from "../../internal/channel-dispatch.js";
|
|
5
4
|
import { continuationSource, normalizeIdentity } from "../../internal/continuation-identity.js";
|
|
6
5
|
import { isDevMode } from "../../internal/dev-mode.js";
|
|
6
|
+
import { hmacSignatureMatchesAny, parseHmacSecrets } from "../../internal/hmac-secret-values.js";
|
|
7
7
|
import { attachHostedAdmissionAdapter } from "../../internal/hosted-admission-adapter.js";
|
|
8
8
|
import { CATCH_DELIVERY_ID_HEADER, replayCatchRequest } from "../../internal/hosted-catch.js";
|
|
9
9
|
import { AGENT_SDK_CATCH_EVENT_TYPE } from "../../internal/hosted-catch-protocol.js";
|
|
@@ -253,32 +253,23 @@ export function parseGitHubPullRequestEvent(args) {
|
|
|
253
253
|
return { ctx, pullRequest };
|
|
254
254
|
}
|
|
255
255
|
export async function verifyGitHubWebhookSignature(args) {
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
// A value over the secret cap holds no usable secret, the same as unset.
|
|
257
|
+
const parsed = parseHmacSecrets(await resolveCredentialValue(args.secret));
|
|
258
|
+
if (!parsed.ok) {
|
|
258
259
|
return "missing_secret";
|
|
259
260
|
}
|
|
260
261
|
if (args.signatureHeader === null) {
|
|
261
262
|
return "missing_signature";
|
|
262
263
|
}
|
|
263
|
-
const isVerified =
|
|
264
|
-
secret,
|
|
264
|
+
const isVerified = hmacSignatureMatchesAny({
|
|
265
265
|
body: args.body,
|
|
266
|
-
|
|
266
|
+
presented: args.signatureHeader,
|
|
267
|
+
secrets: parsed.secrets,
|
|
268
|
+
prefix: GITHUB_SIGNATURE_PREFIX,
|
|
269
|
+
separator: undefined,
|
|
267
270
|
});
|
|
268
271
|
return isVerified ? "verified" : "mismatch";
|
|
269
272
|
}
|
|
270
|
-
function verifyWebhookSha256Signature(args) {
|
|
271
|
-
if (!args.signatureHeader.startsWith(GITHUB_SIGNATURE_PREFIX)) {
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
const receivedHex = args.signatureHeader.slice(GITHUB_SIGNATURE_PREFIX.length);
|
|
275
|
-
if (!/^[0-9a-f]+$/i.test(receivedHex) || receivedHex.length % 2 !== 0) {
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
const expected = createHmac("sha256", args.secret).update(args.body).digest();
|
|
279
|
-
const received = Buffer.from(receivedHex, "hex");
|
|
280
|
-
return received.length === expected.length && timingSafeEqual(received, expected);
|
|
281
|
-
}
|
|
282
273
|
/**
|
|
283
274
|
* Run the authored hooks for one GitHub delivery and `send()` the turn.
|
|
284
275
|
* Callers own delivery auth: the HTTP route verifies the HMAC; trigger
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal PagerDuty REST client for write-backs (notes, incident updates).
|
|
3
|
+
* Every credential defaults to a well-known env var / deployment secret and
|
|
4
|
+
* is read per call, so a hosted deployment, which receives its secrets per
|
|
5
|
+
* request, sees them.
|
|
6
|
+
*/
|
|
7
|
+
import type { WebhookSecretValue } from "../../internal/named-webhook-secret.js";
|
|
8
|
+
import type { PagerDutyChannelOptions } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* API token: a REST API key (user or account level), or an OAuth access
|
|
11
|
+
* token written as `Bearer <token>`.
|
|
12
|
+
*/
|
|
13
|
+
export declare const PAGERDUTY_TOKEN_ENV = "PAGERDUTY_TOKEN";
|
|
14
|
+
/** REST base override, e.g. `https://api.eu.pagerduty.com` for the EU service region. */
|
|
15
|
+
export declare const PAGERDUTY_API_BASE_URL_ENV = "PAGERDUTY_API_BASE_URL";
|
|
16
|
+
/** `From` email for write calls made with an account-level REST API key. */
|
|
17
|
+
export declare const PAGERDUTY_FROM_EMAIL_ENV = "PAGERDUTY_FROM_EMAIL";
|
|
18
|
+
export declare const PAGERDUTY_DEFAULT_API_BASE_URL = "https://api.pagerduty.com";
|
|
19
|
+
/**
|
|
20
|
+
* The REST base for a call: the authored `apiBaseUrl`, else
|
|
21
|
+
* `PAGERDUTY_API_BASE_URL`, else `https://api.pagerduty.com`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function pagerDutyApiBaseUrl(apiBaseUrl?: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* `Authorization` for a token: a value already written as `Bearer <token>`
|
|
26
|
+
* (an OAuth access token) is sent as-is; anything else is a REST API key.
|
|
27
|
+
*/
|
|
28
|
+
export declare function pagerDutyAuthorizationHeader(token: string): string;
|
|
29
|
+
export interface PagerDutyClientOptions {
|
|
30
|
+
/** Falls back to `PAGERDUTY_TOKEN`. */
|
|
31
|
+
token?: WebhookSecretValue;
|
|
32
|
+
/** Falls back to `PAGERDUTY_API_BASE_URL`, else `https://api.pagerduty.com`. */
|
|
33
|
+
apiBaseUrl?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Email of a PagerDuty user, sent as `From` on every call. PagerDuty
|
|
36
|
+
* requires it for writes made with an account-level API key; a user token
|
|
37
|
+
* acts as its own user. Falls back to `PAGERDUTY_FROM_EMAIL`.
|
|
38
|
+
*/
|
|
39
|
+
from?: WebhookSecretValue;
|
|
40
|
+
/** Fetch implementation; defaults to the global `fetch`. */
|
|
41
|
+
fetch?: typeof fetch;
|
|
42
|
+
}
|
|
43
|
+
export declare class PagerDutyApiError extends Error {
|
|
44
|
+
readonly status: number;
|
|
45
|
+
readonly body: string;
|
|
46
|
+
constructor(input: {
|
|
47
|
+
method: string;
|
|
48
|
+
path: string;
|
|
49
|
+
status: number;
|
|
50
|
+
body: string;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export interface PagerDutyClient {
|
|
54
|
+
/** One REST call; `path` is relative to the API base, e.g. `/incidents/PINC001`. */
|
|
55
|
+
request<T = unknown>(input: {
|
|
56
|
+
method: string;
|
|
57
|
+
path: string;
|
|
58
|
+
body?: unknown;
|
|
59
|
+
}): Promise<T>;
|
|
60
|
+
/** `POST /incidents/{id}/notes`. Returns the created note. */
|
|
61
|
+
addNote(input: {
|
|
62
|
+
incidentId: string;
|
|
63
|
+
content: string;
|
|
64
|
+
}): Promise<{
|
|
65
|
+
id: string;
|
|
66
|
+
content: string;
|
|
67
|
+
}>;
|
|
68
|
+
/** `GET /incidents/{id}`, the incident's current state. */
|
|
69
|
+
getIncident(incidentId: string): Promise<Record<string, unknown>>;
|
|
70
|
+
}
|
|
71
|
+
export declare function createPagerDutyClient(options?: PagerDutyClientOptions): PagerDutyClient;
|
|
72
|
+
/** The REST client for a channel's credentials, each falling back to its well-known secret. */
|
|
73
|
+
export declare function pagerDutyChannelClient(options: Pick<PagerDutyChannelOptions, "token" | "from" | "apiBaseUrl">): PagerDutyClient;
|
|
74
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/channels/pagerduty/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAEjF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AACrD,yFAAyF;AACzF,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AACnE,4EAA4E;AAC5E,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAE1E;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAM/D;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAKhF;CACF;AAED,MAAM,WAAW,eAAe;IAC9B,oFAAoF;IACpF,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1F,8DAA8D;IAC9D,OAAO,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClG,2DAA2D;IAC3D,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACnE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAyD3F;AAED,+FAA+F;AAC/F,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC,GACtE,eAAe,CAMjB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal PagerDuty REST client for write-backs (notes, incident updates).
|
|
3
|
+
* Every credential defaults to a well-known env var / deployment secret and
|
|
4
|
+
* is read per call, so a hosted deployment, which receives its secrets per
|
|
5
|
+
* request, sees them.
|
|
6
|
+
*/
|
|
7
|
+
import { pagerDutySecretName, resolvePagerDutySecret } from "./secrets.js";
|
|
8
|
+
/**
|
|
9
|
+
* API token: a REST API key (user or account level), or an OAuth access
|
|
10
|
+
* token written as `Bearer <token>`.
|
|
11
|
+
*/
|
|
12
|
+
export const PAGERDUTY_TOKEN_ENV = "PAGERDUTY_TOKEN";
|
|
13
|
+
/** REST base override, e.g. `https://api.eu.pagerduty.com` for the EU service region. */
|
|
14
|
+
export const PAGERDUTY_API_BASE_URL_ENV = "PAGERDUTY_API_BASE_URL";
|
|
15
|
+
/** `From` email for write calls made with an account-level REST API key. */
|
|
16
|
+
export const PAGERDUTY_FROM_EMAIL_ENV = "PAGERDUTY_FROM_EMAIL";
|
|
17
|
+
export const PAGERDUTY_DEFAULT_API_BASE_URL = "https://api.pagerduty.com";
|
|
18
|
+
/**
|
|
19
|
+
* The REST base for a call: the authored `apiBaseUrl`, else
|
|
20
|
+
* `PAGERDUTY_API_BASE_URL`, else `https://api.pagerduty.com`.
|
|
21
|
+
*/
|
|
22
|
+
export function pagerDutyApiBaseUrl(apiBaseUrl) {
|
|
23
|
+
return (apiBaseUrl ??
|
|
24
|
+
resolvePagerDutySecret(undefined, PAGERDUTY_API_BASE_URL_ENV) ??
|
|
25
|
+
PAGERDUTY_DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* `Authorization` for a token: a value already written as `Bearer <token>`
|
|
29
|
+
* (an OAuth access token) is sent as-is; anything else is a REST API key.
|
|
30
|
+
*/
|
|
31
|
+
export function pagerDutyAuthorizationHeader(token) {
|
|
32
|
+
return /^bearer\s/i.test(token) ? token : `Token token=${token}`;
|
|
33
|
+
}
|
|
34
|
+
export class PagerDutyApiError extends Error {
|
|
35
|
+
constructor(input) {
|
|
36
|
+
super(`PagerDuty ${input.method} ${input.path} failed with ${input.status}`);
|
|
37
|
+
this.name = "PagerDutyApiError";
|
|
38
|
+
this.status = input.status;
|
|
39
|
+
this.body = input.body;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function createPagerDutyClient(options = {}) {
|
|
43
|
+
const request = async (input) => {
|
|
44
|
+
const token = resolvePagerDutySecret(options.token, PAGERDUTY_TOKEN_ENV);
|
|
45
|
+
if (token === undefined) {
|
|
46
|
+
const name = pagerDutySecretName(options.token, PAGERDUTY_TOKEN_ENV) ?? PAGERDUTY_TOKEN_ENV;
|
|
47
|
+
throw new Error(`PagerDuty API token is not set: set ${name} (\`bdk secrets set <slug> ${name}\`) or pass \`token\`.`);
|
|
48
|
+
}
|
|
49
|
+
const from = resolvePagerDutySecret(options.from, PAGERDUTY_FROM_EMAIL_ENV);
|
|
50
|
+
const base = pagerDutyApiBaseUrl(options.apiBaseUrl);
|
|
51
|
+
const headers = {
|
|
52
|
+
Accept: "application/vnd.pagerduty+json;version=2",
|
|
53
|
+
Authorization: pagerDutyAuthorizationHeader(token),
|
|
54
|
+
"Content-Type": "application/json",
|
|
55
|
+
};
|
|
56
|
+
if (from !== undefined) {
|
|
57
|
+
headers.From = from;
|
|
58
|
+
}
|
|
59
|
+
const response = await (options.fetch ?? fetch)(`${base}${input.path}`, {
|
|
60
|
+
method: input.method,
|
|
61
|
+
headers,
|
|
62
|
+
body: input.body === undefined ? undefined : JSON.stringify(input.body),
|
|
63
|
+
});
|
|
64
|
+
const text = await response.text();
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
throw new PagerDutyApiError({
|
|
67
|
+
method: input.method,
|
|
68
|
+
path: input.path,
|
|
69
|
+
status: response.status,
|
|
70
|
+
body: text,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return (text === "" ? undefined : JSON.parse(text));
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
request,
|
|
77
|
+
addNote: async ({ incidentId, content }) => {
|
|
78
|
+
const created = await request({
|
|
79
|
+
method: "POST",
|
|
80
|
+
path: `/incidents/${encodeURIComponent(incidentId)}/notes`,
|
|
81
|
+
body: { note: { content } },
|
|
82
|
+
});
|
|
83
|
+
return created.note;
|
|
84
|
+
},
|
|
85
|
+
getIncident: async (incidentId) => {
|
|
86
|
+
const found = await request({
|
|
87
|
+
method: "GET",
|
|
88
|
+
path: `/incidents/${encodeURIComponent(incidentId)}`,
|
|
89
|
+
});
|
|
90
|
+
return found.incident;
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** The REST client for a channel's credentials, each falling back to its well-known secret. */
|
|
95
|
+
export function pagerDutyChannelClient(options) {
|
|
96
|
+
return createPagerDutyClient({
|
|
97
|
+
token: options.token,
|
|
98
|
+
from: options.from,
|
|
99
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default dispatch decisions for the PagerDuty channel: turn auth derived
|
|
3
|
+
* from the event's agent, the title and message a turn starts with, which
|
|
4
|
+
* lifecycle events dispatch when no `onIncident` hook exists, and the
|
|
5
|
+
* stream handlers that post replies back to the incident.
|
|
6
|
+
*/
|
|
7
|
+
import type { AuthContext, ChannelEventHandlers } from "../../types.js";
|
|
8
|
+
import type { PagerDutyChannelState } from "./state.js";
|
|
9
|
+
import type { PagerDutyChannelOptions, PagerDutyEventContext, PagerDutyIncidentEvent, PagerDutyTurnDispatch } from "./types.js";
|
|
10
|
+
type DispatchContext = Omit<PagerDutyEventContext, "host" | "artifacts" | "send" | "pagerduty">;
|
|
11
|
+
/**
|
|
12
|
+
* Derive the turn's auth from who made the change: a PagerDuty user, a
|
|
13
|
+
* service integration, or PagerDuty itself. The webhook subscriber is not
|
|
14
|
+
* the turn principal (same pattern as `defaultGitHubAuth`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function defaultPagerDutyAuth(ctx: DispatchContext): AuthContext;
|
|
17
|
+
export declare function defaultPagerDutyTitle(ctx: Pick<PagerDutyEventContext, "eventType" | "incidentId">, incident?: {
|
|
18
|
+
number?: number;
|
|
19
|
+
title?: string;
|
|
20
|
+
}): string;
|
|
21
|
+
/** The facts of a lifecycle event, one per line, for the turn's first message. */
|
|
22
|
+
export declare function defaultPagerDutyIncidentMessage(ctx: DispatchContext, event: PagerDutyIncidentEvent): string;
|
|
23
|
+
/**
|
|
24
|
+
* Default gate when no `onIncident` hook is declared: a new or reopened
|
|
25
|
+
* incident starts a turn as the event's agent. Acknowledgements,
|
|
26
|
+
* escalations, and resolves are acknowledged without one.
|
|
27
|
+
*/
|
|
28
|
+
export declare function defaultPagerDutyIncidentDispatch(ctx: DispatchContext, event: PagerDutyIncidentEvent): PagerDutyTurnDispatch | null;
|
|
29
|
+
/**
|
|
30
|
+
* Opt-in delivery (`deliverReplies: true`): post each completed assistant
|
|
31
|
+
* reply as a note on the session's incident, and a short note when a turn
|
|
32
|
+
* or session fails. Skipped when the session names no incident or is an
|
|
33
|
+
* eval run, or when the channel has no token (a read-only agent).
|
|
34
|
+
*
|
|
35
|
+
* A posted note comes back as an `incident.annotated` event, which only the
|
|
36
|
+
* echo skip keeps from starting another turn. So nothing is posted until the
|
|
37
|
+
* agent's own PagerDuty user resolves (see `selfUserIds`); until then each
|
|
38
|
+
* skipped note logs a warning.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildDefaultPagerDutyEvents(options: Pick<PagerDutyChannelOptions, "deliverReplies" | "selfUserIds" | "token" | "from" | "apiBaseUrl">): ChannelEventHandlers<PagerDutyChannelState>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../src/channels/pagerduty/defaults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAIxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB,KAAK,eAAe,GAAG,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC;AAEhG;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,GAAG,WAAW,CA2BtE;AAED,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,qBAAqB,EAAE,WAAW,GAAG,YAAY,CAAC,EAC5D,QAAQ,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,MAAM,CAOR;AAED,kFAAkF;AAClF,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,sBAAsB,GAC5B,MAAM,CAeR;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,sBAAsB,GAC5B,qBAAqB,GAAG,IAAI,CAK9B;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,IAAI,CACX,uBAAuB,EACvB,gBAAgB,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,CACnE,GACA,oBAAoB,CAAC,qBAAqB,CAAC,CAgD7C"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default dispatch decisions for the PagerDuty channel: turn auth derived
|
|
3
|
+
* from the event's agent, the title and message a turn starts with, which
|
|
4
|
+
* lifecycle events dispatch when no `onIncident` hook exists, and the
|
|
5
|
+
* stream handlers that post replies back to the incident.
|
|
6
|
+
*/
|
|
7
|
+
import { PAGERDUTY_TOKEN_ENV, pagerDutyChannelClient } from "./api.js";
|
|
8
|
+
import { resolvePagerDutySecret } from "./secrets.js";
|
|
9
|
+
import { PAGERDUTY_USER_ID_ENV, resolvePagerDutySelfUserIds } from "./self-user.js";
|
|
10
|
+
/**
|
|
11
|
+
* Derive the turn's auth from who made the change: a PagerDuty user, a
|
|
12
|
+
* service integration, or PagerDuty itself. The webhook subscriber is not
|
|
13
|
+
* the turn principal (same pattern as `defaultGitHubAuth`).
|
|
14
|
+
*/
|
|
15
|
+
export function defaultPagerDutyAuth(ctx) {
|
|
16
|
+
const agent = ctx.agent;
|
|
17
|
+
const isUser = agent?.type === "user_reference" || agent?.type === "user";
|
|
18
|
+
const attributes = {
|
|
19
|
+
conversation_kind: "incident",
|
|
20
|
+
event_type: ctx.eventType,
|
|
21
|
+
event_id: ctx.eventId,
|
|
22
|
+
issuer: ctx.accountSubdomain === undefined ? "pagerduty" : `pagerduty:${ctx.accountSubdomain}`,
|
|
23
|
+
};
|
|
24
|
+
if (ctx.incidentId !== undefined) {
|
|
25
|
+
attributes.incident_id = ctx.incidentId;
|
|
26
|
+
}
|
|
27
|
+
if (ctx.incidentKey !== undefined) {
|
|
28
|
+
attributes.incident_key = ctx.incidentKey;
|
|
29
|
+
}
|
|
30
|
+
if (ctx.deliveryId !== undefined) {
|
|
31
|
+
attributes.delivery_id = ctx.deliveryId;
|
|
32
|
+
}
|
|
33
|
+
if (agent !== undefined) {
|
|
34
|
+
attributes.subject = agent.id;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
authenticator: "pagerduty-webhook",
|
|
38
|
+
principalId: agent === undefined ? "pagerduty" : `pagerduty:${agent.id}`,
|
|
39
|
+
principalType: isUser ? "user" : "service",
|
|
40
|
+
attributes,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function defaultPagerDutyTitle(ctx, incident) {
|
|
44
|
+
if (incident?.number !== undefined && incident.title !== undefined) {
|
|
45
|
+
return `PagerDuty #${incident.number}: ${incident.title}`;
|
|
46
|
+
}
|
|
47
|
+
return ctx.incidentId === undefined
|
|
48
|
+
? `PagerDuty ${ctx.eventType}`
|
|
49
|
+
: `PagerDuty incident ${ctx.incidentId}`;
|
|
50
|
+
}
|
|
51
|
+
/** The facts of a lifecycle event, one per line, for the turn's first message. */
|
|
52
|
+
export function defaultPagerDutyIncidentMessage(ctx, event) {
|
|
53
|
+
const incident = event.incident;
|
|
54
|
+
return [
|
|
55
|
+
`PagerDuty ${ctx.eventType}: ${incident.number === undefined ? incident.id : `#${incident.number}`}`,
|
|
56
|
+
...(incident.title === undefined ? [] : [`Title: ${incident.title}`]),
|
|
57
|
+
...(incident.status === undefined ? [] : [`Status: ${incident.status}`]),
|
|
58
|
+
...(incident.urgency === undefined ? [] : [`Urgency: ${incident.urgency}`]),
|
|
59
|
+
...(incident.service?.summary === undefined ? [] : [`Service: ${incident.service.summary}`]),
|
|
60
|
+
...(incident.priority?.summary === undefined ? [] : [`Priority: ${incident.priority.summary}`]),
|
|
61
|
+
...(incident.incidentKey === undefined ? [] : [`Incident key: ${incident.incidentKey}`]),
|
|
62
|
+
...(incident.htmlUrl === undefined ? [] : [`URL: ${incident.htmlUrl}`]),
|
|
63
|
+
...(ctx.agent?.summary === undefined ? [] : [`By: ${ctx.agent.summary}`]),
|
|
64
|
+
...(ctx.occurredAt === undefined ? [] : [`Occurred at: ${ctx.occurredAt}`]),
|
|
65
|
+
"Handle this PagerDuty incident event.",
|
|
66
|
+
].join("\n");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Default gate when no `onIncident` hook is declared: a new or reopened
|
|
70
|
+
* incident starts a turn as the event's agent. Acknowledgements,
|
|
71
|
+
* escalations, and resolves are acknowledged without one.
|
|
72
|
+
*/
|
|
73
|
+
export function defaultPagerDutyIncidentDispatch(ctx, event) {
|
|
74
|
+
if (event.eventType !== "incident.triggered" && event.eventType !== "incident.reopened") {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return { auth: defaultPagerDutyAuth(ctx) };
|
|
78
|
+
}
|
|
79
|
+
const PAGERDUTY_FAILURE_NOTE = "The agent hit an error while handling this incident. Check the agent's session for details.";
|
|
80
|
+
/**
|
|
81
|
+
* Opt-in delivery (`deliverReplies: true`): post each completed assistant
|
|
82
|
+
* reply as a note on the session's incident, and a short note when a turn
|
|
83
|
+
* or session fails. Skipped when the session names no incident or is an
|
|
84
|
+
* eval run, or when the channel has no token (a read-only agent).
|
|
85
|
+
*
|
|
86
|
+
* A posted note comes back as an `incident.annotated` event, which only the
|
|
87
|
+
* echo skip keeps from starting another turn. So nothing is posted until the
|
|
88
|
+
* agent's own PagerDuty user resolves (see `selfUserIds`); until then each
|
|
89
|
+
* skipped note logs a warning.
|
|
90
|
+
*/
|
|
91
|
+
export function buildDefaultPagerDutyEvents(options) {
|
|
92
|
+
if (options.deliverReplies !== true) {
|
|
93
|
+
return {};
|
|
94
|
+
}
|
|
95
|
+
const postNote = async (state, content) => {
|
|
96
|
+
if (state.incidentId === null ||
|
|
97
|
+
resolvePagerDutySecret(options.token, PAGERDUTY_TOKEN_ENV) === undefined) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if ((await resolvePagerDutySelfUserIds({ options })).size === 0) {
|
|
101
|
+
console.warn(`[bdk/pagerduty] warn not posting a reply note to incident ${state.incidentId}: the agent's own PagerDuty user is unknown, so the note would come back as a new event. Set ${PAGERDUTY_USER_ID_ENV} or selfUserIds, or use a token that names one user.`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
await pagerDutyChannelClient(options).addNote({ incidentId: state.incidentId, content });
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.warn(`[bdk/pagerduty] warn could not post a note to incident ${state.incidentId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
async "message.completed"(event, channel, ctx) {
|
|
113
|
+
if (ctx.session.purpose === "eval" ||
|
|
114
|
+
event.data.parentCallId !== undefined ||
|
|
115
|
+
event.data.finishReason === "tool_call" ||
|
|
116
|
+
event.data.text === "") {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
await postNote(channel.state, event.data.text);
|
|
120
|
+
},
|
|
121
|
+
async "turn.failed"(_event, channel, ctx) {
|
|
122
|
+
if (ctx.session.purpose !== "eval") {
|
|
123
|
+
await postNote(channel.state, PAGERDUTY_FAILURE_NOTE);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
async "session.failed"(_event, channel, ctx) {
|
|
127
|
+
if (ctx.session.purpose !== "eval") {
|
|
128
|
+
await postNote(channel.state, PAGERDUTY_FAILURE_NOTE);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|