@cursor/bdk 0.2.3 → 0.2.5

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 (760) hide show
  1. package/README.md +76 -1154
  2. package/dist/bin/agent-serve.js +9 -1
  3. package/dist/channels/slack/attachments.d.ts +2 -1
  4. package/dist/channels/slack/attachments.d.ts.map +1 -1
  5. package/dist/channels/slack/attachments.js +19 -9
  6. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  7. package/dist/channels/slack/dispatch.js +26 -24
  8. package/dist/channels/slack/thread-context.d.ts +21 -11
  9. package/dist/channels/slack/thread-context.d.ts.map +1 -1
  10. package/dist/channels/slack/thread-context.js +75 -27
  11. package/dist/docs/404.html +2 -2
  12. package/dist/docs/assets/{app.BOIHhrKi.js → app.94Iu5dyD.js} +4 -4
  13. package/dist/docs/assets/{building-with-agents.md.-fcjCmJU.js → building-with-agents.md.BPjPFxFg.js} +2 -2
  14. package/dist/docs/assets/{building-with-agents.md.-fcjCmJU.lean.js → building-with-agents.md.BPjPFxFg.lean.js} +1 -1
  15. package/dist/docs/assets/chunks/@localSearchIndexroot.BITLoOQa.js +1 -0
  16. package/dist/docs/assets/chunks/{VPLocalSearchBox.D49zVZqM.js → VPLocalSearchBox.DTKFDlBr.js} +1 -1
  17. package/dist/docs/assets/chunks/{arc.hmjb-sc4.js → arc.DuzwHEeg.js} +1 -1
  18. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.CxEI1KqM.js → architectureDiagram-Q4EWVU46.C6lyhLs0.js} +1 -1
  19. package/dist/docs/assets/chunks/{baseUniq.DHHvBWoV.js → baseUniq.DUNEWlY8.js} +1 -1
  20. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.DnXW-3bu.js → blockDiagram-DXYQGD6D.CXOQGI0O.js} +1 -1
  21. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.e-47O2jM.js → c4Diagram-AHTNJAMY.BYdPE-Oe.js} +1 -1
  22. package/dist/docs/assets/chunks/channel.B46uXH41.js +1 -0
  23. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.3ry4pYXB.js → chunk-4BX2VUAB.YIV9HeX0.js} +1 -1
  24. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.DGIZFRx6.js → chunk-4TB4RGXK.BG80DEOc.js} +1 -1
  25. package/dist/docs/assets/chunks/{chunk-55IACEB6.DKBnqg9U.js → chunk-55IACEB6.BDKJSZQc.js} +1 -1
  26. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.BIU8Ue5k.js → chunk-EDXVE4YY.CtYnQqts.js} +1 -1
  27. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.DP-TFhjI.js → chunk-FMBD7UC4.CityOth-.js} +1 -1
  28. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.Ux0OYj5v.js → chunk-OYMX7WX6.CMD22CQX.js} +1 -1
  29. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BzHMwYox.js → chunk-QZHKN3VN.WWpc3ND0.js} +1 -1
  30. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.D4OGAsSP.js → chunk-YZCP3GAM.BMg-yhj3.js} +1 -1
  31. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.0cmCFsSf.js +1 -0
  32. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.0cmCFsSf.js +1 -0
  33. package/dist/docs/assets/chunks/clone.1vTOFZT1.js +1 -0
  34. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.Jq_7BUNx.js → cose-bilkent-S5V4N54A.Buu_LC5q.js} +1 -1
  35. package/dist/docs/assets/chunks/{dagre-KV5264BT.Di-skR2x.js → dagre-KV5264BT.DW7onj6E.js} +1 -1
  36. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.DeREHIdH.js → diagram-5BDNPKRD.B3NxIbEV.js} +1 -1
  37. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.C7Kcqxro.js → diagram-G4DWMVQ6.BJvN6Vkv.js} +1 -1
  38. package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BK3eohyo.js → diagram-MMDJMWI5.wfRWrexs.js} +1 -1
  39. package/dist/docs/assets/chunks/{diagram-TYMM5635.C6TyymXT.js → diagram-TYMM5635.7QtjSYio.js} +1 -1
  40. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.DYGG-gGx.js → erDiagram-SMLLAGMA.jxPgDH1t.js} +1 -1
  41. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.C9nBcSV4.js → flowDiagram-DWJPFMVM.BhDWA-TO.js} +1 -1
  42. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.wAg_ymsp.js → ganttDiagram-T4ZO3ILL.Ijq8iYKv.js} +1 -1
  43. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.B87j9Oeg.js → gitGraphDiagram-UUTBAWPF.DXpfW4YG.js} +1 -1
  44. package/dist/docs/assets/chunks/{graph.CuFMj31w.js → graph.CoPlssRl.js} +1 -1
  45. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.P_mLGumP.js → infoDiagram-42DDH7IO.eJuv_EOz.js} +1 -1
  46. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DyuL_MsT.js → ishikawaDiagram-UXIWVN3A._OEzenCR.js} +1 -1
  47. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.CtP09IoJ.js → journeyDiagram-VCZTEJTY.CwlTjirB.js} +1 -1
  48. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.BoeSYPZo.js → kanban-definition-6JOO6SKY.DSp_C8cZ.js} +1 -1
  49. package/dist/docs/assets/chunks/{layout.B0lMMtNo.js → layout.Bms9s7uB.js} +1 -1
  50. package/dist/docs/assets/chunks/{linear.HxRBiAFX.js → linear.BjnmB4je.js} +1 -1
  51. package/dist/docs/assets/chunks/{min.BGlFFHwS.js → min.CKkYlMsn.js} +1 -1
  52. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.JyLBD9M8.js → mindmap-definition-QFDTVHPH.T2d0vJ7X.js} +1 -1
  53. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.DnSmNZF8.js → pieDiagram-DEJITSTG.DU0RoCvx.js} +1 -1
  54. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.CUCnbfCa.js → quadrantDiagram-34T5L4WZ.9QZjM-x0.js} +1 -1
  55. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.py0IVUn5.js → requirementDiagram-MS252O5E.CZpylJMd.js} +1 -1
  56. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.Bkc-HWYp.js → sankeyDiagram-XADWPNL6.CnFdfW95.js} +1 -1
  57. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.Dqn8Mlv2.js → sequenceDiagram-FGHM5R23.-jC0PP1t.js} +1 -1
  58. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.JikkoQUU.js → stateDiagram-FHFEXIEX.DG7yBRUU.js} +1 -1
  59. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CbsZcOOu.js +1 -0
  60. package/dist/docs/assets/chunks/{theme.b6HQ6zG_.js → theme.B3O9koXV.js} +2 -2
  61. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BvpSXiBj.js → timeline-definition-GMOUNBTQ.Bf9u4Ebb.js} +1 -1
  62. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CU7MVnZx.js → vennDiagram-DHZGUBPP.BjhbbYE6.js} +1 -1
  63. package/dist/docs/assets/chunks/{wardley-RL74JXVD.BKwC4ctG.js → wardley-RL74JXVD.DEA21akR.js} +1 -1
  64. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.BfaF6Uhe.js → wardleyDiagram-NUSXRM2D.8fRb4Nb5.js} +1 -1
  65. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.Bg5dcpj4.js → xychartDiagram-5P7HB3ND.DoOP3zZM.js} +1 -1
  66. package/dist/docs/assets/{deployment.md.BJ8i7Q6p.js → deployment.md.BdqTiGdc.js} +5 -5
  67. package/dist/docs/assets/{deployment.md.BJ8i7Q6p.lean.js → deployment.md.BdqTiGdc.lean.js} +1 -1
  68. package/dist/docs/assets/{evals.md.CCAtNcuL.js → evals.md.LRCSn6Ik.js} +2 -2
  69. package/dist/docs/assets/{evals.md.CCAtNcuL.lean.js → evals.md.LRCSn6Ik.lean.js} +1 -1
  70. package/dist/docs/assets/{guides_agent-to-agent.md.CGkicXeB.js → guides_agent-to-agent.md.Cps5NiCV.js} +2 -2
  71. package/dist/docs/assets/{guides_agent-to-agent.md.CGkicXeB.lean.js → guides_agent-to-agent.md.Cps5NiCV.lean.js} +1 -1
  72. package/dist/docs/assets/{guides_bitbucket.md.Cb3LPKt3.js → guides_bitbucket.md.BB6fqD-M.js} +2 -2
  73. package/dist/docs/assets/{guides_bitbucket.md.Cb3LPKt3.lean.js → guides_bitbucket.md.BB6fqD-M.lean.js} +1 -1
  74. package/dist/docs/assets/{guides_cloud-agents.md.BuEkDCwo.js → guides_cloud-agents.md.CWJjS9No.js} +2 -2
  75. package/dist/docs/assets/{guides_cloud-agents.md.BuEkDCwo.lean.js → guides_cloud-agents.md.CWJjS9No.lean.js} +1 -1
  76. package/dist/docs/assets/{guides_convert-automation.md.Ci-Y2iD5.js → guides_convert-automation.md.DMEX9nF-.js} +3 -3
  77. package/dist/docs/assets/{guides_convert-automation.md.Ci-Y2iD5.lean.js → guides_convert-automation.md.DMEX9nF-.lean.js} +1 -1
  78. package/dist/docs/assets/{guides_github.md.Bq9kQU9B.js → guides_github.md.Cr1Xlf-m.js} +3 -3
  79. package/dist/docs/assets/{guides_github.md.Bq9kQU9B.lean.js → guides_github.md.Cr1Xlf-m.lean.js} +1 -1
  80. package/dist/docs/assets/{guides_gitlab.md.BM27P43u.js → guides_gitlab.md.CMpmFi4M.js} +2 -2
  81. package/dist/docs/assets/{guides_gitlab.md.BM27P43u.lean.js → guides_gitlab.md.CMpmFi4M.lean.js} +1 -1
  82. package/dist/docs/assets/{guides_grokbot-agents.md.yxVbSlKA.js → guides_grokbot-agents.md.tD1smFhU.js} +2 -2
  83. package/dist/docs/assets/{guides_grokbot-agents.md.yxVbSlKA.lean.js → guides_grokbot-agents.md.tD1smFhU.lean.js} +1 -1
  84. package/dist/docs/assets/{guides_hooks.md.BWoiNaMq.js → guides_hooks.md.5Ce3NXxZ.js} +2 -2
  85. package/dist/docs/assets/{guides_hooks.md.BWoiNaMq.lean.js → guides_hooks.md.5Ce3NXxZ.lean.js} +1 -1
  86. package/dist/docs/assets/{guides_improve.md.COtL-6ft.js → guides_improve.md.CRrYq22s.js} +2 -2
  87. package/dist/docs/assets/{guides_improve.md.COtL-6ft.lean.js → guides_improve.md.CRrYq22s.lean.js} +1 -1
  88. package/dist/docs/assets/{guides_jev.md.BNDm14Gy.js → guides_jev.md.D7XH4JH3.js} +2 -2
  89. package/dist/docs/assets/{guides_mcp-oauth.md.Cu6mhZ_3.js → guides_mcp-oauth.md.DR3zhC9r.js} +2 -2
  90. package/dist/docs/assets/{guides_mcp-oauth.md.Cu6mhZ_3.lean.js → guides_mcp-oauth.md.DR3zhC9r.lean.js} +1 -1
  91. package/dist/docs/assets/{guides_opentelemetry.md.DLlIB5rv.js → guides_opentelemetry.md.jcPNrQbH.js} +8 -6
  92. package/dist/docs/assets/{guides_opentelemetry.md.DLlIB5rv.lean.js → guides_opentelemetry.md.jcPNrQbH.lean.js} +1 -1
  93. package/dist/docs/assets/{guides_slack.md.diqqXTTm.js → guides_slack.md.Bn-WupSE.js} +8 -8
  94. package/dist/docs/assets/{guides_slack.md.diqqXTTm.lean.js → guides_slack.md.Bn-WupSE.lean.js} +1 -1
  95. package/dist/docs/assets/{guides_webhooks.md.D0furjw0.js → guides_webhooks.md.BBvAm_VF.js} +2 -2
  96. package/dist/docs/assets/{guides_webhooks.md.D0furjw0.lean.js → guides_webhooks.md.BBvAm_VF.lean.js} +1 -1
  97. package/dist/docs/assets/{hillclimbing.md.Biy0m-Qb.js → hillclimbing.md.Dxvd-0gT.js} +2 -2
  98. package/dist/docs/assets/{hillclimbing.md.Biy0m-Qb.lean.js → hillclimbing.md.Dxvd-0gT.lean.js} +1 -1
  99. package/dist/docs/assets/index.md.Dxxr7pFa.js +27 -0
  100. package/dist/docs/assets/{index.md.CVc_oOA3.lean.js → index.md.Dxxr7pFa.lean.js} +1 -1
  101. package/dist/docs/assets/{quickstart.md.CHpHPBUN.js → quickstart.md.BK5gjHM2.js} +2 -2
  102. package/dist/docs/assets/{quickstart.md.CHpHPBUN.lean.js → quickstart.md.BK5gjHM2.lean.js} +1 -1
  103. package/dist/docs/assets/{reference_agent-config.md.DzGI777n.js → reference_agent-config.md.DrtLxWgR.js} +4 -4
  104. package/dist/docs/assets/{reference_agent-config.md.DzGI777n.lean.js → reference_agent-config.md.DrtLxWgR.lean.js} +1 -1
  105. package/dist/docs/assets/{reference_artifacts.md.CQfKq8F2.js → reference_artifacts.md.DLV9MZES.js} +2 -2
  106. package/dist/docs/assets/{reference_artifacts.md.CQfKq8F2.lean.js → reference_artifacts.md.DLV9MZES.lean.js} +1 -1
  107. package/dist/docs/assets/{reference_channels.md.mbNtKCiR.js → reference_channels.md.LbNIJBwd.js} +2 -2
  108. package/dist/docs/assets/{reference_channels.md.mbNtKCiR.lean.js → reference_channels.md.LbNIJBwd.lean.js} +1 -1
  109. package/dist/docs/assets/{reference_cli.md.DgeLTO18.js → reference_cli.md.BsgDqYPh.js} +4 -4
  110. package/dist/docs/assets/{reference_cli.md.DgeLTO18.lean.js → reference_cli.md.BsgDqYPh.lean.js} +1 -1
  111. package/dist/docs/assets/{reference_connections.md.COq--gAm.js → reference_connections.md.Bljpve-y.js} +4 -4
  112. package/dist/docs/assets/{reference_connections.md.COq--gAm.lean.js → reference_connections.md.Bljpve-y.lean.js} +1 -1
  113. package/dist/docs/assets/{reference_evals.md.CJm3uCUm.js → reference_evals.md.D5i8PuXJ.js} +2 -2
  114. package/dist/docs/assets/{reference_evals.md.CJm3uCUm.lean.js → reference_evals.md.D5i8PuXJ.lean.js} +1 -1
  115. package/dist/docs/assets/{reference_extensions.md.CPPrkWlJ.js → reference_extensions.md.OUacPetl.js} +5 -4
  116. package/dist/docs/assets/{reference_extensions.md.CPPrkWlJ.lean.js → reference_extensions.md.OUacPetl.lean.js} +1 -1
  117. package/dist/docs/assets/{reference_hooks.md.DbthhtIR.js → reference_hooks.md.C5LCJ1R3.js} +2 -2
  118. package/dist/docs/assets/{reference_hooks.md.DbthhtIR.lean.js → reference_hooks.md.C5LCJ1R3.lean.js} +1 -1
  119. package/dist/docs/assets/{reference_http-api.md.BZOvhCqY.js → reference_http-api.md.DbFNOubV.js} +1 -1
  120. package/dist/docs/assets/{reference_instructions.md.Bdwscs4G.js → reference_instructions.md.DrcHZXig.js} +2 -2
  121. package/dist/docs/assets/{reference_instructions.md.Bdwscs4G.lean.js → reference_instructions.md.DrcHZXig.lean.js} +1 -1
  122. package/dist/docs/assets/reference_playground.md.1hx0gcIu.js +1 -0
  123. package/dist/docs/assets/{reference_playground.md.BdQzRJc2.lean.js → reference_playground.md.1hx0gcIu.lean.js} +1 -1
  124. package/dist/docs/assets/{reference_project-layout.md.CpLQ9j4K.js → reference_project-layout.md.C2JMRh7p.js} +2 -2
  125. package/dist/docs/assets/{reference_prompt.md.BQZB4eaV.js → reference_prompt.md.DqPh71XN.js} +3 -3
  126. package/dist/docs/assets/{reference_prompt.md.BQZB4eaV.lean.js → reference_prompt.md.DqPh71XN.lean.js} +1 -1
  127. package/dist/docs/assets/{reference_schedules.md.BVU5EFbz.js → reference_schedules.md.BuJ8fgMa.js} +2 -2
  128. package/dist/docs/assets/{reference_schedules.md.BVU5EFbz.lean.js → reference_schedules.md.BuJ8fgMa.lean.js} +1 -1
  129. package/dist/docs/assets/reference_sessions.md.CM5zo3w4.js +1 -0
  130. package/dist/docs/assets/{reference_sessions.md.DeRUItHD.lean.js → reference_sessions.md.CM5zo3w4.lean.js} +1 -1
  131. package/dist/docs/assets/{reference_skills.md.Cy00QMKS.js → reference_skills.md.C0guGcH0.js} +4 -4
  132. package/dist/docs/assets/{reference_skills.md.Cy00QMKS.lean.js → reference_skills.md.C0guGcH0.lean.js} +1 -1
  133. package/dist/docs/assets/{reference_subagents.md.B8oyeXOI.js → reference_subagents.md.gmPt5J-M.js} +2 -2
  134. package/dist/docs/assets/{reference_subagents.md.B8oyeXOI.lean.js → reference_subagents.md.gmPt5J-M.lean.js} +1 -1
  135. package/dist/docs/assets/{reference_tools.md.hg2Wi5Bq.js → reference_tools.md.v3SXVSs_.js} +2 -2
  136. package/dist/docs/assets/{reference_tools.md.hg2Wi5Bq.lean.js → reference_tools.md.v3SXVSs_.lean.js} +1 -1
  137. package/dist/docs/assets/{templates_agentic-owners.md.BykUiZ8j.js → templates_agentic-owners.md.vtjfwxbf.js} +2 -2
  138. package/dist/docs/assets/{templates_agentic-owners.md.BykUiZ8j.lean.js → templates_agentic-owners.md.vtjfwxbf.lean.js} +1 -1
  139. package/dist/docs/assets/templates_grokbot-agents.md.2sydjFiO.js +5 -0
  140. package/dist/docs/assets/templates_grokbot-agents.md.2sydjFiO.lean.js +1 -0
  141. package/dist/docs/assets/{templates_security-reviewer.md.DXMmKl_o.js → templates_security-reviewer.md.CX9l9bcg.js} +2 -2
  142. package/dist/docs/assets/{templates_security-reviewer.md.DXMmKl_o.lean.js → templates_security-reviewer.md.CX9l9bcg.lean.js} +1 -1
  143. package/dist/docs/assets/{templates_thermo-quality-review.md.Dg1p1MsG.js → templates_thermo-quality-review.md.95qmTmr1.js} +2 -2
  144. package/dist/docs/assets/{templates_thermo-quality-review.md.Dg1p1MsG.lean.js → templates_thermo-quality-review.md.95qmTmr1.lean.js} +1 -1
  145. package/dist/docs/assets/{templates_thermo-review.md.Dlylkowj.js → templates_thermo-review.md.DQh6Q0C-.js} +2 -2
  146. package/dist/docs/assets/{templates_thermo-review.md.Dlylkowj.lean.js → templates_thermo-review.md.DQh6Q0C-.lean.js} +1 -1
  147. package/dist/docs/assets/{templates_triage.md.CvJyx81N.js → templates_triage.md.BFlQhWXf.js} +3 -3
  148. package/dist/docs/assets/{templates_triage.md.CvJyx81N.lean.js → templates_triage.md.BFlQhWXf.lean.js} +1 -1
  149. package/dist/docs/assets/troubleshooting.md.Bscj6ODe.js +1 -0
  150. package/dist/docs/assets/{troubleshooting.md.Cw5PKa3t.lean.js → troubleshooting.md.Bscj6ODe.lean.js} +1 -1
  151. package/dist/docs/building-with-agents.html +36 -36
  152. package/dist/docs/building-with-agents.md +0 -3
  153. package/dist/docs/deployment.html +39 -39
  154. package/dist/docs/deployment.md +6 -10
  155. package/dist/docs/evals.html +36 -36
  156. package/dist/docs/evals.md +0 -3
  157. package/dist/docs/guides/agent-to-agent.html +36 -36
  158. package/dist/docs/guides/agent-to-agent.md +0 -3
  159. package/dist/docs/guides/bitbucket.html +36 -36
  160. package/dist/docs/guides/bitbucket.md +0 -3
  161. package/dist/docs/guides/cloud-agents.html +36 -36
  162. package/dist/docs/guides/cloud-agents.md +0 -4
  163. package/dist/docs/guides/convert-automation.html +37 -37
  164. package/dist/docs/guides/convert-automation.md +2 -5
  165. package/dist/docs/guides/github.html +37 -37
  166. package/dist/docs/guides/github.md +1 -4
  167. package/dist/docs/guides/gitlab.html +36 -36
  168. package/dist/docs/guides/gitlab.md +0 -3
  169. package/dist/docs/guides/grokbot-agents.html +37 -37
  170. package/dist/docs/guides/grokbot-agents.md +1 -4
  171. package/dist/docs/guides/hooks.html +36 -36
  172. package/dist/docs/guides/hooks.md +0 -3
  173. package/dist/docs/guides/improve.html +36 -36
  174. package/dist/docs/guides/improve.md +0 -3
  175. package/dist/docs/guides/jev.html +37 -37
  176. package/dist/docs/guides/jev.md +7 -3
  177. package/dist/docs/guides/mcp-oauth.html +37 -37
  178. package/dist/docs/guides/mcp-oauth.md +1 -4
  179. package/dist/docs/guides/opentelemetry.html +42 -40
  180. package/dist/docs/guides/opentelemetry.md +4 -5
  181. package/dist/docs/guides/slack.html +43 -43
  182. package/dist/docs/guides/slack.md +14 -24
  183. package/dist/docs/guides/webhooks.html +36 -36
  184. package/dist/docs/guides/webhooks.md +0 -3
  185. package/dist/docs/hashmap.json +1 -1
  186. package/dist/docs/hillclimbing.html +36 -36
  187. package/dist/docs/hillclimbing.md +0 -3
  188. package/dist/docs/index.html +38 -38
  189. package/dist/docs/index.md +9 -16
  190. package/dist/docs/llms-full.txt +156 -220
  191. package/dist/docs/llms.txt +1 -0
  192. package/dist/docs/quickstart.html +36 -36
  193. package/dist/docs/quickstart.md +2 -7
  194. package/dist/docs/reference/agent-config.html +38 -38
  195. package/dist/docs/reference/agent-config.md +4 -7
  196. package/dist/docs/reference/artifacts.html +36 -36
  197. package/dist/docs/reference/artifacts.md +0 -3
  198. package/dist/docs/reference/channels.html +37 -37
  199. package/dist/docs/reference/channels.md +1 -6
  200. package/dist/docs/reference/cli.html +38 -38
  201. package/dist/docs/reference/cli.md +7 -14
  202. package/dist/docs/reference/connections.html +38 -38
  203. package/dist/docs/reference/connections.md +7 -10
  204. package/dist/docs/reference/evals.html +36 -36
  205. package/dist/docs/reference/evals.md +0 -3
  206. package/dist/docs/reference/extensions.html +40 -39
  207. package/dist/docs/reference/extensions.md +15 -5
  208. package/dist/docs/reference/hooks.html +36 -36
  209. package/dist/docs/reference/hooks.md +0 -3
  210. package/dist/docs/reference/http-api.html +37 -37
  211. package/dist/docs/reference/http-api.md +1 -1
  212. package/dist/docs/reference/instructions.html +36 -36
  213. package/dist/docs/reference/instructions.md +0 -3
  214. package/dist/docs/reference/playground.html +36 -36
  215. package/dist/docs/reference/playground.md +0 -3
  216. package/dist/docs/reference/project-layout.html +37 -37
  217. package/dist/docs/reference/project-layout.md +2 -2
  218. package/dist/docs/reference/prompt.html +37 -37
  219. package/dist/docs/reference/prompt.md +0 -3
  220. package/dist/docs/reference/schedules.html +36 -36
  221. package/dist/docs/reference/schedules.md +0 -3
  222. package/dist/docs/reference/sessions.html +36 -36
  223. package/dist/docs/reference/sessions.md +0 -3
  224. package/dist/docs/reference/skills.html +38 -38
  225. package/dist/docs/reference/skills.md +0 -3
  226. package/dist/docs/reference/subagents.html +36 -36
  227. package/dist/docs/reference/subagents.md +0 -3
  228. package/dist/docs/reference/tools.html +36 -36
  229. package/dist/docs/reference/tools.md +1 -5
  230. package/dist/docs/templates/agentic-owners.html +36 -36
  231. package/dist/docs/templates/agentic-owners.md +0 -3
  232. package/dist/docs/templates/grokbot-agents.html +64 -0
  233. package/dist/docs/templates/grokbot-agents.md +55 -0
  234. package/dist/docs/templates/security-reviewer.html +37 -37
  235. package/dist/docs/templates/security-reviewer.md +0 -3
  236. package/dist/docs/templates/thermo-quality-review.html +36 -36
  237. package/dist/docs/templates/thermo-quality-review.md +3 -6
  238. package/dist/docs/templates/thermo-review.html +36 -36
  239. package/dist/docs/templates/thermo-review.md +3 -5
  240. package/dist/docs/templates/triage.html +37 -37
  241. package/dist/docs/templates/triage.md +2 -3
  242. package/dist/docs/troubleshooting.html +36 -36
  243. package/dist/docs/troubleshooting.md +3 -7
  244. package/dist/extensions/jev/extension.d.ts +3 -0
  245. package/dist/extensions/jev/extension.d.ts.map +1 -1
  246. package/dist/extensions/jev/extension.js +10 -1
  247. package/dist/extensions/jev/lib/evaluate.d.ts +4 -0
  248. package/dist/extensions/jev/lib/evaluate.d.ts.map +1 -1
  249. package/dist/extensions/jev/lib/evaluate.js +6 -2
  250. package/dist/extensions.d.ts +4 -2
  251. package/dist/extensions.d.ts.map +1 -1
  252. package/dist/extensions.js +5 -2
  253. package/dist/internal/cli-deploy.d.ts.map +1 -1
  254. package/dist/internal/cli-deploy.js +19 -5
  255. package/dist/internal/discovery/agent-config.d.ts +6 -5
  256. package/dist/internal/discovery/agent-config.d.ts.map +1 -1
  257. package/dist/internal/discovery/agent-config.js +29 -28
  258. package/dist/internal/discovery/agent.js +1 -1
  259. package/dist/internal/discovery/extensions.d.ts.map +1 -1
  260. package/dist/internal/discovery/extensions.js +12 -0
  261. package/dist/internal/hosting.d.ts +8 -0
  262. package/dist/internal/hosting.d.ts.map +1 -1
  263. package/dist/internal/hosting.js +24 -0
  264. package/dist/types.d.ts +18 -2
  265. package/dist/types.d.ts.map +1 -1
  266. package/docs/README.md +9 -16
  267. package/docs/building-with-agents.md +0 -3
  268. package/docs/deployment.md +6 -10
  269. package/docs/evals.md +0 -3
  270. package/docs/guides/agent-to-agent.md +0 -3
  271. package/docs/guides/bitbucket.md +0 -3
  272. package/docs/guides/cloud-agents.md +0 -4
  273. package/docs/guides/convert-automation.md +2 -5
  274. package/docs/guides/github.md +1 -4
  275. package/docs/guides/gitlab.md +0 -3
  276. package/docs/guides/grokbot-agents.md +1 -4
  277. package/docs/guides/hooks.md +0 -3
  278. package/docs/guides/improve.md +0 -3
  279. package/docs/guides/jev.md +7 -3
  280. package/docs/guides/mcp-oauth.md +1 -4
  281. package/docs/guides/opentelemetry.md +4 -5
  282. package/docs/guides/slack.md +14 -24
  283. package/docs/guides/webhooks.md +0 -3
  284. package/docs/hillclimbing.md +0 -3
  285. package/docs/quickstart.md +2 -7
  286. package/docs/reference/agent-config.md +4 -7
  287. package/docs/reference/artifacts.md +0 -3
  288. package/docs/reference/channels.md +1 -6
  289. package/docs/reference/cli.md +7 -14
  290. package/docs/reference/connections.md +7 -10
  291. package/docs/reference/evals.md +0 -3
  292. package/docs/reference/extensions.md +15 -5
  293. package/docs/reference/hooks.md +0 -3
  294. package/docs/reference/http-api.md +1 -1
  295. package/docs/reference/instructions.md +0 -3
  296. package/docs/reference/playground.md +0 -3
  297. package/docs/reference/project-layout.md +2 -2
  298. package/docs/reference/prompt.md +0 -3
  299. package/docs/reference/schedules.md +0 -3
  300. package/docs/reference/sessions.md +0 -3
  301. package/docs/reference/skills.md +0 -3
  302. package/docs/reference/subagents.md +0 -3
  303. package/docs/reference/tools.md +1 -5
  304. package/docs/templates/agentic-owners.md +0 -3
  305. package/docs/templates/grokbot-agents.md +60 -0
  306. package/docs/templates/security-reviewer.md +0 -3
  307. package/docs/templates/thermo-quality-review.md +3 -6
  308. package/docs/templates/thermo-review.md +3 -5
  309. package/docs/templates/triage.md +2 -3
  310. package/docs/troubleshooting.md +3 -7
  311. package/package.json +2 -10
  312. package/templates/agentic-owners/README.md +0 -3
  313. package/templates/agents-md/README.md +4 -3
  314. package/templates/code-wiki/README.md +0 -3
  315. package/templates/demo/README.md +0 -3
  316. package/templates/grokbot-agents/README.md +4 -6
  317. package/templates/security-help/README.md +12 -6
  318. package/templates/security-reviewer/README.md +0 -3
  319. package/templates/thermo-quality-review/README.md +0 -3
  320. package/templates/thermo-review/README.md +0 -3
  321. package/templates/triage/README.md +0 -3
  322. package/templates/triage/overlays/jira/README.md +0 -3
  323. package/templates/triage/overlays/linear/README.md +0 -3
  324. package/dist/docs/assets/chunks/@localSearchIndexroot.D5L-b34G.js +0 -1
  325. package/dist/docs/assets/chunks/channel.BbOGaJQP.js +0 -1
  326. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.Db58HCb1.js +0 -1
  327. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.Db58HCb1.js +0 -1
  328. package/dist/docs/assets/chunks/clone.Co4MBflG.js +0 -1
  329. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CMsKhrW0.js +0 -1
  330. package/dist/docs/assets/index.md.CVc_oOA3.js +0 -27
  331. package/dist/docs/assets/reference_playground.md.BdQzRJc2.js +0 -1
  332. package/dist/docs/assets/reference_sessions.md.DeRUItHD.js +0 -1
  333. package/dist/docs/assets/troubleshooting.md.Cw5PKa3t.js +0 -1
  334. package/src/artifacts.ts +0 -68
  335. package/src/bin/agent-serve.ts +0 -1854
  336. package/src/channels/bitbucket/api.ts +0 -891
  337. package/src/channels/bitbucket/binding.ts +0 -417
  338. package/src/channels/bitbucket/bitbucket-channel.ts +0 -162
  339. package/src/channels/bitbucket/bitbucket-webhook.ts +0 -519
  340. package/src/channels/bitbucket/checks.ts +0 -146
  341. package/src/channels/bitbucket/cursor-account.ts +0 -106
  342. package/src/channels/bitbucket/defaults.ts +0 -100
  343. package/src/channels/bitbucket/events.ts +0 -74
  344. package/src/channels/bitbucket/index.ts +0 -51
  345. package/src/channels/bitbucket/replay.ts +0 -421
  346. package/src/channels/bitbucket/state.ts +0 -59
  347. package/src/channels/bitbucket/types.ts +0 -261
  348. package/src/channels/change-monitors/change-monitors-channel.ts +0 -63
  349. package/src/channels/change-monitors/index.ts +0 -8
  350. package/src/channels/change-monitors/types.ts +0 -42
  351. package/src/channels/checks.ts +0 -185
  352. package/src/channels/deployments/deployments-channel.ts +0 -224
  353. package/src/channels/deployments/index.ts +0 -25
  354. package/src/channels/deployments/types.ts +0 -92
  355. package/src/channels/github/api.ts +0 -526
  356. package/src/channels/github/auth.ts +0 -293
  357. package/src/channels/github/binding.ts +0 -233
  358. package/src/channels/github/checks.ts +0 -145
  359. package/src/channels/github/cursor-account.ts +0 -303
  360. package/src/channels/github/defaults.ts +0 -168
  361. package/src/channels/github/events.ts +0 -67
  362. package/src/channels/github/forward.ts +0 -359
  363. package/src/channels/github/github-channel.ts +0 -2334
  364. package/src/channels/github/index.ts +0 -54
  365. package/src/channels/github/progress.ts +0 -365
  366. package/src/channels/github/replay.ts +0 -372
  367. package/src/channels/github/state.ts +0 -124
  368. package/src/channels/github/types.ts +0 -590
  369. package/src/channels/gitlab/api.ts +0 -329
  370. package/src/channels/gitlab/binding.ts +0 -231
  371. package/src/channels/gitlab/checks.ts +0 -228
  372. package/src/channels/gitlab/cursor-account.ts +0 -105
  373. package/src/channels/gitlab/defaults.ts +0 -80
  374. package/src/channels/gitlab/events.ts +0 -37
  375. package/src/channels/gitlab/gitlab-channel.ts +0 -160
  376. package/src/channels/gitlab/gitlab-webhook.ts +0 -509
  377. package/src/channels/gitlab/index.ts +0 -44
  378. package/src/channels/gitlab/replay.ts +0 -328
  379. package/src/channels/gitlab/state.ts +0 -55
  380. package/src/channels/gitlab/types.ts +0 -247
  381. package/src/channels/issues/index.ts +0 -9
  382. package/src/channels/issues/issues-channel.ts +0 -45
  383. package/src/channels/issues/types.ts +0 -38
  384. package/src/channels/origin/api.ts +0 -507
  385. package/src/channels/origin/binding.ts +0 -114
  386. package/src/channels/origin/checks.ts +0 -250
  387. package/src/channels/origin/cursor-account.ts +0 -58
  388. package/src/channels/origin/defaults.ts +0 -140
  389. package/src/channels/origin/events.ts +0 -35
  390. package/src/channels/origin/index.ts +0 -35
  391. package/src/channels/origin/origin-channel.ts +0 -815
  392. package/src/channels/origin/origin-webhook.ts +0 -296
  393. package/src/channels/origin/reactions.ts +0 -72
  394. package/src/channels/origin/state.ts +0 -54
  395. package/src/channels/origin/types.ts +0 -295
  396. package/src/channels/slack/agentic-delivery.ts +0 -634
  397. package/src/channels/slack/agentic-posted.ts +0 -135
  398. package/src/channels/slack/agentic-signals.ts +0 -231
  399. package/src/channels/slack/api.ts +0 -761
  400. package/src/channels/slack/approvals.ts +0 -279
  401. package/src/channels/slack/assistant.ts +0 -76
  402. package/src/channels/slack/attachments.ts +0 -596
  403. package/src/channels/slack/auth.ts +0 -127
  404. package/src/channels/slack/blocks.ts +0 -131
  405. package/src/channels/slack/bot-mentions.ts +0 -318
  406. package/src/channels/slack/channel-watch.ts +0 -314
  407. package/src/channels/slack/cli-project.ts +0 -249
  408. package/src/channels/slack/code-fences.ts +0 -171
  409. package/src/channels/slack/constants.ts +0 -38
  410. package/src/channels/slack/credentials.ts +0 -88
  411. package/src/channels/slack/defaults.ts +0 -714
  412. package/src/channels/slack/dispatch.ts +0 -1060
  413. package/src/channels/slack/doctor.ts +0 -338
  414. package/src/channels/slack/eval-directive.ts +0 -306
  415. package/src/channels/slack/event-id-dedupe.ts +0 -30
  416. package/src/channels/slack/external-policy.ts +0 -75
  417. package/src/channels/slack/footer.ts +0 -106
  418. package/src/channels/slack/inbound.ts +0 -416
  419. package/src/channels/slack/index.ts +0 -53
  420. package/src/channels/slack/init.ts +0 -169
  421. package/src/channels/slack/interactive.ts +0 -406
  422. package/src/channels/slack/links.ts +0 -23
  423. package/src/channels/slack/live-delivery.ts +0 -489
  424. package/src/channels/slack/log.ts +0 -70
  425. package/src/channels/slack/manifest.ts +0 -240
  426. package/src/channels/slack/message-body.ts +0 -82
  427. package/src/channels/slack/nudge-carrier.ts +0 -224
  428. package/src/channels/slack/nudge-store.ts +0 -334
  429. package/src/channels/slack/paint-start.ts +0 -93
  430. package/src/channels/slack/placeholder.ts +0 -358
  431. package/src/channels/slack/pr-ref.ts +0 -74
  432. package/src/channels/slack/progress-delivery.ts +0 -138
  433. package/src/channels/slack/reasoning-card.ts +0 -125
  434. package/src/channels/slack/reasoning-chip.ts +0 -41
  435. package/src/channels/slack/recording-sink.ts +0 -167
  436. package/src/channels/slack/redact.ts +0 -6
  437. package/src/channels/slack/reply-options.ts +0 -279
  438. package/src/channels/slack/setup.ts +0 -125
  439. package/src/channels/slack/slack-channel.ts +0 -744
  440. package/src/channels/slack/socket-mode.ts +0 -140
  441. package/src/channels/slack/stop.ts +0 -25
  442. package/src/channels/slack/stream.ts +0 -66
  443. package/src/channels/slack/thread-context.ts +0 -485
  444. package/src/channels/slack/tool-approval-events.ts +0 -233
  445. package/src/channels/slack/tool-cards.ts +0 -198
  446. package/src/channels/slack/tool-chip.ts +0 -34
  447. package/src/channels/slack/types.ts +0 -787
  448. package/src/channels/slack/upload.ts +0 -137
  449. package/src/channels.ts +0 -543
  450. package/src/connections.ts +0 -153
  451. package/src/dashboard-session-url.ts +0 -30
  452. package/src/evals/assertions.ts +0 -688
  453. package/src/evals/expect.ts +0 -250
  454. package/src/evals/judge.ts +0 -329
  455. package/src/evals/loaders.ts +0 -111
  456. package/src/evals/matchers.ts +0 -223
  457. package/src/evals/reporters.ts +0 -257
  458. package/src/evals/results.ts +0 -130
  459. package/src/evals/run-facts.ts +0 -306
  460. package/src/evals.ts +0 -709
  461. package/src/extensions/cursor-cloud-agents/extension.ts +0 -131
  462. package/src/extensions/cursor-cloud-agents/lib/backend.ts +0 -386
  463. package/src/extensions/cursor-cloud-agents/lib/channels.ts +0 -11
  464. package/src/extensions/cursor-cloud-agents/lib/fleet.ts +0 -98
  465. package/src/extensions/cursor-cloud-agents/lib/inputs.ts +0 -5
  466. package/src/extensions/cursor-cloud-agents/lib/repos.ts +0 -80
  467. package/src/extensions/cursor-cloud-agents/lib/transcript.ts +0 -19
  468. package/src/extensions/cursor-cloud-agents/skills/handoff.md +0 -37
  469. package/src/extensions/cursor-cloud-agents/tools/cancel.ts +0 -21
  470. package/src/extensions/cursor-cloud-agents/tools/dump.ts +0 -47
  471. package/src/extensions/cursor-cloud-agents/tools/get.ts +0 -18
  472. package/src/extensions/cursor-cloud-agents/tools/launch.ts +0 -62
  473. package/src/extensions/cursor-cloud-agents/tools/list.ts +0 -31
  474. package/src/extensions/cursor-cloud-agents/tools/reply.ts +0 -36
  475. package/src/extensions/cursor-grokbot-agents/extension.ts +0 -132
  476. package/src/extensions/cursor-grokbot-agents/lib/agents.ts +0 -42
  477. package/src/extensions/cursor-grokbot-agents/lib/backend.ts +0 -208
  478. package/src/extensions/cursor-grokbot-agents/lib/contacts.ts +0 -74
  479. package/src/extensions/cursor-grokbot-agents/lib/conversation.ts +0 -260
  480. package/src/extensions/cursor-grokbot-agents/lib/inputs.ts +0 -21
  481. package/src/extensions/cursor-grokbot-agents/lib/lock.ts +0 -26
  482. package/src/extensions/cursor-grokbot-agents/skills/consult.md +0 -40
  483. package/src/extensions/cursor-grokbot-agents/tools/ask.ts +0 -32
  484. package/src/extensions/cursor-grokbot-agents/tools/check.ts +0 -25
  485. package/src/extensions/cursor-grokbot-agents/tools/interrupt.ts +0 -17
  486. package/src/extensions/cursor-grokbot-agents/tools/list.ts +0 -26
  487. package/src/extensions/improve/extension.ts +0 -69
  488. package/src/extensions/improve/skills/yourself.ts +0 -50
  489. package/src/extensions/jev/extension.ts +0 -95
  490. package/src/extensions/jev/lib/evaluate.ts +0 -266
  491. package/src/extensions/jev/skills/gated-write.md +0 -25
  492. package/src/extensions/jev/skills/questions.md +0 -33
  493. package/src/extensions/jev/tools/evaluate.ts +0 -82
  494. package/src/extensions/slack-communication/evals/harness.ts +0 -705
  495. package/src/extensions/slack-communication/evals/slack-communication.eval.ts +0 -830
  496. package/src/extensions/slack-communication/evals/slack-placeholder.eval.ts +0 -172
  497. package/src/extensions/slack-communication/extension.ts +0 -44
  498. package/src/extensions/slack-communication/skills/slack-voice.ts +0 -56
  499. package/src/extensions/slack-communication/tools/delete-message.ts +0 -33
  500. package/src/extensions/slack-communication/tools/edit-message.ts +0 -42
  501. package/src/extensions/slack-communication/tools/post-card.ts +0 -28
  502. package/src/extensions/slack-communication/tools/post-file.ts +0 -82
  503. package/src/extensions/slack-communication/tools/post-update.ts +0 -40
  504. package/src/extensions/slack-communication/tools/react.ts +0 -30
  505. package/src/extensions/slack-communication/tools/set-status.ts +0 -21
  506. package/src/extensions.ts +0 -179
  507. package/src/files-backends/agent-store-presigned-url.ts +0 -11
  508. package/src/files-backends/cursor-hosted.ts +0 -1212
  509. package/src/files-backends/local-fs.ts +0 -163
  510. package/src/files.ts +0 -293
  511. package/src/filesystem.ts +0 -2005
  512. package/src/hooks.ts +0 -30
  513. package/src/index.ts +0 -259
  514. package/src/internal/advertise-tools.ts +0 -370
  515. package/src/internal/approval-gate.ts +0 -103
  516. package/src/internal/artifacts-store.ts +0 -836
  517. package/src/internal/as-of.ts +0 -257
  518. package/src/internal/auth.ts +0 -46
  519. package/src/internal/authored-alias-hooks.ts +0 -138
  520. package/src/internal/authored-loaders.ts +0 -188
  521. package/src/internal/bounded-int.ts +0 -24
  522. package/src/internal/bounded.ts +0 -25
  523. package/src/internal/brand.ts +0 -28
  524. package/src/internal/browser-origin-guard.ts +0 -67
  525. package/src/internal/builtin-tools/artifacts.ts +0 -62
  526. package/src/internal/builtin-tools/index.ts +0 -53
  527. package/src/internal/builtin-tools/reminders.ts +0 -145
  528. package/src/internal/channel-dispatch.ts +0 -129
  529. package/src/internal/channel-route-dispatch.ts +0 -58
  530. package/src/internal/channel-state.ts +0 -83
  531. package/src/internal/chat-client.ts +0 -594
  532. package/src/internal/cli-ax.ts +0 -2318
  533. package/src/internal/cli-bitbucket.ts +0 -438
  534. package/src/internal/cli-convert-automation.ts +0 -335
  535. package/src/internal/cli-cursor.ts +0 -282
  536. package/src/internal/cli-deploy.ts +0 -2519
  537. package/src/internal/cli-docs.ts +0 -192
  538. package/src/internal/cli-github.ts +0 -806
  539. package/src/internal/cli-gitlab.ts +0 -452
  540. package/src/internal/cli-images.ts +0 -672
  541. package/src/internal/cli-manifest.ts +0 -56
  542. package/src/internal/cli-mcp-oauth.ts +0 -396
  543. package/src/internal/cli-mcp.ts +0 -808
  544. package/src/internal/cli-skills.ts +0 -98
  545. package/src/internal/cli-slack-manual.ts +0 -418
  546. package/src/internal/cli-slack.ts +0 -874
  547. package/src/internal/cloud-merge.ts +0 -51
  548. package/src/internal/cloud-turn-cost.ts +0 -159
  549. package/src/internal/connection-env.ts +0 -106
  550. package/src/internal/continuation-channel.ts +0 -233
  551. package/src/internal/continuation-identity.ts +0 -935
  552. package/src/internal/conversation-mirror.ts +0 -423
  553. package/src/internal/convert-automation/convert-workflow.ts +0 -1377
  554. package/src/internal/convert-automation/slug.ts +0 -29
  555. package/src/internal/convert-automation/types.ts +0 -212
  556. package/src/internal/cron.ts +0 -76
  557. package/src/internal/cursor/account-mcp.ts +0 -692
  558. package/src/internal/cursor/backend-client.ts +0 -984
  559. package/src/internal/cursor/bound-secret-file.ts +0 -101
  560. package/src/internal/cursor/credentials.ts +0 -560
  561. package/src/internal/cursor/cursor-api-transport.ts +0 -65
  562. package/src/internal/cursor/github-credentials.ts +0 -228
  563. package/src/internal/cursor/hosted-bound-secrets.ts +0 -71
  564. package/src/internal/cursor/hosted-deployment-secrets.ts +0 -100
  565. package/src/internal/cursor/hosted-store-secrets.ts +0 -152
  566. package/src/internal/cursor/session-token.ts +0 -111
  567. package/src/internal/cursor/store-api-client.ts +0 -323
  568. package/src/internal/cursor-account-mcp-auth.ts +0 -303
  569. package/src/internal/cursor-agent-template.ts +0 -50
  570. package/src/internal/cursor-deployment-relay.ts +0 -315
  571. package/src/internal/cursor-event-relay.ts +0 -675
  572. package/src/internal/cursor-relay-core.ts +0 -563
  573. package/src/internal/deferred-channel-session.ts +0 -61
  574. package/src/internal/deploy-client.ts +0 -1574
  575. package/src/internal/deploy-manifest.ts +0 -361
  576. package/src/internal/deploy-source.ts +0 -144
  577. package/src/internal/describe-error.ts +0 -32
  578. package/src/internal/dev-mode.ts +0 -20
  579. package/src/internal/discovery/agent-config.ts +0 -288
  580. package/src/internal/discovery/agent.ts +0 -381
  581. package/src/internal/discovery/channels.ts +0 -100
  582. package/src/internal/discovery/connections.ts +0 -516
  583. package/src/internal/discovery/context.ts +0 -38
  584. package/src/internal/discovery/cursor-plugin.ts +0 -628
  585. package/src/internal/discovery/extension-overlay.ts +0 -247
  586. package/src/internal/discovery/extensions.ts +0 -490
  587. package/src/internal/discovery/fs.ts +0 -103
  588. package/src/internal/discovery/hooks.ts +0 -63
  589. package/src/internal/discovery/info.ts +0 -174
  590. package/src/internal/discovery/instructions.ts +0 -98
  591. package/src/internal/discovery/modules.ts +0 -107
  592. package/src/internal/discovery/names.ts +0 -45
  593. package/src/internal/discovery/project.ts +0 -319
  594. package/src/internal/discovery/reminders.ts +0 -65
  595. package/src/internal/discovery/runtime.ts +0 -158
  596. package/src/internal/discovery/schedules.ts +0 -120
  597. package/src/internal/discovery/seed-files.ts +0 -34
  598. package/src/internal/discovery/services.ts +0 -151
  599. package/src/internal/discovery/skills.ts +0 -174
  600. package/src/internal/discovery/subagent.ts +0 -138
  601. package/src/internal/discovery/tools.ts +0 -170
  602. package/src/internal/discovery.ts +0 -27
  603. package/src/internal/distribution.ts +0 -126
  604. package/src/internal/docs-site.ts +0 -248
  605. package/src/internal/duration.ts +0 -37
  606. package/src/internal/env-file.ts +0 -83
  607. package/src/internal/eval-judge-model.ts +0 -142
  608. package/src/internal/eval-run-store.ts +0 -585
  609. package/src/internal/eval-runner.ts +0 -823
  610. package/src/internal/evals-client.ts +0 -475
  611. package/src/internal/event-log.ts +0 -342
  612. package/src/internal/event-mapper.ts +0 -811
  613. package/src/internal/expected-delivery-failure.ts +0 -34
  614. package/src/internal/factory-resource-channel.ts +0 -103
  615. package/src/internal/filesystem/errors.ts +0 -207
  616. package/src/internal/filesystem/format.ts +0 -253
  617. package/src/internal/filesystem/merge.ts +0 -192
  618. package/src/internal/filesystem/nearest.ts +0 -112
  619. package/src/internal/filesystem/scratch.ts +0 -239
  620. package/src/internal/filesystem/sdk-schemas.ts +0 -204
  621. package/src/internal/filesystem/tools.ts +0 -804
  622. package/src/internal/filesystem/walk.ts +0 -366
  623. package/src/internal/fixtures/units-server.ts +0 -52
  624. package/src/internal/framework-file-storage.ts +0 -357
  625. package/src/internal/framework-storage-selection.ts +0 -156
  626. package/src/internal/frontmatter.ts +0 -108
  627. package/src/internal/github-fanout.ts +0 -144
  628. package/src/internal/guest-network.ts +0 -391
  629. package/src/internal/handleAgentServeTrigger.ts +0 -286
  630. package/src/internal/host-files.ts +0 -341
  631. package/src/internal/host-kv.ts +0 -81
  632. package/src/internal/host-otel.ts +0 -231
  633. package/src/internal/host-platforms.ts +0 -170
  634. package/src/internal/hosted-admission-adapter.ts +0 -47
  635. package/src/internal/hosted-admission-context.ts +0 -37
  636. package/src/internal/hosted-catch-protocol.ts +0 -112
  637. package/src/internal/hosted-catch.ts +0 -179
  638. package/src/internal/hosted-delivery-protocol.ts +0 -824
  639. package/src/internal/hosted-delivery.ts +0 -1410
  640. package/src/internal/hosted-execution-diag.ts +0 -291
  641. package/src/internal/hosted-execution-flush.ts +0 -136
  642. package/src/internal/hosted-execution-latency.ts +0 -301
  643. package/src/internal/hosted-managed-automation.ts +0 -116
  644. package/src/internal/hosting.ts +0 -114
  645. package/src/internal/http-channel-define.ts +0 -25
  646. package/src/internal/http-channel.ts +0 -669
  647. package/src/internal/http-control-plane-session.ts +0 -110
  648. package/src/internal/ids.ts +0 -39
  649. package/src/internal/incoming-headers-to-fetch.ts +0 -45
  650. package/src/internal/init-interview.ts +0 -360
  651. package/src/internal/init-project.ts +0 -711
  652. package/src/internal/init-scaffold.ts +0 -182
  653. package/src/internal/inline-stdio-define-stub.ts +0 -4
  654. package/src/internal/inline-stdio-mcp.ts +0 -230
  655. package/src/internal/install-cursor-skills.ts +0 -604
  656. package/src/internal/is-record.ts +0 -3
  657. package/src/internal/json-schema.ts +0 -95
  658. package/src/internal/legacy-command-guard.ts +0 -66
  659. package/src/internal/listen-port.ts +0 -85
  660. package/src/internal/local-control-plane.ts +0 -442
  661. package/src/internal/local-env.ts +0 -59
  662. package/src/internal/local-ingress.ts +0 -90
  663. package/src/internal/log-ring.ts +0 -59
  664. package/src/internal/logs-client.ts +0 -477
  665. package/src/internal/map-pool.ts +0 -39
  666. package/src/internal/mcp-endpoint.ts +0 -747
  667. package/src/internal/mcp-host.ts +0 -509
  668. package/src/internal/mcp-oauth-on-demand.ts +0 -337
  669. package/src/internal/mcp-oauth-persist.ts +0 -118
  670. package/src/internal/mcp-oauth.ts +0 -549
  671. package/src/internal/net.ts +0 -29
  672. package/src/internal/open-browser.ts +0 -41
  673. package/src/internal/otel/attrs.ts +0 -16
  674. package/src/internal/otel/collector.ts +0 -937
  675. package/src/internal/otel/config.ts +0 -287
  676. package/src/internal/otel/http.ts +0 -122
  677. package/src/internal/otel/mcp.ts +0 -56
  678. package/src/internal/otel/propagation.ts +0 -17
  679. package/src/internal/otel/runtime.ts +0 -441
  680. package/src/internal/package-inline-stdio.ts +0 -114
  681. package/src/internal/peer-connections.ts +0 -96
  682. package/src/internal/platform-schedule-sync.ts +0 -75
  683. package/src/internal/platform-timers.ts +0 -365
  684. package/src/internal/playground/static.ts +0 -278
  685. package/src/internal/playground/toolchain.ts +0 -270
  686. package/src/internal/playground-proxy.ts +0 -564
  687. package/src/internal/process-memory-telemetry.ts +0 -334
  688. package/src/internal/project-layout.ts +0 -31
  689. package/src/internal/prompt-context.ts +0 -116
  690. package/src/internal/reminder-control-plane-protocol.ts +0 -482
  691. package/src/internal/reminder-runner.ts +0 -1559
  692. package/src/internal/reminder-schedule.ts +0 -104
  693. package/src/internal/reminder-store.ts +0 -176
  694. package/src/internal/request-error-status.ts +0 -95
  695. package/src/internal/request-headers.ts +0 -21
  696. package/src/internal/resolve-prod-target.ts +0 -334
  697. package/src/internal/resolved-connections.ts +0 -190
  698. package/src/internal/router.ts +0 -143
  699. package/src/internal/run-client.ts +0 -354
  700. package/src/internal/runtime-dispatch-runner.ts +0 -50
  701. package/src/internal/sanitize-mcp-tool-name.ts +0 -31
  702. package/src/internal/schedule-runner.ts +0 -154
  703. package/src/internal/scm/pr-url.ts +0 -245
  704. package/src/internal/sdk-runner.ts +0 -959
  705. package/src/internal/serve-restart.ts +0 -113
  706. package/src/internal/server.ts +0 -3147
  707. package/src/internal/session-cost.ts +0 -208
  708. package/src/internal/session-engine.ts +0 -5622
  709. package/src/internal/session-links.ts +0 -84
  710. package/src/internal/session-run-log.ts +0 -535
  711. package/src/internal/session-store.ts +0 -307
  712. package/src/internal/session-urls.ts +0 -32
  713. package/src/internal/sessions-client.ts +0 -239
  714. package/src/internal/skill-catalog.ts +0 -66
  715. package/src/internal/skills-sync.ts +0 -55
  716. package/src/internal/slack-provision-client.ts +0 -544
  717. package/src/internal/slack-thread-key.ts +0 -11
  718. package/src/internal/sleep.ts +0 -3
  719. package/src/internal/start-log-store.ts +0 -164
  720. package/src/internal/steering.ts +0 -17
  721. package/src/internal/storage-coordinator.ts +0 -800
  722. package/src/internal/storage-roles.ts +0 -86
  723. package/src/internal/storage.ts +0 -1
  724. package/src/internal/store-api-protocol.ts +0 -205
  725. package/src/internal/store-mirror.ts +0 -73
  726. package/src/internal/stream-progress.ts +0 -294
  727. package/src/internal/terminal-style.ts +0 -133
  728. package/src/internal/testing/factory-resource-fixtures.ts +0 -84
  729. package/src/internal/testing/scm-continuation-fixtures.ts +0 -285
  730. package/src/internal/tool-catalog.ts +0 -104
  731. package/src/internal/tool-policy.ts +0 -222
  732. package/src/internal/tool-result.ts +0 -50
  733. package/src/internal/trajectory.ts +0 -418
  734. package/src/internal/turn-cost.ts +0 -136
  735. package/src/internal/turn-governor.ts +0 -145
  736. package/src/internal/turn-lease-store.ts +0 -144
  737. package/src/internal/turn-outbox.ts +0 -77
  738. package/src/internal/update-check.ts +0 -517
  739. package/src/internal/v2-hosting.ts +0 -52
  740. package/src/internal/workspace-sync.ts +0 -114
  741. package/src/internal/workspace.ts +0 -505
  742. package/src/kv/memory-kv.ts +0 -94
  743. package/src/kv.ts +0 -18
  744. package/src/memory.ts +0 -487
  745. package/src/otel-public.ts +0 -24
  746. package/src/otel.ts +0 -320
  747. package/src/prompt.ts +0 -80
  748. package/src/reminders.ts +0 -65
  749. package/src/schedules.ts +0 -31
  750. package/src/skills.ts +0 -27
  751. package/src/storage-backends/cursor-hosted-v2.ts +0 -204
  752. package/src/storage-backends/cursor-hosted.ts +0 -388
  753. package/src/storage-backends/file-kv.ts +0 -276
  754. package/src/storage-protocol.ts +0 -261
  755. package/src/storage.ts +0 -408
  756. package/src/tools.ts +0 -166
  757. package/src/types.ts +0 -3776
  758. /package/dist/docs/assets/{guides_jev.md.BNDm14Gy.lean.js → guides_jev.md.D7XH4JH3.lean.js} +0 -0
  759. /package/dist/docs/assets/{reference_http-api.md.BZOvhCqY.lean.js → reference_http-api.md.DbFNOubV.lean.js} +0 -0
  760. /package/dist/docs/assets/{reference_project-layout.md.CpLQ9j4K.lean.js → reference_project-layout.md.C2JMRh7p.lean.js} +0 -0
@@ -1,1377 +0,0 @@
1
- /**
2
- * Pure Workflow → BDK project converter.
3
- *
4
- * Maps an exported Cursor automation (proto3 workflow JSON + enriched MCP
5
- * server list) to project files, warnings, and setup steps. No I/O, no
6
- * clock — `exportedAt` comes from the caller.
7
- */
8
-
9
- import { envPrefixFromName } from "../../channels/slack/credentials.js";
10
- import { CLI_COMMAND_NAME, PACKAGE_NAME } from "../distribution.js";
11
- import { MEMORY_TS } from "../init-scaffold.js";
12
- import { CANONICAL_PROJECT_ROOT, projectPath, type ProjectRoot } from "../project-layout.js";
13
- import { SlugRegistry, slugify } from "./slug.js";
14
- import type {
15
- ActionJson,
16
- ConvertedFile,
17
- ConvertedMcpConnection,
18
- ConvertMcpServer,
19
- ConvertWorkflowInput,
20
- ConvertWorkflowResult,
21
- GitTriggerJson,
22
- PromptJson,
23
- SlackActionJson,
24
- SlackChannelsTriggerJson,
25
- SlackWatchTriggerJson,
26
- TriggerJson,
27
- WorkflowJson,
28
- } from "./types.js";
29
-
30
- /** Mutable result the emitters append to (also the returned value). */
31
- interface ConvertOutput {
32
- projectRoot: ProjectRoot;
33
- files: ConvertedFile[];
34
- warnings: string[];
35
- setupSteps: string[];
36
- mcpConnections: ConvertedMcpConnection[];
37
- }
38
-
39
- export function convertWorkflow(input: ConvertWorkflowInput): ConvertWorkflowResult {
40
- const { automation, workflow, mcpServers, exportedAt } = input;
41
- const projectRoot = input.projectRoot ?? CANONICAL_PROJECT_ROOT;
42
- const out: ConvertOutput = {
43
- projectRoot,
44
- files: [],
45
- warnings: [],
46
- setupSteps: [],
47
- mcpConnections: [],
48
- };
49
-
50
- if (workflow.managedConfig) {
51
- out.warnings.push(
52
- "This is a Cursor-managed automation: its behavior lives in managed configuration that is not exported. The exported project will NOT reproduce what this automation does.",
53
- );
54
- }
55
-
56
- // Pin the model the prompt actually ran with; the workflow-level model is
57
- // only a fallback. Silently swapping models changes cost and behavior.
58
- const promptModel = workflow.prompts?.[0]?.model;
59
- const pinnedModel =
60
- promptModel !== undefined && promptModel !== "" ? promptModel : workflow.model;
61
- if (
62
- promptModel !== undefined &&
63
- promptModel !== "" &&
64
- workflow.model !== undefined &&
65
- workflow.model !== "" &&
66
- promptModel !== workflow.model
67
- ) {
68
- out.warnings.push(
69
- `The automation ran its prompt with model ${JSON.stringify(promptModel)} (pinned in ${projectPath(projectRoot, "agent.ts")}); its workflow-level default was ${JSON.stringify(workflow.model)}.`,
70
- );
71
- }
72
-
73
- out.files.push({
74
- path: projectPath(projectRoot, "instructions.md"),
75
- contents: renderInstructions(automation, workflow, exportedAt, out.warnings, projectRoot),
76
- });
77
- out.files.push({
78
- path: projectPath(projectRoot, "agent.ts"),
79
- contents: renderAgentTs(automation, workflow, pinnedModel),
80
- });
81
-
82
- const triggers = workflow.triggers ?? [];
83
- const scheduleSlugs = new SlugRegistry();
84
- const channelSlugs = new SlugRegistry();
85
-
86
- const gitTriggers: TriggerJson[] = [];
87
- const slackTriggers: TriggerJson[] = [];
88
- const boilerplate: Array<{ trigger: TriggerJson; kind: BoilerplateKind }> = [];
89
-
90
- for (const trigger of triggers) {
91
- if (trigger.cron !== undefined) {
92
- emitSchedule(automation, trigger, scheduleSlugs, out);
93
- } else if (trigger.git !== undefined) {
94
- gitTriggers.push(trigger);
95
- } else if (isSlackTrigger(trigger)) {
96
- slackTriggers.push(trigger);
97
- } else {
98
- const kind = boilerplateKind(trigger);
99
- if (kind === undefined) {
100
- out.warnings.push(
101
- `Unrecognized trigger (keys: ${Object.keys(trigger).join(", ") || "none"}) was skipped — export it manually.`,
102
- );
103
- } else {
104
- boilerplate.push({ trigger, kind });
105
- }
106
- }
107
- }
108
-
109
- if (gitTriggers.length > 0) {
110
- emitGithubChannel(automation, workflow, gitTriggers, channelSlugs, out);
111
- }
112
- if (slackTriggers.length > 0) {
113
- emitSlackChannel(automation, slackTriggers, channelSlugs, out);
114
- }
115
- for (const { trigger, kind } of boilerplate) {
116
- emitBoilerplateChannel(automation, trigger, kind, channelSlugs, out);
117
- }
118
-
119
- emitMcpConnections(automation, mcpServers, out);
120
- const hasSlackAction = (workflow.actions ?? []).some(
121
- action => action.slack !== undefined || action.readSlack !== undefined,
122
- );
123
- const hasSlackConnection = hasSlackAction && emitSlackAccountConnection(automation, out);
124
-
125
- if (workflow.memoryEnabled === true) {
126
- out.files.push({
127
- path: projectPath(projectRoot, "hooks/memory.ts"),
128
- contents: MEMORY_TS,
129
- });
130
- }
131
-
132
- out.setupSteps.push(
133
- ...behaviorSteps(
134
- workflow,
135
- out.warnings,
136
- {
137
- hasSlackChannel: slackTriggers.length > 0,
138
- hasSlackConnection,
139
- },
140
- projectRoot,
141
- ),
142
- );
143
- out.setupSteps.push(
144
- `Disable the source automation before deploying this agent so both do not fire on the same events: ${automation.webUrl}${automation.enabled ? "" : " (it is currently disabled — keep it that way)"}`,
145
- );
146
-
147
- return out;
148
- }
149
-
150
- // ============================================================================
151
- // instructions.md
152
- // ============================================================================
153
-
154
- function renderInstructions(
155
- automation: ConvertWorkflowInput["automation"],
156
- workflow: WorkflowJson,
157
- exportedAt: string,
158
- warnings: string[],
159
- projectRoot: ProjectRoot,
160
- ): string {
161
- const header = [
162
- "<!--",
163
- ` Exported from Cursor automation "${commentSafe(automation.name)}"`,
164
- ` uuid: ${commentSafe(automation.uuid)}`,
165
- ` source: ${commentSafe(automation.webUrl)}`,
166
- ` exported: ${commentSafe(exportedAt)}`,
167
- "-->",
168
- ].join("\n");
169
-
170
- const prompts = workflow.prompts ?? [];
171
- if (prompts.length === 0) {
172
- warnings.push(
173
- `The source automation has no prompts — ${projectPath(projectRoot, "instructions.md")} contains a placeholder.`,
174
- );
175
- return `${header}\n\nTODO: the source automation had no prompt text. Write this agent's instructions.\n`;
176
- }
177
- // Prompt chaining was internal-only and never shipped; export the first
178
- // prompt and warn if a legacy row somehow carries more.
179
- if (prompts.length > 1) {
180
- warnings.push(
181
- `The source automation has ${prompts.length} prompts (a legacy internal feature); only the first was exported to ${projectPath(projectRoot, "instructions.md")}.`,
182
- );
183
- }
184
- const prompt = prompts[0];
185
- const meta = promptMeta(prompt);
186
- const heading = meta === "" ? "" : `<!-- ${meta} -->\n\n`;
187
- return `${header}\n\n${heading}${sanitizePromptText(prompt.prompt ?? "", warnings, projectRoot)}\n`;
188
- }
189
-
190
- /**
191
- * Strip Cursor-backend prompt markup that means nothing in BDK:
192
- * `@[label](action:...)` action tokens become their label text, and
193
- * unresolvable `%%INLINECODE<n>%%` storage placeholders are flagged (their
194
- * content is not in the export).
195
- */
196
- function sanitizePromptText(text: string, warnings: string[], projectRoot: ProjectRoot): string {
197
- let sanitized = text;
198
- if (/@\[[^\]]*\]\(action:[^)]*\)/.test(sanitized)) {
199
- warnings.push(
200
- "The prompt referenced Cursor automation actions (@[...](action:...)); the tokens were replaced with their label text. Wire the equivalent channel/connection (see setup steps) to restore the behavior.",
201
- );
202
- sanitized = sanitized.replace(/@\[([^\]]*)\]\(action:[^)]*\)/g, "$1");
203
- }
204
- if (/%%INLINECODE\d+%%/.test(sanitized)) {
205
- warnings.push(
206
- `${projectPath(projectRoot, "instructions.md")} contains unresolved %%INLINECODE<n>%% placeholders from Cursor's prompt storage — open the automation in the dashboard and paste the original snippet back in.`,
207
- );
208
- }
209
- return sanitized;
210
- }
211
-
212
- const EFFORT_LABELS: Record<string, string> = {
213
- PROMPT_EFFORT_LEVEL_STANDARD: "standard",
214
- 1: "standard",
215
- PROMPT_EFFORT_LEVEL_HARD: "hard",
216
- 10: "hard",
217
- };
218
-
219
- function promptMeta(prompt: PromptJson): string {
220
- const parts: string[] = [];
221
- const effort = EFFORT_LABELS[String(prompt.effortLevel)];
222
- if (effort !== undefined && effort !== "standard") {
223
- parts.push(`effort: ${effort}`);
224
- }
225
- if (prompt.model !== undefined && prompt.model !== "") {
226
- parts.push(`model: ${prompt.model}`);
227
- }
228
- return parts.join("; ");
229
- }
230
-
231
- // ============================================================================
232
- // agent.ts
233
- // ============================================================================
234
-
235
- function renderAgentTs(
236
- automation: ConvertWorkflowInput["automation"],
237
- workflow: WorkflowJson,
238
- pinnedModel: string | undefined,
239
- ): string {
240
- const comments: string[] = [
241
- `// Exported from Cursor automation "${commentSafe(automation.name)}"`,
242
- `// ${commentSafe(automation.webUrl)}`,
243
- ];
244
- if (workflow.gitConfig !== undefined) {
245
- comments.push("// git_config (repo/branch the automation worked in):");
246
- comments.push(...jsonComment(workflow.gitConfig));
247
- }
248
- if (workflow.agentOptions !== undefined) {
249
- comments.push("// agent_options:");
250
- comments.push(...jsonComment(workflow.agentOptions));
251
- }
252
- const body =
253
- pinnedModel !== undefined && pinnedModel !== ""
254
- ? `export default defineAgent({\n model: ${JSON.stringify(pinnedModel)},\n});`
255
- : "export default defineAgent({\n // The source automation used Cursor's default model.\n});";
256
- return `import { defineAgent } from "${PACKAGE_NAME}";\n\n${comments.join("\n")}\n${body}\n`;
257
- }
258
-
259
- // ============================================================================
260
- // Schedules (cron triggers)
261
- // ============================================================================
262
-
263
- function emitSchedule(
264
- automation: ConvertWorkflowInput["automation"],
265
- trigger: TriggerJson,
266
- slugs: SlugRegistry,
267
- out: ConvertOutput,
268
- ): void {
269
- const cron = trigger.cron?.cron;
270
- if (cron === undefined || cron === "") {
271
- out.warnings.push("A cron trigger had no cron expression and was skipped.");
272
- return;
273
- }
274
- const slug = slugs.claim(slugify(automation.name, "schedule"));
275
- const path = projectPath(out.projectRoot, `schedules/${slug}.ts`);
276
- const lines = [
277
- `import { defineSchedule } from "${PACKAGE_NAME}/schedules";`,
278
- "",
279
- `// Exported from Cursor automation "${commentSafe(automation.name)}" cron trigger.`,
280
- "// Cron is evaluated in UTC in both systems.",
281
- "export default defineSchedule({",
282
- ` cron: ${JSON.stringify(cron)},`,
283
- " markdown:",
284
- ` "Scheduled run: follow the instructions in ${projectPath(out.projectRoot, "instructions.md")}.",`,
285
- "});",
286
- "",
287
- ];
288
- out.files.push({ path, contents: lines.join("\n") });
289
- }
290
-
291
- // ============================================================================
292
- // GitHub channel (git triggers)
293
- // ============================================================================
294
-
295
- const GIT_EVENT_WEBHOOKS: Record<string, string[]> = {
296
- pullRequest: ["pull_request"],
297
- push: ["push"],
298
- ciCompleted: ["check_suite"],
299
- issueLabeled: ["issues"],
300
- label: [],
301
- issueComment: ["issue_comment"],
302
- pullRequestReviewComment: ["pull_request_review_comment"],
303
- pullRequestReview: ["pull_request_review"],
304
- reviewThread: ["pull_request_review_thread"],
305
- workflowRun: ["workflow_run"],
306
- pullRequestReviewRequested: ["pull_request"],
307
- issueAssigned: ["issues"],
308
- };
309
-
310
- /**
311
- * `pr.action`-based dispatch condition for one pull_request trigger,
312
- * mirroring the backend matcher (`webhookHandler.ts`): OPENED is non-draft
313
- * opened-or-ready-for-review; UNSPECIFIED is the legacy opened-or-synchronize
314
- * gated by `only_once`; `ignore_draft_prs` applies per trigger.
315
- */
316
- function prConditionFor(
317
- prAction: string,
318
- eventObject: Record<string, unknown>,
319
- ): string | undefined {
320
- const ignoreDrafts = eventObject.ignoreDraftPrs === true;
321
- switch (prAction) {
322
- case "GIT_PULL_REQUEST_ACTION_UNSPECIFIED": {
323
- const base =
324
- eventObject.onlyOnce === true
325
- ? 'pr.action === "opened"'
326
- : '(pr.action === "opened" || pr.action === "synchronize")';
327
- return `(${base}${ignoreDrafts ? " && !pr.draft" : ""})`;
328
- }
329
- case "GIT_PULL_REQUEST_ACTION_OPENED":
330
- return '((pr.action === "opened" || pr.action === "ready_for_review") && !pr.draft)';
331
- case "GIT_PULL_REQUEST_ACTION_PUSHED":
332
- return ignoreDrafts
333
- ? '(pr.action === "synchronize" && !pr.draft)'
334
- : '(pr.action === "synchronize")';
335
- case "GIT_PULL_REQUEST_ACTION_MERGED":
336
- return '(pr.action === "closed" && pr.merged)';
337
- case "GIT_PULL_REQUEST_ACTION_DRAFT_OPENED":
338
- return '(pr.action === "opened" && pr.draft)';
339
- case "GIT_PULL_REQUEST_ACTION_LABELED":
340
- return '(pr.action === "labeled")';
341
- case "GIT_PULL_REQUEST_ACTION_UNLABELED":
342
- return '(pr.action === "unlabeled")';
343
- default:
344
- return undefined;
345
- }
346
- }
347
- const PR_ACTION_NUMBERS: Record<string, string> = {
348
- 0: "GIT_PULL_REQUEST_ACTION_UNSPECIFIED",
349
- 1: "GIT_PULL_REQUEST_ACTION_OPENED",
350
- 2: "GIT_PULL_REQUEST_ACTION_PUSHED",
351
- 3: "GIT_PULL_REQUEST_ACTION_MERGED",
352
- 4: "GIT_PULL_REQUEST_ACTION_COMMENTED",
353
- 5: "GIT_PULL_REQUEST_ACTION_DRAFT_OPENED",
354
- 6: "GIT_PULL_REQUEST_ACTION_LABELED",
355
- 7: "GIT_PULL_REQUEST_ACTION_UNLABELED",
356
- };
357
-
358
- function emitGithubChannel(
359
- automation: ConvertWorkflowInput["automation"],
360
- workflow: WorkflowJson,
361
- triggers: TriggerJson[],
362
- slugs: SlugRegistry,
363
- out: ConvertOutput,
364
- ): void {
365
- const slug = slugs.claim("github");
366
- const path = projectPath(out.projectRoot, `channels/${slug}.ts`);
367
- const webhookEvents: string[] = [];
368
- const repos: string[] = [];
369
- let hasOrgs = false;
370
-
371
- // Mechanical filters recovered from the triggers, turned into real hooks
372
- // below so the exported channel dispatches on the same events the
373
- // automation did instead of shipping inert.
374
- const prConditions: string[] = [];
375
- let hasCommentedAction = false;
376
- let hasIssueCommentTrigger = false;
377
- // COMMENTED / review-comment triggers whose backend gates (PR-author
378
- // provenance via user_allowlist, commenter_allowlist, comment_contains)
379
- // cannot be reproduced by an onComment hook.
380
- let commentGatesLost = false;
381
- let hasUnknownPrAction = false;
382
- const pushBranches: string[] = [];
383
- let hasCheckSuite = false;
384
- let hasWorkflowRun = false;
385
- const issueActions: string[] = [];
386
- const userAllowlist: string[] = [];
387
-
388
- for (const trigger of triggers) {
389
- const git = trigger.git as GitTriggerJson;
390
- userAllowlist.push(...(git.userAllowlist ?? []).filter(user => user !== ""));
391
- for (const [eventKey, events] of Object.entries(GIT_EVENT_WEBHOOKS)) {
392
- const event = git[eventKey as keyof GitTriggerJson];
393
- if (event === undefined || typeof event !== "object") {
394
- continue;
395
- }
396
- webhookEvents.push(...events);
397
- const eventObject = event as Record<string, unknown>;
398
- if (eventKey === "pullRequest") {
399
- const raw = String(eventObject.prAction ?? "");
400
- const prAction =
401
- PR_ACTION_NUMBERS[raw] ?? (raw === "" ? "GIT_PULL_REQUEST_ACTION_UNSPECIFIED" : raw);
402
- if (prAction === "GIT_PULL_REQUEST_ACTION_COMMENTED") {
403
- webhookEvents.push("issue_comment");
404
- hasCommentedAction = true;
405
- if (
406
- (git.userAllowlist ?? []).length > 0 ||
407
- (Array.isArray(eventObject.commenterAllowlist) &&
408
- eventObject.commenterAllowlist.length > 0) ||
409
- (typeof eventObject.commentContains === "string" && eventObject.commentContains !== "")
410
- ) {
411
- commentGatesLost = true;
412
- }
413
- } else {
414
- const condition = prConditionFor(prAction, eventObject);
415
- if (condition === undefined) {
416
- hasUnknownPrAction = true;
417
- out.warnings.push(
418
- `A PR trigger${repoLabel(eventObject)} used unrecognized pr_action ${JSON.stringify(raw)} — add its dispatch condition to onPullRequest in ${path} (exported fail-closed).`,
419
- );
420
- } else {
421
- prConditions.push(condition);
422
- }
423
- }
424
- }
425
- if (eventKey === "pullRequestReviewRequested") {
426
- prConditions.push('(pr.action === "review_requested")');
427
- }
428
- if (eventKey === "issueComment") {
429
- hasIssueCommentTrigger = true;
430
- // A separate commenter_allowlist means BOTH lists must pass
431
- // (intersection), and comment_contains filters the body — neither
432
- // fits the single exported commenter gate.
433
- if (
434
- (Array.isArray(eventObject.commenterAllowlist) &&
435
- eventObject.commenterAllowlist.length > 0) ||
436
- (typeof eventObject.commentContains === "string" && eventObject.commentContains !== "")
437
- ) {
438
- commentGatesLost = true;
439
- }
440
- }
441
- if (eventKey === "pullRequestReviewComment") {
442
- // user_allowlist gates the PR author and commenter_allowlist the
443
- // commenter here — neither identity is visible to onComment — and
444
- // comment_contains filters the body.
445
- if (
446
- (git.userAllowlist ?? []).length > 0 ||
447
- (Array.isArray(eventObject.commenterAllowlist) &&
448
- eventObject.commenterAllowlist.length > 0) ||
449
- (typeof eventObject.commentContains === "string" && eventObject.commentContains !== "")
450
- ) {
451
- commentGatesLost = true;
452
- }
453
- }
454
- if (eventKey === "push") {
455
- if (typeof eventObject.branch === "string" && eventObject.branch !== "") {
456
- pushBranches.push(eventObject.branch);
457
- } else {
458
- // The backend matcher rejects push triggers without a branch —
459
- // they never fired, so exporting a dispatch would invent runs.
460
- out.warnings.push(
461
- `A push trigger${repoLabel(eventObject)} had no branch filter and never fired in the backend — exported without a dispatch.`,
462
- );
463
- }
464
- }
465
- if (eventKey === "ciCompleted") {
466
- hasCheckSuite = true;
467
- }
468
- if (eventKey === "workflowRun") {
469
- hasWorkflowRun = true;
470
- }
471
- if (eventKey === "issueLabeled") {
472
- if (typeof eventObject.labelName === "string" && eventObject.labelName !== "") {
473
- // The label-name filter is not visible to the typed hooks, so a
474
- // dispatch would fire on EVERY label change.
475
- out.warnings.push(
476
- `An issue-label trigger filtered on label ${JSON.stringify(eventObject.labelName)}, which the exported hooks cannot check — exported without a dispatch; re-add the filter in an onEvent hook reading the raw payload.`,
477
- );
478
- } else {
479
- // `unlabeled: true` flips the legacy trigger to label removal.
480
- issueActions.push(eventObject.unlabeled === true ? "unlabeled" : "labeled");
481
- }
482
- }
483
- if (eventKey === "issueAssigned") {
484
- issueActions.push("assigned");
485
- }
486
- // Review events export fail-closed: the backend gated review/thread
487
- // state and PR-author provenance, none of which the export can
488
- // reproduce. Without an onEvent hook the SDK drops the deliveries.
489
- if (eventKey === "pullRequestReview" || eventKey === "reviewThread") {
490
- out.warnings.push(
491
- `A ${eventKey === "pullRequestReview" ? "pull_request_review" : "review_thread"} trigger exported without a dispatch: the backend's review-state and PR-author provenance gates cannot be exported. Add an onEvent hook in ${path} to re-enable it with your own filters.`,
492
- );
493
- }
494
- if (typeof eventObject.repo === "string" && eventObject.repo !== "") {
495
- repos.push(eventObject.repo);
496
- }
497
- if (Array.isArray(eventObject.repos)) {
498
- repos.push(
499
- ...eventObject.repos.filter(
500
- (repo): repo is string => typeof repo === "string" && repo !== "",
501
- ),
502
- );
503
- }
504
- if (Array.isArray(eventObject.orgs) && eventObject.orgs.length > 0) {
505
- hasOrgs = true;
506
- }
507
- }
508
- const label = git.label;
509
- if (label !== undefined) {
510
- const labelObject = label as Record<string, unknown>;
511
- // The backend fires only for the configured direction(s); neither
512
- // flag set means the trigger never fired.
513
- let labelActions = [
514
- ...(labelObject.onAdded === true ? ["labeled"] : []),
515
- ...(labelObject.onRemoved === true ? ["unlabeled"] : []),
516
- ];
517
- if (labelActions.length === 0) {
518
- out.warnings.push(
519
- "A label trigger had neither on_added nor on_removed set and never fired in the backend — exported without a dispatch.",
520
- );
521
- }
522
- if (typeof labelObject.labelName === "string" && labelObject.labelName !== "") {
523
- // Label names are not visible to the typed hooks; dispatching would
524
- // fire on EVERY label change instead of the filtered one.
525
- out.warnings.push(
526
- `A label trigger filtered on label ${JSON.stringify(labelObject.labelName)}, which the exported hooks cannot check — exported without a dispatch; re-add the filter in a hook reading the raw payload.`,
527
- );
528
- labelActions = [];
529
- }
530
- if (label.pullRequests === true || label.issues !== true) {
531
- webhookEvents.push("pull_request");
532
- prConditions.push(
533
- ...labelActions.map(action => `(pr.action === ${JSON.stringify(action)})`),
534
- );
535
- }
536
- if (label.issues === true) {
537
- webhookEvents.push("issues");
538
- issueActions.push(...labelActions);
539
- }
540
- }
541
- }
542
- if (workflow.gitConfig?.repo !== undefined && workflow.gitConfig.repo !== "") {
543
- repos.push(workflow.gitConfig.repo);
544
- }
545
- repos.push(...(workflow.gitConfig?.repos ?? []));
546
-
547
- const uniqueEvents = dedupe(webhookEvents);
548
- const uniqueRepos = dedupe(
549
- dedupe(repos.filter(repo => repo !== "")).flatMap(repo => {
550
- const normalized = normalizeRepoIdentifier(repo, out);
551
- return normalized === undefined ? [] : [normalized];
552
- }),
553
- );
554
-
555
- if (hasOrgs) {
556
- out.warnings.push(
557
- `A git trigger watched whole GitHub orgs; the GitHub channel's cursorAccount scope needs explicit repos. List them in ${path}.`,
558
- );
559
- }
560
- out.setupSteps.push(
561
- `Review the generated hook filters in ${path} — mechanical trigger filters (PR action, push branch, issue action, user allowlist) were exported, but bespoke conditions Cursor's backend enforced (comment matching, CI conclusions, label names) must be re-added by hand.`,
562
- );
563
- if (hasCheckSuite || hasWorkflowRun) {
564
- out.warnings.push(
565
- `A CI trigger (ci_completed / workflow_run) exported FAIL-CLOSED: its backend filters (conclusion, branch, actor allowlist) cannot be exported, so the generated hook in ${path} returns null until you re-add them and dispatch.`,
566
- );
567
- }
568
- if (uniqueRepos.length === 0) {
569
- out.setupSteps.push(
570
- `No repositories could be derived for the GitHub channel — set githubChannel({ cursorAccount: { repos: [...] } }) or GitHub App credentials in ${path}.`,
571
- );
572
- }
573
-
574
- const configLines: string[] = [];
575
- if (uniqueRepos.length > 0) {
576
- configLines.push(" cursorAccount: {");
577
- configLines.push(` repos: [${uniqueRepos.map(repo => JSON.stringify(repo)).join(", ")}],`);
578
- configLines.push(" },");
579
- }
580
- configLines.push(
581
- ` webhookEvents: [${uniqueEvents.map(event => JSON.stringify(event)).join(", ")}],`,
582
- );
583
-
584
- const uniqueAllowlist = dedupe(userAllowlist.map(user => user.toLowerCase()));
585
- if (triggers.length > 1 && uniqueAllowlist.length > 0) {
586
- out.warnings.push(
587
- `user_allowlist applies per trigger in the backend; the export unions every trigger's allowlist across all hooks in ${path} — tighten per hook if the triggers differed.`,
588
- );
589
- }
590
- // The cursorAccount SCM-event relay delivers PR/comment snapshots only —
591
- // no push ref, no issue payload, no CI nodes, and no sender for
592
- // non-comment events — so hooks needing those fields only work with a
593
- // real GitHub App webhook or `github forward`.
594
- const relayLimited = [
595
- ...(dedupe(pushBranches).length > 0 ? ["push branch filters"] : []),
596
- ...(dedupe(issueActions).length > 0 ? ["issue triggers"] : []),
597
- ...(hasCheckSuite || hasWorkflowRun ? ["CI triggers"] : []),
598
- ];
599
- if (uniqueRepos.length > 0 && relayLimited.length > 0) {
600
- out.warnings.push(
601
- `cursorAccount event delivery carries PR/comment data only, so ${relayLimited.join(", ")} will NOT fire through it — deliver real GitHub webhooks to the deployed agent (GitHub App or \`github forward\`) for those triggers.`,
602
- );
603
- }
604
-
605
- const hasCommentEvents =
606
- uniqueEvents.includes("issue_comment") || uniqueEvents.includes("pull_request_review_comment");
607
- const commentGate: CommentGate = !hasCommentEvents
608
- ? "none"
609
- : commentGatesLost
610
- ? "failClosed"
611
- : hasIssueCommentTrigger && uniqueAllowlist.length > 0
612
- ? "commenterAllowlist"
613
- : "mentionDefault";
614
- if (commentGate === "failClosed") {
615
- out.warnings.push(
616
- `A comment trigger's backend gates (PR-author provenance via user_allowlist, commenter_allowlist, comment_contains) cannot be exported — comments dispatch NOTHING until you re-add them in onComment in ${path}.`,
617
- );
618
- }
619
-
620
- const { constLines, hookLines, usesAuth } = renderGithubHooks({
621
- prConditions: dedupe(prConditions),
622
- hasUnknownPrAction,
623
- pushBranches: dedupe(pushBranches),
624
- hasCheckSuite,
625
- hasWorkflowRun,
626
- issueActions: dedupe(issueActions),
627
- userAllowlist: uniqueAllowlist,
628
- hasPullRequestEvents: uniqueEvents.includes("pull_request"),
629
- commentGate,
630
- hasCommentedAction,
631
- });
632
- const imports = usesAuth
633
- ? "import { defaultGitHubAuth, githubChannel }"
634
- : "import { githubChannel }";
635
-
636
- const lines = [
637
- `${imports} from "${PACKAGE_NAME}/channels/github";`,
638
- "",
639
- `// Exported from Cursor automation "${commentSafe(automation.name)}" git trigger(s).`,
640
- "// Original trigger config:",
641
- ...jsonComment(triggers.map(trigger => trigger.git)),
642
- "//",
643
- "// The hooks below reproduce the triggers' mechanical filters. Cursor's",
644
- "// backend also enforced any bespoke conditions (comment matching, CI",
645
- "// conclusions, label names) — re-add those before relying on this.",
646
- ...constLines,
647
- "export default githubChannel({",
648
- ...configLines,
649
- ...hookLines,
650
- "});",
651
- "",
652
- ];
653
- out.files.push({ path, contents: lines.join("\n") });
654
- }
655
-
656
- type CommentGate = "none" | "mentionDefault" | "commenterAllowlist" | "failClosed";
657
-
658
- /** Render the dispatch hooks for {@link emitGithubChannel}. */
659
- function renderGithubHooks(args: {
660
- prConditions: string[];
661
- hasUnknownPrAction: boolean;
662
- pushBranches: string[];
663
- hasCheckSuite: boolean;
664
- hasWorkflowRun: boolean;
665
- issueActions: string[];
666
- userAllowlist: string[];
667
- hasPullRequestEvents: boolean;
668
- commentGate: CommentGate;
669
- hasCommentedAction: boolean;
670
- }): { constLines: string[]; hookLines: string[]; usesAuth: boolean } {
671
- const lines: string[] = [];
672
- const hasAllowlist = args.userAllowlist.length > 0;
673
- const hasPush = args.pushBranches.length > 0;
674
- let allowlistUsed = false;
675
- let usesAuth = false;
676
-
677
- if (args.prConditions.length > 0) {
678
- lines.push(" onPullRequest: (ctx, pr) => {");
679
- if (hasAllowlist) {
680
- allowlistUsed = true;
681
- lines.push(
682
- " if (",
683
- " pr.authorLogin === undefined ||",
684
- " !ALLOWED_USERS.includes(pr.authorLogin.toLowerCase())",
685
- " ) {",
686
- " return null;",
687
- " }",
688
- );
689
- }
690
- lines.push(
691
- " return (",
692
- ...args.prConditions.map(
693
- (condition, index) =>
694
- ` ${condition}${index < args.prConditions.length - 1 ? " ||" : ""}`,
695
- ),
696
- " )",
697
- " ? { auth: defaultGitHubAuth(ctx) }",
698
- " : null;",
699
- " },",
700
- );
701
- usesAuth = true;
702
- } else if (args.hasPullRequestEvents) {
703
- // Without this fail-safe the SDK's default gate would dispatch on
704
- // opened/reopened/synchronize/ready_for_review — broader than any
705
- // exported trigger. COMMENTED triggers get comments via the comment
706
- // gate; unrecognized/label-filtered triggers need their condition
707
- // re-added here.
708
- lines.push(" onPullRequest: () => null,");
709
- }
710
-
711
- if (hasPush) {
712
- lines.push(" onEvent: (ctx, event) => {");
713
- if (hasAllowlist) {
714
- allowlistUsed = true;
715
- lines.push(
716
- " // The backend gated push on the user allowlist (actor).",
717
- " if (",
718
- " ctx.senderLogin === undefined ||",
719
- " !ALLOWED_USERS.includes(ctx.senderLogin.toLowerCase())",
720
- " ) {",
721
- " return null;",
722
- " }",
723
- );
724
- }
725
- const refs = args.pushBranches.map(branch => JSON.stringify(`refs/heads/${branch}`));
726
- lines.push(
727
- ' if (event.eventName === "push") {',
728
- " // Branch filter from the original trigger.",
729
- " const ref = (event.payload as { ref?: string }).ref;",
730
- refs.length === 1
731
- ? ` if (ref !== ${refs[0]}) {`
732
- : ` if (ref === undefined || ![${refs.join(", ")}].includes(ref)) {`,
733
- " return null;",
734
- " }",
735
- " return { auth: defaultGitHubAuth(ctx) };",
736
- " }",
737
- );
738
- usesAuth = true;
739
- lines.push(" return null;", " },");
740
- }
741
-
742
- // check_suite / workflow_run only dispatch through their typed hooks —
743
- // the onEvent catch-all never sees them. They export FAIL-CLOSED: the
744
- // backend filters they relied on (CI conclusion/branch, and for
745
- // workflow_run the actor AND triggering-actor allowlist) cannot be
746
- // reproduced mechanically, and dispatching unfiltered would let any CI
747
- // delivery start an agent turn.
748
- if (args.hasCheckSuite) {
749
- lines.push(
750
- " onCheckSuite: () => {",
751
- " // Fail closed: re-add the original ci_completed filters —",
752
- ' // `suite.action === "completed"`, conclusion/branch, user',
753
- " // allowlist (see the trigger config above) — then dispatch with",
754
- " // `(ctx, suite) => ({ auth: defaultGitHubAuth(ctx) })`.",
755
- " return null;",
756
- " },",
757
- );
758
- }
759
- if (args.hasWorkflowRun) {
760
- lines.push(
761
- " onWorkflowRun: () => {",
762
- " // Fail closed: re-add the original workflow_run filters — the",
763
- ' // backend required `run.action === "completed"`, a push-origin',
764
- " // same-repo (non-fork) run, and gated the user allowlist on the",
765
- " // run's actor AND triggering actor — then dispatch with",
766
- " // `(ctx, run) => ({ auth: defaultGitHubAuth(ctx) })`.",
767
- " return null;",
768
- " },",
769
- );
770
- }
771
-
772
- if (args.issueActions.length > 0) {
773
- const condition =
774
- args.issueActions.length === 1
775
- ? `issue.action === ${JSON.stringify(args.issueActions[0])}`
776
- : `[${args.issueActions.map(action => JSON.stringify(action)).join(", ")}].includes(issue.action)`;
777
- lines.push(" onIssue: (ctx, issue) => {");
778
- if (hasAllowlist) {
779
- allowlistUsed = true;
780
- lines.push(
781
- " // The backend allowlisted the ACTOR (who labeled/assigned),",
782
- " // not the issue author.",
783
- " if (",
784
- " ctx.senderLogin === undefined ||",
785
- " !ALLOWED_USERS.includes(ctx.senderLogin.toLowerCase())",
786
- " ) {",
787
- " return null;",
788
- " }",
789
- );
790
- }
791
- lines.push(` return ${condition} ? { auth: defaultGitHubAuth(ctx) } : null;`, " },");
792
- usesAuth = true;
793
- }
794
-
795
- if (args.commentGate === "failClosed") {
796
- lines.push(
797
- " onComment: () => {",
798
- " // Fail closed: the trigger's backend comment gates (PR-author",
799
- " // provenance via user_allowlist, commenter_allowlist,",
800
- " // comment_contains — see the trigger config above) cannot be",
801
- " // exported. Re-add them here (PR author needs a ctx.github",
802
- " // lookup), then return { auth: defaultGitHubAuth(ctx) }.",
803
- " return null;",
804
- " },",
805
- );
806
- } else if (args.commentGate === "commenterAllowlist" && hasAllowlist) {
807
- // issue_comment triggers gate the COMMENTER on user_allowlist — the one
808
- // comment gate that is faithfully exportable.
809
- allowlistUsed = true;
810
- usesAuth = true;
811
- lines.push(
812
- " // Replaces the default @mention gate: the original fired on ALL",
813
- " // comments by allowlisted commenters.",
814
- " onComment: (ctx, comment) => {",
815
- " const author = comment.author?.login;",
816
- " if (",
817
- " author === undefined ||",
818
- " !ALLOWED_USERS.includes(author.toLowerCase())",
819
- " ) {",
820
- " return null;",
821
- " }",
822
- " return { auth: defaultGitHubAuth(ctx) };",
823
- " },",
824
- );
825
- } else if (args.commentGate === "mentionDefault" && lines.length > 0) {
826
- lines.push(
827
- " // Comments dispatch via the default @mention gate; the original",
828
- " // fired on ALL comments — declare onComment to widen it.",
829
- );
830
- }
831
-
832
- const constLines = allowlistUsed
833
- ? [
834
- "// user_allowlist from the original trigger(s), lowercased — GitHub",
835
- "// logins are case-insensitive and the backend compared them that way.",
836
- `const ALLOWED_USERS = [${args.userAllowlist.map(user => JSON.stringify(user)).join(", ")}];`,
837
- "",
838
- ]
839
- : [];
840
- return { constLines, hookLines: lines, usesAuth };
841
- }
842
-
843
- function repoLabel(eventObject: Record<string, unknown>): string {
844
- const repos = dedupe(
845
- [
846
- typeof eventObject.repo === "string" ? eventObject.repo : "",
847
- ...(Array.isArray(eventObject.repos)
848
- ? eventObject.repos.filter((repo): repo is string => typeof repo === "string")
849
- : []),
850
- ].filter(repo => repo !== ""),
851
- );
852
- return repos.length > 0 ? ` (${repos.join(", ")})` : "";
853
- }
854
-
855
- /**
856
- * Normalize a trigger/git_config repo into a GitHub `owner/repo` identifier
857
- * for `cursorAccount: { repos: [...] }`. github.com URLs (https or ssh) are
858
- * reduced to `owner/repo`; non-GitHub URLs are excluded with a warning;
859
- * plain strings pass through.
860
- */
861
- function normalizeRepoIdentifier(raw: string, out: ConvertOutput): string | undefined {
862
- let candidate = raw;
863
- if (raw.startsWith("git@") && !raw.includes("://")) {
864
- // git@host:path SSH shorthand → a parseable ssh:// URL.
865
- candidate = `ssh://${raw.replace(":", "/")}`;
866
- }
867
- if (!candidate.includes("://")) {
868
- return raw;
869
- }
870
- if (!URL.canParse(candidate)) {
871
- out.warnings.push(
872
- `Repo ${JSON.stringify(raw)} could not be parsed as a URL — excluded from the GitHub channel's cursorAccount repos; list it manually as owner/repo if it is GitHub-hosted.`,
873
- );
874
- return undefined;
875
- }
876
- const url = new URL(candidate);
877
- const host = url.hostname.toLowerCase();
878
- if (host !== "github.com" && host !== "www.github.com") {
879
- out.warnings.push(
880
- `Repo ${JSON.stringify(raw)} is not GitHub-hosted (host: ${url.hostname}) — excluded from the GitHub channel's cursorAccount repos; cursorAccount can only watch GitHub repositories.`,
881
- );
882
- // Losing a trigger repo silently halves coverage for dual-host setups,
883
- // so surface it as a required setup step, not just a warning.
884
- out.setupSteps.push(
885
- `Trigger repo ${JSON.stringify(raw)} is not on GitHub, so its events will NOT reach this agent. Re-deliver them yourself (e.g. a webhook to the deployed agent's /v1/channels/github route) or drop that trigger.`,
886
- );
887
- return undefined;
888
- }
889
- const segments = url.pathname.split("/").filter(s => s !== "");
890
- if (segments.length < 2) {
891
- out.warnings.push(
892
- `Repo URL ${JSON.stringify(raw)} has no owner/repo path — excluded from the GitHub channel's cursorAccount repos.`,
893
- );
894
- return undefined;
895
- }
896
- return `${segments[0]}/${segments[1].replace(/\.git$/, "")}`;
897
- }
898
-
899
- // ============================================================================
900
- // Slack channel
901
- // ============================================================================
902
-
903
- function isSlackTrigger(trigger: TriggerJson): boolean {
904
- return (
905
- trigger.slackMention !== undefined ||
906
- trigger.slackTrigger !== undefined ||
907
- trigger.slackReactionAdded !== undefined ||
908
- trigger.slackAnyReactionAdded !== undefined ||
909
- trigger.slackChannelCreated !== undefined
910
- );
911
- }
912
-
913
- function emitSlackChannel(
914
- automation: ConvertWorkflowInput["automation"],
915
- triggers: TriggerJson[],
916
- slugs: SlugRegistry,
917
- out: ConvertOutput,
918
- ): void {
919
- const slug = slugs.claim("slack");
920
- const path = projectPath(out.projectRoot, `channels/${slug}.ts`);
921
-
922
- const watches = triggers.filter(t => t.slackTrigger !== undefined);
923
- const unsupported = triggers.filter(
924
- t =>
925
- t.slackReactionAdded !== undefined ||
926
- t.slackAnyReactionAdded !== undefined ||
927
- t.slackChannelCreated !== undefined,
928
- );
929
- const socketMode = watches.length > 0 || unsupported.length > 0;
930
-
931
- for (const trigger of unsupported) {
932
- const kind = trigger.slackChannelCreated !== undefined ? "channel-created" : "reaction-added";
933
- out.warnings.push(
934
- `Slack ${kind} trigger has no BDK equivalent — its config is inlined as a comment in ${path}; handle the Slack event yourself on a dedicated Socket Mode app.`,
935
- );
936
- }
937
- let reactionDropped = false;
938
- for (const watch of watches) {
939
- const config = watch.slackTrigger as SlackWatchTriggerJson;
940
- if (config.messageContains !== undefined && config.messageContains !== "") {
941
- out.warnings.push(
942
- `Slack channel-watch message filter (${JSON.stringify(config.messageContains)}) was enforced by Cursor's backend — reimplement it (e.g. onChannelPost) in ${path}.`,
943
- );
944
- }
945
- // The backend defaults a missing/UNSPECIFIED mode to ON (checkmark
946
- // reaction); only explicit OFF means no reaction was added.
947
- const reactionMode = String(config.slackCompletionReactionMode ?? "");
948
- if (reactionMode !== "SLACK_COMPLETION_REACTION_MODE_OFF" && reactionMode !== "2") {
949
- reactionDropped = true;
950
- }
951
- }
952
- if (reactionDropped) {
953
- out.warnings.push(
954
- `The Slack trigger marked triggering messages with a completion reaction; BDK has no completion-reaction option, so that signal is lost unless ${projectPath(out.projectRoot, "instructions.md")} tells the agent to add the reaction itself via Slack tools.`,
955
- );
956
- }
957
- out.setupSteps.push(
958
- socketMode
959
- ? `Slack channel-watch / reaction / channel-created triggers need a dedicated Socket Mode Slack app: run \`${CLI_COMMAND_NAME} slack create --channel-posts\`, then finish in the dashboard wizard.`
960
- : `Slack mentions need a dedicated Socket Mode Slack app: run \`${CLI_COMMAND_NAME} slack create\`, then finish in the dashboard wizard.`,
961
- );
962
-
963
- const header = [
964
- `import { slackChannel } from "${PACKAGE_NAME}/channels/slack";`,
965
- "",
966
- `// Exported from Cursor automation "${commentSafe(automation.name)}" Slack trigger(s).`,
967
- "// Original trigger config:",
968
- ...jsonComment(triggers),
969
- ];
970
-
971
- let body: string[];
972
- if (socketMode) {
973
- const allow = dedupe(watches.flatMap(watch => slackChannelList(watch.slackTrigger)));
974
- const anyThreadReplies = watches.some(
975
- watch => (watch.slackTrigger as SlackWatchTriggerJson).topLevelOnly === false,
976
- );
977
- // "Authenticated Cursor users" watches require a linked Cursor account
978
- // on the owning team, which bots never have — so the backend blocked
979
- // bot posts for them, and the sender gate itself has no SDK equivalent.
980
- // The SDK has ONE bot-post setting per channel, so mixed watches must
981
- // pick a side: keep bots when any watch allowed everyone (alert /
982
- // scorebot watches depend on them), and say so loudly.
983
- const blocksUnauthenticated = watches.some(
984
- watch =>
985
- (watch.slackTrigger as SlackWatchTriggerJson).blockUnauthenticatedSlackUsers === true,
986
- );
987
- const includeBotPosts =
988
- watches.length > 0 &&
989
- watches.some(
990
- watch =>
991
- (watch.slackTrigger as SlackWatchTriggerJson).blockUnauthenticatedSlackUsers !== true,
992
- );
993
- if (blocksUnauthenticated) {
994
- out.warnings.push(
995
- includeBotPosts
996
- ? "Some Slack watches only fired for authenticated Cursor users while others allowed anyone; BDK has one bot-post setting per channel, so the export keeps bot posts ENABLED (the open watches depend on them) and the authenticated-only watches lose both their sender gate and their bot exclusion. Split the channels or add an onChannelPost gate."
997
- : "The Slack trigger only fired for authenticated Cursor users (linked accounts on the owning team); BDK has no equivalent sender gate, so the exported watch dispatches for ANY channel member (bot posts stay excluded). Add an onChannelPost gate in the channel if that matters.",
998
- );
999
- }
1000
- const engagement: string[] = [];
1001
- if (allow.length > 0) {
1002
- engagement.push(" engagement: {");
1003
- engagement.push(" channelPosts: {");
1004
- engagement.push(
1005
- ` allow: [${allow.map(channel => JSON.stringify(channel)).join(", ")}],`,
1006
- );
1007
- if (anyThreadReplies) {
1008
- engagement.push(' posts: "all",');
1009
- }
1010
- if (includeBotPosts) {
1011
- engagement.push(
1012
- " // Cursor's channel-watch dispatched on bot-authored posts",
1013
- " // (alerts, scorebots, ...); the SDK drops them by default and",
1014
- " // always ignores this agent's own posts.",
1015
- " includeBotPosts: true,",
1016
- );
1017
- }
1018
- engagement.push(" },");
1019
- engagement.push(" },");
1020
- }
1021
- body = [
1022
- "//",
1023
- `// Run \`${CLI_COMMAND_NAME} slack create --channel-posts\` for a dedicated Slack app.`,
1024
- ...slackChannelExport(automation.name, engagement),
1025
- ];
1026
- } else {
1027
- body = [
1028
- "//",
1029
- `// Run \`${CLI_COMMAND_NAME} slack create\` for a dedicated Slack app.`,
1030
- ...slackChannelExport(automation.name, []),
1031
- ];
1032
- }
1033
- out.files.push({ path, contents: `${[...header, ...body].join("\n")}\n` });
1034
- }
1035
-
1036
- /**
1037
- * `slack create` writes `<DIR>_SLACK_*` from the project directory. Convert
1038
- * names that directory from the automation (`Nightly Triage` →
1039
- * `nightly-triage` → `NIGHTLY_TRIAGE`). Emit the same prefix so minted
1040
- * tokens bind.
1041
- */
1042
- function slackChannelExport(name: string, optionLines: string[]): string[] {
1043
- const prefix = envPrefixFromName(slugify(name, "automation"));
1044
- const options = [
1045
- ...(prefix === "" ? [] : [` envPrefix: ${JSON.stringify(prefix)},`]),
1046
- ...optionLines,
1047
- ];
1048
- if (options.length === 0) {
1049
- return ["export default slackChannel();"];
1050
- }
1051
- return ["export default slackChannel({", ...options, "});"];
1052
- }
1053
-
1054
- function slackChannelList(trigger: SlackChannelsTriggerJson | undefined): string[] {
1055
- return [...(trigger?.channels ?? []), trigger?.channel].filter(
1056
- (channel): channel is string => typeof channel === "string" && channel !== "",
1057
- );
1058
- }
1059
-
1060
- // ============================================================================
1061
- // Boilerplate webhook channels (Linear / PagerDuty / Sentry / Teams / email / webhook)
1062
- // ============================================================================
1063
-
1064
- type BoilerplateKind = {
1065
- key:
1066
- | "linear"
1067
- | "pagerduty"
1068
- | "sentry"
1069
- | "webhook"
1070
- | "emailReceived"
1071
- | "microsoftTeamsTrigger"
1072
- | "microsoftTeamsChannelCreated";
1073
- slug: string;
1074
- label: string;
1075
- };
1076
-
1077
- const BOILERPLATE_KINDS: BoilerplateKind[] = [
1078
- { key: "linear", slug: "linear", label: "Linear" },
1079
- { key: "pagerduty", slug: "pagerduty", label: "PagerDuty" },
1080
- { key: "sentry", slug: "sentry", label: "Sentry" },
1081
- { key: "webhook", slug: "webhook", label: "webhook" },
1082
- { key: "emailReceived", slug: "email", label: "email received" },
1083
- {
1084
- key: "microsoftTeamsTrigger",
1085
- slug: "teams",
1086
- label: "Microsoft Teams message",
1087
- },
1088
- {
1089
- key: "microsoftTeamsChannelCreated",
1090
- slug: "teams-channel-created",
1091
- label: "Microsoft Teams channel-created",
1092
- },
1093
- ];
1094
-
1095
- function boilerplateKind(trigger: TriggerJson): BoilerplateKind | undefined {
1096
- return BOILERPLATE_KINDS.find(kind => trigger[kind.key] !== undefined);
1097
- }
1098
-
1099
- function emitBoilerplateChannel(
1100
- automation: ConvertWorkflowInput["automation"],
1101
- trigger: TriggerJson,
1102
- kind: BoilerplateKind,
1103
- slugs: SlugRegistry,
1104
- out: ConvertOutput,
1105
- ): void {
1106
- const slug = slugs.claim(kind.slug);
1107
- const path = projectPath(out.projectRoot, `channels/${slug}.ts`);
1108
- out.warnings.push(
1109
- `${kind.label} trigger exported as a boilerplate webhook channel (${path}) — Cursor-managed webhook delivery and event filtering do not carry over.`,
1110
- );
1111
- out.setupSteps.push(
1112
- `Re-register the ${kind.label} webhook against the deployed agent URL (/v1/channels/${slug}) and reimplement event filtering in ${path} — Cursor's backend did both before. The generated route accepts ANY unauthenticated POST and starts a run from it: add auth (e.g. bearerAuth or provider signature verification) before exposing it.`,
1113
- );
1114
- const lines = [
1115
- `import { defineChannel, POST } from "${PACKAGE_NAME}/channels";`,
1116
- 'import { z } from "zod";',
1117
- "",
1118
- `// Exported from Cursor automation "${commentSafe(automation.name)}" ${kind.label} trigger.`,
1119
- "// Original trigger config:",
1120
- ...jsonComment(trigger[kind.key]),
1121
- "//",
1122
- `// TODO: Cursor's backend previously received ${kind.label} webhooks and`,
1123
- "// applied the filtering above. Re-register the provider webhook against",
1124
- `// the deployed agent URL (/v1/channels/${slug}) and reimplement the event`,
1125
- "// filtering in this handler before dispatching.",
1126
- "export default defineChannel({",
1127
- " routes: [",
1128
- ' POST("/", {',
1129
- " bodySchema: z.unknown(),",
1130
- " handler: async (_req, { send, body }) => {",
1131
- " const session = await send(",
1132
- " [",
1133
- ` "Handle this ${kind.label} event:",`,
1134
- ' "",',
1135
- " JSON.stringify(body, null, 2),",
1136
- ' ].join("\\n")',
1137
- " );",
1138
- " return Response.json({ sessionId: session.id });",
1139
- " },",
1140
- " }),",
1141
- " ],",
1142
- "});",
1143
- "",
1144
- ];
1145
- out.files.push({ path, contents: lines.join("\n") });
1146
- }
1147
-
1148
- // ============================================================================
1149
- // MCP connections
1150
- // ============================================================================
1151
-
1152
- function emitMcpConnections(
1153
- automation: ConvertWorkflowInput["automation"],
1154
- mcpServers: ConvertMcpServer[],
1155
- out: ConvertOutput,
1156
- ): void {
1157
- const slugs = new SlugRegistry();
1158
- for (const server of mcpServers) {
1159
- const slug = slugs.claim(slugify(server.name, "mcp-server"));
1160
- if (server.transportType !== "stdio") {
1161
- out.mcpConnections.push({ name: slug, kind: "cursorAccount" });
1162
- const lines = [
1163
- `import { defineConnection } from "${PACKAGE_NAME}/connections";`,
1164
- "",
1165
- `// MCP server "${commentSafe(server.name)}" from Cursor automation "${commentSafe(automation.name)}".`,
1166
- "// Resolved at runtime through your Cursor account: tools list and",
1167
- "// execute on the Cursor backend with the account's stored credentials,",
1168
- "// so no URL or tokens live in this project. Sign this host in",
1169
- `// (\`${CLI_COMMAND_NAME} login\`) and manage the server's authorization`,
1170
- "// in Cursor (dashboard -> MCP).",
1171
- "export default defineConnection({",
1172
- " cursorAccount: true,",
1173
- ` servers: [${JSON.stringify(server.name)}],`,
1174
- "});",
1175
- "",
1176
- ];
1177
- out.files.push({
1178
- path: projectPath(out.projectRoot, `mcp-connections/${slug}.ts`),
1179
- contents: lines.join("\n"),
1180
- });
1181
- continue;
1182
- }
1183
- out.mcpConnections.push({ name: slug, kind: "stdioStub" });
1184
- const reason =
1185
- "it is a stdio server (its command, args, and env stay on Cursor's server). Run the server yourself and point a connection at it.";
1186
- // A comment-only .ts in mcp-connections/ fails discovery (a connection
1187
- // module must default-export defineConnection), so the stub is a .md the
1188
- // framework ignores.
1189
- const connectionPath = projectPath(out.projectRoot, `mcp-connections/${slug}.ts`);
1190
- const stubPath = projectPath(out.projectRoot, `mcp-connections/${slug}.todo.md`);
1191
- out.warnings.push(`MCP server "${server.name}" exported as a stub (${stubPath}): ${reason}`);
1192
- const lines = [
1193
- `# TODO: MCP server "${commentSafe(server.name)}"`,
1194
- "",
1195
- `The source automation used MCP server "${commentSafe(server.name)}", which could not`,
1196
- "be exported as a working connection:",
1197
- "",
1198
- `- ${reason}`,
1199
- "",
1200
- "Credentials are never exported. Once the server is reachable over",
1201
- `HTTP, create \`${connectionPath}\`:`,
1202
- "",
1203
- "```ts",
1204
- `import { defineConnection } from "${PACKAGE_NAME}/connections";`,
1205
- "",
1206
- "export default defineConnection({",
1207
- ' url: "https://example.com/mcp",',
1208
- ' oauth: true, // or headers: { authorization: "Bearer <token>" }',
1209
- "});",
1210
- "```",
1211
- "",
1212
- "This .md file is ignored by the framework; delete it once resolved.",
1213
- "",
1214
- ];
1215
- out.files.push({ path: stubPath, contents: lines.join("\n") });
1216
- }
1217
- }
1218
-
1219
- /**
1220
- * The automation posted to / read Slack via Cursor's built-in Slack action;
1221
- * restore that access with a Cursor-account Slack connection so the exported
1222
- * agent has Slack tools without any token plumbing. Returns whether the
1223
- * project ends up with a Slack MCP connection. An MCP server named "slack"
1224
- * may already have produced an equivalent connection, which counts.
1225
- */
1226
- function emitSlackAccountConnection(
1227
- automation: ConvertWorkflowInput["automation"],
1228
- out: ConvertOutput,
1229
- ): boolean {
1230
- const path = projectPath(out.projectRoot, "mcp-connections/slack.ts");
1231
- if (out.files.some(file => file.path === path)) {
1232
- return true;
1233
- }
1234
- const lines = [
1235
- `import { defineConnection } from "${PACKAGE_NAME}/connections";`,
1236
- "",
1237
- `// Cursor automation "${commentSafe(automation.name)}" used the built-in Slack action.`,
1238
- "// This connection restores Slack access through your Cursor account's",
1239
- "// Slack connector (dashboard -> MCP): tools execute on the Cursor",
1240
- "// backend with the account's stored credentials.",
1241
- "export default defineConnection({",
1242
- " cursorAccount: true,",
1243
- ' servers: ["Slack"],',
1244
- "});",
1245
- "",
1246
- ];
1247
- out.files.push({ path, contents: lines.join("\n") });
1248
- if (!out.mcpConnections.some(connection => connection.name === "slack")) {
1249
- out.mcpConnections.push({ name: "slack", kind: "cursorAccount" });
1250
- }
1251
- return true;
1252
- }
1253
-
1254
- // ============================================================================
1255
- // Built-in actions → behaviors to verify
1256
- // ============================================================================
1257
-
1258
- function actionSteps(projectRoot: ProjectRoot): Partial<Record<keyof ActionJson, string>> {
1259
- const instructionsPath = projectPath(projectRoot, "instructions.md");
1260
- return {
1261
- gitPr:
1262
- 'Verify: git_pr — the automation auto-opened PRs. Have the agent push and open PRs itself; githubChannel needs permissions: "contents-write" to push code.',
1263
- prComment: `Verify: pr_comment — githubChannel's default permissions ("pr-write") covers PR comments and reviews; guide comment behavior in ${instructionsPath}.`,
1264
- manageCheckRun:
1265
- "Verify: manage_check_run — no built-in equivalent; create/update check runs via ctx.github in a github channel hook.",
1266
- requestReviewers:
1267
- "Verify: request_reviewers — no built-in equivalent; request reviewers via ctx.github in a github channel hook.",
1268
- approvePr: `Verify: approve_pr — PR approval needs githubChannel "pr-write" plus explicit approval guidance in ${instructionsPath}.`,
1269
- resolveReviewThreads:
1270
- "Verify: resolve_review_threads — no built-in equivalent; resolve threads via the GitHub GraphQL API in a hook or tool.",
1271
- microsoftTeams:
1272
- "Verify: microsoft_teams post — BDK has no Teams channel; wire the Microsoft Teams API yourself.",
1273
- readMicrosoftTeams:
1274
- "Verify: read_microsoft_teams — BDK has no Teams tools; wire the Microsoft Teams API yourself.",
1275
- };
1276
- }
1277
-
1278
- interface SlackIntegrationState {
1279
- hasSlackChannel: boolean;
1280
- hasSlackConnection: boolean;
1281
- }
1282
-
1283
- function slackActionStep(
1284
- action: SlackActionJson,
1285
- { hasSlackChannel, hasSlackConnection }: SlackIntegrationState,
1286
- projectRoot: ProjectRoot,
1287
- ): string {
1288
- const channels = dedupe(slackChannelList(action));
1289
- const target =
1290
- action.generalized === true
1291
- ? "any channel (generalized)"
1292
- : channels.length > 0
1293
- ? channels.join(", ")
1294
- : "unspecified channel";
1295
- if (hasSlackChannel) {
1296
- return `Verify: slack post (target: ${target}) — the Slack channel replies in the triggering thread; posting to other channels needs Slack tools or a Cursor account MCP connection.`;
1297
- }
1298
- if (hasSlackConnection) {
1299
- return `Verify: slack post (target: ${target}) — ${projectPath(projectRoot, "mcp-connections/slack.ts")} restores Slack through your Cursor account's Slack connector; confirm it is connected in Cursor (dashboard -> MCP) and that ${projectPath(projectRoot, "instructions.md")} names the target channel.`;
1300
- }
1301
- return `Verify: slack post (target: ${target}) — the automation posted to Slack, but the exported project has no Slack integration; wire a Slack channel or a Cursor account MCP connection (defineConnection({ cursorAccount: true, servers: ["Slack"] })) to restore it.`;
1302
- }
1303
-
1304
- function behaviorSteps(
1305
- workflow: WorkflowJson,
1306
- warnings: string[],
1307
- slack: SlackIntegrationState,
1308
- projectRoot: ProjectRoot,
1309
- ): string[] {
1310
- const steps: string[] = [];
1311
- const knownActionSteps = actionSteps(projectRoot);
1312
- for (const action of workflow.actions ?? []) {
1313
- if (action.mcp !== undefined) {
1314
- continue; // Covered by the exported mcpServers list.
1315
- }
1316
- if (action.slack !== undefined) {
1317
- steps.push(slackActionStep(action.slack, slack, projectRoot));
1318
- continue;
1319
- }
1320
- if (action.readSlack !== undefined) {
1321
- steps.push(
1322
- slack.hasSlackConnection
1323
- ? `Verify: read_slack — Slack read access is available through the generated ${projectPath(projectRoot, "mcp-connections/slack.ts")} (Cursor-account Slack connector).`
1324
- : 'Verify: read_slack — expose Slack read access via a Cursor account MCP connection (defineConnection({ cursorAccount: true, servers: ["Slack"] })).',
1325
- );
1326
- continue;
1327
- }
1328
- const step = Object.entries(knownActionSteps).find(
1329
- ([key]) => action[key as keyof ActionJson] !== undefined,
1330
- )?.[1];
1331
- if (step === undefined) {
1332
- warnings.push(
1333
- `Unrecognized action (keys: ${Object.keys(action).join(", ") || "none"}) was skipped — verify its behavior manually.`,
1334
- );
1335
- continue;
1336
- }
1337
- steps.push(step);
1338
- }
1339
- const disabled = workflow.disabledDefaultTools ?? [];
1340
- if (disabled.length > 0) {
1341
- steps.push(
1342
- `Verify: disabled_default_tools (${disabled.join(", ")}) — BDK has no default automation tools; enforce the equivalent restriction in ${projectPath(projectRoot, "instructions.md")}.`,
1343
- );
1344
- }
1345
- return steps;
1346
- }
1347
-
1348
- // ============================================================================
1349
- // Shared helpers
1350
- // ============================================================================
1351
-
1352
- /**
1353
- * Neutralize comment-terminator sequences in server-provided text embedded
1354
- * in generated comments: JS line terminators (\r, \n, U+2028, U+2029) end a
1355
- * `//` comment, `-->` ends an HTML comment, and `*` + `/` ends a block
1356
- * comment. Without this, a crafted automation or MCP server name injects
1357
- * live code into the generated project.
1358
- */
1359
- function commentSafe(text: string): string {
1360
- return text
1361
- .replace(/[\r\n\u2028\u2029]+/g, " ")
1362
- .replace(/-->/g, "-- >")
1363
- .replace(/\*\//g, "* /");
1364
- }
1365
-
1366
- function jsonComment(value: unknown): string[] {
1367
- // JSON.stringify leaves U+2028/U+2029 raw; both terminate a `//` comment.
1368
- return JSON.stringify(value, null, 2)
1369
- .replace(/\u2028/g, "\\u2028")
1370
- .replace(/\u2029/g, "\\u2029")
1371
- .split("\n")
1372
- .map(line => `// ${line}`);
1373
- }
1374
-
1375
- function dedupe(values: string[]): string[] {
1376
- return [...new Set(values)];
1377
- }