@cursor/bdk 0.2.15 → 0.2.17

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 (280) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/agent-serve.js +41 -3
  3. package/dist/channels/github/index.d.ts +1 -1
  4. package/dist/channels/github/index.d.ts.map +1 -1
  5. package/dist/channels/github/index.js +1 -1
  6. package/dist/channels/slack/agentic-delivery.js +4 -4
  7. package/dist/channels/slack/api.d.ts.map +1 -1
  8. package/dist/channels/slack/api.js +7 -4
  9. package/dist/channels/slack/channel-watch.d.ts +2 -0
  10. package/dist/channels/slack/channel-watch.d.ts.map +1 -1
  11. package/dist/channels/slack/channel-watch.js +7 -3
  12. package/dist/channels/slack/dispatch.d.ts +3 -0
  13. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  14. package/dist/channels/slack/dispatch.js +6 -2
  15. package/dist/channels/slack/thread-context.d.ts.map +1 -1
  16. package/dist/channels/slack/thread-context.js +58 -26
  17. package/dist/channels/slack/types.d.ts +19 -0
  18. package/dist/channels/slack/types.d.ts.map +1 -1
  19. package/dist/docs/404.html +3 -3
  20. package/dist/docs/assets/{app.CRMxF0qX.js → app.CUNuFTSm.js} +4 -4
  21. package/dist/docs/assets/{building-with-agents.md.Bi9CQ-bR.js → building-with-agents.md.FZXrY8Nk.js} +1 -1
  22. package/dist/docs/assets/chunks/@localSearchIndexroot.3c56VHUt.js +1 -0
  23. package/dist/docs/assets/chunks/{VPLocalSearchBox.C4BiQe53.js → VPLocalSearchBox.Dez74k0W.js} +1 -1
  24. package/dist/docs/assets/chunks/{arc.D1TA2Mxn.js → arc.CJ3FhK7H.js} +1 -1
  25. package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.CA-hBJCN.js → architectureDiagram-Q4EWVU46.CfUdbHsa.js} +1 -1
  26. package/dist/docs/assets/chunks/{baseUniq.CzsSgiab.js → baseUniq.D93LawU9.js} +1 -1
  27. package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.sxrH_f0l.js → blockDiagram-DXYQGD6D.Zvsd6UHP.js} +1 -1
  28. package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.D_Z3mqAl.js → c4Diagram-AHTNJAMY.CGX5xZ9d.js} +1 -1
  29. package/dist/docs/assets/chunks/channel.S8-FFjmE.js +1 -0
  30. package/dist/docs/assets/chunks/{chunk-4BX2VUAB.BS6_uTUf.js → chunk-4BX2VUAB.CCIf0QCo.js} +1 -1
  31. package/dist/docs/assets/chunks/{chunk-4TB4RGXK.D-URAeTU.js → chunk-4TB4RGXK.D_N1RPyi.js} +1 -1
  32. package/dist/docs/assets/chunks/{chunk-55IACEB6.b4SZc5kO.js → chunk-55IACEB6.B1oecjzx.js} +1 -1
  33. package/dist/docs/assets/chunks/{chunk-EDXVE4YY.DLKEEDkN.js → chunk-EDXVE4YY.BzUNVPGX.js} +1 -1
  34. package/dist/docs/assets/chunks/{chunk-FMBD7UC4.3SyQHgpY.js → chunk-FMBD7UC4.DheI8WSO.js} +1 -1
  35. package/dist/docs/assets/chunks/{chunk-OYMX7WX6.DBKKaFeS.js → chunk-OYMX7WX6.Bg4iL0sM.js} +1 -1
  36. package/dist/docs/assets/chunks/{chunk-QZHKN3VN.BhCYeR7H.js → chunk-QZHKN3VN.CSQjDhAD.js} +1 -1
  37. package/dist/docs/assets/chunks/{chunk-YZCP3GAM.Cpg0VgI7.js → chunk-YZCP3GAM.BDdxnPU4.js} +1 -1
  38. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.BB98tFjZ.js +1 -0
  39. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.BB98tFjZ.js +1 -0
  40. package/dist/docs/assets/chunks/clone.B98w8OEv.js +1 -0
  41. package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.4q0YNZN6.js → cose-bilkent-S5V4N54A.AT0weO8r.js} +1 -1
  42. package/dist/docs/assets/chunks/{dagre-KV5264BT.Bk_CcQPr.js → dagre-KV5264BT.CJ30TxV0.js} +1 -1
  43. package/dist/docs/assets/chunks/{diagram-5BDNPKRD.CgreoM_Z.js → diagram-5BDNPKRD.KtE--1fW.js} +1 -1
  44. package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.DlZGpm6W.js → diagram-G4DWMVQ6.BFGygSUQ.js} +1 -1
  45. package/dist/docs/assets/chunks/{diagram-MMDJMWI5.BxtXxgIR.js → diagram-MMDJMWI5.BLU-79eb.js} +1 -1
  46. package/dist/docs/assets/chunks/{diagram-TYMM5635.DSzlJp2D.js → diagram-TYMM5635.CdjfJdVG.js} +1 -1
  47. package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.BN1YUmEV.js → erDiagram-SMLLAGMA.Dj1Iwypl.js} +1 -1
  48. package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.B61NGNYu.js → flowDiagram-DWJPFMVM.BXqj_Su2.js} +1 -1
  49. package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.DR-tto3M.js → ganttDiagram-T4ZO3ILL.CNfgGSst.js} +1 -1
  50. package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.CBPs2W_2.js → gitGraphDiagram-UUTBAWPF.2tgvFDBr.js} +1 -1
  51. package/dist/docs/assets/chunks/{graph.DmlaqzCE.js → graph.CWHZMxx6.js} +1 -1
  52. package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.obPv-fFg.js → infoDiagram-42DDH7IO.DhLIK8m1.js} +1 -1
  53. package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.CXHTUcM3.js → ishikawaDiagram-UXIWVN3A.BIN11n1G.js} +1 -1
  54. package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.BoVHerYZ.js → journeyDiagram-VCZTEJTY.BARmNJ0n.js} +1 -1
  55. package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.CfYmPHZg.js → kanban-definition-6JOO6SKY.BrTJYFyF.js} +1 -1
  56. package/dist/docs/assets/chunks/{layout.621UdAhB.js → layout.CPZIIywK.js} +1 -1
  57. package/dist/docs/assets/chunks/{linear.Cz_zRKjr.js → linear.DTpmzI5S.js} +1 -1
  58. package/dist/docs/assets/chunks/{min.ON4GjCH7.js → min.BBLQmXwZ.js} +1 -1
  59. package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.DLPMLJlv.js → mindmap-definition-QFDTVHPH.5qkWJvdl.js} +1 -1
  60. package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.BFp11AYt.js → pieDiagram-DEJITSTG.-4wufv_f.js} +1 -1
  61. package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.ChX7xo6B.js → quadrantDiagram-34T5L4WZ.C0jrp1-8.js} +1 -1
  62. package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.DbKtHG_Q.js → requirementDiagram-MS252O5E.DUDpANfe.js} +1 -1
  63. package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.Spw8tv-7.js → sankeyDiagram-XADWPNL6.74Lvg6Gu.js} +1 -1
  64. package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.BYso9LlE.js → sequenceDiagram-FGHM5R23.BHDIH286.js} +1 -1
  65. package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.D8l54jqW.js → stateDiagram-FHFEXIEX.Dr-HIuLb.js} +1 -1
  66. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.DW_lwpZY.js +1 -0
  67. package/dist/docs/assets/chunks/{theme.m_Ethbkv.js → theme.H8zSBhlM.js} +2 -2
  68. package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.BLdhhyy9.js → timeline-definition-GMOUNBTQ.GtyCaSiL.js} +1 -1
  69. package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CyGT2F_P.js → vennDiagram-DHZGUBPP.DLId0rxH.js} +1 -1
  70. package/dist/docs/assets/chunks/{wardley-RL74JXVD.C5JJS3bh.js → wardley-RL74JXVD.CSlECTHi.js} +1 -1
  71. package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.p_Sz9p1i.js → wardleyDiagram-NUSXRM2D.CI6mGYNG.js} +1 -1
  72. package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.DtXsNUaf.js → xychartDiagram-5P7HB3ND.CG1n865F.js} +1 -1
  73. package/dist/docs/assets/{deployment.md.hKKN9I4c.js → deployment.md.ajc3VM0m.js} +1 -1
  74. package/dist/docs/assets/{guides_migrate.md.sCAvvlC6.js → guides_migrate.md.DZBL7dqT.js} +1 -1
  75. package/dist/docs/assets/index.md.CHAFTf6m.js +27 -0
  76. package/dist/docs/assets/index.md.CHAFTf6m.lean.js +1 -0
  77. package/dist/docs/assets/{quickstart.md.CduLGBAB.js → quickstart.md.D8JDfkKO.js} +1 -1
  78. package/dist/docs/assets/{reference_agent-config.md.DrtLxWgR.js → reference_agent-config.md.DYA6ge6t.js} +7 -4
  79. package/dist/docs/assets/{reference_agent-config.md.DrtLxWgR.lean.js → reference_agent-config.md.DYA6ge6t.lean.js} +1 -1
  80. package/dist/docs/assets/{reference_cli.md.BYNIHwbi.js → reference_cli.md.Bt3sAfat.js} +3 -3
  81. package/dist/docs/assets/{reference_evals.md.if--BLd0.js → reference_evals.md.Ccwp4x3o.js} +3 -3
  82. package/dist/docs/assets/{reference_evals.md.if--BLd0.lean.js → reference_evals.md.Ccwp4x3o.lean.js} +1 -1
  83. package/dist/docs/assets/{reference_http-api.md.CrqhTv6S.js → reference_http-api.md.Dji-DD_Z.js} +1 -1
  84. package/dist/docs/assets/{reference_project-layout.md.C2JMRh7p.js → reference_project-layout.md.SNzIvnmC.js} +1 -1
  85. package/dist/docs/building-with-agents.html +37 -37
  86. package/dist/docs/building-with-agents.md +4 -4
  87. package/dist/docs/deployment.html +37 -37
  88. package/dist/docs/deployment.md +3 -4
  89. package/dist/docs/evals.html +36 -36
  90. package/dist/docs/guides/agent-to-agent.html +36 -36
  91. package/dist/docs/guides/bitbucket.html +36 -36
  92. package/dist/docs/guides/cloud-agents.html +36 -36
  93. package/dist/docs/guides/convert-automation.html +36 -36
  94. package/dist/docs/guides/github.html +36 -36
  95. package/dist/docs/guides/gitlab.html +36 -36
  96. package/dist/docs/guides/grokbot-agents.html +36 -36
  97. package/dist/docs/guides/hooks.html +36 -36
  98. package/dist/docs/guides/improve.html +36 -36
  99. package/dist/docs/guides/jev.html +36 -36
  100. package/dist/docs/guides/mcp-oauth.html +36 -36
  101. package/dist/docs/guides/migrate.html +37 -37
  102. package/dist/docs/guides/migrate.md +3 -3
  103. package/dist/docs/guides/opentelemetry.html +36 -36
  104. package/dist/docs/guides/slack.html +36 -36
  105. package/dist/docs/guides/webhooks.html +36 -36
  106. package/dist/docs/hashmap.json +1 -1
  107. package/dist/docs/hillclimbing.html +36 -36
  108. package/dist/docs/index.html +38 -38
  109. package/dist/docs/index.md +2 -2
  110. package/dist/docs/llms-full.txt +64 -28
  111. package/dist/docs/llms.txt +2 -2
  112. package/dist/docs/quickstart.html +37 -37
  113. package/dist/docs/quickstart.md +3 -3
  114. package/dist/docs/reference/agent-config.html +42 -39
  115. package/dist/docs/reference/agent-config.md +26 -1
  116. package/dist/docs/reference/artifacts.html +36 -36
  117. package/dist/docs/reference/channels.html +36 -36
  118. package/dist/docs/reference/cli.html +39 -39
  119. package/dist/docs/reference/cli.md +3 -3
  120. package/dist/docs/reference/connections.html +36 -36
  121. package/dist/docs/reference/evals.html +38 -38
  122. package/dist/docs/reference/evals.md +13 -0
  123. package/dist/docs/reference/extensions.html +36 -36
  124. package/dist/docs/reference/hooks.html +36 -36
  125. package/dist/docs/reference/http-api.html +37 -37
  126. package/dist/docs/reference/http-api.md +4 -4
  127. package/dist/docs/reference/instructions.html +36 -36
  128. package/dist/docs/reference/playground.html +36 -36
  129. package/dist/docs/reference/project-layout.html +37 -37
  130. package/dist/docs/reference/project-layout.md +2 -3
  131. package/dist/docs/reference/prompt.html +36 -36
  132. package/dist/docs/reference/schedules.html +36 -36
  133. package/dist/docs/reference/sessions.html +36 -36
  134. package/dist/docs/reference/skills.html +36 -36
  135. package/dist/docs/reference/subagents.html +36 -36
  136. package/dist/docs/reference/tools.html +36 -36
  137. package/dist/docs/templates/agentic-owners.html +36 -36
  138. package/dist/docs/templates/grokbot-agents.html +36 -36
  139. package/dist/docs/templates/security-reviewer.html +36 -36
  140. package/dist/docs/templates/thermo-quality-review.html +36 -36
  141. package/dist/docs/templates/thermo-review.html +36 -36
  142. package/dist/docs/templates/triage.html +36 -36
  143. package/dist/docs/troubleshooting.html +36 -36
  144. package/dist/filesystem.d.ts.map +1 -1
  145. package/dist/filesystem.js +4 -8
  146. package/dist/internal/cli-convert-automation.js +9 -19
  147. package/dist/internal/cli-deploy.d.ts +1 -1
  148. package/dist/internal/cli-deploy.d.ts.map +1 -1
  149. package/dist/internal/cli-deploy.js +4 -3
  150. package/dist/internal/cli-init-grokbot.d.ts +29 -0
  151. package/dist/internal/cli-init-grokbot.d.ts.map +1 -0
  152. package/dist/internal/cli-init-grokbot.js +181 -0
  153. package/dist/internal/cli-slack.js +1 -1
  154. package/dist/internal/comment-safe.d.ts +8 -0
  155. package/dist/internal/comment-safe.d.ts.map +1 -0
  156. package/dist/internal/comment-safe.js +12 -0
  157. package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -1
  158. package/dist/internal/convert-automation/convert-workflow.js +2 -14
  159. package/dist/internal/convert-grokbot/answers.d.ts +127 -0
  160. package/dist/internal/convert-grokbot/answers.d.ts.map +1 -0
  161. package/dist/internal/convert-grokbot/answers.js +443 -0
  162. package/dist/internal/convert-grokbot/bot.d.ts +50 -0
  163. package/dist/internal/convert-grokbot/bot.d.ts.map +1 -0
  164. package/dist/internal/convert-grokbot/bot.js +72 -0
  165. package/dist/internal/convert-grokbot/checks.d.ts +26 -0
  166. package/dist/internal/convert-grokbot/checks.d.ts.map +1 -0
  167. package/dist/internal/convert-grokbot/checks.js +170 -0
  168. package/dist/internal/convert-grokbot/convert.d.ts +60 -0
  169. package/dist/internal/convert-grokbot/convert.d.ts.map +1 -0
  170. package/dist/internal/convert-grokbot/convert.js +470 -0
  171. package/dist/internal/convert-grokbot/handoff.d.ts +44 -0
  172. package/dist/internal/convert-grokbot/handoff.d.ts.map +1 -0
  173. package/dist/internal/convert-grokbot/handoff.js +160 -0
  174. package/dist/internal/convert-grokbot/recipe.d.ts +61 -0
  175. package/dist/internal/convert-grokbot/recipe.d.ts.map +1 -0
  176. package/dist/internal/convert-grokbot/recipe.js +94 -0
  177. package/dist/internal/convert-grokbot/routine.d.ts +51 -0
  178. package/dist/internal/convert-grokbot/routine.d.ts.map +1 -0
  179. package/dist/internal/convert-grokbot/routine.js +128 -0
  180. package/dist/internal/convert-grokbot/slack.d.ts +28 -0
  181. package/dist/internal/convert-grokbot/slack.d.ts.map +1 -0
  182. package/dist/internal/convert-grokbot/slack.js +50 -0
  183. package/dist/internal/deploy-client.d.ts +0 -2
  184. package/dist/internal/deploy-client.d.ts.map +1 -1
  185. package/dist/internal/deploy-client.js +2 -11
  186. package/dist/internal/deploy-manifest.d.ts +6 -0
  187. package/dist/internal/deploy-manifest.d.ts.map +1 -1
  188. package/dist/internal/deploy-manifest.js +3 -0
  189. package/dist/internal/discovery/names.d.ts +2 -0
  190. package/dist/internal/discovery/names.d.ts.map +1 -1
  191. package/dist/internal/discovery/names.js +2 -0
  192. package/dist/internal/discovery/project.d.ts.map +1 -1
  193. package/dist/internal/discovery/project.js +1 -3
  194. package/dist/internal/eval-judge-model.d.ts +10 -5
  195. package/dist/internal/eval-judge-model.d.ts.map +1 -1
  196. package/dist/internal/eval-judge-model.js +36 -25
  197. package/dist/internal/filesystem/subagent-inherit.d.ts +39 -0
  198. package/dist/internal/filesystem/subagent-inherit.d.ts.map +1 -0
  199. package/dist/internal/filesystem/subagent-inherit.js +96 -0
  200. package/dist/internal/filesystem/tools.d.ts +6 -0
  201. package/dist/internal/filesystem/tools.d.ts.map +1 -1
  202. package/dist/internal/filesystem/tools.js +38 -1
  203. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  204. package/dist/internal/hosted-delivery.js +24 -1
  205. package/dist/internal/hosting.d.ts +1 -1
  206. package/dist/internal/hosting.d.ts.map +1 -1
  207. package/dist/internal/hosting.js +7 -3
  208. package/dist/internal/init-interview.d.ts +3 -5
  209. package/dist/internal/init-interview.d.ts.map +1 -1
  210. package/dist/internal/init-interview.js +15 -88
  211. package/dist/internal/init-project.d.ts +13 -0
  212. package/dist/internal/init-project.d.ts.map +1 -1
  213. package/dist/internal/init-project.js +30 -37
  214. package/dist/internal/init-scaffold.d.ts +11 -0
  215. package/dist/internal/init-scaffold.d.ts.map +1 -1
  216. package/dist/internal/init-scaffold.js +48 -14
  217. package/dist/internal/interview/agent-questions.d.ts +19 -0
  218. package/dist/internal/interview/agent-questions.d.ts.map +1 -0
  219. package/dist/internal/interview/agent-questions.js +120 -0
  220. package/dist/internal/interview/question.d.ts +82 -0
  221. package/dist/internal/interview/question.d.ts.map +1 -0
  222. package/dist/internal/interview/question.js +198 -0
  223. package/dist/internal/local-control-plane.d.ts.map +1 -1
  224. package/dist/internal/local-control-plane.js +5 -1
  225. package/dist/internal/otel/collector.d.ts +2 -0
  226. package/dist/internal/otel/collector.d.ts.map +1 -1
  227. package/dist/internal/otel/collector.js +4 -0
  228. package/dist/internal/peer-connections.d.ts +6 -0
  229. package/dist/internal/peer-connections.d.ts.map +1 -1
  230. package/dist/internal/peer-connections.js +9 -0
  231. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  232. package/dist/internal/resolve-prod-target.js +2 -1
  233. package/dist/internal/sdk-runner.d.ts.map +1 -1
  234. package/dist/internal/sdk-runner.js +38 -14
  235. package/dist/internal/sdk-subagent-inherit-support.d.ts +9 -0
  236. package/dist/internal/sdk-subagent-inherit-support.d.ts.map +1 -0
  237. package/dist/internal/sdk-subagent-inherit-support.js +89 -0
  238. package/dist/internal/session-engine.d.ts +13 -0
  239. package/dist/internal/session-engine.d.ts.map +1 -1
  240. package/dist/internal/session-engine.js +59 -11
  241. package/dist/internal/{convert-automation/slug.d.ts → slug.d.ts} +4 -1
  242. package/dist/internal/slug.d.ts.map +1 -0
  243. package/dist/internal/{convert-automation/slug.js → slug.js} +11 -1
  244. package/dist/playground/assets/index-7fVUOA5l.css +1 -0
  245. package/dist/playground/assets/{index-DCsq6f_I.js → index-U3TRnwAP.js} +43 -43
  246. package/dist/playground/index.html +2 -2
  247. package/dist/types.d.ts +10 -1
  248. package/dist/types.d.ts.map +1 -1
  249. package/docs/README.md +4 -4
  250. package/docs/building-with-agents.md +4 -4
  251. package/docs/deployment.md +3 -4
  252. package/docs/guides/migrate.md +3 -3
  253. package/docs/quickstart.md +3 -3
  254. package/docs/reference/agent-config.md +26 -1
  255. package/docs/reference/cli.md +3 -3
  256. package/docs/reference/evals.md +13 -0
  257. package/docs/reference/http-api.md +4 -4
  258. package/docs/reference/project-layout.md +2 -3
  259. package/package.json +5 -4
  260. package/schemas/grokbot-answers.schema.json +343 -0
  261. package/skills/create-agent/SKILL.md +7 -5
  262. package/templates/agentic-owners/bot/lib/owners/handles.ts +1 -1
  263. package/templates/agentic-owners/bot/lib/owners/matching.ts +20 -9
  264. package/dist/docs/assets/chunks/@localSearchIndexroot.BZwvb2LN.js +0 -1
  265. package/dist/docs/assets/chunks/channel.D7DtboxW.js +0 -1
  266. package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.irslOV8B.js +0 -1
  267. package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.irslOV8B.js +0 -1
  268. package/dist/docs/assets/chunks/clone.DosLeDYL.js +0 -1
  269. package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.CAYMmzGj.js +0 -1
  270. package/dist/docs/assets/index.md.BIBHIQtU.js +0 -27
  271. package/dist/docs/assets/index.md.BIBHIQtU.lean.js +0 -1
  272. package/dist/internal/convert-automation/slug.d.ts.map +0 -1
  273. package/dist/playground/assets/index-BVYWBxLU.css +0 -1
  274. /package/dist/docs/assets/{building-with-agents.md.Bi9CQ-bR.lean.js → building-with-agents.md.FZXrY8Nk.lean.js} +0 -0
  275. /package/dist/docs/assets/{deployment.md.hKKN9I4c.lean.js → deployment.md.ajc3VM0m.lean.js} +0 -0
  276. /package/dist/docs/assets/{guides_migrate.md.sCAvvlC6.lean.js → guides_migrate.md.DZBL7dqT.lean.js} +0 -0
  277. /package/dist/docs/assets/{quickstart.md.CduLGBAB.lean.js → quickstart.md.D8JDfkKO.lean.js} +0 -0
  278. /package/dist/docs/assets/{reference_cli.md.BYNIHwbi.lean.js → reference_cli.md.Bt3sAfat.lean.js} +0 -0
  279. /package/dist/docs/assets/{reference_http-api.md.CrqhTv6S.lean.js → reference_http-api.md.Dji-DD_Z.lean.js} +0 -0
  280. /package/dist/docs/assets/{reference_project-layout.md.C2JMRh7p.lean.js → reference_project-layout.md.SNzIvnmC.lean.js} +0 -0
@@ -0,0 +1,443 @@
1
+ /**
2
+ * Answers for `bdk init --from-grokbot`: the create-agent answers an export
3
+ * uses, plus the export decisions. Grok Bot collects them in chat and passes
4
+ * an answers file; a TTY asks the same questions with the same defaults.
5
+ * Answers name secrets and connectors; they never carry secret values.
6
+ */
7
+ import { z } from "zod";
8
+ import { zodToJsonSchema } from "zod-to-json-schema";
9
+ import { envPrefixFromName } from "../../channels/slack/credentials.js";
10
+ import { CLI_COMMAND_NAME } from "../distribution.js";
11
+ import { MAX_SECRET_NAME_LENGTH, validateSettableSecretName } from "../hosting.js";
12
+ import { AGENT_FIELDS, agentName, CHANNELS } from "../interview/agent-questions.js";
13
+ import { checkedString, collectAnswers, field, listAnswer, } from "../interview/question.js";
14
+ import { isRecord } from "../is-record.js";
15
+ import { slugify } from "../slug.js";
16
+ import { connectorUrlError, defaultSlackBotName, namespaceError, redactSecretValues, repoNameError, slackBotNameError, } from "./checks.js";
17
+ import { formatIssues, versionSchema } from "./recipe.js";
18
+ import { liveChannel } from "./routine.js";
19
+ export const GROKBOT_ANSWERS_VERSION = 1;
20
+ export const KINDS = ["skills", "routines", "plugins"];
21
+ export const MEMORY_MODES = ["skill", "kv", "drop"];
22
+ export const CONNECTOR_AUTH = ["cursor-account", "oauth", "secret"];
23
+ export const DEPLOY_WHEN = ["after-review", "now", "scheduled", "never"];
24
+ export const SLACK_APPS = ["new", "move"];
25
+ export const SLACK_CUTOVERS = ["manual", "after-deploy", "scheduled"];
26
+ const slug = z.string().regex(/^[a-z0-9][a-z0-9-]*$/, "must be a lowercase slug");
27
+ const instant = z
28
+ .string()
29
+ .datetime({ offset: true, message: "must be an ISO 8601 time with a timezone" });
30
+ const secretName = checkedString(validateSettableSecretName);
31
+ const slackOn = (answers) => listAnswer(answers.channels).includes("slack");
32
+ function agentField(id) {
33
+ const found = AGENT_FIELDS.find((f) => f.question.id === id);
34
+ if (found === undefined) {
35
+ throw new Error(`No create-agent question "${id}".`);
36
+ }
37
+ return found;
38
+ }
39
+ /** Identity, surface, and item choices; recipe defaults are patched in per bot. */
40
+ const BASE_FIELDS = [
41
+ agentField("name"),
42
+ field("identity", {
43
+ id: "description",
44
+ label: "Description",
45
+ prompt: "What does the bot do, in a sentence or two?",
46
+ }, z.string().min(1)),
47
+ agentField("location"),
48
+ agentField("model"),
49
+ agentField("channels"),
50
+ field("export", {
51
+ id: "memory",
52
+ label: "Memory",
53
+ prompt: "What should happen to the bot's memories?",
54
+ hint: "skill: a knowledge skill the agent reads on demand. kv: data in bot/lib/memory-seed.json for your own seeding code (BDK has no built-in KV seed). drop: leave them behind.",
55
+ choices: [...MEMORY_MODES],
56
+ default: "skill",
57
+ }, z.enum(MEMORY_MODES)),
58
+ ...KINDS.map((kind) => field("export", {
59
+ id: `${kind}.include`,
60
+ label: `Include ${kind}`,
61
+ prompt: `Which ${kind} should come along?`,
62
+ multi: true,
63
+ default: "all",
64
+ }, z.array(slug))),
65
+ ];
66
+ /** One set per recipe plugin; `*` is its slug and `{plugin}` its name. */
67
+ const CONNECTOR_FIELDS = [
68
+ field("export", {
69
+ id: "connectors.*.auth",
70
+ label: "Auth",
71
+ prompt: "How should {plugin} authenticate?",
72
+ hint: `cursor-account: tools run through your Cursor account's connector, with no secret in the project. oauth: host OAuth against the server URL (\`${CLI_COMMAND_NAME} mcp oauth\`). secret: a bearer token read from a named secret.`,
73
+ choices: [...CONNECTOR_AUTH],
74
+ default: "cursor-account",
75
+ }, z.enum(CONNECTOR_AUTH)),
76
+ field("export", {
77
+ id: "connectors.*.server",
78
+ label: "Connector name",
79
+ prompt: "Name of the {plugin} connector in your Cursor account?",
80
+ }, z.string().min(1)),
81
+ field("export", { id: "connectors.*.url", label: "Server URL", prompt: "{plugin} MCP server URL?" }, checkedString(connectorUrlError)),
82
+ field("export", {
83
+ id: "connectors.*.secret",
84
+ label: "Secret name",
85
+ prompt: "Secret that holds the {plugin} token?",
86
+ hint: `A name only, like LINEAR_API_KEY. Set the value later with \`${CLI_COMMAND_NAME} secrets set\`.`,
87
+ }, secretName),
88
+ ];
89
+ /** One per routine placeholder; `*.*` is the routine slug and placeholder id. */
90
+ const FILL_IN_FIELD = field("export", {
91
+ id: "fillIns.*.*",
92
+ label: "{placeholder}",
93
+ prompt: "{routine}: {placeholder}?",
94
+ optional: true,
95
+ }, z.string().min(1));
96
+ const DECISION_FIELDS = [
97
+ field("export", {
98
+ id: "secrets.names",
99
+ label: "Secret names",
100
+ prompt: "Other secret names to list in SECRETS.md?",
101
+ hint: "Names only, UPPER_SNAKE_CASE. Names the generated files read are always listed.",
102
+ multi: true,
103
+ other: true,
104
+ optional: true,
105
+ }, z.array(secretName)),
106
+ field("export", {
107
+ id: "secrets.reauth",
108
+ label: "Fresh sign-in",
109
+ prompt: "Which other connectors need a fresh sign-in?",
110
+ hint: "OAuth connectors always do; they are listed without asking.",
111
+ multi: true,
112
+ optional: true,
113
+ }, z.array(slug)),
114
+ field("export", {
115
+ id: "repo.name",
116
+ label: "Repository",
117
+ prompt: `Repository name? (recorded only; ${CLI_COMMAND_NAME} does not create repositories)`,
118
+ default: (answers) => answers.name?.slice(0, 100),
119
+ }, checkedString(repoNameError)),
120
+ field("export", {
121
+ id: "repo.namespace",
122
+ label: "Repository namespace",
123
+ prompt: "Repository owner or namespace? (recorded only)",
124
+ optional: true,
125
+ }, checkedString(namespaceError)),
126
+ field("export", {
127
+ id: "deploy.when",
128
+ label: "Deploy",
129
+ prompt: `When should it deploy? (recorded only; ${CLI_COMMAND_NAME} does not deploy)`,
130
+ choices: [...DEPLOY_WHEN],
131
+ default: "after-review",
132
+ }, z.enum(DEPLOY_WHEN)),
133
+ field("export", {
134
+ id: "deploy.at",
135
+ label: "Deploy at",
136
+ prompt: "Deploy at (ISO 8601 with a timezone)?",
137
+ when: (answers) => answers["deploy.when"] === "scheduled",
138
+ }, instant),
139
+ field("export", {
140
+ id: "slack.app",
141
+ label: "Slack app",
142
+ prompt: "Mint a new Slack app, or move the bot's existing one?",
143
+ choices: [...SLACK_APPS],
144
+ default: "new",
145
+ when: slackOn,
146
+ }, z.enum(SLACK_APPS)),
147
+ field("export", {
148
+ id: "slack.cutover",
149
+ label: "Slack cutover",
150
+ prompt: "When should Slack traffic switch to the BDK agent?",
151
+ choices: [...SLACK_CUTOVERS],
152
+ default: "manual",
153
+ when: slackOn,
154
+ }, z.enum(SLACK_CUTOVERS)),
155
+ field("export", {
156
+ id: "slack.cutoverAt",
157
+ label: "Slack cutover at",
158
+ prompt: "Switch Slack traffic at (ISO 8601 with a timezone)?",
159
+ when: (answers) => slackOn(answers) && answers["slack.cutover"] === "scheduled",
160
+ }, instant),
161
+ field("export", {
162
+ id: "slack.teamPrefix",
163
+ label: "Team prefix",
164
+ prompt: "Team prefix the Slack bot name must start with?",
165
+ optional: true,
166
+ when: slackOn,
167
+ }, z.string().min(1)),
168
+ field("export", {
169
+ id: "slack.botName",
170
+ label: "Slack bot name",
171
+ prompt: "Slack bot display name?",
172
+ hint: 'Starts with the team prefix and must not contain "Grok".',
173
+ check: (value, answers) => slackBotNameError(value, answers["slack.teamPrefix"]),
174
+ when: slackOn,
175
+ }, z.string().min(1)),
176
+ field("export", {
177
+ id: "slack.justification",
178
+ label: "Security justification",
179
+ prompt: "Security justification for the Slack app review?",
180
+ hint: "What the bot does in Slack and why it needs its scopes. Saved for the Slack app setup.",
181
+ default: (answers) => answers.description,
182
+ when: slackOn,
183
+ }, z.string().min(1)),
184
+ ];
185
+ /** Every question an answers file can answer, in asking order. */
186
+ const FIELDS = [
187
+ ...BASE_FIELDS,
188
+ ...CONNECTOR_FIELDS,
189
+ FILL_IN_FIELD,
190
+ ...DECISION_FIELDS,
191
+ ];
192
+ /** Whether an item survives the include answer; an unasked include keeps everything. */
193
+ function isSelected(answers, kind, item) {
194
+ const include = answers[`${kind}.include`];
195
+ return include === undefined || listAnswer(include).includes(item);
196
+ }
197
+ function exportName(name) {
198
+ const candidate = slugify(name, "grokbot");
199
+ return agentName.safeParse(candidate).success ? candidate : `${candidate}-bot`;
200
+ }
201
+ /** The channels the recipe's live triggers use. */
202
+ function botChannels(bot) {
203
+ const used = new Set([...bot.skills, ...bot.routines].flatMap((item) => item.triggers).map(liveChannel));
204
+ return CHANNELS.filter((channel) => used.has(channel)).join(", ") || "none";
205
+ }
206
+ function defaultSecretName(plugin) {
207
+ const prefix = envPrefixFromName(plugin.slug).slice(0, MAX_SECRET_NAME_LENGTH - "MCP__TOKEN".length);
208
+ const name = `${prefix}_TOKEN`;
209
+ return validateSettableSecretName(name) === undefined ? name : `MCP_${name}`;
210
+ }
211
+ function patch(f, question) {
212
+ return { ...f, question: { ...f.question, ...question } };
213
+ }
214
+ function pluginFields(plugin) {
215
+ const id = (key) => `connectors.${plugin.slug}.${key}`;
216
+ const included = (answers) => isSelected(answers, "plugins", plugin.slug);
217
+ const auth = (answers) => (included(answers) ? answers[id("auth")] : undefined);
218
+ const patches = {
219
+ auth: { when: included },
220
+ server: { default: plugin.name, when: (answers) => auth(answers) === "cursor-account" },
221
+ url: { when: (answers) => auth(answers) === "oauth" || auth(answers) === "secret" },
222
+ secret: { default: defaultSecretName(plugin), when: (answers) => auth(answers) === "secret" },
223
+ };
224
+ return CONNECTOR_FIELDS.map((f) => {
225
+ const key = f.question.id.split(".").at(-1) ?? "";
226
+ return patch(f, {
227
+ id: id(key),
228
+ prompt: f.question.prompt.replace("{plugin}", plugin.name),
229
+ ...patches[key],
230
+ });
231
+ });
232
+ }
233
+ function fillInField(routine, fill) {
234
+ return patch(FILL_IN_FIELD, {
235
+ id: `fillIns.${routine.slug}.${fill.id}`,
236
+ label: fill.label,
237
+ prompt: `${routine.name}: ${fill.label}?`,
238
+ when: (answers) => isSelected(answers, "routines", routine.slug),
239
+ });
240
+ }
241
+ /** The questions for one recipe, in asking order. */
242
+ export function grokbotFields(bot) {
243
+ const patches = {
244
+ name: { default: exportName(bot.name) },
245
+ description: { default: bot.description },
246
+ channels: { default: botChannels(bot) },
247
+ memory: { when: () => bot.memory.length > 0 },
248
+ "secrets.reauth": {
249
+ choices: bot.plugins.map((plugin) => ({ value: plugin.slug, label: plugin.name })),
250
+ when: () => bot.plugins.length > 0,
251
+ },
252
+ "slack.botName": {
253
+ default: (answers) => defaultSlackBotName(bot.name, answers["slack.teamPrefix"]),
254
+ },
255
+ };
256
+ for (const kind of KINDS) {
257
+ const items = bot[kind];
258
+ patches[`${kind}.include`] = {
259
+ choices: items.map((item) => ({ value: item.slug, label: item.name })),
260
+ when: () => items.length > 0,
261
+ };
262
+ }
263
+ return [
264
+ ...BASE_FIELDS.map((f) => patch(f, patches[f.question.id])),
265
+ ...bot.plugins.flatMap(pluginFields),
266
+ ...bot.routines.flatMap((routine) => routine.fillIns.map((fill) => fillInField(routine, fill))),
267
+ ...DECISION_FIELDS.map((f) => patch(f, patches[f.question.id])),
268
+ ];
269
+ }
270
+ function child(node, key) {
271
+ if (!Object.hasOwn(node, key)) {
272
+ node[key] = {};
273
+ }
274
+ return node[key];
275
+ }
276
+ /** Schemas nested by dotted id; a `*` segment becomes a record. */
277
+ function shapeOf(entries) {
278
+ const tree = {};
279
+ for (const [id, schema] of entries) {
280
+ const path = id.split(".");
281
+ const leaf = path.pop() ?? id;
282
+ path.reduce(child, tree)[leaf] = schema;
283
+ }
284
+ return mapValues(tree, (node) => toZod(node).optional());
285
+ }
286
+ function toZod(node) {
287
+ if (node instanceof z.ZodType) {
288
+ return node;
289
+ }
290
+ const record = node;
291
+ return Object.hasOwn(record, "*")
292
+ ? z.record(z.string(), toZod(record["*"]))
293
+ : z.object(mapValues(record, (value) => toZod(value).optional())).strict();
294
+ }
295
+ function mapValues(record, fn) {
296
+ return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, fn(value)]));
297
+ }
298
+ const EXCLUDES = KINDS.map((kind) => [`${kind}.exclude`, z.array(slug)]);
299
+ /** An answers file: every field optional, unknown fields rejected. */
300
+ const answersSchema = z
301
+ .object({
302
+ $schema: z.string().optional(),
303
+ version: versionSchema(GROKBOT_ANSWERS_VERSION),
304
+ ...shapeOf([...FIELDS.map((f) => [f.question.id, f.schema]), ...EXCLUDES]),
305
+ })
306
+ .strict();
307
+ export async function resolveAnswers(input) {
308
+ const file = answersSchema.safeParse(input.answers ?? {});
309
+ if (!file.success) {
310
+ return { ok: false, error: `Invalid answers: ${formatIssues(file.error)}` };
311
+ }
312
+ const { $schema: _schema, version: _version, ...rest } = file.data;
313
+ const given = foldExcludes(flatten(rest), input.bot);
314
+ const fields = grokbotFields(input.bot);
315
+ const collected = await collectAnswers({
316
+ questions: fields.map((f) => f.question),
317
+ given,
318
+ interactive: input.interactive,
319
+ ask: input.ask,
320
+ out: input.out,
321
+ show: (text) => redactSecretValues(text).text,
322
+ missing: (question) => `add ${question.id} to the answers file (${question.prompt})`,
323
+ });
324
+ if (!collected.ok) {
325
+ return collected;
326
+ }
327
+ const multi = new Set(fields.filter((f) => f.question.multi).map((f) => f.question.id));
328
+ const answers = answersSchema.parse({
329
+ version: GROKBOT_ANSWERS_VERSION,
330
+ ...unflatten(collected.answers, multi),
331
+ });
332
+ return {
333
+ ok: true,
334
+ answers,
335
+ defaulted: collected.defaulted,
336
+ ignored: Object.keys(given).filter((id) => !(id in collected.answers)),
337
+ };
338
+ }
339
+ /** `exclude` narrows `include` (everything when unset or `all`), so only `include` is asked. */
340
+ function foldExcludes(given, bot) {
341
+ for (const kind of KINDS) {
342
+ const exclude = given[`${kind}.exclude`];
343
+ if (exclude === undefined || bot[kind].length === 0) {
344
+ continue;
345
+ }
346
+ const include = given[`${kind}.include`];
347
+ const kept = (include === undefined || include.trim() === "all"
348
+ ? bot[kind].map((item) => item.slug)
349
+ : listAnswer(include)).filter((item) => !listAnswer(exclude).includes(item));
350
+ delete given[`${kind}.exclude`];
351
+ given[`${kind}.include`] = kept.length === 0 ? "none" : kept.join(", ");
352
+ }
353
+ return given;
354
+ }
355
+ function flatten(value, prefix = "", out = {}) {
356
+ if (Array.isArray(value)) {
357
+ out[prefix] = value.length === 0 ? "none" : value.join(", ");
358
+ }
359
+ else if (isRecord(value)) {
360
+ for (const [key, nested] of Object.entries(value)) {
361
+ flatten(nested, prefix === "" ? key : `${prefix}.${key}`, out);
362
+ }
363
+ }
364
+ else if (value !== undefined) {
365
+ out[prefix] = String(value);
366
+ }
367
+ return out;
368
+ }
369
+ function unflatten(answers, multi) {
370
+ const out = {};
371
+ for (const [id, raw] of Object.entries(answers)) {
372
+ const path = id.split(".");
373
+ const leaf = path.pop() ?? id;
374
+ path.reduce(child, out)[leaf] = multi.has(id) ? listAnswer(raw) : raw;
375
+ }
376
+ return out;
377
+ }
378
+ /**
379
+ * JSON Schema for answers files, annotated from the questions so a chat
380
+ * client can render one widget per field: `title`, `description`, a static
381
+ * `default`, `x-labels` for choice labels, and `x-round` for the round.
382
+ */
383
+ export function answersJsonSchema() {
384
+ const json = zodToJsonSchema(answersSchema, {
385
+ $refStrategy: "none",
386
+ target: "jsonSchema7",
387
+ });
388
+ for (const f of FIELDS) {
389
+ annotate(json, f.question.id.split("."), fieldMeta(f));
390
+ }
391
+ for (const kind of KINDS) {
392
+ annotate(json, [kind, "exclude"], {
393
+ title: `Exclude ${kind}`,
394
+ description: `Which ${kind} should stay behind, applied after the include list.`,
395
+ "x-round": "export",
396
+ });
397
+ }
398
+ annotate(json, ["$schema"], { description: "Path or URL of this schema, for editors. Ignored." });
399
+ annotate(json, ["version"], { description: "Answers format version." });
400
+ annotate(json, ["connectors"], {
401
+ description: "How each recipe plugin connects, keyed by plugin slug.",
402
+ });
403
+ annotate(json, ["fillIns"], {
404
+ description: "Values for recipe placeholders, keyed by routine slug, then placeholder id (e.g. slack_channel). Unfilled placeholders stay in the text.",
405
+ });
406
+ return {
407
+ $schema: json.$schema,
408
+ title: `${CLI_COMMAND_NAME} init --from-grokbot answers`,
409
+ description: "Decisions for exporting a Grok Bot recipe. Every field is optional: a missing answer takes the default an interactive run offers. Names only, never secret values.",
410
+ ...json,
411
+ };
412
+ }
413
+ function fieldMeta({ question, round }) {
414
+ const meta = {
415
+ title: question.label,
416
+ description: question.hint === undefined ? question.prompt : `${question.prompt} ${question.hint}`,
417
+ "x-round": round,
418
+ };
419
+ if (typeof question.default === "string" && question.default !== "all") {
420
+ meta.default = question.multi ? listAnswer(question.default) : question.default;
421
+ }
422
+ const labeled = (question.choices ?? []).filter((choice) => typeof choice !== "string");
423
+ if (labeled.length > 0) {
424
+ meta["x-labels"] = Object.fromEntries(labeled.map((choice) => [choice.value, choice.label]));
425
+ }
426
+ return meta;
427
+ }
428
+ function annotate(json, path, meta) {
429
+ let node = json;
430
+ for (const key of path) {
431
+ const parent = isRecord(node) ? node : {};
432
+ node =
433
+ key === "*"
434
+ ? parent.additionalProperties
435
+ : isRecord(parent.properties)
436
+ ? parent.properties[key]
437
+ : undefined;
438
+ }
439
+ if (!isRecord(node)) {
440
+ throw new Error(`The answers JSON Schema has no ${path.join(".")}.`);
441
+ }
442
+ Object.assign(node, meta);
443
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The bot a recipe describes. Slugs are claimed here once, so questions,
3
+ * answers, and output paths all name items the same way. Names become one
4
+ * printable line and prose loses unprintable characters, so recipe text is
5
+ * safe to show in a terminal or a list.
6
+ */
7
+ import type { GrokbotRecipe } from "./recipe.js";
8
+ import { type CronTrigger, type FillIn, type Trigger } from "./routine.js";
9
+ export interface BotSkill {
10
+ slug: string;
11
+ name: string;
12
+ description: string;
13
+ body: string;
14
+ /** The skill's own schedule, when its frontmatter has one. */
15
+ triggers: CronTrigger[];
16
+ }
17
+ export interface BotRoutine {
18
+ slug: string;
19
+ name: string;
20
+ description: string;
21
+ job: string;
22
+ triggers: Trigger[];
23
+ fillIns: FillIn[];
24
+ }
25
+ export interface BotPlugin {
26
+ slug: string;
27
+ name: string;
28
+ }
29
+ export interface BotMemory {
30
+ kind?: string;
31
+ createdAt?: string;
32
+ content: string;
33
+ }
34
+ export interface Bot {
35
+ name: string;
36
+ description: string;
37
+ avatar?: {
38
+ color?: string;
39
+ shape?: string;
40
+ };
41
+ skills: BotSkill[];
42
+ routines: BotRoutine[];
43
+ plugins: BotPlugin[];
44
+ memory: BotMemory[];
45
+ /** Slug of the skill a new user starts with. */
46
+ gettingStarted?: string;
47
+ unknownFields: string[];
48
+ }
49
+ export declare function botFromRecipe(recipe: GrokbotRecipe, unknownFields?: string[]): Bot;
50
+ //# sourceMappingURL=bot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/internal/convert-grokbot/bot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,MAAM,EAGX,KAAK,OAAO,EACb,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAOD,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,aAAa,GAAE,MAAM,EAAO,GAAG,GAAG,CA6CtF"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * The bot a recipe describes. Slugs are claimed here once, so questions,
3
+ * answers, and output paths all name items the same way. Names become one
4
+ * printable line and prose loses unprintable characters, so recipe text is
5
+ * safe to show in a terminal or a list.
6
+ */
7
+ import { parseYamlFrontmatter } from "../frontmatter.js";
8
+ import { isRecord } from "../is-record.js";
9
+ import { SlugRegistry, slugify } from "../slug.js";
10
+ import { plainText, singleLine } from "./checks.js";
11
+ import { parseRoutineContent, routineFillIns, } from "./routine.js";
12
+ /** List answers read these as keywords, so no item slug may take them. */
13
+ const LIST_KEYWORDS = ["all", "none"];
14
+ /** Connection file names a plugin slug may not take. */
15
+ const RESERVED_CONNECTIONS = ["cursor", "account"];
16
+ export function botFromRecipe(recipe, unknownFields = []) {
17
+ const skillSlugs = slugRegistry();
18
+ const skills = recipe.skills.map((skill) => {
19
+ const { data, body } = parseYamlFrontmatter(skill.content);
20
+ const trigger = isRecord(data.trigger) ? data.trigger : {};
21
+ const name = singleLine(skill.name);
22
+ return {
23
+ slug: skillSlugs.claim(slugify(name, "skill")),
24
+ name,
25
+ description: plainText(skill.description),
26
+ body: body.trim(),
27
+ triggers: typeof trigger.schedule === "string"
28
+ ? [{ kind: "cron", cron: trigger.schedule, paused: trigger.enabled === false }]
29
+ : [],
30
+ };
31
+ });
32
+ const routineSlugs = slugRegistry();
33
+ const routines = recipe.routines.map((routine) => {
34
+ const parsed = parseRoutineContent(routine.content);
35
+ return {
36
+ slug: routineSlugs.claim(slugify(routine.slug, "routine")),
37
+ name: singleLine(routine.name),
38
+ description: plainText(routine.description),
39
+ job: parsed.job,
40
+ triggers: parsed.triggers,
41
+ fillIns: routineFillIns([parsed.job, routine.description], parsed.askFor),
42
+ };
43
+ });
44
+ const start = recipe.gettingStarted === undefined ? undefined : singleLine(recipe.gettingStarted.skill);
45
+ return {
46
+ name: singleLine(recipe.profile.name),
47
+ description: plainText(recipe.profile.description),
48
+ avatar: recipe.profile.avatarColor === undefined && recipe.profile.avatarShape === undefined
49
+ ? undefined
50
+ : { color: recipe.profile.avatarColor, shape: recipe.profile.avatarShape },
51
+ skills,
52
+ routines,
53
+ plugins: pluginsFrom(recipe.plugins),
54
+ memory: recipe.memory,
55
+ gettingStarted: skills.find((skill) => skill.name === start)?.slug,
56
+ unknownFields,
57
+ };
58
+ }
59
+ function slugRegistry(reserved = []) {
60
+ const slugs = new SlugRegistry();
61
+ for (const slug of [...LIST_KEYWORDS, ...reserved]) {
62
+ slugs.claim(slug);
63
+ }
64
+ return slugs;
65
+ }
66
+ function pluginsFrom(plugins) {
67
+ const slugs = slugRegistry(RESERVED_CONNECTIONS);
68
+ return plugins.map((plugin) => {
69
+ const name = singleLine(plugin.name);
70
+ return { slug: slugs.claim(slugify(name, "connector")), name };
71
+ });
72
+ }
@@ -0,0 +1,26 @@
1
+ /** Validation for export answers that land in names, URLs, and review text. */
2
+ export declare const SLACK_BOT_NAME_MAX = 80;
3
+ /** Recipe text for a name or list item: one line, nothing unprintable. */
4
+ export declare function singleLine(text: string): string;
5
+ /** Recipe prose: line breaks and tabs kept, anything else unprintable dropped. */
6
+ export declare function plainText(text: string): string;
7
+ /** Text as a markdown code span, so it reads as data; a backtick would end the span. */
8
+ export declare function code(text: string): string;
9
+ /**
10
+ * A Slack bot name starts with the team prefix and never reads as "Grok",
11
+ * including through separators, accents, or look-alike letters.
12
+ */
13
+ export declare function slackBotNameError(name: string, teamPrefix?: string): string | undefined;
14
+ /** The recipe name under the team prefix, or `Bot` when that name cannot pass. */
15
+ export declare function defaultSlackBotName(name: string, teamPrefix?: string): string;
16
+ /** Remote MCP URL: https, with credentials kept out of it. */
17
+ export declare function connectorUrlError(url: string): string | undefined;
18
+ export declare function repoNameError(name: string): string | undefined;
19
+ export declare function namespaceError(name: string): string | undefined;
20
+ export declare function redactSecretValues(text: string): {
21
+ text: string;
22
+ redacted: number;
23
+ };
24
+ /** Every string in a JSON-shaped value, redacted. */
25
+ export declare function redactDeep<T>(value: T): T;
26
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../src/internal/convert-grokbot/checks.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAI/E,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAMrC,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED,wFAAwF;AACxF,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC;AAmCD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAmBvF;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAS7E;AA6BD,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoBjE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI9D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI/D;AAeD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAOnF;AAED,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAazC"}