@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.
Files changed (290) hide show
  1. package/AGENTS.md +1 -0
  2. package/dist/bin/agent-serve.d.ts +1 -1
  3. package/dist/bin/agent-serve.js +48 -12
  4. package/dist/channels/bitbucket/bitbucket-webhook.d.ts +3 -2
  5. package/dist/channels/bitbucket/bitbucket-webhook.d.ts.map +1 -1
  6. package/dist/channels/bitbucket/bitbucket-webhook.js +14 -9
  7. package/dist/channels/github/github-channel.d.ts.map +1 -1
  8. package/dist/channels/github/github-channel.js +9 -18
  9. package/dist/channels/pagerduty/api.d.ts +74 -0
  10. package/dist/channels/pagerduty/api.d.ts.map +1 -0
  11. package/dist/channels/pagerduty/api.js +101 -0
  12. package/dist/channels/pagerduty/defaults.d.ts +42 -0
  13. package/dist/channels/pagerduty/defaults.d.ts.map +1 -0
  14. package/dist/channels/pagerduty/defaults.js +132 -0
  15. package/dist/channels/pagerduty/events.d.ts +24 -0
  16. package/dist/channels/pagerduty/events.d.ts.map +1 -0
  17. package/dist/channels/pagerduty/events.js +38 -0
  18. package/dist/channels/pagerduty/index.d.ts +31 -0
  19. package/dist/channels/pagerduty/index.d.ts.map +1 -0
  20. package/dist/channels/pagerduty/index.js +30 -0
  21. package/dist/channels/pagerduty/pagerduty-channel.d.ts +64 -0
  22. package/dist/channels/pagerduty/pagerduty-channel.d.ts.map +1 -0
  23. package/dist/channels/pagerduty/pagerduty-channel.js +195 -0
  24. package/dist/channels/pagerduty/pagerduty-webhook.d.ts +70 -0
  25. package/dist/channels/pagerduty/pagerduty-webhook.d.ts.map +1 -0
  26. package/dist/channels/pagerduty/pagerduty-webhook.js +280 -0
  27. package/dist/channels/pagerduty/payload.d.ts +33 -0
  28. package/dist/channels/pagerduty/payload.d.ts.map +1 -0
  29. package/dist/channels/pagerduty/payload.js +150 -0
  30. package/dist/channels/pagerduty/replay.d.ts +35 -0
  31. package/dist/channels/pagerduty/replay.d.ts.map +1 -0
  32. package/dist/channels/pagerduty/replay.js +115 -0
  33. package/dist/channels/pagerduty/secrets.d.ts +16 -0
  34. package/dist/channels/pagerduty/secrets.d.ts.map +1 -0
  35. package/dist/channels/pagerduty/secrets.js +23 -0
  36. package/dist/channels/pagerduty/self-user.d.ts +51 -0
  37. package/dist/channels/pagerduty/self-user.d.ts.map +1 -0
  38. package/dist/channels/pagerduty/self-user.js +157 -0
  39. package/dist/channels/pagerduty/state.d.ts +31 -0
  40. package/dist/channels/pagerduty/state.d.ts.map +1 -0
  41. package/dist/channels/pagerduty/state.js +30 -0
  42. package/dist/channels/pagerduty/types.d.ts +217 -0
  43. package/dist/channels/pagerduty/types.d.ts.map +1 -0
  44. package/dist/channels/pagerduty/types.js +1 -0
  45. package/dist/channels.d.ts +6 -0
  46. package/dist/channels.d.ts.map +1 -1
  47. package/dist/channels.js +11 -23
  48. package/dist/docs/404.html +2 -2
  49. package/dist/docs/assets/{app.DTIg0uKK.js → app.BjS1QEI4.js} +4 -4
  50. package/dist/docs/assets/chunks/@localSearchIndexroot.oGqZumnJ.js +1 -0
  51. package/dist/docs/assets/chunks/{VPLocalSearchBox.BpJoSaxi.js → VPLocalSearchBox.BOuvjb5Y.js} +1 -1
  52. package/dist/docs/assets/chunks/{arc.ylgNvRNq.js → arc.3WR6Jf-y.js} +1 -1
  53. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.BMrNJqYk.js → architectureDiagram-Q4EWVU46.Dtb6Dqh6.js} +1 -1
  54. package/dist/docs/assets/chunks/{baseUniq.BBWUEqf9.js → baseUniq.BUyrgrZE.js} +1 -1
  55. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.DFMu-Vza.js → blockDiagram-DXYQGD6D.BVLV_voZ.js} +1 -1
  56. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.8nkAAxWv.js → c4Diagram-AHTNJAMY.jXJ1q70M.js} +1 -1
  57. package/dist/docs/assets/chunks/channel.Dt4aweTm.js +1 -0
  58. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.sO-z2Bag.js → chunk-4BX2VUAB.zz1SMBvK.js} +1 -1
  59. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.BMROzTMq.js → chunk-4TB4RGXK.CzYKuv3I.js} +1 -1
  60. package/dist/docs/assets/chunks/{chunk-55IACEB6.X81urwg7.js → chunk-55IACEB6.C7_tcJZD.js} +1 -1
  61. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.eaZVFLZM.js → chunk-EDXVE4YY.DeTwQPVO.js} +1 -1
  62. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.CmZhzstR.js → chunk-FMBD7UC4.DhMTl7ut.js} +1 -1
  63. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.CTezt9Lc.js → chunk-OYMX7WX6.Me7f5hEp.js} +1 -1
  64. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.s-T8zukB.js → chunk-QZHKN3VN.D0E0Bb6g.js} +1 -1
  65. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.DN4Nhy-D.js → chunk-YZCP3GAM.CdOOBFYL.js} +1 -1
  66. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.DGUHZs6j.js +1 -0
  67. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.DGUHZs6j.js +1 -0
  68. package/dist/docs/assets/chunks/clone.DWf3k0Z0.js +1 -0
  69. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.Cqyp4BUH.js → cose-bilkent-S5V4N54A.BNbGESzN.js} +1 -1
  70. package/dist/docs/assets/chunks/{dagre-KV5264BT.BIECOiqR.js → dagre-KV5264BT.zU7Lu_xJ.js} +1 -1
  71. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.1tLyWoTg.js → diagram-5BDNPKRD.B9qOdE5h.js} +1 -1
  72. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.BVY_6VMO.js → diagram-G4DWMVQ6.D8X-sf77.js} +1 -1
  73. package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BSZ7xiBB.js → diagram-MMDJMWI5.CW7MvMlE.js} +1 -1
  74. package/dist/docs/assets/chunks/{diagram-TYMM5635.Bho6GmLh.js → diagram-TYMM5635.J489G0Nd.js} +1 -1
  75. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.A0yVIANn.js → erDiagram-SMLLAGMA.BkW7tGfs.js} +1 -1
  76. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.ZMgbllH6.js → flowDiagram-DWJPFMVM.jc9iWORD.js} +1 -1
  77. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.BCCPBhXo.js → ganttDiagram-T4ZO3ILL.B-UQfd9E.js} +1 -1
  78. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.BOkL0BbA.js → gitGraphDiagram-UUTBAWPF.DFzrTSlJ.js} +1 -1
  79. package/dist/docs/assets/chunks/{graph.DMyZPu86.js → graph.C5IB6_e_.js} +1 -1
  80. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.CjG1IiEw.js → infoDiagram-42DDH7IO.DwF0-c8L.js} +1 -1
  81. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.UCe-kq9g.js → ishikawaDiagram-UXIWVN3A.fBaTqzE7.js} +1 -1
  82. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.3WyOK_eY.js → journeyDiagram-VCZTEJTY.CM8gDVJy.js} +1 -1
  83. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.WoRG2qY1.js → kanban-definition-6JOO6SKY.YiD1p0LB.js} +1 -1
  84. package/dist/docs/assets/chunks/{layout.DV07xDd5.js → layout.6Um-DVJT.js} +1 -1
  85. package/dist/docs/assets/chunks/{linear.CTO8mN6o.js → linear.DcTeg4Hn.js} +1 -1
  86. package/dist/docs/assets/chunks/{min.SvTtcKuZ.js → min.CIxkY8Fe.js} +1 -1
  87. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.DMGgQ-HB.js → mindmap-definition-QFDTVHPH.D4QM_voR.js} +1 -1
  88. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.B7851apI.js → pieDiagram-DEJITSTG.nmB309G1.js} +1 -1
  89. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CEqyypIX.js → quadrantDiagram-34T5L4WZ.D1HtZR3C.js} +1 -1
  90. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.C3Mwsw-H.js → requirementDiagram-MS252O5E.CZgQWob-.js} +1 -1
  91. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.DyYK0XxY.js → sankeyDiagram-XADWPNL6.DtiBfU-P.js} +1 -1
  92. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.SiQPH-XM.js → sequenceDiagram-FGHM5R23.Cld4gDSt.js} +1 -1
  93. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.CTJMsP4p.js → stateDiagram-FHFEXIEX.DatP823_.js} +1 -1
  94. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.C0571l4D.js +1 -0
  95. package/dist/docs/assets/chunks/{theme.DJo4my9R.js → theme.D5jbBys7.js} +2 -2
  96. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.CxSNRlQ6.js → timeline-definition-GMOUNBTQ.DwQLI2be.js} +1 -1
  97. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.BdoJskyD.js → vennDiagram-DHZGUBPP.a5yMfnsa.js} +1 -1
  98. package/dist/docs/assets/chunks/wardley-RL74JXVD.B-FXivgT.js +162 -0
  99. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.IjIbFn_F.js → wardleyDiagram-NUSXRM2D.Dz--Opy3.js} +1 -1
  100. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.CPUxDZLH.js → xychartDiagram-5P7HB3ND.Dl8w8TeT.js} +1 -1
  101. package/dist/docs/assets/{guides_opentelemetry.md.Ck1o2frw.js → guides_opentelemetry.md.DBQtp7_V.js} +4 -4
  102. package/dist/docs/assets/{guides_opentelemetry.md.Ck1o2frw.lean.js → guides_opentelemetry.md.DBQtp7_V.lean.js} +1 -1
  103. package/dist/docs/assets/guides_pagerduty.md.BHXMcMtx.js +60 -0
  104. package/dist/docs/assets/guides_pagerduty.md.BHXMcMtx.lean.js +1 -0
  105. package/dist/docs/assets/{reference_channels.md.DYg0CLud.js → reference_channels.md.Bxaa020x.js} +1 -1
  106. package/dist/docs/assets/{reference_cli.md.DB7Llw3T.js → reference_cli.md.1o_TqKdt.js} +7 -2
  107. package/dist/docs/assets/{reference_cli.md.DB7Llw3T.lean.js → reference_cli.md.1o_TqKdt.lean.js} +1 -1
  108. package/dist/docs/assets/{reference_tools.md.08XR7lIl.js → reference_tools.md.-6pypsWt.js} +1 -1
  109. package/dist/docs/building-with-agents.html +35 -35
  110. package/dist/docs/deployment.html +35 -35
  111. package/dist/docs/evals.html +35 -35
  112. package/dist/docs/guides/agent-to-agent.html +35 -35
  113. package/dist/docs/guides/bitbucket.html +36 -36
  114. package/dist/docs/guides/cloud-agents.html +35 -35
  115. package/dist/docs/guides/convert-automation.html +35 -35
  116. package/dist/docs/guides/export-grokbot.html +35 -35
  117. package/dist/docs/guides/github.html +35 -35
  118. package/dist/docs/guides/gitlab.html +35 -35
  119. package/dist/docs/guides/grokbot-agents.html +35 -35
  120. package/dist/docs/guides/hooks.html +35 -35
  121. package/dist/docs/guides/improve.html +35 -35
  122. package/dist/docs/guides/jev.html +35 -35
  123. package/dist/docs/guides/mcp-oauth.html +35 -35
  124. package/dist/docs/guides/migrate.html +35 -35
  125. package/dist/docs/guides/opentelemetry.html +39 -39
  126. package/dist/docs/guides/opentelemetry.md +10 -5
  127. package/dist/docs/guides/pagerduty.html +119 -0
  128. package/dist/docs/guides/pagerduty.md +336 -0
  129. package/dist/docs/guides/slack.html +35 -35
  130. package/dist/docs/guides/webhooks.html +35 -35
  131. package/dist/docs/hashmap.json +1 -1
  132. package/dist/docs/hillclimbing.html +35 -35
  133. package/dist/docs/index.html +35 -35
  134. package/dist/docs/llms-full.txt +381 -6
  135. package/dist/docs/llms.txt +1 -0
  136. package/dist/docs/quickstart.html +35 -35
  137. package/dist/docs/reference/agent-config.html +35 -35
  138. package/dist/docs/reference/artifacts.html +35 -35
  139. package/dist/docs/reference/channels.html +37 -37
  140. package/dist/docs/reference/channels.md +2 -1
  141. package/dist/docs/reference/cli.html +42 -37
  142. package/dist/docs/reference/cli.md +27 -0
  143. package/dist/docs/reference/connections.html +35 -35
  144. package/dist/docs/reference/evals.html +35 -35
  145. package/dist/docs/reference/extensions.html +36 -36
  146. package/dist/docs/reference/hooks.html +35 -35
  147. package/dist/docs/reference/http-api.html +35 -35
  148. package/dist/docs/reference/instructions.html +35 -35
  149. package/dist/docs/reference/memory.html +35 -35
  150. package/dist/docs/reference/playground.html +35 -35
  151. package/dist/docs/reference/project-layout.html +35 -35
  152. package/dist/docs/reference/prompt.html +35 -35
  153. package/dist/docs/reference/schedules.html +35 -35
  154. package/dist/docs/reference/sessions.html +35 -35
  155. package/dist/docs/reference/skills.html +35 -35
  156. package/dist/docs/reference/subagents.html +35 -35
  157. package/dist/docs/reference/tools.html +37 -37
  158. package/dist/docs/reference/tools.md +1 -0
  159. package/dist/docs/templates/agentic-owners.html +35 -35
  160. package/dist/docs/templates/grokbot-agents.html +35 -35
  161. package/dist/docs/templates/security-reviewer.html +35 -35
  162. package/dist/docs/templates/thermo-quality-review.html +35 -35
  163. package/dist/docs/templates/thermo-review.html +35 -35
  164. package/dist/docs/templates/triage.html +35 -35
  165. package/dist/docs/troubleshooting.html +35 -35
  166. package/dist/internal/approval-gate.d.ts +4 -2
  167. package/dist/internal/approval-gate.d.ts.map +1 -1
  168. package/dist/internal/approval-gate.js +2 -1
  169. package/dist/internal/builtin-tools/artifacts.d.ts.map +1 -1
  170. package/dist/internal/builtin-tools/artifacts.js +45 -12
  171. package/dist/internal/channel-architecture.d.ts +1 -1
  172. package/dist/internal/channel-architecture.d.ts.map +1 -1
  173. package/dist/internal/channel-architecture.js +4 -2
  174. package/dist/internal/cli-deploy.d.ts.map +1 -1
  175. package/dist/internal/cli-deploy.js +21 -12
  176. package/dist/internal/cli-pagerduty.d.ts +32 -0
  177. package/dist/internal/cli-pagerduty.d.ts.map +1 -0
  178. package/dist/internal/cli-pagerduty.js +242 -0
  179. package/dist/internal/continuation-channel.d.ts.map +1 -1
  180. package/dist/internal/continuation-channel.js +7 -0
  181. package/dist/internal/continuation-identity.d.ts +11 -3
  182. package/dist/internal/continuation-identity.d.ts.map +1 -1
  183. package/dist/internal/continuation-identity.js +83 -0
  184. package/dist/internal/deploy-manifest.d.ts +11 -4
  185. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  186. package/dist/internal/deploy-manifest.js +17 -5
  187. package/dist/internal/discovery/agent-config.d.ts.map +1 -1
  188. package/dist/internal/discovery/agent-config.js +10 -10
  189. package/dist/internal/discovery/agent.d.ts.map +1 -1
  190. package/dist/internal/discovery/agent.js +10 -10
  191. package/dist/internal/discovery/channels.d.ts.map +1 -1
  192. package/dist/internal/discovery/channels.js +20 -16
  193. package/dist/internal/discovery/context.d.ts +16 -0
  194. package/dist/internal/discovery/context.d.ts.map +1 -1
  195. package/dist/internal/discovery/context.js +66 -0
  196. package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
  197. package/dist/internal/discovery/extension-overlay.js +2 -6
  198. package/dist/internal/discovery/info.d.ts.map +1 -1
  199. package/dist/internal/discovery/info.js +3 -0
  200. package/dist/internal/discovery/instructions.d.ts.map +1 -1
  201. package/dist/internal/discovery/instructions.js +3 -6
  202. package/dist/internal/discovery/modules.d.ts.map +1 -1
  203. package/dist/internal/discovery/modules.js +3 -6
  204. package/dist/internal/discovery/project.d.ts +6 -0
  205. package/dist/internal/discovery/project.d.ts.map +1 -1
  206. package/dist/internal/discovery/project.js +27 -5
  207. package/dist/internal/discovery/runtime.d.ts.map +1 -1
  208. package/dist/internal/discovery/runtime.js +8 -8
  209. package/dist/internal/discovery.d.ts +1 -1
  210. package/dist/internal/discovery.d.ts.map +1 -1
  211. package/dist/internal/discovery.js +1 -1
  212. package/dist/internal/expected-delivery-failure.d.ts.map +1 -1
  213. package/dist/internal/expected-delivery-failure.js +6 -0
  214. package/dist/internal/filesystem/sdk-schemas.d.ts.map +1 -1
  215. package/dist/internal/filesystem/sdk-schemas.js +4 -3
  216. package/dist/internal/hmac-secret-values.d.ts +48 -0
  217. package/dist/internal/hmac-secret-values.d.ts.map +1 -0
  218. package/dist/internal/hmac-secret-values.js +68 -0
  219. package/dist/internal/host-platforms.d.ts.map +1 -1
  220. package/dist/internal/host-platforms.js +8 -2
  221. package/dist/internal/json-schema.d.ts +7 -7
  222. package/dist/internal/json-schema.d.ts.map +1 -1
  223. package/dist/internal/json-schema.js +13 -16
  224. package/dist/internal/otel/collector.d.ts.map +1 -1
  225. package/dist/internal/otel/collector.js +3 -1
  226. package/dist/internal/otel/config.d.ts +6 -1
  227. package/dist/internal/otel/config.d.ts.map +1 -1
  228. package/dist/internal/otel/config.js +27 -1
  229. package/dist/internal/otel/runtime.d.ts.map +1 -1
  230. package/dist/internal/otel/runtime.js +26 -3
  231. package/dist/internal/package-inline-stdio.d.ts.map +1 -1
  232. package/dist/internal/package-inline-stdio.js +21 -6
  233. package/dist/internal/sdk-runner.d.ts +2 -3
  234. package/dist/internal/sdk-runner.d.ts.map +1 -1
  235. package/dist/internal/sdk-runner.js +8 -4
  236. package/dist/internal/secret-alternatives.d.ts +11 -0
  237. package/dist/internal/secret-alternatives.d.ts.map +1 -0
  238. package/dist/internal/secret-alternatives.js +13 -0
  239. package/dist/internal/server.js +2 -2
  240. package/dist/internal/session-engine.d.ts.map +1 -1
  241. package/dist/internal/session-engine.js +5 -4
  242. package/dist/internal/sqlite-experimental-warning.d.ts +2 -0
  243. package/dist/internal/sqlite-experimental-warning.d.ts.map +1 -0
  244. package/dist/internal/sqlite-experimental-warning.js +22 -0
  245. package/dist/internal/testing/conversation-identity-vectors.d.ts +6 -1
  246. package/dist/internal/testing/conversation-identity-vectors.d.ts.map +1 -1
  247. package/dist/internal/testing/conversation-identity-vectors.js +34 -0
  248. package/dist/internal/testing/hmac-secret-vectors.d.ts +38 -0
  249. package/dist/internal/testing/hmac-secret-vectors.d.ts.map +1 -0
  250. package/dist/internal/testing/hmac-secret-vectors.js +89 -0
  251. package/dist/internal/testing/pagerduty-continuation-fixtures.d.ts +42 -0
  252. package/dist/internal/testing/pagerduty-continuation-fixtures.d.ts.map +1 -0
  253. package/dist/internal/testing/pagerduty-continuation-fixtures.js +175 -0
  254. package/dist/internal/zod-schema.d.ts +14 -0
  255. package/dist/internal/zod-schema.d.ts.map +1 -0
  256. package/dist/internal/zod-schema.js +22 -0
  257. package/dist/playground/assets/cursor-icons-16-DmHBTm1-.woff2 +0 -0
  258. package/dist/playground/assets/index-BdMwybMt.css +1 -0
  259. package/dist/playground/assets/{index-DKKdkF29.js → index-CHk6O92d.js} +38 -38
  260. package/dist/playground/index.html +2 -2
  261. package/dist/tools.d.ts +13 -10
  262. package/dist/tools.d.ts.map +1 -1
  263. package/dist/tools.js +3 -2
  264. package/dist/types.d.ts +67 -16
  265. package/dist/types.d.ts.map +1 -1
  266. package/docs/guides/opentelemetry.md +10 -5
  267. package/docs/guides/pagerduty.md +341 -0
  268. package/docs/reference/channels.md +2 -1
  269. package/docs/reference/cli.md +27 -0
  270. package/docs/reference/tools.md +1 -0
  271. package/package.json +10 -3
  272. package/skills/migrate-v2/SKILL.md +1 -1
  273. package/skills/otel/SKILL.md +7 -3
  274. package/templates/agentic-owners/README.md +6 -1
  275. package/templates/agentic-owners/bot/lib/owners/decision.ts +31 -5
  276. package/templates/agentic-owners/bot/lib/owners/globalOverride.ts +60 -0
  277. package/templates/agentic-owners/bot/lib/owners/match.ts +85 -19
  278. package/templates/agentic-owners/bot/lib/owners/parse.ts +133 -2
  279. package/templates/agentic-owners/bot/lib/owners/types.ts +23 -0
  280. package/dist/docs/assets/chunks/@localSearchIndexroot.3ebvCWKy.js +0 -1
  281. package/dist/docs/assets/chunks/channel.BOebySCN.js +0 -1
  282. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.C55IaN-T.js +0 -1
  283. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.C55IaN-T.js +0 -1
  284. package/dist/docs/assets/chunks/clone.D06pA7ML.js +0 -1
  285. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.DddRVjeq.js +0 -1
  286. package/dist/docs/assets/chunks/wardley-RL74JXVD.CVCRSuQK.js +0 -162
  287. package/dist/playground/assets/cursor-icons-16-gwXtdAvu.woff2 +0 -0
  288. package/dist/playground/assets/index-DpKinTMs.css +0 -1
  289. /package/dist/docs/assets/{reference_channels.md.DYg0CLud.lean.js → reference_channels.md.Bxaa020x.lean.js} +0 -0
  290. /package/dist/docs/assets/{reference_tools.md.08XR7lIl.lean.js → reference_tools.md.-6pypsWt.lean.js} +0 -0
@@ -0,0 +1,280 @@
1
+ import { createHmac } from "node:crypto";
2
+ import { acknowledgeTask, isTaskDispatch, skipped, turnStarted, } from "../../internal/channel-dispatch.js";
3
+ import { continuationSource, mintClaim } from "../../internal/continuation-identity.js";
4
+ import { hmacSignatureMatchesAny, parseHmacSecrets } from "../../internal/hmac-secret-values.js";
5
+ import { bindLocalIngressSend } from "../../internal/local-ingress.js";
6
+ import { defaultPagerDutyIncidentDispatch, defaultPagerDutyIncidentMessage, defaultPagerDutyTitle, } from "./defaults.js";
7
+ import { isPagerDutyIncidentLifecycleEvent, PAGERDUTY_CHANNEL_KIND, PAGERDUTY_NOTE_EVENTS, PAGERDUTY_RESPONDER_EVENTS, } from "./events.js";
8
+ import { asNonEmptyString, pagerDutyAccountSubdomain, pagerDutyEventIncident, pagerDutyEventRecord, pagerDutyIncidentFromData, pagerDutyNoteFromData, pagerDutyReference, pagerDutyResponderFromData, } from "./payload.js";
9
+ import { pagerDutyChannelClient } from "./api.js";
10
+ import { resolvePagerDutySecret } from "./secrets.js";
11
+ import { resolvePagerDutySelfUserIds } from "./self-user.js";
12
+ import { pagerDutyChannelStateForEvent } from "./state.js";
13
+ /** Env var / deployment secret an omitted `webhookSecret` falls back to. */
14
+ export const PAGERDUTY_WEBHOOK_SECRET_ENV = "PAGERDUTY_WEBHOOK_SECRET";
15
+ /** Header PagerDuty signs v3 deliveries with: `v1=<hex>[,v1=<hex>…]`. */
16
+ export const PAGERDUTY_SIGNATURE_HEADER = "x-pagerduty-signature";
17
+ export const PAGERDUTY_SIGNATURE_PREFIX = "v1=";
18
+ /** Separator between signatures while a subscription's secret rotates. */
19
+ export const PAGERDUTY_SIGNATURE_SEPARATOR = ",";
20
+ /**
21
+ * The secret's value for the handler's own signature check, read now: an
22
+ * omitted field names `PAGERDUTY_WEBHOOK_SECRET` (hosted, the addressed
23
+ * installation's secret), and an authored name never falls back to it.
24
+ */
25
+ export function resolvePagerDutyWebhookSecret(options) {
26
+ return resolvePagerDutySecret(options.webhookSecret, PAGERDUTY_WEBHOOK_SECRET_ENV);
27
+ }
28
+ /** One `X-PagerDuty-Signature` entry for a raw body: `v1=<hex>`. */
29
+ export function signPagerDutyWebhookBody(input) {
30
+ return `${PAGERDUTY_SIGNATURE_PREFIX}${createHmac("sha256", input.secret).update(input.rawBody).digest("hex")}`;
31
+ }
32
+ /**
33
+ * True when any `v1=` entry in the header is the body's HMAC-SHA256 under
34
+ * any secret `secret` holds. `secret` is the named secret's value: one
35
+ * signing secret, or one per line when several subscriptions sign the
36
+ * route. Every (secret, entry) pair is compared in constant time with no
37
+ * early exit; malformed entries never match, and a missing header is a
38
+ * plain `false`.
39
+ */
40
+ export function verifyPagerDutyWebhookSignature(input) {
41
+ const parsed = parseHmacSecrets(input.secret);
42
+ if (input.signatureHeader === null || input.signatureHeader === undefined || !parsed.ok) {
43
+ return false;
44
+ }
45
+ return hmacSignatureMatchesAny({
46
+ body: input.rawBody,
47
+ presented: input.signatureHeader,
48
+ secrets: parsed.secrets,
49
+ prefix: PAGERDUTY_SIGNATURE_PREFIX,
50
+ separator: PAGERDUTY_SIGNATURE_SEPARATOR,
51
+ });
52
+ }
53
+ /**
54
+ * True when the event is the agent's own action echoed back: its `agent`
55
+ * is a PagerDuty user the agent acts as. Service integrations and
56
+ * PagerDuty itself never count, so an alert the agent's own monitor opened
57
+ * still dispatches.
58
+ */
59
+ export function isPagerDutySelfEcho(ctx, selfUserIds) {
60
+ const agent = ctx.agent;
61
+ if (agent === undefined || selfUserIds.size === 0) {
62
+ return false;
63
+ }
64
+ if (agent.type !== undefined && agent.type !== "user_reference" && agent.type !== "user") {
65
+ return false;
66
+ }
67
+ return selfUserIds.has(agent.id);
68
+ }
69
+ /**
70
+ * Accept a raw v3 body. The event type comes from the signed body's
71
+ * `event.event_type`, never from a header, so a captured delivery cannot be
72
+ * re-dispatched as another event.
73
+ */
74
+ export function parsePagerDutyWebhookPayload(payload) {
75
+ const event = pagerDutyEventRecord(payload);
76
+ const eventType = asNonEmptyString(event?.event_type);
77
+ if (event === undefined || eventType === undefined) {
78
+ return null;
79
+ }
80
+ return { eventType, payload: payload };
81
+ }
82
+ export function parsePagerDutyEventContext(delivery) {
83
+ const event = pagerDutyEventRecord(delivery.payload);
84
+ const eventId = asNonEmptyString(event?.id);
85
+ if (event === undefined || eventId === undefined) {
86
+ return null;
87
+ }
88
+ const incident = pagerDutyEventIncident(event);
89
+ return {
90
+ deliveryId: delivery.deliveryId,
91
+ eventId,
92
+ eventType: delivery.eventType,
93
+ resourceType: asNonEmptyString(event.resource_type),
94
+ occurredAt: asNonEmptyString(event.occurred_at),
95
+ agent: pagerDutyReference(event.agent),
96
+ incidentId: incident?.id,
97
+ incidentKey: incident?.incidentKey,
98
+ accountSubdomain: pagerDutyAccountSubdomain(event),
99
+ payload: event,
100
+ };
101
+ }
102
+ function invalidPayload(error) {
103
+ return Response.json({ ok: false, error }, { status: 400 });
104
+ }
105
+ async function applyDispatch(input) {
106
+ const extra = { event: input.ctx.eventType };
107
+ if (input.dispatch === null) {
108
+ return skipped("not_dispatched", extra);
109
+ }
110
+ if (isTaskDispatch(input.dispatch)) {
111
+ return acknowledgeTask(input.args, PAGERDUTY_CHANNEL_KIND, input.dispatch, extra);
112
+ }
113
+ const ctx = input.ctx;
114
+ const state = pagerDutyChannelStateForEvent({
115
+ eventType: ctx.eventType,
116
+ eventId: ctx.eventId,
117
+ incidentId: ctx.incidentId,
118
+ incidentNumber: input.incidentNumber,
119
+ incidentKey: ctx.incidentKey,
120
+ serviceId: input.serviceId,
121
+ deliveryId: ctx.deliveryId,
122
+ occurredAt: ctx.occurredAt,
123
+ });
124
+ // v1 agents (omitted continuation resolves to `none/v1`) keep one
125
+ // engine-minted conversation per incident; v2 takes the CP stamp.
126
+ const engineToken = continuationSource(input.options.continuation, PAGERDUTY_CHANNEL_KIND) === "engine" &&
127
+ ctx.incidentId !== undefined
128
+ ? mintClaim({
129
+ type: "pagerduty-incident",
130
+ resource: { incidentId: ctx.incidentId },
131
+ }).slice("cont:".length)
132
+ : undefined;
133
+ const turn = {
134
+ auth: input.dispatch.auth,
135
+ title: input.dispatch.title ?? input.title,
136
+ state: state,
137
+ refreshState: state,
138
+ };
139
+ if (engineToken !== undefined) {
140
+ turn.continuationToken = engineToken;
141
+ }
142
+ if (input.options.cloud !== undefined) {
143
+ turn.cloud = input.options.cloud;
144
+ }
145
+ const session = await input.args.send([input.dispatch.message ?? input.message, ...(input.dispatch.context ?? [])].join("\n"), turn);
146
+ return turnStarted(session);
147
+ }
148
+ /**
149
+ * Run the authored hooks for one verified PagerDuty delivery and `send()`
150
+ * the turn. Callers own delivery auth: the HTTP route verifies
151
+ * `X-PagerDuty-Signature`; hosted admission arrives verified. The v2
152
+ * mailbox is stamped upstream (local CP or hosted ingress), never here.
153
+ */
154
+ export async function dispatchPagerDutyWebhook(input) {
155
+ const parsed = parsePagerDutyEventContext(input.delivery);
156
+ if (parsed === null) {
157
+ return invalidPayload("invalid_pagerduty_payload");
158
+ }
159
+ const args = input.args;
160
+ const ctx = {
161
+ ...parsed,
162
+ pagerduty: pagerDutyChannelClient(input.options),
163
+ host: args.host,
164
+ artifacts: args.artifacts,
165
+ send: args.send,
166
+ };
167
+ const eventType = ctx.eventType;
168
+ if (eventType === "pagey.ping") {
169
+ return skipped("ping");
170
+ }
171
+ if (isPagerDutySelfEcho(ctx, await resolvePagerDutySelfUserIds({ options: input.options }))) {
172
+ return skipped("self_echo", { event: eventType, agent: ctx.agent?.id });
173
+ }
174
+ const data = ctx.payload.data;
175
+ if (isPagerDutyIncidentLifecycleEvent(eventType)) {
176
+ const incident = pagerDutyIncidentFromData(data);
177
+ if (incident === undefined) {
178
+ return invalidPayload("invalid_pagerduty_incident_payload");
179
+ }
180
+ const event = { eventType, action: eventType.slice("incident.".length), incident };
181
+ const dispatch = input.options.onIncident === undefined
182
+ ? defaultPagerDutyIncidentDispatch(ctx, event)
183
+ : await input.options.onIncident(ctx, event);
184
+ return applyDispatch({
185
+ options: input.options,
186
+ args,
187
+ ctx,
188
+ dispatch,
189
+ message: defaultPagerDutyIncidentMessage(ctx, event),
190
+ title: defaultPagerDutyTitle(ctx, incident),
191
+ incidentNumber: incident.number,
192
+ serviceId: incident.service?.id,
193
+ });
194
+ }
195
+ if (PAGERDUTY_NOTE_EVENTS.includes(eventType)) {
196
+ if (input.options.onNote === undefined) {
197
+ return skipped("no_handler", { event: eventType });
198
+ }
199
+ const note = pagerDutyNoteFromData(data);
200
+ if (note === undefined) {
201
+ return invalidPayload("invalid_pagerduty_note_payload");
202
+ }
203
+ return applyDispatch({
204
+ options: input.options,
205
+ args,
206
+ ctx,
207
+ dispatch: await input.options.onNote(ctx, note),
208
+ message: `PagerDuty note on incident ${note.incident.id}:\n${note.content}`,
209
+ title: defaultPagerDutyTitle(ctx),
210
+ });
211
+ }
212
+ if (PAGERDUTY_RESPONDER_EVENTS.includes(eventType)) {
213
+ if (input.options.onResponder === undefined) {
214
+ return skipped("no_handler", { event: eventType });
215
+ }
216
+ const responder = pagerDutyResponderFromData(eventType, data);
217
+ if (responder === undefined) {
218
+ return invalidPayload("invalid_pagerduty_responder_payload");
219
+ }
220
+ return applyDispatch({
221
+ options: input.options,
222
+ args,
223
+ ctx,
224
+ dispatch: await input.options.onResponder(ctx, responder),
225
+ message: `PagerDuty ${eventType} on incident ${responder.incident.id}`,
226
+ title: defaultPagerDutyTitle(ctx),
227
+ });
228
+ }
229
+ if (input.options.onEvent === undefined) {
230
+ return skipped("unsupported_event", { event: eventType });
231
+ }
232
+ return applyDispatch({
233
+ options: input.options,
234
+ args,
235
+ ctx,
236
+ dispatch: await input.options.onEvent(ctx, { eventType, data }),
237
+ message: `PagerDuty ${eventType} event`,
238
+ title: defaultPagerDutyTitle(ctx),
239
+ });
240
+ }
241
+ /**
242
+ * HTTP entry for one agent's PagerDuty channel: the `X-PagerDuty-Signature`
243
+ * check when a secret is configured, then {@link dispatchPagerDutyWebhook}.
244
+ * Without a secret the route auth owns admission (`serve --dev` admits
245
+ * loopback only; production stays loopback-strict).
246
+ */
247
+ export async function handlePagerDutyWebhookRequest(input) {
248
+ const bodyText = await input.request.text();
249
+ const secret = resolvePagerDutyWebhookSecret(input.options);
250
+ if (secret !== undefined &&
251
+ !verifyPagerDutyWebhookSignature({
252
+ rawBody: bodyText,
253
+ signatureHeader: input.request.headers.get(PAGERDUTY_SIGNATURE_HEADER),
254
+ secret,
255
+ })) {
256
+ return Response.json({ ok: false, error: "invalid_signature" }, { status: 401 });
257
+ }
258
+ let payload;
259
+ try {
260
+ payload = JSON.parse(bodyText);
261
+ }
262
+ catch {
263
+ return Response.json({ ok: false, error: "invalid_json" }, { status: 400 });
264
+ }
265
+ const delivery = parsePagerDutyWebhookPayload(payload);
266
+ if (delivery === null) {
267
+ return invalidPayload("invalid_pagerduty_payload");
268
+ }
269
+ delivery.deliveryId = input.request.headers.get("x-webhook-id") ?? undefined;
270
+ return dispatchPagerDutyWebhook({
271
+ options: input.options,
272
+ delivery,
273
+ args: bindLocalIngressSend(input.args, {
274
+ identity: input.options.continuation,
275
+ kind: PAGERDUTY_CHANNEL_KIND,
276
+ eventType: delivery.eventType,
277
+ payload: delivery.payload,
278
+ }),
279
+ });
280
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Typed views over a PagerDuty v3 webhook body. Every reader tolerates
3
+ * missing optional fields and returns `undefined` for a shape it does not
4
+ * recognize, so a new PagerDuty field never fails a delivery.
5
+ */
6
+ import type { PagerDutyIncident, PagerDutyIncidentNote, PagerDutyReference, PagerDutyResponderEvent } from "./types.js";
7
+ export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
8
+ export declare function asNonEmptyString(value: unknown): string | undefined;
9
+ /** The delivery's `event` record, or `undefined` when the body is not a v3 event. */
10
+ export declare function pagerDutyEventRecord(payload: unknown): Record<string, unknown> | undefined;
11
+ export declare function pagerDutyReference(value: unknown): PagerDutyReference | undefined;
12
+ /** `data` of a lifecycle event: the full incident. */
13
+ export declare function pagerDutyIncidentFromData(data: unknown): PagerDutyIncident | undefined;
14
+ /** `data` of `incident.annotated`. */
15
+ export declare function pagerDutyNoteFromData(data: unknown): PagerDutyIncidentNote | undefined;
16
+ /** `data` of `incident.responder.added` / `.replied`. */
17
+ export declare function pagerDutyResponderFromData(eventType: string, data: unknown): PagerDutyResponderEvent | undefined;
18
+ /**
19
+ * The incident any incident event names: `data` itself for lifecycle
20
+ * events, `data.incident` for sub-resources. Mirrors the continuation
21
+ * selector, so a hook's `ctx.incidentId` names the session's incident.
22
+ */
23
+ export declare function pagerDutyEventIncident(event: Record<string, unknown>): {
24
+ id: string;
25
+ incidentKey?: string;
26
+ } | undefined;
27
+ /**
28
+ * The account subdomain (`acme` for `acme.pagerduty.com` or
29
+ * `acme.eu.pagerduty.com`) from the first PagerDuty web URL the event
30
+ * carries: the incident's, the agent's, or the data's own.
31
+ */
32
+ export declare function pagerDutyAccountSubdomain(event: Record<string, unknown>): string | undefined;
33
+ //# sourceMappingURL=payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../src/channels/pagerduty/payload.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EAErB,kBAAkB,EAClB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAI5E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEnE;AAMD,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAG1F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CAYjF;AAYD,sDAAsD;AACtD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAsBtF;AAUD,sCAAsC;AACtC,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,qBAAqB,GAAG,SAAS,CAYtF;AAED,yDAAyD;AACzD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,GACZ,uBAAuB,GAAG,SAAS,CAcrC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAUlD;AAID;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAuB5F"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Typed views over a PagerDuty v3 webhook body. Every reader tolerates
3
+ * missing optional fields and returns `undefined` for a shape it does not
4
+ * recognize, so a new PagerDuty field never fails a delivery.
5
+ */
6
+ export function asRecord(value) {
7
+ return typeof value === "object" && value !== null && !Array.isArray(value)
8
+ ? value
9
+ : undefined;
10
+ }
11
+ export function asNonEmptyString(value) {
12
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : undefined;
13
+ }
14
+ function asPositiveInt(value) {
15
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : undefined;
16
+ }
17
+ /** The delivery's `event` record, or `undefined` when the body is not a v3 event. */
18
+ export function pagerDutyEventRecord(payload) {
19
+ const event = asRecord(asRecord(payload)?.event);
20
+ return asNonEmptyString(event?.event_type) === undefined ? undefined : event;
21
+ }
22
+ export function pagerDutyReference(value) {
23
+ const record = asRecord(value);
24
+ const id = asNonEmptyString(record?.id);
25
+ if (record === undefined || id === undefined) {
26
+ return undefined;
27
+ }
28
+ return {
29
+ id,
30
+ type: asNonEmptyString(record.type),
31
+ summary: asNonEmptyString(record.summary),
32
+ htmlUrl: asNonEmptyString(record.html_url),
33
+ };
34
+ }
35
+ function references(value) {
36
+ if (!Array.isArray(value)) {
37
+ return [];
38
+ }
39
+ return value.flatMap((entry) => {
40
+ const reference = pagerDutyReference(entry);
41
+ return reference === undefined ? [] : [reference];
42
+ });
43
+ }
44
+ /** `data` of a lifecycle event: the full incident. */
45
+ export function pagerDutyIncidentFromData(data) {
46
+ const record = asRecord(data);
47
+ const id = asNonEmptyString(record?.id);
48
+ if (record === undefined || id === undefined || record.type !== "incident") {
49
+ return undefined;
50
+ }
51
+ return {
52
+ id,
53
+ number: asPositiveInt(record.number),
54
+ title: asNonEmptyString(record.title),
55
+ status: asNonEmptyString(record.status),
56
+ urgency: asNonEmptyString(record.urgency),
57
+ incidentKey: asNonEmptyString(record.incident_key),
58
+ htmlUrl: asNonEmptyString(record.html_url),
59
+ createdAt: asNonEmptyString(record.created_at),
60
+ service: pagerDutyReference(record.service),
61
+ escalationPolicy: pagerDutyReference(record.escalation_policy),
62
+ priority: pagerDutyReference(record.priority),
63
+ assignees: references(record.assignees),
64
+ teams: references(record.teams),
65
+ resolveReason: asNonEmptyString(record.resolve_reason),
66
+ };
67
+ }
68
+ function incidentRef(value) {
69
+ const reference = pagerDutyReference(value);
70
+ if (reference === undefined) {
71
+ return undefined;
72
+ }
73
+ return { ...reference, incidentKey: asNonEmptyString(asRecord(value)?.incident_key) };
74
+ }
75
+ /** `data` of `incident.annotated`. */
76
+ export function pagerDutyNoteFromData(data) {
77
+ const record = asRecord(data);
78
+ const incident = incidentRef(record?.incident);
79
+ if (record === undefined || incident === undefined || typeof record.content !== "string") {
80
+ return undefined;
81
+ }
82
+ return {
83
+ id: asNonEmptyString(record.id),
84
+ content: record.content,
85
+ trimmed: record.trimmed === true,
86
+ incident,
87
+ };
88
+ }
89
+ /** `data` of `incident.responder.added` / `.replied`. */
90
+ export function pagerDutyResponderFromData(eventType, data) {
91
+ const record = asRecord(data);
92
+ const incident = incidentRef(record?.incident);
93
+ if (record === undefined || incident === undefined) {
94
+ return undefined;
95
+ }
96
+ return {
97
+ action: eventType === "incident.responder.replied" ? "replied" : "added",
98
+ incident,
99
+ user: pagerDutyReference(record.user),
100
+ escalationPolicy: pagerDutyReference(record.escalation_policy),
101
+ message: asNonEmptyString(record.message),
102
+ state: asNonEmptyString(record.state),
103
+ };
104
+ }
105
+ /**
106
+ * The incident any incident event names: `data` itself for lifecycle
107
+ * events, `data.incident` for sub-resources. Mirrors the continuation
108
+ * selector, so a hook's `ctx.incidentId` names the session's incident.
109
+ */
110
+ export function pagerDutyEventIncident(event) {
111
+ const data = asRecord(event.data);
112
+ const record = asRecord(data?.incident) ??
113
+ (data?.type === "incident" || event.resource_type === "incident" ? data : undefined);
114
+ const id = asNonEmptyString(record?.id);
115
+ if (id === undefined) {
116
+ return undefined;
117
+ }
118
+ return { id, incidentKey: asNonEmptyString(record?.incident_key) };
119
+ }
120
+ const PAGERDUTY_HOST = /^([a-z0-9][a-z0-9-]*)\.(?:[a-z]{2}\.)?pagerduty\.com$/i;
121
+ /**
122
+ * The account subdomain (`acme` for `acme.pagerduty.com` or
123
+ * `acme.eu.pagerduty.com`) from the first PagerDuty web URL the event
124
+ * carries: the incident's, the agent's, or the data's own.
125
+ */
126
+ export function pagerDutyAccountSubdomain(event) {
127
+ const data = asRecord(event.data);
128
+ const candidates = [
129
+ asRecord(data?.incident)?.html_url,
130
+ data?.html_url,
131
+ asRecord(event.agent)?.html_url,
132
+ asRecord(data?.service)?.html_url,
133
+ ];
134
+ for (const candidate of candidates) {
135
+ const url = asNonEmptyString(candidate);
136
+ if (url === undefined) {
137
+ continue;
138
+ }
139
+ try {
140
+ const match = PAGERDUTY_HOST.exec(new URL(url).hostname);
141
+ if (match?.[1] !== undefined) {
142
+ return match[1].toLowerCase();
143
+ }
144
+ }
145
+ catch {
146
+ // Not a URL; try the next one.
147
+ }
148
+ }
149
+ return undefined;
150
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Synthesize PagerDuty v3 webhook bodies for `bdk pagerduty replay`, so a
3
+ * local `pagerdutyChannel()` can be exercised without a PagerDuty account
4
+ * or tunnel. The bodies follow PagerDuty's documented v3 shapes: lifecycle
5
+ * events carry the incident as `data`, notes carry it as `data.incident`.
6
+ */
7
+ /** Event types `replay` can synthesize, in the order an incident usually sees them. */
8
+ export declare const PAGERDUTY_REPLAYABLE_EVENTS: readonly ["incident.triggered", "incident.acknowledged", "incident.annotated", "incident.escalated", "incident.resolved", "incident.reopened"];
9
+ export type PagerDutyReplayableEvent = (typeof PAGERDUTY_REPLAYABLE_EVENTS)[number];
10
+ export declare const PAGERDUTY_REPLAY_DEFAULT_INCIDENT_ID = "PREPLAY1";
11
+ /**
12
+ * Pick the events to replay. Accepts full names (`incident.resolved`) or
13
+ * the action alone (`resolved`); `*` selects every declared event that can
14
+ * be synthesized. Defaults to `incident.triggered`.
15
+ */
16
+ export declare function selectPagerDutyReplayEvents(input: {
17
+ /** Event names from `--events`; omitted selects the default. */
18
+ requested: readonly string[] | undefined;
19
+ /** The event types the target channels declare. */
20
+ declared: readonly string[];
21
+ }): {
22
+ events: PagerDutyReplayableEvent[];
23
+ unsupported: string[];
24
+ };
25
+ /**
26
+ * One v3 delivery body for `eventType` on `incidentId`. A trigger comes
27
+ * from PagerDuty itself (no `agent`); every other event is a person's
28
+ * action, so it dispatches rather than being skipped as the agent's echo.
29
+ */
30
+ export declare function synthesizePagerDutyEvent(input: {
31
+ eventType: PagerDutyReplayableEvent;
32
+ incidentId?: string;
33
+ note?: string;
34
+ }): Record<string, unknown>;
35
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../../src/channels/pagerduty/replay.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,uFAAuF;AACvF,eAAO,MAAM,2BAA2B,YACtC,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,CACX,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAWpF,eAAO,MAAM,oCAAoC,aAAa,CAAC;AAe/D;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,gEAAgE;IAChE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACzC,mDAAmD;IACnD,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,GAAG;IAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAAE,CAwBhE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,SAAS,EAAE,wBAAwB,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyC1B"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Synthesize PagerDuty v3 webhook bodies for `bdk pagerduty replay`, so a
3
+ * local `pagerdutyChannel()` can be exercised without a PagerDuty account
4
+ * or tunnel. The bodies follow PagerDuty's documented v3 shapes: lifecycle
5
+ * events carry the incident as `data`, notes carry it as `data.incident`.
6
+ */
7
+ import { randomUUID } from "node:crypto";
8
+ /** Event types `replay` can synthesize, in the order an incident usually sees them. */
9
+ export const PAGERDUTY_REPLAYABLE_EVENTS = [
10
+ "incident.triggered",
11
+ "incident.acknowledged",
12
+ "incident.annotated",
13
+ "incident.escalated",
14
+ "incident.resolved",
15
+ "incident.reopened",
16
+ ];
17
+ const STATUS_BY_EVENT = {
18
+ "incident.triggered": "triggered",
19
+ "incident.acknowledged": "acknowledged",
20
+ "incident.annotated": "triggered",
21
+ "incident.escalated": "triggered",
22
+ "incident.resolved": "resolved",
23
+ "incident.reopened": "triggered",
24
+ };
25
+ export const PAGERDUTY_REPLAY_DEFAULT_INCIDENT_ID = "PREPLAY1";
26
+ const SUBDOMAIN = "example";
27
+ const SERVICE = {
28
+ id: "PSVCREP",
29
+ type: "service_reference",
30
+ summary: "replayed-service",
31
+ html_url: `https://${SUBDOMAIN}.pagerduty.com/service-directory/PSVCREP`,
32
+ };
33
+ const RESPONDER = {
34
+ id: "PUSERREP",
35
+ type: "user_reference",
36
+ summary: "Replay Responder",
37
+ html_url: `https://${SUBDOMAIN}.pagerduty.com/users/PUSERREP`,
38
+ };
39
+ /**
40
+ * Pick the events to replay. Accepts full names (`incident.resolved`) or
41
+ * the action alone (`resolved`); `*` selects every declared event that can
42
+ * be synthesized. Defaults to `incident.triggered`.
43
+ */
44
+ export function selectPagerDutyReplayEvents(input) {
45
+ const { requested, declared } = input;
46
+ const replayable = new Set(PAGERDUTY_REPLAYABLE_EVENTS);
47
+ if (requested === undefined) {
48
+ return { events: ["incident.triggered"], unsupported: [] };
49
+ }
50
+ if (requested.length === 1 && requested[0] === "*") {
51
+ const pool = declared.length === 0 ? PAGERDUTY_REPLAYABLE_EVENTS : declared;
52
+ return {
53
+ events: PAGERDUTY_REPLAYABLE_EVENTS.filter((event) => pool.includes(event)),
54
+ unsupported: [],
55
+ };
56
+ }
57
+ const events = [];
58
+ const unsupported = [];
59
+ for (const raw of requested) {
60
+ const name = raw.startsWith("incident.") ? raw : `incident.${raw}`;
61
+ if (replayable.has(name)) {
62
+ events.push(name);
63
+ }
64
+ else {
65
+ unsupported.push(raw);
66
+ }
67
+ }
68
+ return { events, unsupported };
69
+ }
70
+ /**
71
+ * One v3 delivery body for `eventType` on `incidentId`. A trigger comes
72
+ * from PagerDuty itself (no `agent`); every other event is a person's
73
+ * action, so it dispatches rather than being skipped as the agent's echo.
74
+ */
75
+ export function synthesizePagerDutyEvent(input) {
76
+ const incidentId = input.incidentId ?? PAGERDUTY_REPLAY_DEFAULT_INCIDENT_ID;
77
+ const incidentUrl = `https://${SUBDOMAIN}.pagerduty.com/incidents/${incidentId}`;
78
+ const data = input.eventType === "incident.annotated"
79
+ ? {
80
+ id: `PNOTE${randomUUID().slice(0, 6).toUpperCase()}`,
81
+ type: "incident_note",
82
+ content: input.note ?? "Replayed note from bdk pagerduty replay.",
83
+ trimmed: false,
84
+ incident: {
85
+ id: incidentId,
86
+ type: "incident_reference",
87
+ html_url: incidentUrl,
88
+ },
89
+ }
90
+ : {
91
+ id: incidentId,
92
+ type: "incident",
93
+ number: 1,
94
+ title: "Replayed incident from bdk pagerduty replay",
95
+ status: STATUS_BY_EVENT[input.eventType],
96
+ urgency: "high",
97
+ incident_key: `replay-${incidentId}`,
98
+ html_url: incidentUrl,
99
+ created_at: new Date().toISOString(),
100
+ service: SERVICE,
101
+ assignees: [RESPONDER],
102
+ teams: [],
103
+ };
104
+ return {
105
+ event: {
106
+ id: randomUUID(),
107
+ event_type: input.eventType,
108
+ resource_type: "incident",
109
+ occurred_at: new Date().toISOString(),
110
+ agent: input.eventType === "incident.triggered" ? null : RESPONDER,
111
+ client: { name: "bdk pagerduty replay" },
112
+ data,
113
+ },
114
+ };
115
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * How a PagerDuty setting turns into a value. An omitted setting reads its
3
+ * well-known env var / deployment secret, which on Cursor hosting is the
4
+ * addressed installation's own secret of that name. An authored
5
+ * `{ secretName }` reads that secret instead and never falls back.
6
+ */
7
+ import { type WebhookSecretValue } from "../../internal/named-webhook-secret.js";
8
+ /**
9
+ * The secret name a setting reads: the authored `{ secretName }`, the
10
+ * default name when the setting is omitted, or `undefined` for a literal
11
+ * or getter authored in code.
12
+ */
13
+ export declare function pagerDutySecretName(value: WebhookSecretValue | undefined, defaultName: string): string | undefined;
14
+ /** The setting's value, read now; blank counts as unset. */
15
+ export declare function resolvePagerDutySecret(value: WebhookSecretValue | undefined, defaultName: string): string | undefined;
16
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../src/channels/pagerduty/secrets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,wCAAwC,CAAC;AAGhD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,kBAAkB,GAAG,SAAS,EACrC,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAKpB;AAED,4DAA4D;AAC5D,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,kBAAkB,GAAG,SAAS,EACrC,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAEpB"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * How a PagerDuty setting turns into a value. An omitted setting reads its
3
+ * well-known env var / deployment secret, which on Cursor hosting is the
4
+ * addressed installation's own secret of that name. An authored
5
+ * `{ secretName }` reads that secret instead and never falls back.
6
+ */
7
+ import { resolveWebhookSecretValue, } from "../../internal/named-webhook-secret.js";
8
+ import { isSecretRef } from "../../types.js";
9
+ /**
10
+ * The secret name a setting reads: the authored `{ secretName }`, the
11
+ * default name when the setting is omitted, or `undefined` for a literal
12
+ * or getter authored in code.
13
+ */
14
+ export function pagerDutySecretName(value, defaultName) {
15
+ if (value === undefined) {
16
+ return defaultName;
17
+ }
18
+ return isSecretRef(value) ? value.secretName : undefined;
19
+ }
20
+ /** The setting's value, read now; blank counts as unset. */
21
+ export function resolvePagerDutySecret(value, defaultName) {
22
+ return resolveWebhookSecretValue(value ?? { secretName: defaultName });
23
+ }