@openhands/agent-canvas 1.18.0 → 1.19.0

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 (331) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/acp-providers-BQ4o4vqy.js +1 -0
  4. package/build/assets/{active-backend-context-BnH4-L8h.js → active-backend-context-BsLfwrXB.js} +1 -1
  5. package/build/assets/{agent-context-settings-D3peZkjX.js → agent-context-settings-D9i6ezoJ.js} +1 -1
  6. package/build/assets/{agent-profiles-service.api-DkeZaqIl.js → agent-profiles-service.api-U-9YzDFU.js} +1 -1
  7. package/build/assets/{agent-profiles-settings-7yMWYjGF.js → agent-profiles-settings-D-bUV2PX.js} +1 -1
  8. package/build/assets/agent-server-conversation-service.api-BaVQ6NpE.js +88 -0
  9. package/build/assets/agent-settings-BZJHtaIK.js +2 -0
  10. package/build/assets/agent-settings-D4snDd6u.js +1 -0
  11. package/build/assets/{alert-banner-eYyqvHL3.js → alert-banner-BkVt_8Or.js} +1 -1
  12. package/build/assets/{api-key-entry-screen-CCBvBD8u.js → api-key-entry-screen-fAIld-n7.js} +1 -1
  13. package/build/assets/{app-settings-BtYDs-Be.js → app-settings-DITbrM2u.js} +1 -1
  14. package/build/assets/automation-detail-DawHmaOl.js +3 -0
  15. package/build/assets/automation-disabled-reason-DtgC8Ppt.js +1 -0
  16. package/build/assets/{automation-export-BJsfi7n2.js → automation-export-Kv6e0bHx.js} +1 -1
  17. package/build/assets/{automation-git-sync-B7o_Nbl-.js → automation-git-sync-Dd98G_Oz.js} +1 -1
  18. package/build/assets/{automation-setup-route-qaJ6lLCf.js → automation-setup-route-Cdc109ZD.js} +1 -1
  19. package/build/assets/{automation-templates-Bb98r-kx.js → automation-templates-Xhr-FDAB.js} +1 -1
  20. package/build/assets/automations-list-BeP1LuzQ.js +1 -0
  21. package/build/assets/{back-nav-button-B2yBiVMB.js → back-nav-button-DWNiN277.js} +1 -1
  22. package/build/assets/backend-form-modal-DeaUJIik.js +1 -0
  23. package/build/assets/{backend-synced-settings-badge-DLEp6cq7.js → backend-synced-settings-badge-Br85iWIY.js} +1 -1
  24. package/build/assets/{badge-ehL-kgeO.js → badge-Cdnei7Ly.js} +1 -1
  25. package/build/assets/{base-modal-C1a0TsSx.js → base-modal-Ds7grR67.js} +1 -1
  26. package/build/assets/{brand-button-CUMfjb99.js → brand-button-mQq2Ld1I.js} +1 -1
  27. package/build/assets/{browser-SE24Tk8g.js → browser-Bfum8fkE.js} +2 -2
  28. package/build/assets/{browser-tab-HjJxHA0V.js → browser-tab-CmYT4j_r.js} +1 -1
  29. package/build/assets/{canvas-extension-page-BsUGBb1T.js → canvas-extension-page-CokKSVRG.js} +1 -1
  30. package/build/assets/{canvas-extensions-C9Tm6s_E.js → canvas-extensions-BoQEYG-2.js} +1 -1
  31. package/build/assets/{canvas-extensions-runtime-B8kxM4rO.js → canvas-extensions-runtime-Du2M5iEX.js} +1 -1
  32. package/build/assets/{chat-send-button-CGvc2wpE.js → chat-send-button-DM3JgMc2.js} +1 -1
  33. package/build/assets/{circle-plus-check-toggle-BDX_ctNs.js → circle-plus-check-toggle-BbYBiUwv.js} +1 -1
  34. package/build/assets/{cloud-funnel-analytics-D5uJ_4JE.js → cloud-funnel-analytics-D02kgq1s.js} +1 -1
  35. package/build/assets/{cog-CAEugqtV.js → cog-Dy1eWbSZ.js} +1 -1
  36. package/build/assets/{command-menu-CQxs4mtX.js → command-menu-mehU3Evb.js} +1 -1
  37. package/build/assets/{commits-tab-D0xgjipP.js → commits-tab-DhQW8CXi.js} +1 -1
  38. package/build/assets/{condenser-settings-D63NJRBT.js → condenser-settings-eRk6Fkx6.js} +1 -1
  39. package/build/assets/{confirmation-modal-78sd9Vny.js → confirmation-modal-BmVt_c0I.js} +1 -1
  40. package/build/assets/{context-menu-list-item-Cm7-7Y-7.js → context-menu-list-item-lx2zk9G7.js} +1 -1
  41. package/build/assets/{conversation-B_nweu5p.js → conversation-BOj0ENI6.js} +4 -4
  42. package/build/assets/conversation-SouWlGvs.js +1 -0
  43. package/build/assets/conversation-panel-SouWlGvs.js +1 -0
  44. package/build/assets/{conversation-state-store-9D_3P7q4.js → conversation-state-store-C6YncQNo.js} +1 -1
  45. package/build/assets/{conversation-tab-empty-state-B3dpJXX0.js → conversation-tab-empty-state-DIhwCC2J.js} +1 -1
  46. package/build/assets/{copy-to-clipboard-button-B1ljgNxO.js → copy-to-clipboard-button-DVNXLylP.js} +1 -1
  47. package/build/assets/{device-verify-D5QRIS_x.js → device-verify-LP-x7nra.js} +1 -1
  48. package/build/assets/{dropdown-classes-BGvOvW2_.js → dropdown-classes-goDldkiu.js} +1 -1
  49. package/build/assets/edit-automation-modal-BJJR9wSW.js +1 -0
  50. package/build/assets/empty-state-Cd-TFe7i.js +1 -0
  51. package/build/assets/{entry.client-BMafTpjO.js → entry.client-CJdjIvMZ.js} +2 -2
  52. package/build/assets/{enum-filter-dropdown-UNaom12H.js → enum-filter-dropdown-pocrz9AL.js} +1 -1
  53. package/build/assets/{environment-switch-overlay-COibRUA-.js → environment-switch-overlay-Dwe78wRl.js} +1 -1
  54. package/build/assets/{error-state-Cf8LRuuY.js → error-state-SuWwztxV.js} +1 -1
  55. package/build/assets/{extensions-hub-C_6ahIua.js → extensions-hub-O0esK3Er.js} +1 -1
  56. package/build/assets/{extensions-navigation-C5GfpzFe.js → extensions-navigation-CgCVSXje.js} +1 -1
  57. package/build/assets/{files-tab-D5PPIWI1.js → files-tab-B_6t8ljw.js} +1 -1
  58. package/build/assets/{form-control-classes-Dbq-7YP_.js → form-control-classes-lQfLxzH4.js} +1 -1
  59. package/build/assets/{get-git-path-jU2zjqIB.js → get-git-path-Bp5rsUkl.js} +1 -1
  60. package/build/assets/git-repo-dropdown-CbD0_LPN.js +1 -0
  61. package/build/assets/{git-repo-dropdown-uxlFw2gn.js → git-repo-dropdown-DPQVumZg.js} +1 -1
  62. package/build/assets/{highlighted-source-view-C7pAXrT0.js → highlighted-source-view-Bp0sgK-f.js} +1 -1
  63. package/build/assets/home-BghzJd-D.js +1 -0
  64. package/build/assets/home-CXZ8zawS.js +1 -0
  65. package/build/assets/home-automation-run-tooltip-BdpCckKO.js +1 -0
  66. package/build/assets/{home-store-DCbei3DX.js → home-store-DNQpfIEO.js} +1 -1
  67. package/build/assets/{hooks-service-Dnmhqc0Z.js → hooks-service-DkxnQa4N.js} +1 -1
  68. package/build/assets/index-home-Ca6Q5CtT.js +1 -0
  69. package/build/assets/{install-server-modal-B81I-5OE.js → install-server-modal-DvxxYKia.js} +1 -1
  70. package/build/assets/{key-O84CMFHb.js → key-CwTE6XJj.js} +1 -1
  71. package/build/assets/{launch-ZLxI4opd.js → launch-jsRGPRBx.js} +1 -1
  72. package/build/assets/link-external-B4gx3EeM.js +1 -0
  73. package/build/assets/{llm-not-configured-banner-Dh_ajcM8.js → llm-not-configured-banner-DMdL1vaX.js} +4 -4
  74. package/build/assets/{llm-settings-CODhjQzy.js → llm-settings-dkQ5Oq7W.js} +1 -1
  75. package/build/assets/llm-settings-lNDerSlu.js +1 -0
  76. package/build/assets/{llm-subscription-service-CgIDc38n.js → llm-subscription-service-BiQaZbvv.js} +1 -1
  77. package/build/assets/{loading-spinner-BeLV0IXf.js → loading-spinner-DK1sAwVg.js} +1 -1
  78. package/build/assets/{manage-backends-modal-cMXqCb-B.js → manage-backends-modal-DqCJohsX.js} +1 -1
  79. package/build/assets/manifest-ff93dc8c.js +1 -0
  80. package/build/assets/{manifest-subpage-layout-CVZgVKoY.js → manifest-subpage-layout-sxuPqfUr.js} +1 -1
  81. package/build/assets/{markdown-renderer-DyFl9-mL.js → markdown-renderer-BH5pqDuJ.js} +1 -1
  82. package/build/assets/mcp-BtaJDXnP.js +1 -0
  83. package/build/assets/mcp-installed-servers-Br4ZLsjr.js +1 -0
  84. package/build/assets/mcp-marketplace-utils-BwEnDYqm.js +1 -0
  85. package/build/assets/mcp-page-DwbnQpVs.js +9 -0
  86. package/build/assets/{messages-Bk1xhbU2.js → messages-DmFJlW6c.js} +4 -4
  87. package/build/assets/{modal-body-C24WsdFb.js → modal-body-DBweM2EN.js} +1 -1
  88. package/build/assets/{modal-classes-B0b9eiL8.js → modal-classes-jvG85nkU.js} +1 -1
  89. package/build/assets/{modal-close-button-DfqfB2Nj.js → modal-close-button-BrM5fNnn.js} +1 -1
  90. package/build/assets/onboarding-CQ8T6T0U.js +1 -0
  91. package/build/assets/{onboarding-modal-BT3Gx_sZ.js → onboarding-modal-CnliiaSN.js} +1 -1
  92. package/build/assets/{organization-service.api-B5CvmnYQ.js → organization-service.api-DmFUEmu5.js} +1 -1
  93. package/build/assets/parse-git-remote-url-BG8pcKL8.js +1 -0
  94. package/build/assets/{planner-tab-CstoOlAB.js → planner-tab-CXph_C9F.js} +1 -1
  95. package/build/assets/{plugins-management-service-5rqVPEGN.js → plugins-management-service-CcEpfNKz.js} +1 -1
  96. package/build/assets/{profiles-service.api-D1XKMgr0.js → profiles-service.api-DdF_4Zhe.js} +1 -1
  97. package/build/assets/{providers-XmZ9HM4Q.js → providers-BWRnl31s.js} +1 -1
  98. package/build/assets/{proxy-XP6U1Dhv.js → proxy-DbEf3Nqr.js} +1 -1
  99. package/build/assets/recommended-automations-launcher-r0oI91HN.js +1 -0
  100. package/build/assets/root-j2fFRlWS.js +2 -0
  101. package/build/assets/{root-layout-DUquNZTU.js → root-layout-CfGgm2lo.js} +2 -2
  102. package/build/assets/root-sEWn3ha1.css +1 -0
  103. package/build/assets/{schema-field-Y3F8JvXd.js → schema-field-c3Ncgm4x.js} +1 -1
  104. package/build/assets/{sdk-section-page-CNZTLwH9.js → sdk-section-page-DFEiuiFQ.js} +1 -1
  105. package/build/assets/{secret-form-9-BoGA40.js → secret-form-WXXNFqTM.js} +1 -1
  106. package/build/assets/{secrets-service-BOIsfD9j.js → secrets-service-DU6wh3wX.js} +1 -1
  107. package/build/assets/{secrets-settings-CBJgFr42.js → secrets-settings-BEqbPvjy.js} +1 -1
  108. package/build/assets/{settings-D4hdToD4.js → settings-DjaSQwFh.js} +1 -1
  109. package/build/assets/{settings-dropdown-input-DBvsZ7-Q.js → settings-dropdown-input-BRR2OZwi.js} +1 -1
  110. package/build/assets/{settings-index-DeQphyBK.js → settings-index-DHv4XFcM.js} +1 -1
  111. package/build/assets/{settings-input-dVuzapBA.js → settings-input-Cm4VxUon.js} +1 -1
  112. package/build/assets/{settings-list-classes-DhAPuXm6.js → settings-list-classes-CaUfKZ33.js} +1 -1
  113. package/build/assets/{settings-modal-tHiJ8iYV.js → settings-modal-djXuAnBO.js} +1 -1
  114. package/build/assets/{settings-nav-GAQjW1a-.js → settings-nav-DFb3hBMr.js} +1 -1
  115. package/build/assets/{settings-service.api-C1vZH9Vh.js → settings-service.api-Q9lKW1TX.js} +1 -1
  116. package/build/assets/{settings-switch-DDd1cQ8t.js → settings-switch-seaSJc7t.js} +1 -1
  117. package/build/assets/{shared-conversation-Cyg7m7ns.js → shared-conversation-x3rxVCon.js} +1 -1
  118. package/build/assets/{sidebar-layout-DH0E-5KW.js → sidebar-layout-B6mcvvdV.js} +1 -1
  119. package/build/assets/{sidebar-mobile-menu-toggle-CQ4iky__.js → sidebar-mobile-menu-toggle-CEqS8KnA.js} +1 -1
  120. package/build/assets/{sidebar-nav-link-oLQiKUBu.js → sidebar-nav-link-BTHX11LG.js} +1 -1
  121. package/build/assets/{sidebar-onboarding-checklist-storage-TfvNNnnr.js → sidebar-onboarding-checklist-storage-BP1kzn6p.js} +1 -1
  122. package/build/assets/{skill-card-pill-row-DfjIfj0K.js → skill-card-pill-row-TD39nfP3.js} +1 -1
  123. package/build/assets/{skill-filter-DsNLmn76.js → skill-filter-CdBbbwjm.js} +1 -1
  124. package/build/assets/{skill-icon-badge-0MK_68Nc.js → skill-icon-badge-vUEp7gsC.js} +1 -1
  125. package/build/assets/{skill-scope-BE-H9TSZ.js → skill-scope-BTRBQt0-.js} +1 -1
  126. package/build/assets/{skills-plugins-vzSdxSk_.js → skills-plugins-k1tUNAw4.js} +1 -1
  127. package/build/assets/{skills-settings-BiPOH9H9.js → skills-settings-CENviPT7.js} +1 -1
  128. package/build/assets/{styled-tooltip-CejG0rqv.js → styled-tooltip-DVAlWYnL.js} +1 -1
  129. package/build/assets/{task-list-tab-OkZSqnTp.js → task-list-tab-BLKF_x9f.js} +1 -1
  130. package/build/assets/{terminal-Dph60VFZ.js → terminal-Ckbnqb23.js} +1 -1
  131. package/build/assets/{toggle-switch-B2uXaAUS.js → toggle-switch-DeiG9Mf6.js} +1 -1
  132. package/build/assets/trash-CXN2R54L.js +1 -0
  133. package/build/assets/{typography-DgcLGdHk.js → typography-NarNyelM.js} +1 -1
  134. package/build/assets/{usage-tab-MCmNRAnR.js → usage-tab-Drd3O006.js} +1 -1
  135. package/build/assets/{use-acp-credential-form-ychoGqjC.js → use-acp-credential-form-CJ5wPsQm.js} +1 -1
  136. package/build/assets/{use-activate-agent-profile-8L8Xdghy.js → use-activate-agent-profile-iQZ0U3qV.js} +1 -1
  137. package/build/assets/{use-agent-profiles-Bi8hSkze.js → use-agent-profiles-LCvb5OXT.js} +1 -1
  138. package/build/assets/{use-automation-health-U99vvHxx.js → use-automation-health-DdgSa8sA.js} +1 -1
  139. package/build/assets/{use-automation-permissions-Buus0R6h.js → use-automation-permissions-D3kEeieu.js} +1 -1
  140. package/build/assets/{use-automations-Bq5hVuv0.js → use-automations-CEubcYTD.js} +1 -1
  141. package/build/assets/{use-can-manage-org-profiles-MzIeEV8F.js → use-can-manage-org-profiles-CB8ybxFK.js} +1 -1
  142. package/build/assets/{use-canvas-extensions-Ca9KoVEm.js → use-canvas-extensions-BMacwi2v.js} +1 -1
  143. package/build/assets/{use-cloud-current-user-id-B4ZLUZSa.js → use-cloud-current-user-id-BEKRd6XZ.js} +1 -1
  144. package/build/assets/{use-config-l5tkDHyD.js → use-config-3WYcJsgC.js} +1 -1
  145. package/build/assets/{use-create-conversation-i_PdFdIs.js → use-create-conversation-Be-eVpFp.js} +1 -1
  146. package/build/assets/use-create-secret-Bk9ZxTjl.js +1 -0
  147. package/build/assets/{use-free-models-gCsJ5BV0.js → use-free-models-Ci3FkKEm.js} +1 -1
  148. package/build/assets/{use-get-secrets-CMTuWEp_.js → use-get-secrets-fqS0kxt6.js} +1 -1
  149. package/build/assets/{use-llm-configured-Dl4zg8ht.js → use-llm-configured-B71ZEVg2.js} +1 -1
  150. package/build/assets/{use-llm-profiles-SWsuFmFu.js → use-llm-profiles-xtCBMbef.js} +1 -1
  151. package/build/assets/{use-manifest-capabilities-CdqYfUAC.js → use-manifest-capabilities-Bso6A_-A.js} +1 -1
  152. package/build/assets/{use-onboarding-completion-Xl63ZvzQ.js → use-onboarding-completion-CEgjL02y.js} +1 -1
  153. package/build/assets/{use-pinned-home-route-BXDIUaxQ.js → use-pinned-home-route-pK4IlJ-p.js} +1 -1
  154. package/build/assets/{use-plugins-marketplace-BIIaPiaB.js → use-plugins-marketplace-B8-ZEB34.js} +1 -1
  155. package/build/assets/{use-save-agent-profile-D-ZHHE94.js → use-save-agent-profile-D7hJuW_u.js} +1 -1
  156. package/build/assets/{use-save-settings-Dapkf4cC.js → use-save-settings-CikTu5xV.js} +1 -1
  157. package/build/assets/{use-settings-C2KKQKVC.js → use-settings-BWIH5EuN.js} +1 -1
  158. package/build/assets/{use-settings-nav-items-TOc0Rsfd.js → use-settings-nav-items-DSKwLDnd.js} +1 -1
  159. package/build/assets/use-tracking-ChnSFChv.js +3 -0
  160. package/build/assets/{use-user-conversation-5UFqMoO4.js → use-user-conversation-C_l65DqW.js} +1 -1
  161. package/build/assets/utils-D-gOfhmN.js +1 -0
  162. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0x1wrp2-D6owle9R.js +2 -0
  163. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~inibp4qe-BFRW8wt-.js +48 -0
  164. package/build/assets/{verification-settings-DdBpaVPz.js → verification-settings-PKtoIUUY.js} +1 -1
  165. package/build/index.html +4 -4
  166. package/build/locales/ar/openhands.json +10 -0
  167. package/build/locales/ca/openhands.json +10 -0
  168. package/build/locales/de/openhands.json +10 -0
  169. package/build/locales/en/openhands.json +10 -0
  170. package/build/locales/es/openhands.json +10 -0
  171. package/build/locales/fr/openhands.json +10 -0
  172. package/build/locales/it/openhands.json +10 -0
  173. package/build/locales/ja/openhands.json +10 -0
  174. package/build/locales/ko-KR/openhands.json +10 -0
  175. package/build/locales/no/openhands.json +10 -0
  176. package/build/locales/pt/openhands.json +10 -0
  177. package/build/locales/tr/openhands.json +10 -0
  178. package/build/locales/uk/openhands.json +10 -0
  179. package/build/locales/zh-CN/openhands.json +10 -0
  180. package/build/locales/zh-TW/openhands.json +10 -0
  181. package/config/defaults.json +3 -3
  182. package/dist/components/conversation-events/chat/event-content-helpers/get-skill-ready-content.cjs +3 -3
  183. package/dist/components/conversation-events/chat/event-content-helpers/get-skill-ready-content.cjs.map +1 -1
  184. package/dist/components/conversation-events/chat/event-content-helpers/get-skill-ready-content.js +12 -16
  185. package/dist/components/conversation-events/chat/event-content-helpers/get-skill-ready-content.js.map +1 -1
  186. package/dist/components/features/automations/detail/disabled-reason-banner.d.ts +16 -0
  187. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs +1 -1
  188. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs.map +1 -1
  189. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js +38 -29
  190. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js.map +1 -1
  191. package/dist/components/features/settings/agent-profiles/profile-scope-list.d.ts +20 -0
  192. package/dist/config/defaults.cjs +1 -1
  193. package/dist/config/defaults.cjs.map +1 -1
  194. package/dist/config/defaults.js +3 -3
  195. package/dist/config/defaults.js.map +1 -1
  196. package/dist/constants/acp-providers.cjs +1 -1
  197. package/dist/constants/acp-providers.cjs.map +1 -1
  198. package/dist/constants/acp-providers.d.ts +0 -5
  199. package/dist/constants/acp-providers.js +20 -16
  200. package/dist/constants/acp-providers.js.map +1 -1
  201. package/dist/constants/profile-scope.d.ts +21 -0
  202. package/dist/hooks/query/use-automation-sdk-version.cjs +1 -1
  203. package/dist/hooks/query/use-automation-sdk-version.cjs.map +1 -1
  204. package/dist/hooks/query/use-automation-sdk-version.js +3 -1
  205. package/dist/hooks/query/use-automation-sdk-version.js.map +1 -1
  206. package/dist/hooks/use-drag-resize.cjs +1 -1
  207. package/dist/hooks/use-drag-resize.cjs.map +1 -1
  208. package/dist/hooks/use-drag-resize.js +8 -9
  209. package/dist/hooks/use-drag-resize.js.map +1 -1
  210. package/dist/i18n/declaration.cjs +1 -1
  211. package/dist/i18n/declaration.cjs.map +1 -1
  212. package/dist/i18n/declaration.d.ts +10 -0
  213. package/dist/i18n/declaration.js +1 -1
  214. package/dist/i18n/declaration.js.map +1 -1
  215. package/dist/i18n/translation.cjs +2 -2
  216. package/dist/i18n/translation.cjs.map +1 -1
  217. package/dist/i18n/translation.js +170 -0
  218. package/dist/i18n/translation.js.map +1 -1
  219. package/dist/locales/ar/openhands.json +10 -0
  220. package/dist/locales/ca/openhands.json +10 -0
  221. package/dist/locales/de/openhands.json +10 -0
  222. package/dist/locales/en/openhands.json +10 -0
  223. package/dist/locales/es/openhands.json +10 -0
  224. package/dist/locales/fr/openhands.json +10 -0
  225. package/dist/locales/it/openhands.json +10 -0
  226. package/dist/locales/ja/openhands.json +10 -0
  227. package/dist/locales/ko-KR/openhands.json +10 -0
  228. package/dist/locales/no/openhands.json +10 -0
  229. package/dist/locales/pt/openhands.json +10 -0
  230. package/dist/locales/tr/openhands.json +10 -0
  231. package/dist/locales/uk/openhands.json +10 -0
  232. package/dist/locales/zh-CN/openhands.json +10 -0
  233. package/dist/locales/zh-TW/openhands.json +10 -0
  234. package/dist/manifests/manifest-validation.cjs +1 -1
  235. package/dist/manifests/manifest-validation.cjs.map +1 -1
  236. package/dist/manifests/manifest-validation.js +2 -2
  237. package/dist/manifests/manifest-validation.js.map +1 -1
  238. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.cjs +1 -1
  239. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.cjs.map +1 -1
  240. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js +15 -8
  241. package/dist/node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js.map +1 -1
  242. package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.cjs +1 -1
  243. package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.cjs.map +1 -1
  244. package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.js +11 -13
  245. package/dist/node_modules/@openhands/typescript-client/dist/client/bash-client.js.map +1 -1
  246. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs +1 -1
  247. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.cjs.map +1 -1
  248. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js +6 -0
  249. package/dist/node_modules/@openhands/typescript-client/dist/client/conversation-client.js.map +1 -1
  250. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs +1 -1
  251. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs.map +1 -1
  252. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js +3 -6
  253. package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js.map +1 -1
  254. package/dist/node_modules/@openhands/typescript-client/dist/client/file-client.cjs +1 -1
  255. package/dist/node_modules/@openhands/typescript-client/dist/client/file-client.cjs.map +1 -1
  256. package/dist/node_modules/@openhands/typescript-client/dist/client/file-client.js +9 -12
  257. package/dist/node_modules/@openhands/typescript-client/dist/client/file-client.js.map +1 -1
  258. package/dist/node_modules/@openhands/typescript-client/dist/client/runtime-transport.cjs +2 -0
  259. package/dist/node_modules/@openhands/typescript-client/dist/client/runtime-transport.cjs.map +1 -0
  260. package/dist/node_modules/@openhands/typescript-client/dist/client/runtime-transport.js +41 -0
  261. package/dist/node_modules/@openhands/typescript-client/dist/client/runtime-transport.js.map +1 -0
  262. package/dist/node_modules/@openhands/typescript-client/dist/client/vscode-client.cjs +1 -1
  263. package/dist/node_modules/@openhands/typescript-client/dist/client/vscode-client.cjs.map +1 -1
  264. package/dist/node_modules/@openhands/typescript-client/dist/client/vscode-client.js +3 -6
  265. package/dist/node_modules/@openhands/typescript-client/dist/client/vscode-client.js.map +1 -1
  266. package/dist/node_modules/@openhands/typescript-client/dist/clients.cjs +1 -1
  267. package/dist/node_modules/@openhands/typescript-client/dist/clients.js +1 -1
  268. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs +1 -1
  269. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs.map +1 -1
  270. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js +199 -61
  271. package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js.map +1 -1
  272. package/dist/node_modules/@openhands/typescript-client/dist/workspace/remote-workspace.cjs +1 -1
  273. package/dist/node_modules/@openhands/typescript-client/dist/workspace/remote-workspace.cjs.map +1 -1
  274. package/dist/node_modules/@openhands/typescript-client/dist/workspace/remote-workspace.js +9 -8
  275. package/dist/node_modules/@openhands/typescript-client/dist/workspace/remote-workspace.js.map +1 -1
  276. package/dist/package.cjs +1 -1
  277. package/dist/package.cjs.map +1 -1
  278. package/dist/package.js +2 -2
  279. package/dist/package.js.map +1 -1
  280. package/dist/routes/agent-settings.d.ts +5 -0
  281. package/dist/types/automation.cjs.map +1 -1
  282. package/dist/types/automation.d.ts +23 -1
  283. package/dist/types/automation.js.map +1 -1
  284. package/dist/utils/automation-disabled-reason.cjs +2 -0
  285. package/dist/utils/automation-disabled-reason.cjs.map +1 -0
  286. package/dist/utils/automation-disabled-reason.d.ts +32 -0
  287. package/dist/utils/automation-disabled-reason.js +19 -0
  288. package/dist/utils/automation-disabled-reason.js.map +1 -0
  289. package/dist/utils/parse-git-remote-url.cjs +1 -1
  290. package/dist/utils/parse-git-remote-url.cjs.map +1 -1
  291. package/dist/utils/parse-git-remote-url.d.ts +5 -1
  292. package/dist/utils/parse-git-remote-url.js +20 -13
  293. package/dist/utils/parse-git-remote-url.js.map +1 -1
  294. package/package.json +2 -2
  295. package/scripts/check-sdk-version-sync.mjs +79 -8
  296. package/scripts/dev-safe.mjs +1 -1
  297. package/scripts/static-server.mjs +24 -7
  298. package/build/assets/acp-providers-DcY_mKYa.js +0 -1
  299. package/build/assets/agent-server-conversation-service.api-jiCopc2E.js +0 -88
  300. package/build/assets/agent-settings-BF8hM6wb.js +0 -2
  301. package/build/assets/agent-settings-YPutBAeR.js +0 -1
  302. package/build/assets/automation-detail-BxXhb_m2.js +0 -3
  303. package/build/assets/automations-list-DEPVNud3.js +0 -1
  304. package/build/assets/backend-form-modal-DxisQV_6.js +0 -1
  305. package/build/assets/conversation-edjzrv5w.js +0 -1
  306. package/build/assets/conversation-panel-edjzrv5w.js +0 -1
  307. package/build/assets/edit-automation-modal-D_JWSmxT.js +0 -1
  308. package/build/assets/empty-state-FK_s1B60.js +0 -1
  309. package/build/assets/git-repo-dropdown-BoDDWXfX.js +0 -1
  310. package/build/assets/home-BM5_Wz_R.js +0 -1
  311. package/build/assets/home-Ivfm7KC4.js +0 -1
  312. package/build/assets/home-automation-run-tooltip-B1N2uO9p.js +0 -1
  313. package/build/assets/index-home-td9BN2T3.js +0 -1
  314. package/build/assets/kebab-menu-item-content-SCJBwZnp.js +0 -1
  315. package/build/assets/link-external-BNZzCM1I.js +0 -1
  316. package/build/assets/llm-settings-CZaXYgtw.js +0 -1
  317. package/build/assets/manifest-bfeccb98.js +0 -1
  318. package/build/assets/mcp-CraxoXQv.js +0 -1
  319. package/build/assets/mcp-marketplace-utils-C7PYr293.js +0 -1
  320. package/build/assets/mcp-page-CteH_K0N.js +0 -9
  321. package/build/assets/onboarding-DXFBRqEy.js +0 -1
  322. package/build/assets/parse-git-remote-url-DpDM9bK6.js +0 -1
  323. package/build/assets/recommended-automations-launcher-DEHRKIAg.js +0 -1
  324. package/build/assets/root-CM6IZHlg.css +0 -1
  325. package/build/assets/root-DdFkodKW.js +0 -2
  326. package/build/assets/trash-Ckh7yCaB.js +0 -1
  327. package/build/assets/use-create-secret-CjWq0J4O.js +0 -1
  328. package/build/assets/use-tracking-j4uo9VEW.js +0 -3
  329. package/build/assets/utils-BgLSZdyy.js +0 -1
  330. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0x1wrp2-Z0lly3FE.js +0 -2
  331. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~inibp4qe-CnsDDzeE.js +0 -48
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-validation.cjs","names":[],"sources":["../../src/manifests/manifest-validation.ts"],"sourcesContent":["/**\n * Admission policy for extension-authored catalog manifests.\n *\n * A manifest is data authored in a different repository that instructs this host\n * to render copy and compose a request. The host therefore decides what a\n * manifest is *permitted* to do rather than trusting the file — validation here\n * is a trust boundary, not a convenience check, and it deliberately does not\n * defer to a schema shipped alongside the manifests it would be validating.\n *\n * Beyond mirroring the published schema, this adds the invariants the host's own\n * derivation depends on: a single trigger kind to read, a repository field for\n * an event trigger's source, and field names unique across the form. Without\n * them the derived request body would be silently wrong rather than rejected.\n *\n * A manifest that fails any check is rejected outright. It never renders a\n * partial UI, because everything downstream treats its content as instructions.\n */\n\nimport {\n BUNDLE_CONFIG_FILENAME,\n SETUP_PLACEHOLDER_NAMESPACES,\n SETUP_VERSION,\n} from \"./types\";\n\nconst ENTRY_ID_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;\nconst FIELD_NAME_PATTERN = /^[a-z][A-Za-z0-9]*$/;\n/** Copy must never be able to inject markup into the host. */\nconst MARKUP_PATTERN = /<[A-Za-z/!]/;\n/**\n * A template version, declared as `version` by a prompt entry and as\n * `setup.bundle.version` by a bundle one. Sent to the service as template\n * provenance, so it is checked at admission. Full semver, as the spec at\n * semver.org states it: a catalog entry published with a pre-release or build\n * suffix is still a version this host may forward, and refusing one would drop\n * the entry from the registry outright.\n */\nconst TEMPLATE_VERSION_PATTERN =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\\+[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*)?$/;\n// The characters a command of plain words and paths is made of. No shell\n// metacharacters, which the service rejects anyway and a bundle has no reason\n// to need; where those words may point is `isPlainCommand`'s to say.\nconst BUNDLE_COMMAND_PATTERN = /^[A-Za-z0-9 ._/-]+$/;\nconst BUNDLE_PATH_PATTERN = /^[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*$/;\nconst BUNDLE_SOURCE_PATTERN =\n /^(skills|automations)\\/[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*$/;\n/** Every `{{` must open a known namespace and close immediately. */\nconst UNKNOWN_PLACEHOLDER_PATTERN = new RegExp(\n `\\\\{\\\\{(?!(?:${SETUP_PLACEHOLDER_NAMESPACES.join(\"|\")})\\\\.[A-Za-z0-9_.]+\\\\}\\\\})`,\n);\n\nconst SETUP_MODES = [\"direct\", \"assisted\"] as const;\nconst FIELD_TYPES = [\n \"text\",\n \"textarea\",\n \"select\",\n \"number\",\n \"cron\",\n \"timezone\",\n \"repo-picker\",\n \"llm-profile\",\n \"event-source\",\n \"event-type\",\n \"plugin-sources\",\n \"tarball-upload\",\n] as const;\nconst GIT_PROVIDERS = [\"github\", \"gitlab\", \"bitbucket\"] as const;\nconst TRIGGER_KINDS = [\"cron\", \"event\"] as const;\nconst CONSTRAINT_FORMATS = [\"safeExpressionLiteral\"] as const;\n\n/** Setup context only, so this can never become a channel for runtime instructions. */\nconst MAX_MESSAGE_LENGTH = 2000;\n\nexport interface SetupValidationResult {\n valid: boolean;\n errors: string[];\n}\n\ntype Rec = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Rec {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOneOf<T extends readonly string[]>(\n value: unknown,\n allowed: T,\n): value is T[number] {\n return (\n typeof value === \"string\" && (allowed as readonly string[]).includes(value)\n );\n}\n\nfunction isInteger(value: unknown, minimum: number): boolean {\n return (\n typeof value === \"number\" && Number.isInteger(value) && value >= minimum\n );\n}\n\nclass SetupChecker {\n readonly errors: string[] = [];\n\n fail(path: string, reason: string): false {\n this.errors.push(`${path}: ${reason}`);\n return false;\n }\n\n /** Literal user-visible copy. Carries no markup. */\n copy(value: unknown, path: string): boolean {\n if (typeof value !== \"string\" || value.length === 0) {\n return this.fail(path, \"must be a non-empty string\");\n }\n if (MARKUP_PATTERN.test(value)) {\n return this.fail(path, \"must not contain markup\");\n }\n return true;\n }\n\n placeholders(value: string, path: string): boolean {\n if (UNKNOWN_PLACEHOLDER_PATTERN.test(value)) {\n return this.fail(path, \"uses an unknown placeholder namespace\");\n }\n return true;\n }\n\n /** Copy that may embed `{{namespace.key}}` placeholders. */\n templateCopy(value: unknown, path: string): boolean {\n return this.copy(value, path) && this.placeholders(value as string, path);\n }\n\n /**\n * A request-body string that may embed placeholders. Never rendered, so\n * expression syntax such as a JMESPath filter is allowed through.\n */\n templateValue(value: unknown, path: string): boolean {\n if (typeof value !== \"string\" || value.length === 0) {\n return this.fail(path, \"must be a non-empty string\");\n }\n return this.placeholders(value, path);\n }\n\n absent(container: Rec, key: string, path: string, reason: string): boolean {\n if (key in container) return this.fail(`${path}.${key}`, reason);\n return true;\n }\n}\n\n/**\n * A relative path that stays inside the archive it names.\n *\n * The character class alone is not enough: `.` and `..` are made of allowed\n * characters, so a segment check is what actually keeps a packed file from\n * climbing out of the directory it is extracted into.\n */\nfunction isRelativePath(value: unknown, pattern: RegExp): value is string {\n return (\n typeof value === \"string\" &&\n pattern.test(value) &&\n !value.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n );\n}\n\n/**\n * A command whose every word stays inside the archive it is run in.\n *\n * The character class is not what keeps it there: `/` and `.` are allowed\n * characters, so `/bin/sh setup.sh` and `python3 ../../etc/x.py` are made of\n * them and each names something outside the extracted directory. The segment\n * rule packed paths are held to is what refuses those, and requiring a word at\n * all is what refuses an entrypoint of nothing but spaces.\n */\nfunction isPlainCommand(value: unknown): value is string {\n if (typeof value !== \"string\" || !BUNDLE_COMMAND_PATTERN.test(value)) {\n return false;\n }\n const words = value.split(\" \").filter((word) => word.length > 0);\n return (\n words.length > 0 &&\n words.every(\n (word) =>\n !word.startsWith(\"/\") &&\n !word.split(\"/\").some((segment) => segment === \"..\"),\n )\n );\n}\n\nfunction checkRequires(check: SetupChecker, requires: unknown): void {\n if (!isRecord(requires)) {\n check.fail(\"requires\", \"must be an object\");\n return;\n }\n\n const { integrations, features } = requires;\n // Empty is meaningful rather than malformed: an automation that needs no\n // credential connects to nothing, and the key stays required so that saying\n // so is a deliberate statement instead of an omission.\n if (!isRecord(integrations)) {\n check.fail(\"requires.integrations\", \"must be an object\");\n } else {\n Object.entries(integrations).forEach(([id, requirement]) => {\n const path = `requires.integrations.${id}`;\n if (!isRecord(requirement)) {\n check.fail(path, \"must be an object\");\n return;\n }\n check.copy(requirement.message, `${path}.message`);\n if (\"required\" in requirement && requirement.required !== false) {\n check.fail(`${path}.required`, \"may only be false\");\n }\n const allowed = [\"message\", \"required\"];\n Object.keys(requirement)\n .filter((key) => !allowed.includes(key))\n .forEach((key) => check.fail(`${path}.${key}`, \"is not allowed\"));\n });\n }\n\n if (features !== undefined) {\n if (!Array.isArray(features) || features.length === 0) {\n check.fail(\"requires.features\", \"must be a non-empty array\");\n } else {\n features.forEach((feature, index) => {\n if (typeof feature !== \"string\" || feature.length === 0) {\n check.fail(\n `requires.features[${index}]`,\n \"must be a non-empty string\",\n );\n }\n });\n }\n }\n}\n\nfunction checkConstraints(\n check: SetupChecker,\n constraints: unknown,\n path: string,\n): void {\n if (!isRecord(constraints) || Object.keys(constraints).length === 0) {\n check.fail(path, \"must be a non-empty object\");\n return;\n }\n\n const { minLength, maxLength, min, max, format } = constraints;\n if (minLength !== undefined && !isInteger(minLength, 0)) {\n check.fail(`${path}.minLength`, \"must be a non-negative integer\");\n }\n if (maxLength !== undefined && !isInteger(maxLength, 1)) {\n check.fail(`${path}.maxLength`, \"must be a positive integer\");\n }\n if (min !== undefined && !isInteger(min, 0)) {\n check.fail(`${path}.min`, \"must be a non-negative integer\");\n }\n if (max !== undefined && !isInteger(max, 1)) {\n check.fail(`${path}.max`, \"must be a positive integer\");\n }\n if (format !== undefined && !isOneOf(format, CONSTRAINT_FORMATS)) {\n check.fail(`${path}.format`, \"is not a supported format\");\n }\n}\n\nfunction checkField(check: SetupChecker, field: unknown, path: string): void {\n if (!isRecord(field)) {\n check.fail(path, \"must be an object\");\n return;\n }\n\n const { type, label, help, placeholder, required, provider, options } = field;\n\n if (!isOneOf(type, FIELD_TYPES)) {\n check.fail(`${path}.type`, \"is not a supported field type\");\n }\n check.copy(label, `${path}.label`);\n check.copy(help, `${path}.help`);\n if (placeholder !== undefined) check.copy(placeholder, `${path}.placeholder`);\n if (\n field.default !== undefined &&\n typeof field.default !== \"string\" &&\n typeof field.default !== \"number\" &&\n typeof field.default !== \"boolean\" &&\n field.default !== null\n ) {\n check.fail(`${path}.default`, \"must be a string, number, boolean or null\");\n }\n if (typeof required !== \"boolean\") {\n check.fail(`${path}.required`, \"must be a boolean\");\n }\n if (provider !== undefined && !isOneOf(provider, GIT_PROVIDERS)) {\n check.fail(`${path}.provider`, \"is not a supported provider\");\n }\n if (type === \"repo-picker\" && provider === undefined) {\n check.fail(`${path}.provider`, \"is required for a repository field\");\n }\n // The host branches on this key to decide whether a field's value is a list,\n // so a field declaring it anywhere else would be seeded with a list and\n // rendered as a string.\n if (\n field.multiple !== undefined &&\n (field.multiple !== true || type !== \"repo-picker\")\n ) {\n check.fail(\n `${path}.multiple`,\n \"may only be true, and only on a repository field\",\n );\n }\n\n if (options !== undefined) {\n if (type !== \"select\") {\n check.fail(`${path}.options`, \"is only allowed on a select field\");\n } else if (!Array.isArray(options) || options.length === 0) {\n check.fail(`${path}.options`, \"must be a non-empty array\");\n } else {\n options.forEach((option, index) => {\n const optionPath = `${path}.options[${index}]`;\n if (!isRecord(option)) {\n check.fail(optionPath, \"must be an object\");\n return;\n }\n if (typeof option.value !== \"string\" || option.value.length === 0) {\n check.fail(`${optionPath}.value`, \"must be a non-empty string\");\n }\n check.copy(option.label, `${optionPath}.label`);\n });\n }\n }\n\n if (field.constraints !== undefined) {\n checkConstraints(check, field.constraints, `${path}.constraints`);\n }\n}\n\n/** Returns the declared field names, so the caller can check them for collisions. */\nfunction checkFields(\n check: SetupChecker,\n fields: unknown,\n path: string,\n): string[] {\n if (!isRecord(fields) || Object.keys(fields).length === 0) {\n check.fail(path, \"must be a non-empty object\");\n return [];\n }\n\n return Object.entries(fields).map(([name, field]) => {\n if (!FIELD_NAME_PATTERN.test(name)) {\n check.fail(`${path}.${name}`, \"is not a valid field name\");\n }\n checkField(check, field, `${path}.${name}`);\n return name;\n });\n}\n\n/** Returns the trigger kinds declared, in order. */\nfunction checkForm(\n check: SetupChecker,\n form: unknown,\n): { kinds: string[]; fieldNames: string[] } {\n if (!isRecord(form)) {\n check.fail(\"setup.form\", \"must be an object\");\n return { kinds: [], fieldNames: [] };\n }\n\n if (form.note !== undefined) check.copy(form.note, \"setup.form.note\");\n\n const names = checkFields(check, form.args, \"setup.form.args\");\n const kinds: string[] = [];\n\n if (form.triggers !== undefined) {\n if (!isRecord(form.triggers) || Object.keys(form.triggers).length === 0) {\n check.fail(\"setup.form.triggers\", \"must be a non-empty object\");\n } else {\n Object.entries(form.triggers).forEach(([kind, fields]) => {\n if (!isOneOf(kind, TRIGGER_KINDS)) {\n check.fail(`setup.form.triggers.${kind}`, \"is not a trigger kind\");\n return;\n }\n kinds.push(kind);\n names.push(\n ...checkFields(check, fields, `setup.form.triggers.${kind}`),\n );\n });\n }\n }\n\n // The host merges both halves into one value map, so a repeated name would\n // silently shadow a field and misaddress every error reported against it.\n const duplicates = names.filter(\n (name, index) => names.indexOf(name) !== index,\n );\n Array.from(new Set(duplicates)).forEach((name) =>\n check.fail(`setup.form.${name}`, \"is declared more than once\"),\n );\n\n return { kinds, fieldNames: names };\n}\n\nfunction checkActionFeatures(\n check: SetupChecker,\n features: unknown,\n path: string,\n): void {\n if (!Array.isArray(features) || features.length === 0) {\n check.fail(path, \"must be a non-empty array\");\n return;\n }\n features.forEach((feature, index) => {\n if (typeof feature !== \"string\" || feature.length === 0) {\n check.fail(`${path}[${index}]`, \"must be a non-empty string\");\n }\n });\n}\n\nfunction checkAction(\n check: SetupChecker,\n kind: string,\n action: unknown,\n commonFieldNames: string[],\n): void {\n const path = `setup.actions.${kind}`;\n if (!isRecord(action)) {\n check.fail(path, \"must be an object\");\n return;\n }\n\n check.copy(action.label, `${path}.label`);\n check.copy(action.help, `${path}.help`);\n checkActionFeatures(check, action.features, `${path}.features`);\n const actionFieldNames = checkFields(check, action.args, `${path}.args`);\n actionFieldNames\n .filter((name) => commonFieldNames.includes(name))\n .forEach((name) =>\n check.fail(`${path}.args.${name}`, \"is already declared by the form\"),\n );\n\n if (kind === \"prompt\") {\n check.templateValue(action.prompt, `${path}.prompt`);\n } else if (kind === \"plugin\") {\n check.templateValue(action.prompt, `${path}.prompt`);\n check.templateValue(action.plugins, `${path}.plugins`);\n } else if (kind === \"upload\") {\n check.templateValue(action.tarballPath, `${path}.tarballPath`);\n check.templateValue(action.entrypoint, `${path}.entrypoint`);\n if (action.setupScript !== undefined) {\n check.templateValue(action.setupScript, `${path}.setupScript`);\n }\n } else {\n check.fail(path, \"is not a supported action kind\");\n }\n\n const allowedByKind: Record<string, string[]> = {\n prompt: [\"label\", \"help\", \"features\", \"args\", \"prompt\"],\n plugin: [\"label\", \"help\", \"features\", \"args\", \"prompt\", \"plugins\"],\n upload: [\n \"label\",\n \"help\",\n \"features\",\n \"args\",\n \"tarballPath\",\n \"entrypoint\",\n \"setupScript\",\n ],\n };\n const allowed = allowedByKind[kind] ?? [];\n Object.keys(action)\n .filter((key) => !allowed.includes(key))\n .forEach((key) => check.fail(`${path}.${key}`, \"is not allowed\"));\n}\n\nfunction checkActions(\n check: SetupChecker,\n actions: unknown,\n commonFieldNames: string[],\n): void {\n if (!isRecord(actions) || Object.keys(actions).length === 0) {\n check.fail(\"setup.actions\", \"must be a non-empty object\");\n return;\n }\n Object.entries(actions).forEach(([kind, action]) =>\n checkAction(check, kind, action, commonFieldNames),\n );\n}\n\nfunction fieldsContainType(fields: unknown, type: string): boolean {\n if (!isRecord(fields)) return false;\n return Object.values(fields).some(\n (field) => isRecord(field) && field.type === type,\n );\n}\n\nfunction actionHasRepoPicker(action: unknown): boolean {\n return isRecord(action) && fieldsContainType(action.args, \"repo-picker\");\n}\n\n/**\n * Whether an event trigger's `source` is derivable for every selectable action.\n *\n * `buildTrigger` fills `source` from a field named `source` in the event\n * trigger, or failing that from the selected action's repo-picker provider. A\n * picker in another trigger group (such as `cron`) is never collected for the\n * event trigger, and a picker in only some actions is invisible when one of the\n * others is selected — so neither may satisfy this check, or the user can end\n * up with an empty `source` no form field can fix.\n */\nfunction setupSuppliesEventSource(setup: Rec): boolean {\n const form = isRecord(setup.form) ? setup.form : {};\n const triggers = isRecord(form.triggers) ? form.triggers : {};\n const eventFields = triggers.event;\n\n // An explicit event-source field fills `source` directly, regardless of which\n // action is selected.\n if (fieldsContainType(eventFields, \"event-source\")) return true;\n\n // A repo-picker in the event trigger is only collected when `event` is the\n // sole trigger kind; with a sibling trigger the derivation reads no trigger\n // fields for the picker. `form.args` is shared across every selection, so a\n // picker there is always available.\n const singleEventTrigger =\n \"event\" in triggers && Object.keys(triggers).length === 1;\n if (\n (singleEventTrigger && fieldsContainType(eventFields, \"repo-picker\")) ||\n fieldsContainType(form.args, \"repo-picker\")\n ) {\n return true;\n }\n\n // Without a shared or event-trigger picker, every selectable action must\n // carry its own repo-picker; otherwise selecting an action without one\n // derives `source: \"\"`.\n if (!isRecord(setup.actions) || Object.keys(setup.actions).length === 0) {\n return false;\n }\n return Object.values(setup.actions).every(actionHasRepoPicker);\n}\n\nfunction checkMessage(check: SetupChecker, message: unknown): void {\n if (check.templateCopy(message, \"setup.message\")) {\n if ((message as string).length > MAX_MESSAGE_LENGTH) {\n check.fail(\n \"setup.message\",\n `must be at most ${MAX_MESSAGE_LENGTH} characters`,\n );\n }\n }\n}\n\n/**\n * The script tarball a direct entry may ship.\n *\n * The strings here are commands and paths this host acts on, so they are held\n * to a closed character set rather than the placeholder rules copy uses: an\n * entrypoint with a shell metacharacter, or a packed path that escapes the\n * archive, is refused here rather than by the service.\n */\nfunction checkBundle(check: SetupChecker, bundle: unknown): void {\n if (!isRecord(bundle)) {\n check.fail(\"setup.bundle\", \"must be an object\");\n return;\n }\n\n if (\n typeof bundle.version !== \"string\" ||\n !TEMPLATE_VERSION_PATTERN.test(bundle.version)\n ) {\n check.fail(\"setup.bundle.version\", \"must be a semantic version\");\n }\n if (!isPlainCommand(bundle.entrypoint)) {\n check.fail(\n \"setup.bundle.entrypoint\",\n \"must be a plain command that stays inside the archive\",\n );\n }\n if (\n bundle.setupScript !== undefined &&\n !isRelativePath(bundle.setupScript, BUNDLE_PATH_PATTERN)\n ) {\n check.fail(\"setup.bundle.setupScript\", \"must be a relative path\");\n }\n if (bundle.timeout !== undefined && !isInteger(bundle.timeout, 1)) {\n check.fail(\"setup.bundle.timeout\", \"must be a positive integer\");\n }\n\n if (!isRecord(bundle.files) || Object.keys(bundle.files).length === 0) {\n check.fail(\"setup.bundle.files\", \"must be a non-empty object\");\n } else {\n Object.entries(bundle.files).forEach(([packedPath, source]) => {\n if (!isRelativePath(packedPath, BUNDLE_PATH_PATTERN)) {\n check.fail(`setup.bundle.files.${packedPath}`, \"is not a packed path\");\n }\n // The rendered config is packed under this name too, and a tar carrying\n // the name twice leaves which one the script reads to whichever\n // extractor unpacks it.\n if (packedPath === BUNDLE_CONFIG_FILENAME) {\n check.fail(\n `setup.bundle.files.${packedPath}`,\n \"is the name the rendered config is packed under\",\n );\n }\n if (!isRelativePath(source, BUNDLE_SOURCE_PATTERN)) {\n check.fail(\n `setup.bundle.files.${packedPath}`,\n \"must name a file under skills/ or automations/\",\n );\n }\n });\n\n // A setup script the archive does not carry is a create request the\n // service accepts and the first run fails on, and it is also the only\n // thing packed executable - naming an unpacked file makes that rule\n // unreachable.\n if (\n typeof bundle.setupScript === \"string\" &&\n !(bundle.setupScript in bundle.files)\n ) {\n check.fail(\"setup.bundle.setupScript\", \"must name a packed file\");\n }\n }\n\n if (!isRecord(bundle.config) || Object.keys(bundle.config).length === 0) {\n check.fail(\"setup.bundle.config\", \"must be a non-empty object\");\n } else {\n checkBundleConfig(check, bundle.config, \"setup.bundle.config\");\n }\n}\n\n/** Every string leaf of the config is a payload value: placeholders, no markup rule. */\nfunction checkBundleConfig(\n check: SetupChecker,\n node: unknown,\n path: string,\n): void {\n if (typeof node === \"string\") {\n check.templateValue(node, path);\n return;\n }\n if (Array.isArray(node)) {\n node.forEach((item, index) =>\n checkBundleConfig(check, item, `${path}[${index}]`),\n );\n return;\n }\n if (isRecord(node)) {\n Object.entries(node).forEach(([key, value]) =>\n checkBundleConfig(check, value, `${path}.${key}`),\n );\n return;\n }\n if (node !== null && typeof node !== \"number\" && typeof node !== \"boolean\") {\n check.fail(\n path,\n \"must be a string, number, boolean, null, array or object\",\n );\n }\n}\n\nfunction checkMode(\n check: SetupChecker,\n setup: Rec,\n kinds: string[],\n commonFieldNames: string[],\n): void {\n if (!isOneOf(setup.mode, SETUP_MODES)) {\n check.fail(\"setup.mode\", \"is not a supported mode\");\n return;\n }\n\n if (setup.mode === \"direct\") {\n // A direct entry produces one of three things: a prompt, a script bundle\n // the host packs and uploads, or a selectable set of action variants.\n // More than one would be ambiguous, and none is nothing to create.\n const hasPrompt = setup.prompt !== undefined;\n const hasBundle = setup.bundle !== undefined;\n const hasActions = setup.actions !== undefined;\n const variants = [hasPrompt, hasBundle, hasActions].filter(Boolean);\n if (variants.length !== 1) {\n check.fail(\n \"setup\",\n \"must declare exactly one of prompt, bundle or actions for direct setup\",\n );\n } else if (hasBundle) {\n checkBundle(check, setup.bundle);\n } else if (hasActions) {\n checkActions(check, setup.actions, commonFieldNames);\n } else {\n check.templateValue(setup.prompt, \"setup.prompt\");\n }\n // A direct entry may carry a fallback-conversation seed for deployments\n // that cannot run the direct path, held to the same rules as an assisted\n // message.\n if (setup.message !== undefined) checkMessage(check, setup.message);\n\n if (kinds.length === 0) {\n check.fail(\n \"setup.form.triggers\",\n \"must declare at least one trigger kind\",\n );\n }\n if (kinds.includes(\"event\") && !setupSuppliesEventSource(setup)) {\n check.fail(\n \"setup.form.triggers.event\",\n \"must declare an event source field or repository picker\",\n );\n }\n if (setup.filter !== undefined) {\n if (!kinds.includes(\"event\")) {\n check.fail(\"setup.filter\", \"is only allowed for an event trigger\");\n } else {\n check.templateValue(setup.filter, \"setup.filter\");\n }\n }\n return;\n }\n\n checkMessage(check, setup.message);\n check.absent(setup, \"prompt\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"bundle\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"actions\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"filter\", \"setup\", \"is only allowed for direct setup\");\n}\n\n/** Whether a catalog entry ships a setup experience at all. It is optional. */\nexport function hasSetupBlock(candidate: unknown): boolean {\n return isRecord(candidate) && candidate.setup !== undefined;\n}\n\n/**\n * Decide whether this host will act on a catalog manifest.\n *\n * The version is checked first and fails closed: a format this host does not\n * recognise is refused rather than interpreted with today's rules.\n */\nexport function validateSetupEntry(candidate: unknown): SetupValidationResult {\n const check = new SetupChecker();\n\n if (!isRecord(candidate)) {\n return { valid: false, errors: [\"manifest: must be an object\"] };\n }\n\n const { setup } = candidate;\n if (!isRecord(setup)) {\n return { valid: false, errors: [\"setup: must be an object\"] };\n }\n if (setup.version !== SETUP_VERSION) {\n return {\n valid: false,\n errors: [`setup.version: must be \"${SETUP_VERSION}\"`],\n };\n }\n\n if (\n typeof candidate.id !== \"string\" ||\n !ENTRY_ID_PATTERN.test(candidate.id)\n ) {\n check.fail(\"id\", \"must be a lowercase slug\");\n }\n check.copy(candidate.name, \"name\");\n check.copy(candidate.description, \"description\");\n if (\n candidate.version !== undefined &&\n (typeof candidate.version !== \"string\" ||\n !TEMPLATE_VERSION_PATTERN.test(candidate.version))\n ) {\n check.fail(\"version\", \"must be a semantic version\");\n }\n if (\n candidate.skill !== undefined &&\n (typeof candidate.skill !== \"string\" ||\n !ENTRY_ID_PATTERN.test(candidate.skill))\n ) {\n check.fail(\"skill\", \"must be a lowercase slug\");\n }\n\n checkRequires(check, candidate.requires);\n const { kinds, fieldNames } = checkForm(check, setup.form);\n checkMode(check, setup, kinds, fieldNames);\n\n return { valid: check.errors.length === 0, errors: check.errors };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manifest-validation.cjs","names":[],"sources":["../../src/manifests/manifest-validation.ts"],"sourcesContent":["/**\n * Admission policy for extension-authored catalog manifests.\n *\n * A manifest is data authored in a different repository that instructs this host\n * to render copy and compose a request. The host therefore decides what a\n * manifest is *permitted* to do rather than trusting the file — validation here\n * is a trust boundary, not a convenience check, and it deliberately does not\n * defer to a schema shipped alongside the manifests it would be validating.\n *\n * Beyond mirroring the published schema, this adds the invariants the host's own\n * derivation depends on: a single trigger kind to read, a repository field for\n * an event trigger's source, and field names unique across the form. Without\n * them the derived request body would be silently wrong rather than rejected.\n *\n * A manifest that fails any check is rejected outright. It never renders a\n * partial UI, because everything downstream treats its content as instructions.\n */\n\nimport {\n BUNDLE_CONFIG_FILENAME,\n SETUP_PLACEHOLDER_NAMESPACES,\n SETUP_VERSION,\n} from \"./types\";\n\nconst ENTRY_ID_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;\nconst FIELD_NAME_PATTERN = /^[a-z][A-Za-z0-9]*$/;\n/** Copy must never be able to inject markup into the host. */\nconst MARKUP_PATTERN = /<[A-Za-z/!]/;\n/**\n * A template version, declared as `version` by a prompt entry and as\n * `setup.bundle.version` by a bundle one. Sent to the service as template\n * provenance, so it is checked at admission. Full semver, as the spec at\n * semver.org states it: a catalog entry published with a pre-release or build\n * suffix is still a version this host may forward, and refusing one would drop\n * the entry from the registry outright.\n */\nconst TEMPLATE_VERSION_PATTERN =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\\+[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*)?$/;\n// The characters a command of plain words and paths is made of. No shell\n// metacharacters, which the service rejects anyway and a bundle has no reason\n// to need; where those words may point is `isPlainCommand`'s to say.\nconst BUNDLE_COMMAND_PATTERN = /^[A-Za-z0-9 ._/-]+$/;\nconst BUNDLE_PATH_PATTERN = /^[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*$/;\nconst BUNDLE_SOURCE_PATTERN =\n /^(skills|automations|plugins)\\/[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*$/;\n/** Every `{{` must open a known namespace and close immediately. */\nconst UNKNOWN_PLACEHOLDER_PATTERN = new RegExp(\n `\\\\{\\\\{(?!(?:${SETUP_PLACEHOLDER_NAMESPACES.join(\"|\")})\\\\.[A-Za-z0-9_.]+\\\\}\\\\})`,\n);\n\nconst SETUP_MODES = [\"direct\", \"assisted\"] as const;\nconst FIELD_TYPES = [\n \"text\",\n \"textarea\",\n \"select\",\n \"number\",\n \"cron\",\n \"timezone\",\n \"repo-picker\",\n \"llm-profile\",\n \"event-source\",\n \"event-type\",\n \"plugin-sources\",\n \"tarball-upload\",\n] as const;\nconst GIT_PROVIDERS = [\"github\", \"gitlab\", \"bitbucket\"] as const;\nconst TRIGGER_KINDS = [\"cron\", \"event\"] as const;\nconst CONSTRAINT_FORMATS = [\"safeExpressionLiteral\"] as const;\n\n/** Setup context only, so this can never become a channel for runtime instructions. */\nconst MAX_MESSAGE_LENGTH = 2000;\n\nexport interface SetupValidationResult {\n valid: boolean;\n errors: string[];\n}\n\ntype Rec = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Rec {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOneOf<T extends readonly string[]>(\n value: unknown,\n allowed: T,\n): value is T[number] {\n return (\n typeof value === \"string\" && (allowed as readonly string[]).includes(value)\n );\n}\n\nfunction isInteger(value: unknown, minimum: number): boolean {\n return (\n typeof value === \"number\" && Number.isInteger(value) && value >= minimum\n );\n}\n\nclass SetupChecker {\n readonly errors: string[] = [];\n\n fail(path: string, reason: string): false {\n this.errors.push(`${path}: ${reason}`);\n return false;\n }\n\n /** Literal user-visible copy. Carries no markup. */\n copy(value: unknown, path: string): boolean {\n if (typeof value !== \"string\" || value.length === 0) {\n return this.fail(path, \"must be a non-empty string\");\n }\n if (MARKUP_PATTERN.test(value)) {\n return this.fail(path, \"must not contain markup\");\n }\n return true;\n }\n\n placeholders(value: string, path: string): boolean {\n if (UNKNOWN_PLACEHOLDER_PATTERN.test(value)) {\n return this.fail(path, \"uses an unknown placeholder namespace\");\n }\n return true;\n }\n\n /** Copy that may embed `{{namespace.key}}` placeholders. */\n templateCopy(value: unknown, path: string): boolean {\n return this.copy(value, path) && this.placeholders(value as string, path);\n }\n\n /**\n * A request-body string that may embed placeholders. Never rendered, so\n * expression syntax such as a JMESPath filter is allowed through.\n */\n templateValue(value: unknown, path: string): boolean {\n if (typeof value !== \"string\" || value.length === 0) {\n return this.fail(path, \"must be a non-empty string\");\n }\n return this.placeholders(value, path);\n }\n\n absent(container: Rec, key: string, path: string, reason: string): boolean {\n if (key in container) return this.fail(`${path}.${key}`, reason);\n return true;\n }\n}\n\n/**\n * A relative path that stays inside the archive it names.\n *\n * The character class alone is not enough: `.` and `..` are made of allowed\n * characters, so a segment check is what actually keeps a packed file from\n * climbing out of the directory it is extracted into.\n */\nfunction isRelativePath(value: unknown, pattern: RegExp): value is string {\n return (\n typeof value === \"string\" &&\n pattern.test(value) &&\n !value.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n );\n}\n\n/**\n * A command whose every word stays inside the archive it is run in.\n *\n * The character class is not what keeps it there: `/` and `.` are allowed\n * characters, so `/bin/sh setup.sh` and `python3 ../../etc/x.py` are made of\n * them and each names something outside the extracted directory. The segment\n * rule packed paths are held to is what refuses those, and requiring a word at\n * all is what refuses an entrypoint of nothing but spaces.\n */\nfunction isPlainCommand(value: unknown): value is string {\n if (typeof value !== \"string\" || !BUNDLE_COMMAND_PATTERN.test(value)) {\n return false;\n }\n const words = value.split(\" \").filter((word) => word.length > 0);\n return (\n words.length > 0 &&\n words.every(\n (word) =>\n !word.startsWith(\"/\") &&\n !word.split(\"/\").some((segment) => segment === \"..\"),\n )\n );\n}\n\nfunction checkRequires(check: SetupChecker, requires: unknown): void {\n if (!isRecord(requires)) {\n check.fail(\"requires\", \"must be an object\");\n return;\n }\n\n const { integrations, features } = requires;\n // Empty is meaningful rather than malformed: an automation that needs no\n // credential connects to nothing, and the key stays required so that saying\n // so is a deliberate statement instead of an omission.\n if (!isRecord(integrations)) {\n check.fail(\"requires.integrations\", \"must be an object\");\n } else {\n Object.entries(integrations).forEach(([id, requirement]) => {\n const path = `requires.integrations.${id}`;\n if (!isRecord(requirement)) {\n check.fail(path, \"must be an object\");\n return;\n }\n check.copy(requirement.message, `${path}.message`);\n if (\"required\" in requirement && requirement.required !== false) {\n check.fail(`${path}.required`, \"may only be false\");\n }\n const allowed = [\"message\", \"required\"];\n Object.keys(requirement)\n .filter((key) => !allowed.includes(key))\n .forEach((key) => check.fail(`${path}.${key}`, \"is not allowed\"));\n });\n }\n\n if (features !== undefined) {\n if (!Array.isArray(features) || features.length === 0) {\n check.fail(\"requires.features\", \"must be a non-empty array\");\n } else {\n features.forEach((feature, index) => {\n if (typeof feature !== \"string\" || feature.length === 0) {\n check.fail(\n `requires.features[${index}]`,\n \"must be a non-empty string\",\n );\n }\n });\n }\n }\n}\n\nfunction checkConstraints(\n check: SetupChecker,\n constraints: unknown,\n path: string,\n): void {\n if (!isRecord(constraints) || Object.keys(constraints).length === 0) {\n check.fail(path, \"must be a non-empty object\");\n return;\n }\n\n const { minLength, maxLength, min, max, format } = constraints;\n if (minLength !== undefined && !isInteger(minLength, 0)) {\n check.fail(`${path}.minLength`, \"must be a non-negative integer\");\n }\n if (maxLength !== undefined && !isInteger(maxLength, 1)) {\n check.fail(`${path}.maxLength`, \"must be a positive integer\");\n }\n if (min !== undefined && !isInteger(min, 0)) {\n check.fail(`${path}.min`, \"must be a non-negative integer\");\n }\n if (max !== undefined && !isInteger(max, 1)) {\n check.fail(`${path}.max`, \"must be a positive integer\");\n }\n if (format !== undefined && !isOneOf(format, CONSTRAINT_FORMATS)) {\n check.fail(`${path}.format`, \"is not a supported format\");\n }\n}\n\nfunction checkField(check: SetupChecker, field: unknown, path: string): void {\n if (!isRecord(field)) {\n check.fail(path, \"must be an object\");\n return;\n }\n\n const { type, label, help, placeholder, required, provider, options } = field;\n\n if (!isOneOf(type, FIELD_TYPES)) {\n check.fail(`${path}.type`, \"is not a supported field type\");\n }\n check.copy(label, `${path}.label`);\n check.copy(help, `${path}.help`);\n if (placeholder !== undefined) check.copy(placeholder, `${path}.placeholder`);\n if (\n field.default !== undefined &&\n typeof field.default !== \"string\" &&\n typeof field.default !== \"number\" &&\n typeof field.default !== \"boolean\" &&\n field.default !== null\n ) {\n check.fail(`${path}.default`, \"must be a string, number, boolean or null\");\n }\n if (typeof required !== \"boolean\") {\n check.fail(`${path}.required`, \"must be a boolean\");\n }\n if (provider !== undefined && !isOneOf(provider, GIT_PROVIDERS)) {\n check.fail(`${path}.provider`, \"is not a supported provider\");\n }\n if (type === \"repo-picker\" && provider === undefined) {\n check.fail(`${path}.provider`, \"is required for a repository field\");\n }\n // The host branches on this key to decide whether a field's value is a list,\n // so a field declaring it anywhere else would be seeded with a list and\n // rendered as a string.\n if (\n field.multiple !== undefined &&\n (field.multiple !== true || type !== \"repo-picker\")\n ) {\n check.fail(\n `${path}.multiple`,\n \"may only be true, and only on a repository field\",\n );\n }\n\n if (options !== undefined) {\n if (type !== \"select\") {\n check.fail(`${path}.options`, \"is only allowed on a select field\");\n } else if (!Array.isArray(options) || options.length === 0) {\n check.fail(`${path}.options`, \"must be a non-empty array\");\n } else {\n options.forEach((option, index) => {\n const optionPath = `${path}.options[${index}]`;\n if (!isRecord(option)) {\n check.fail(optionPath, \"must be an object\");\n return;\n }\n if (typeof option.value !== \"string\" || option.value.length === 0) {\n check.fail(`${optionPath}.value`, \"must be a non-empty string\");\n }\n check.copy(option.label, `${optionPath}.label`);\n });\n }\n }\n\n if (field.constraints !== undefined) {\n checkConstraints(check, field.constraints, `${path}.constraints`);\n }\n}\n\n/** Returns the declared field names, so the caller can check them for collisions. */\nfunction checkFields(\n check: SetupChecker,\n fields: unknown,\n path: string,\n): string[] {\n if (!isRecord(fields) || Object.keys(fields).length === 0) {\n check.fail(path, \"must be a non-empty object\");\n return [];\n }\n\n return Object.entries(fields).map(([name, field]) => {\n if (!FIELD_NAME_PATTERN.test(name)) {\n check.fail(`${path}.${name}`, \"is not a valid field name\");\n }\n checkField(check, field, `${path}.${name}`);\n return name;\n });\n}\n\n/** Returns the trigger kinds declared, in order. */\nfunction checkForm(\n check: SetupChecker,\n form: unknown,\n): { kinds: string[]; fieldNames: string[] } {\n if (!isRecord(form)) {\n check.fail(\"setup.form\", \"must be an object\");\n return { kinds: [], fieldNames: [] };\n }\n\n if (form.note !== undefined) check.copy(form.note, \"setup.form.note\");\n\n const names = checkFields(check, form.args, \"setup.form.args\");\n const kinds: string[] = [];\n\n if (form.triggers !== undefined) {\n if (!isRecord(form.triggers) || Object.keys(form.triggers).length === 0) {\n check.fail(\"setup.form.triggers\", \"must be a non-empty object\");\n } else {\n Object.entries(form.triggers).forEach(([kind, fields]) => {\n if (!isOneOf(kind, TRIGGER_KINDS)) {\n check.fail(`setup.form.triggers.${kind}`, \"is not a trigger kind\");\n return;\n }\n kinds.push(kind);\n names.push(\n ...checkFields(check, fields, `setup.form.triggers.${kind}`),\n );\n });\n }\n }\n\n // The host merges both halves into one value map, so a repeated name would\n // silently shadow a field and misaddress every error reported against it.\n const duplicates = names.filter(\n (name, index) => names.indexOf(name) !== index,\n );\n Array.from(new Set(duplicates)).forEach((name) =>\n check.fail(`setup.form.${name}`, \"is declared more than once\"),\n );\n\n return { kinds, fieldNames: names };\n}\n\nfunction checkActionFeatures(\n check: SetupChecker,\n features: unknown,\n path: string,\n): void {\n if (!Array.isArray(features) || features.length === 0) {\n check.fail(path, \"must be a non-empty array\");\n return;\n }\n features.forEach((feature, index) => {\n if (typeof feature !== \"string\" || feature.length === 0) {\n check.fail(`${path}[${index}]`, \"must be a non-empty string\");\n }\n });\n}\n\nfunction checkAction(\n check: SetupChecker,\n kind: string,\n action: unknown,\n commonFieldNames: string[],\n): void {\n const path = `setup.actions.${kind}`;\n if (!isRecord(action)) {\n check.fail(path, \"must be an object\");\n return;\n }\n\n check.copy(action.label, `${path}.label`);\n check.copy(action.help, `${path}.help`);\n checkActionFeatures(check, action.features, `${path}.features`);\n const actionFieldNames = checkFields(check, action.args, `${path}.args`);\n actionFieldNames\n .filter((name) => commonFieldNames.includes(name))\n .forEach((name) =>\n check.fail(`${path}.args.${name}`, \"is already declared by the form\"),\n );\n\n if (kind === \"prompt\") {\n check.templateValue(action.prompt, `${path}.prompt`);\n } else if (kind === \"plugin\") {\n check.templateValue(action.prompt, `${path}.prompt`);\n check.templateValue(action.plugins, `${path}.plugins`);\n } else if (kind === \"upload\") {\n check.templateValue(action.tarballPath, `${path}.tarballPath`);\n check.templateValue(action.entrypoint, `${path}.entrypoint`);\n if (action.setupScript !== undefined) {\n check.templateValue(action.setupScript, `${path}.setupScript`);\n }\n } else {\n check.fail(path, \"is not a supported action kind\");\n }\n\n const allowedByKind: Record<string, string[]> = {\n prompt: [\"label\", \"help\", \"features\", \"args\", \"prompt\"],\n plugin: [\"label\", \"help\", \"features\", \"args\", \"prompt\", \"plugins\"],\n upload: [\n \"label\",\n \"help\",\n \"features\",\n \"args\",\n \"tarballPath\",\n \"entrypoint\",\n \"setupScript\",\n ],\n };\n const allowed = allowedByKind[kind] ?? [];\n Object.keys(action)\n .filter((key) => !allowed.includes(key))\n .forEach((key) => check.fail(`${path}.${key}`, \"is not allowed\"));\n}\n\nfunction checkActions(\n check: SetupChecker,\n actions: unknown,\n commonFieldNames: string[],\n): void {\n if (!isRecord(actions) || Object.keys(actions).length === 0) {\n check.fail(\"setup.actions\", \"must be a non-empty object\");\n return;\n }\n Object.entries(actions).forEach(([kind, action]) =>\n checkAction(check, kind, action, commonFieldNames),\n );\n}\n\nfunction fieldsContainType(fields: unknown, type: string): boolean {\n if (!isRecord(fields)) return false;\n return Object.values(fields).some(\n (field) => isRecord(field) && field.type === type,\n );\n}\n\nfunction actionHasRepoPicker(action: unknown): boolean {\n return isRecord(action) && fieldsContainType(action.args, \"repo-picker\");\n}\n\n/**\n * Whether an event trigger's `source` is derivable for every selectable action.\n *\n * `buildTrigger` fills `source` from a field named `source` in the event\n * trigger, or failing that from the selected action's repo-picker provider. A\n * picker in another trigger group (such as `cron`) is never collected for the\n * event trigger, and a picker in only some actions is invisible when one of the\n * others is selected — so neither may satisfy this check, or the user can end\n * up with an empty `source` no form field can fix.\n */\nfunction setupSuppliesEventSource(setup: Rec): boolean {\n const form = isRecord(setup.form) ? setup.form : {};\n const triggers = isRecord(form.triggers) ? form.triggers : {};\n const eventFields = triggers.event;\n\n // An explicit event-source field fills `source` directly, regardless of which\n // action is selected.\n if (fieldsContainType(eventFields, \"event-source\")) return true;\n\n // A repo-picker in the event trigger is only collected when `event` is the\n // sole trigger kind; with a sibling trigger the derivation reads no trigger\n // fields for the picker. `form.args` is shared across every selection, so a\n // picker there is always available.\n const singleEventTrigger =\n \"event\" in triggers && Object.keys(triggers).length === 1;\n if (\n (singleEventTrigger && fieldsContainType(eventFields, \"repo-picker\")) ||\n fieldsContainType(form.args, \"repo-picker\")\n ) {\n return true;\n }\n\n // Without a shared or event-trigger picker, every selectable action must\n // carry its own repo-picker; otherwise selecting an action without one\n // derives `source: \"\"`.\n if (!isRecord(setup.actions) || Object.keys(setup.actions).length === 0) {\n return false;\n }\n return Object.values(setup.actions).every(actionHasRepoPicker);\n}\n\nfunction checkMessage(check: SetupChecker, message: unknown): void {\n if (check.templateCopy(message, \"setup.message\")) {\n if ((message as string).length > MAX_MESSAGE_LENGTH) {\n check.fail(\n \"setup.message\",\n `must be at most ${MAX_MESSAGE_LENGTH} characters`,\n );\n }\n }\n}\n\n/**\n * The script tarball a direct entry may ship.\n *\n * The strings here are commands and paths this host acts on, so they are held\n * to a closed character set rather than the placeholder rules copy uses: an\n * entrypoint with a shell metacharacter, or a packed path that escapes the\n * archive, is refused here rather than by the service.\n */\nfunction checkBundle(check: SetupChecker, bundle: unknown): void {\n if (!isRecord(bundle)) {\n check.fail(\"setup.bundle\", \"must be an object\");\n return;\n }\n\n if (\n typeof bundle.version !== \"string\" ||\n !TEMPLATE_VERSION_PATTERN.test(bundle.version)\n ) {\n check.fail(\"setup.bundle.version\", \"must be a semantic version\");\n }\n if (!isPlainCommand(bundle.entrypoint)) {\n check.fail(\n \"setup.bundle.entrypoint\",\n \"must be a plain command that stays inside the archive\",\n );\n }\n if (\n bundle.setupScript !== undefined &&\n !isRelativePath(bundle.setupScript, BUNDLE_PATH_PATTERN)\n ) {\n check.fail(\"setup.bundle.setupScript\", \"must be a relative path\");\n }\n if (bundle.timeout !== undefined && !isInteger(bundle.timeout, 1)) {\n check.fail(\"setup.bundle.timeout\", \"must be a positive integer\");\n }\n\n if (!isRecord(bundle.files) || Object.keys(bundle.files).length === 0) {\n check.fail(\"setup.bundle.files\", \"must be a non-empty object\");\n } else {\n Object.entries(bundle.files).forEach(([packedPath, source]) => {\n if (!isRelativePath(packedPath, BUNDLE_PATH_PATTERN)) {\n check.fail(`setup.bundle.files.${packedPath}`, \"is not a packed path\");\n }\n // The rendered config is packed under this name too, and a tar carrying\n // the name twice leaves which one the script reads to whichever\n // extractor unpacks it.\n if (packedPath === BUNDLE_CONFIG_FILENAME) {\n check.fail(\n `setup.bundle.files.${packedPath}`,\n \"is the name the rendered config is packed under\",\n );\n }\n if (!isRelativePath(source, BUNDLE_SOURCE_PATTERN)) {\n check.fail(\n `setup.bundle.files.${packedPath}`,\n \"must name a file under skills/, automations/, or plugins/\",\n );\n }\n });\n\n // A setup script the archive does not carry is a create request the\n // service accepts and the first run fails on, and it is also the only\n // thing packed executable - naming an unpacked file makes that rule\n // unreachable.\n if (\n typeof bundle.setupScript === \"string\" &&\n !(bundle.setupScript in bundle.files)\n ) {\n check.fail(\"setup.bundle.setupScript\", \"must name a packed file\");\n }\n }\n\n if (!isRecord(bundle.config) || Object.keys(bundle.config).length === 0) {\n check.fail(\"setup.bundle.config\", \"must be a non-empty object\");\n } else {\n checkBundleConfig(check, bundle.config, \"setup.bundle.config\");\n }\n}\n\n/** Every string leaf of the config is a payload value: placeholders, no markup rule. */\nfunction checkBundleConfig(\n check: SetupChecker,\n node: unknown,\n path: string,\n): void {\n if (typeof node === \"string\") {\n check.templateValue(node, path);\n return;\n }\n if (Array.isArray(node)) {\n node.forEach((item, index) =>\n checkBundleConfig(check, item, `${path}[${index}]`),\n );\n return;\n }\n if (isRecord(node)) {\n Object.entries(node).forEach(([key, value]) =>\n checkBundleConfig(check, value, `${path}.${key}`),\n );\n return;\n }\n if (node !== null && typeof node !== \"number\" && typeof node !== \"boolean\") {\n check.fail(\n path,\n \"must be a string, number, boolean, null, array or object\",\n );\n }\n}\n\nfunction checkMode(\n check: SetupChecker,\n setup: Rec,\n kinds: string[],\n commonFieldNames: string[],\n): void {\n if (!isOneOf(setup.mode, SETUP_MODES)) {\n check.fail(\"setup.mode\", \"is not a supported mode\");\n return;\n }\n\n if (setup.mode === \"direct\") {\n // A direct entry produces one of three things: a prompt, a script bundle\n // the host packs and uploads, or a selectable set of action variants.\n // More than one would be ambiguous, and none is nothing to create.\n const hasPrompt = setup.prompt !== undefined;\n const hasBundle = setup.bundle !== undefined;\n const hasActions = setup.actions !== undefined;\n const variants = [hasPrompt, hasBundle, hasActions].filter(Boolean);\n if (variants.length !== 1) {\n check.fail(\n \"setup\",\n \"must declare exactly one of prompt, bundle or actions for direct setup\",\n );\n } else if (hasBundle) {\n checkBundle(check, setup.bundle);\n } else if (hasActions) {\n checkActions(check, setup.actions, commonFieldNames);\n } else {\n check.templateValue(setup.prompt, \"setup.prompt\");\n }\n // A direct entry may carry a fallback-conversation seed for deployments\n // that cannot run the direct path, held to the same rules as an assisted\n // message.\n if (setup.message !== undefined) checkMessage(check, setup.message);\n\n if (kinds.length === 0) {\n check.fail(\n \"setup.form.triggers\",\n \"must declare at least one trigger kind\",\n );\n }\n if (kinds.includes(\"event\") && !setupSuppliesEventSource(setup)) {\n check.fail(\n \"setup.form.triggers.event\",\n \"must declare an event source field or repository picker\",\n );\n }\n if (setup.filter !== undefined) {\n if (!kinds.includes(\"event\")) {\n check.fail(\"setup.filter\", \"is only allowed for an event trigger\");\n } else {\n check.templateValue(setup.filter, \"setup.filter\");\n }\n }\n return;\n }\n\n checkMessage(check, setup.message);\n check.absent(setup, \"prompt\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"bundle\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"actions\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"filter\", \"setup\", \"is only allowed for direct setup\");\n}\n\n/** Whether a catalog entry ships a setup experience at all. It is optional. */\nexport function hasSetupBlock(candidate: unknown): boolean {\n return isRecord(candidate) && candidate.setup !== undefined;\n}\n\n/**\n * Decide whether this host will act on a catalog manifest.\n *\n * The version is checked first and fails closed: a format this host does not\n * recognise is refused rather than interpreted with today's rules.\n */\nexport function validateSetupEntry(candidate: unknown): SetupValidationResult {\n const check = new SetupChecker();\n\n if (!isRecord(candidate)) {\n return { valid: false, errors: [\"manifest: must be an object\"] };\n }\n\n const { setup } = candidate;\n if (!isRecord(setup)) {\n return { valid: false, errors: [\"setup: must be an object\"] };\n }\n if (setup.version !== SETUP_VERSION) {\n return {\n valid: false,\n errors: [`setup.version: must be \"${SETUP_VERSION}\"`],\n };\n }\n\n if (\n typeof candidate.id !== \"string\" ||\n !ENTRY_ID_PATTERN.test(candidate.id)\n ) {\n check.fail(\"id\", \"must be a lowercase slug\");\n }\n check.copy(candidate.name, \"name\");\n check.copy(candidate.description, \"description\");\n if (\n candidate.version !== undefined &&\n (typeof candidate.version !== \"string\" ||\n !TEMPLATE_VERSION_PATTERN.test(candidate.version))\n ) {\n check.fail(\"version\", \"must be a semantic version\");\n }\n if (\n candidate.skill !== undefined &&\n (typeof candidate.skill !== \"string\" ||\n !ENTRY_ID_PATTERN.test(candidate.skill))\n ) {\n check.fail(\"skill\", \"must be a lowercase slug\");\n }\n\n checkRequires(check, candidate.requires);\n const { kinds, fieldNames } = checkForm(check, setup.form);\n checkMode(check, setup, kinds, fieldNames);\n\n return { valid: check.errors.length === 0, errors: check.errors };\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { SETUP_PLACEHOLDER_NAMESPACES as e } from "./types.js";
2
2
  //#region src/manifests/manifest-validation.ts
3
- var t = /^[a-z0-9]+(-[a-z0-9]+)*$/, n = /^[a-z][A-Za-z0-9]*$/, r = /<[A-Za-z/!]/, i = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/, a = /^[A-Za-z0-9 ._/-]+$/, o = /^[A-Za-z0-9._-]+(\/[A-Za-z0-9._-]+)*$/, s = /^(skills|automations)\/[A-Za-z0-9._-]+(\/[A-Za-z0-9._-]+)*$/, c = RegExp(`\\{\\{(?!(?:${e.join("|")})\\.[A-Za-z0-9_.]+\\}\\})`), l = ["direct", "assisted"], u = [
3
+ var t = /^[a-z0-9]+(-[a-z0-9]+)*$/, n = /^[a-z][A-Za-z0-9]*$/, r = /<[A-Za-z/!]/, i = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/, a = /^[A-Za-z0-9 ._/-]+$/, o = /^[A-Za-z0-9._-]+(\/[A-Za-z0-9._-]+)*$/, s = /^(skills|automations|plugins)\/[A-Za-z0-9._-]+(\/[A-Za-z0-9._-]+)*$/, c = RegExp(`\\{\\{(?!(?:${e.join("|")})\\.[A-Za-z0-9_.]+\\}\\})`), l = ["direct", "assisted"], u = [
4
4
  "text",
5
5
  "textarea",
6
6
  "select",
@@ -191,7 +191,7 @@ function N(e, t) {
191
191
  return;
192
192
  }
193
193
  (typeof t.version != "string" || !i.test(t.version)) && e.fail("setup.bundle.version", "must be a semantic version"), b(t.entrypoint) || e.fail("setup.bundle.entrypoint", "must be a plain command that stays inside the archive"), t.setupScript !== void 0 && !y(t.setupScript, o) && e.fail("setup.bundle.setupScript", "must be a relative path"), t.timeout !== void 0 && !_(t.timeout, 1) && e.fail("setup.bundle.timeout", "must be a positive integer"), !h(t.files) || Object.keys(t.files).length === 0 ? e.fail("setup.bundle.files", "must be a non-empty object") : (Object.entries(t.files).forEach(([t, n]) => {
194
- y(t, o) || e.fail(`setup.bundle.files.${t}`, "is not a packed path"), t === "config.json" && e.fail(`setup.bundle.files.${t}`, "is the name the rendered config is packed under"), y(n, s) || e.fail(`setup.bundle.files.${t}`, "must name a file under skills/ or automations/");
194
+ y(t, o) || e.fail(`setup.bundle.files.${t}`, "is not a packed path"), t === "config.json" && e.fail(`setup.bundle.files.${t}`, "is the name the rendered config is packed under"), y(n, s) || e.fail(`setup.bundle.files.${t}`, "must name a file under skills/, automations/, or plugins/");
195
195
  }), typeof t.setupScript == "string" && !(t.setupScript in t.files) && e.fail("setup.bundle.setupScript", "must name a packed file")), !h(t.config) || Object.keys(t.config).length === 0 ? e.fail("setup.bundle.config", "must be a non-empty object") : P(e, t.config, "setup.bundle.config");
196
196
  }
197
197
  function P(e, t, n) {
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-validation.js","names":[],"sources":["../../src/manifests/manifest-validation.ts"],"sourcesContent":["/**\n * Admission policy for extension-authored catalog manifests.\n *\n * A manifest is data authored in a different repository that instructs this host\n * to render copy and compose a request. The host therefore decides what a\n * manifest is *permitted* to do rather than trusting the file — validation here\n * is a trust boundary, not a convenience check, and it deliberately does not\n * defer to a schema shipped alongside the manifests it would be validating.\n *\n * Beyond mirroring the published schema, this adds the invariants the host's own\n * derivation depends on: a single trigger kind to read, a repository field for\n * an event trigger's source, and field names unique across the form. Without\n * them the derived request body would be silently wrong rather than rejected.\n *\n * A manifest that fails any check is rejected outright. It never renders a\n * partial UI, because everything downstream treats its content as instructions.\n */\n\nimport {\n BUNDLE_CONFIG_FILENAME,\n SETUP_PLACEHOLDER_NAMESPACES,\n SETUP_VERSION,\n} from \"./types\";\n\nconst ENTRY_ID_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;\nconst FIELD_NAME_PATTERN = /^[a-z][A-Za-z0-9]*$/;\n/** Copy must never be able to inject markup into the host. */\nconst MARKUP_PATTERN = /<[A-Za-z/!]/;\n/**\n * A template version, declared as `version` by a prompt entry and as\n * `setup.bundle.version` by a bundle one. Sent to the service as template\n * provenance, so it is checked at admission. Full semver, as the spec at\n * semver.org states it: a catalog entry published with a pre-release or build\n * suffix is still a version this host may forward, and refusing one would drop\n * the entry from the registry outright.\n */\nconst TEMPLATE_VERSION_PATTERN =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\\+[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*)?$/;\n// The characters a command of plain words and paths is made of. No shell\n// metacharacters, which the service rejects anyway and a bundle has no reason\n// to need; where those words may point is `isPlainCommand`'s to say.\nconst BUNDLE_COMMAND_PATTERN = /^[A-Za-z0-9 ._/-]+$/;\nconst BUNDLE_PATH_PATTERN = /^[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*$/;\nconst BUNDLE_SOURCE_PATTERN =\n /^(skills|automations)\\/[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*$/;\n/** Every `{{` must open a known namespace and close immediately. */\nconst UNKNOWN_PLACEHOLDER_PATTERN = new RegExp(\n `\\\\{\\\\{(?!(?:${SETUP_PLACEHOLDER_NAMESPACES.join(\"|\")})\\\\.[A-Za-z0-9_.]+\\\\}\\\\})`,\n);\n\nconst SETUP_MODES = [\"direct\", \"assisted\"] as const;\nconst FIELD_TYPES = [\n \"text\",\n \"textarea\",\n \"select\",\n \"number\",\n \"cron\",\n \"timezone\",\n \"repo-picker\",\n \"llm-profile\",\n \"event-source\",\n \"event-type\",\n \"plugin-sources\",\n \"tarball-upload\",\n] as const;\nconst GIT_PROVIDERS = [\"github\", \"gitlab\", \"bitbucket\"] as const;\nconst TRIGGER_KINDS = [\"cron\", \"event\"] as const;\nconst CONSTRAINT_FORMATS = [\"safeExpressionLiteral\"] as const;\n\n/** Setup context only, so this can never become a channel for runtime instructions. */\nconst MAX_MESSAGE_LENGTH = 2000;\n\nexport interface SetupValidationResult {\n valid: boolean;\n errors: string[];\n}\n\ntype Rec = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Rec {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOneOf<T extends readonly string[]>(\n value: unknown,\n allowed: T,\n): value is T[number] {\n return (\n typeof value === \"string\" && (allowed as readonly string[]).includes(value)\n );\n}\n\nfunction isInteger(value: unknown, minimum: number): boolean {\n return (\n typeof value === \"number\" && Number.isInteger(value) && value >= minimum\n );\n}\n\nclass SetupChecker {\n readonly errors: string[] = [];\n\n fail(path: string, reason: string): false {\n this.errors.push(`${path}: ${reason}`);\n return false;\n }\n\n /** Literal user-visible copy. Carries no markup. */\n copy(value: unknown, path: string): boolean {\n if (typeof value !== \"string\" || value.length === 0) {\n return this.fail(path, \"must be a non-empty string\");\n }\n if (MARKUP_PATTERN.test(value)) {\n return this.fail(path, \"must not contain markup\");\n }\n return true;\n }\n\n placeholders(value: string, path: string): boolean {\n if (UNKNOWN_PLACEHOLDER_PATTERN.test(value)) {\n return this.fail(path, \"uses an unknown placeholder namespace\");\n }\n return true;\n }\n\n /** Copy that may embed `{{namespace.key}}` placeholders. */\n templateCopy(value: unknown, path: string): boolean {\n return this.copy(value, path) && this.placeholders(value as string, path);\n }\n\n /**\n * A request-body string that may embed placeholders. Never rendered, so\n * expression syntax such as a JMESPath filter is allowed through.\n */\n templateValue(value: unknown, path: string): boolean {\n if (typeof value !== \"string\" || value.length === 0) {\n return this.fail(path, \"must be a non-empty string\");\n }\n return this.placeholders(value, path);\n }\n\n absent(container: Rec, key: string, path: string, reason: string): boolean {\n if (key in container) return this.fail(`${path}.${key}`, reason);\n return true;\n }\n}\n\n/**\n * A relative path that stays inside the archive it names.\n *\n * The character class alone is not enough: `.` and `..` are made of allowed\n * characters, so a segment check is what actually keeps a packed file from\n * climbing out of the directory it is extracted into.\n */\nfunction isRelativePath(value: unknown, pattern: RegExp): value is string {\n return (\n typeof value === \"string\" &&\n pattern.test(value) &&\n !value.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n );\n}\n\n/**\n * A command whose every word stays inside the archive it is run in.\n *\n * The character class is not what keeps it there: `/` and `.` are allowed\n * characters, so `/bin/sh setup.sh` and `python3 ../../etc/x.py` are made of\n * them and each names something outside the extracted directory. The segment\n * rule packed paths are held to is what refuses those, and requiring a word at\n * all is what refuses an entrypoint of nothing but spaces.\n */\nfunction isPlainCommand(value: unknown): value is string {\n if (typeof value !== \"string\" || !BUNDLE_COMMAND_PATTERN.test(value)) {\n return false;\n }\n const words = value.split(\" \").filter((word) => word.length > 0);\n return (\n words.length > 0 &&\n words.every(\n (word) =>\n !word.startsWith(\"/\") &&\n !word.split(\"/\").some((segment) => segment === \"..\"),\n )\n );\n}\n\nfunction checkRequires(check: SetupChecker, requires: unknown): void {\n if (!isRecord(requires)) {\n check.fail(\"requires\", \"must be an object\");\n return;\n }\n\n const { integrations, features } = requires;\n // Empty is meaningful rather than malformed: an automation that needs no\n // credential connects to nothing, and the key stays required so that saying\n // so is a deliberate statement instead of an omission.\n if (!isRecord(integrations)) {\n check.fail(\"requires.integrations\", \"must be an object\");\n } else {\n Object.entries(integrations).forEach(([id, requirement]) => {\n const path = `requires.integrations.${id}`;\n if (!isRecord(requirement)) {\n check.fail(path, \"must be an object\");\n return;\n }\n check.copy(requirement.message, `${path}.message`);\n if (\"required\" in requirement && requirement.required !== false) {\n check.fail(`${path}.required`, \"may only be false\");\n }\n const allowed = [\"message\", \"required\"];\n Object.keys(requirement)\n .filter((key) => !allowed.includes(key))\n .forEach((key) => check.fail(`${path}.${key}`, \"is not allowed\"));\n });\n }\n\n if (features !== undefined) {\n if (!Array.isArray(features) || features.length === 0) {\n check.fail(\"requires.features\", \"must be a non-empty array\");\n } else {\n features.forEach((feature, index) => {\n if (typeof feature !== \"string\" || feature.length === 0) {\n check.fail(\n `requires.features[${index}]`,\n \"must be a non-empty string\",\n );\n }\n });\n }\n }\n}\n\nfunction checkConstraints(\n check: SetupChecker,\n constraints: unknown,\n path: string,\n): void {\n if (!isRecord(constraints) || Object.keys(constraints).length === 0) {\n check.fail(path, \"must be a non-empty object\");\n return;\n }\n\n const { minLength, maxLength, min, max, format } = constraints;\n if (minLength !== undefined && !isInteger(minLength, 0)) {\n check.fail(`${path}.minLength`, \"must be a non-negative integer\");\n }\n if (maxLength !== undefined && !isInteger(maxLength, 1)) {\n check.fail(`${path}.maxLength`, \"must be a positive integer\");\n }\n if (min !== undefined && !isInteger(min, 0)) {\n check.fail(`${path}.min`, \"must be a non-negative integer\");\n }\n if (max !== undefined && !isInteger(max, 1)) {\n check.fail(`${path}.max`, \"must be a positive integer\");\n }\n if (format !== undefined && !isOneOf(format, CONSTRAINT_FORMATS)) {\n check.fail(`${path}.format`, \"is not a supported format\");\n }\n}\n\nfunction checkField(check: SetupChecker, field: unknown, path: string): void {\n if (!isRecord(field)) {\n check.fail(path, \"must be an object\");\n return;\n }\n\n const { type, label, help, placeholder, required, provider, options } = field;\n\n if (!isOneOf(type, FIELD_TYPES)) {\n check.fail(`${path}.type`, \"is not a supported field type\");\n }\n check.copy(label, `${path}.label`);\n check.copy(help, `${path}.help`);\n if (placeholder !== undefined) check.copy(placeholder, `${path}.placeholder`);\n if (\n field.default !== undefined &&\n typeof field.default !== \"string\" &&\n typeof field.default !== \"number\" &&\n typeof field.default !== \"boolean\" &&\n field.default !== null\n ) {\n check.fail(`${path}.default`, \"must be a string, number, boolean or null\");\n }\n if (typeof required !== \"boolean\") {\n check.fail(`${path}.required`, \"must be a boolean\");\n }\n if (provider !== undefined && !isOneOf(provider, GIT_PROVIDERS)) {\n check.fail(`${path}.provider`, \"is not a supported provider\");\n }\n if (type === \"repo-picker\" && provider === undefined) {\n check.fail(`${path}.provider`, \"is required for a repository field\");\n }\n // The host branches on this key to decide whether a field's value is a list,\n // so a field declaring it anywhere else would be seeded with a list and\n // rendered as a string.\n if (\n field.multiple !== undefined &&\n (field.multiple !== true || type !== \"repo-picker\")\n ) {\n check.fail(\n `${path}.multiple`,\n \"may only be true, and only on a repository field\",\n );\n }\n\n if (options !== undefined) {\n if (type !== \"select\") {\n check.fail(`${path}.options`, \"is only allowed on a select field\");\n } else if (!Array.isArray(options) || options.length === 0) {\n check.fail(`${path}.options`, \"must be a non-empty array\");\n } else {\n options.forEach((option, index) => {\n const optionPath = `${path}.options[${index}]`;\n if (!isRecord(option)) {\n check.fail(optionPath, \"must be an object\");\n return;\n }\n if (typeof option.value !== \"string\" || option.value.length === 0) {\n check.fail(`${optionPath}.value`, \"must be a non-empty string\");\n }\n check.copy(option.label, `${optionPath}.label`);\n });\n }\n }\n\n if (field.constraints !== undefined) {\n checkConstraints(check, field.constraints, `${path}.constraints`);\n }\n}\n\n/** Returns the declared field names, so the caller can check them for collisions. */\nfunction checkFields(\n check: SetupChecker,\n fields: unknown,\n path: string,\n): string[] {\n if (!isRecord(fields) || Object.keys(fields).length === 0) {\n check.fail(path, \"must be a non-empty object\");\n return [];\n }\n\n return Object.entries(fields).map(([name, field]) => {\n if (!FIELD_NAME_PATTERN.test(name)) {\n check.fail(`${path}.${name}`, \"is not a valid field name\");\n }\n checkField(check, field, `${path}.${name}`);\n return name;\n });\n}\n\n/** Returns the trigger kinds declared, in order. */\nfunction checkForm(\n check: SetupChecker,\n form: unknown,\n): { kinds: string[]; fieldNames: string[] } {\n if (!isRecord(form)) {\n check.fail(\"setup.form\", \"must be an object\");\n return { kinds: [], fieldNames: [] };\n }\n\n if (form.note !== undefined) check.copy(form.note, \"setup.form.note\");\n\n const names = checkFields(check, form.args, \"setup.form.args\");\n const kinds: string[] = [];\n\n if (form.triggers !== undefined) {\n if (!isRecord(form.triggers) || Object.keys(form.triggers).length === 0) {\n check.fail(\"setup.form.triggers\", \"must be a non-empty object\");\n } else {\n Object.entries(form.triggers).forEach(([kind, fields]) => {\n if (!isOneOf(kind, TRIGGER_KINDS)) {\n check.fail(`setup.form.triggers.${kind}`, \"is not a trigger kind\");\n return;\n }\n kinds.push(kind);\n names.push(\n ...checkFields(check, fields, `setup.form.triggers.${kind}`),\n );\n });\n }\n }\n\n // The host merges both halves into one value map, so a repeated name would\n // silently shadow a field and misaddress every error reported against it.\n const duplicates = names.filter(\n (name, index) => names.indexOf(name) !== index,\n );\n Array.from(new Set(duplicates)).forEach((name) =>\n check.fail(`setup.form.${name}`, \"is declared more than once\"),\n );\n\n return { kinds, fieldNames: names };\n}\n\nfunction checkActionFeatures(\n check: SetupChecker,\n features: unknown,\n path: string,\n): void {\n if (!Array.isArray(features) || features.length === 0) {\n check.fail(path, \"must be a non-empty array\");\n return;\n }\n features.forEach((feature, index) => {\n if (typeof feature !== \"string\" || feature.length === 0) {\n check.fail(`${path}[${index}]`, \"must be a non-empty string\");\n }\n });\n}\n\nfunction checkAction(\n check: SetupChecker,\n kind: string,\n action: unknown,\n commonFieldNames: string[],\n): void {\n const path = `setup.actions.${kind}`;\n if (!isRecord(action)) {\n check.fail(path, \"must be an object\");\n return;\n }\n\n check.copy(action.label, `${path}.label`);\n check.copy(action.help, `${path}.help`);\n checkActionFeatures(check, action.features, `${path}.features`);\n const actionFieldNames = checkFields(check, action.args, `${path}.args`);\n actionFieldNames\n .filter((name) => commonFieldNames.includes(name))\n .forEach((name) =>\n check.fail(`${path}.args.${name}`, \"is already declared by the form\"),\n );\n\n if (kind === \"prompt\") {\n check.templateValue(action.prompt, `${path}.prompt`);\n } else if (kind === \"plugin\") {\n check.templateValue(action.prompt, `${path}.prompt`);\n check.templateValue(action.plugins, `${path}.plugins`);\n } else if (kind === \"upload\") {\n check.templateValue(action.tarballPath, `${path}.tarballPath`);\n check.templateValue(action.entrypoint, `${path}.entrypoint`);\n if (action.setupScript !== undefined) {\n check.templateValue(action.setupScript, `${path}.setupScript`);\n }\n } else {\n check.fail(path, \"is not a supported action kind\");\n }\n\n const allowedByKind: Record<string, string[]> = {\n prompt: [\"label\", \"help\", \"features\", \"args\", \"prompt\"],\n plugin: [\"label\", \"help\", \"features\", \"args\", \"prompt\", \"plugins\"],\n upload: [\n \"label\",\n \"help\",\n \"features\",\n \"args\",\n \"tarballPath\",\n \"entrypoint\",\n \"setupScript\",\n ],\n };\n const allowed = allowedByKind[kind] ?? [];\n Object.keys(action)\n .filter((key) => !allowed.includes(key))\n .forEach((key) => check.fail(`${path}.${key}`, \"is not allowed\"));\n}\n\nfunction checkActions(\n check: SetupChecker,\n actions: unknown,\n commonFieldNames: string[],\n): void {\n if (!isRecord(actions) || Object.keys(actions).length === 0) {\n check.fail(\"setup.actions\", \"must be a non-empty object\");\n return;\n }\n Object.entries(actions).forEach(([kind, action]) =>\n checkAction(check, kind, action, commonFieldNames),\n );\n}\n\nfunction fieldsContainType(fields: unknown, type: string): boolean {\n if (!isRecord(fields)) return false;\n return Object.values(fields).some(\n (field) => isRecord(field) && field.type === type,\n );\n}\n\nfunction actionHasRepoPicker(action: unknown): boolean {\n return isRecord(action) && fieldsContainType(action.args, \"repo-picker\");\n}\n\n/**\n * Whether an event trigger's `source` is derivable for every selectable action.\n *\n * `buildTrigger` fills `source` from a field named `source` in the event\n * trigger, or failing that from the selected action's repo-picker provider. A\n * picker in another trigger group (such as `cron`) is never collected for the\n * event trigger, and a picker in only some actions is invisible when one of the\n * others is selected — so neither may satisfy this check, or the user can end\n * up with an empty `source` no form field can fix.\n */\nfunction setupSuppliesEventSource(setup: Rec): boolean {\n const form = isRecord(setup.form) ? setup.form : {};\n const triggers = isRecord(form.triggers) ? form.triggers : {};\n const eventFields = triggers.event;\n\n // An explicit event-source field fills `source` directly, regardless of which\n // action is selected.\n if (fieldsContainType(eventFields, \"event-source\")) return true;\n\n // A repo-picker in the event trigger is only collected when `event` is the\n // sole trigger kind; with a sibling trigger the derivation reads no trigger\n // fields for the picker. `form.args` is shared across every selection, so a\n // picker there is always available.\n const singleEventTrigger =\n \"event\" in triggers && Object.keys(triggers).length === 1;\n if (\n (singleEventTrigger && fieldsContainType(eventFields, \"repo-picker\")) ||\n fieldsContainType(form.args, \"repo-picker\")\n ) {\n return true;\n }\n\n // Without a shared or event-trigger picker, every selectable action must\n // carry its own repo-picker; otherwise selecting an action without one\n // derives `source: \"\"`.\n if (!isRecord(setup.actions) || Object.keys(setup.actions).length === 0) {\n return false;\n }\n return Object.values(setup.actions).every(actionHasRepoPicker);\n}\n\nfunction checkMessage(check: SetupChecker, message: unknown): void {\n if (check.templateCopy(message, \"setup.message\")) {\n if ((message as string).length > MAX_MESSAGE_LENGTH) {\n check.fail(\n \"setup.message\",\n `must be at most ${MAX_MESSAGE_LENGTH} characters`,\n );\n }\n }\n}\n\n/**\n * The script tarball a direct entry may ship.\n *\n * The strings here are commands and paths this host acts on, so they are held\n * to a closed character set rather than the placeholder rules copy uses: an\n * entrypoint with a shell metacharacter, or a packed path that escapes the\n * archive, is refused here rather than by the service.\n */\nfunction checkBundle(check: SetupChecker, bundle: unknown): void {\n if (!isRecord(bundle)) {\n check.fail(\"setup.bundle\", \"must be an object\");\n return;\n }\n\n if (\n typeof bundle.version !== \"string\" ||\n !TEMPLATE_VERSION_PATTERN.test(bundle.version)\n ) {\n check.fail(\"setup.bundle.version\", \"must be a semantic version\");\n }\n if (!isPlainCommand(bundle.entrypoint)) {\n check.fail(\n \"setup.bundle.entrypoint\",\n \"must be a plain command that stays inside the archive\",\n );\n }\n if (\n bundle.setupScript !== undefined &&\n !isRelativePath(bundle.setupScript, BUNDLE_PATH_PATTERN)\n ) {\n check.fail(\"setup.bundle.setupScript\", \"must be a relative path\");\n }\n if (bundle.timeout !== undefined && !isInteger(bundle.timeout, 1)) {\n check.fail(\"setup.bundle.timeout\", \"must be a positive integer\");\n }\n\n if (!isRecord(bundle.files) || Object.keys(bundle.files).length === 0) {\n check.fail(\"setup.bundle.files\", \"must be a non-empty object\");\n } else {\n Object.entries(bundle.files).forEach(([packedPath, source]) => {\n if (!isRelativePath(packedPath, BUNDLE_PATH_PATTERN)) {\n check.fail(`setup.bundle.files.${packedPath}`, \"is not a packed path\");\n }\n // The rendered config is packed under this name too, and a tar carrying\n // the name twice leaves which one the script reads to whichever\n // extractor unpacks it.\n if (packedPath === BUNDLE_CONFIG_FILENAME) {\n check.fail(\n `setup.bundle.files.${packedPath}`,\n \"is the name the rendered config is packed under\",\n );\n }\n if (!isRelativePath(source, BUNDLE_SOURCE_PATTERN)) {\n check.fail(\n `setup.bundle.files.${packedPath}`,\n \"must name a file under skills/ or automations/\",\n );\n }\n });\n\n // A setup script the archive does not carry is a create request the\n // service accepts and the first run fails on, and it is also the only\n // thing packed executable - naming an unpacked file makes that rule\n // unreachable.\n if (\n typeof bundle.setupScript === \"string\" &&\n !(bundle.setupScript in bundle.files)\n ) {\n check.fail(\"setup.bundle.setupScript\", \"must name a packed file\");\n }\n }\n\n if (!isRecord(bundle.config) || Object.keys(bundle.config).length === 0) {\n check.fail(\"setup.bundle.config\", \"must be a non-empty object\");\n } else {\n checkBundleConfig(check, bundle.config, \"setup.bundle.config\");\n }\n}\n\n/** Every string leaf of the config is a payload value: placeholders, no markup rule. */\nfunction checkBundleConfig(\n check: SetupChecker,\n node: unknown,\n path: string,\n): void {\n if (typeof node === \"string\") {\n check.templateValue(node, path);\n return;\n }\n if (Array.isArray(node)) {\n node.forEach((item, index) =>\n checkBundleConfig(check, item, `${path}[${index}]`),\n );\n return;\n }\n if (isRecord(node)) {\n Object.entries(node).forEach(([key, value]) =>\n checkBundleConfig(check, value, `${path}.${key}`),\n );\n return;\n }\n if (node !== null && typeof node !== \"number\" && typeof node !== \"boolean\") {\n check.fail(\n path,\n \"must be a string, number, boolean, null, array or object\",\n );\n }\n}\n\nfunction checkMode(\n check: SetupChecker,\n setup: Rec,\n kinds: string[],\n commonFieldNames: string[],\n): void {\n if (!isOneOf(setup.mode, SETUP_MODES)) {\n check.fail(\"setup.mode\", \"is not a supported mode\");\n return;\n }\n\n if (setup.mode === \"direct\") {\n // A direct entry produces one of three things: a prompt, a script bundle\n // the host packs and uploads, or a selectable set of action variants.\n // More than one would be ambiguous, and none is nothing to create.\n const hasPrompt = setup.prompt !== undefined;\n const hasBundle = setup.bundle !== undefined;\n const hasActions = setup.actions !== undefined;\n const variants = [hasPrompt, hasBundle, hasActions].filter(Boolean);\n if (variants.length !== 1) {\n check.fail(\n \"setup\",\n \"must declare exactly one of prompt, bundle or actions for direct setup\",\n );\n } else if (hasBundle) {\n checkBundle(check, setup.bundle);\n } else if (hasActions) {\n checkActions(check, setup.actions, commonFieldNames);\n } else {\n check.templateValue(setup.prompt, \"setup.prompt\");\n }\n // A direct entry may carry a fallback-conversation seed for deployments\n // that cannot run the direct path, held to the same rules as an assisted\n // message.\n if (setup.message !== undefined) checkMessage(check, setup.message);\n\n if (kinds.length === 0) {\n check.fail(\n \"setup.form.triggers\",\n \"must declare at least one trigger kind\",\n );\n }\n if (kinds.includes(\"event\") && !setupSuppliesEventSource(setup)) {\n check.fail(\n \"setup.form.triggers.event\",\n \"must declare an event source field or repository picker\",\n );\n }\n if (setup.filter !== undefined) {\n if (!kinds.includes(\"event\")) {\n check.fail(\"setup.filter\", \"is only allowed for an event trigger\");\n } else {\n check.templateValue(setup.filter, \"setup.filter\");\n }\n }\n return;\n }\n\n checkMessage(check, setup.message);\n check.absent(setup, \"prompt\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"bundle\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"actions\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"filter\", \"setup\", \"is only allowed for direct setup\");\n}\n\n/** Whether a catalog entry ships a setup experience at all. It is optional. */\nexport function hasSetupBlock(candidate: unknown): boolean {\n return isRecord(candidate) && candidate.setup !== undefined;\n}\n\n/**\n * Decide whether this host will act on a catalog manifest.\n *\n * The version is checked first and fails closed: a format this host does not\n * recognise is refused rather than interpreted with today's rules.\n */\nexport function validateSetupEntry(candidate: unknown): SetupValidationResult {\n const check = new SetupChecker();\n\n if (!isRecord(candidate)) {\n return { valid: false, errors: [\"manifest: must be an object\"] };\n }\n\n const { setup } = candidate;\n if (!isRecord(setup)) {\n return { valid: false, errors: [\"setup: must be an object\"] };\n }\n if (setup.version !== SETUP_VERSION) {\n return {\n valid: false,\n errors: [`setup.version: must be \"${SETUP_VERSION}\"`],\n };\n }\n\n if (\n typeof candidate.id !== \"string\" ||\n !ENTRY_ID_PATTERN.test(candidate.id)\n ) {\n check.fail(\"id\", \"must be a lowercase slug\");\n }\n check.copy(candidate.name, \"name\");\n check.copy(candidate.description, \"description\");\n if (\n candidate.version !== undefined &&\n (typeof candidate.version !== \"string\" ||\n !TEMPLATE_VERSION_PATTERN.test(candidate.version))\n ) {\n check.fail(\"version\", \"must be a semantic version\");\n }\n if (\n candidate.skill !== undefined &&\n (typeof candidate.skill !== \"string\" ||\n !ENTRY_ID_PATTERN.test(candidate.skill))\n ) {\n check.fail(\"skill\", \"must be a lowercase slug\");\n }\n\n checkRequires(check, candidate.requires);\n const { kinds, fieldNames } = checkForm(check, setup.form);\n checkMode(check, setup, kinds, fieldNames);\n\n return { valid: check.errors.length === 0, errors: check.errors };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manifest-validation.js","names":[],"sources":["../../src/manifests/manifest-validation.ts"],"sourcesContent":["/**\n * Admission policy for extension-authored catalog manifests.\n *\n * A manifest is data authored in a different repository that instructs this host\n * to render copy and compose a request. The host therefore decides what a\n * manifest is *permitted* to do rather than trusting the file — validation here\n * is a trust boundary, not a convenience check, and it deliberately does not\n * defer to a schema shipped alongside the manifests it would be validating.\n *\n * Beyond mirroring the published schema, this adds the invariants the host's own\n * derivation depends on: a single trigger kind to read, a repository field for\n * an event trigger's source, and field names unique across the form. Without\n * them the derived request body would be silently wrong rather than rejected.\n *\n * A manifest that fails any check is rejected outright. It never renders a\n * partial UI, because everything downstream treats its content as instructions.\n */\n\nimport {\n BUNDLE_CONFIG_FILENAME,\n SETUP_PLACEHOLDER_NAMESPACES,\n SETUP_VERSION,\n} from \"./types\";\n\nconst ENTRY_ID_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;\nconst FIELD_NAME_PATTERN = /^[a-z][A-Za-z0-9]*$/;\n/** Copy must never be able to inject markup into the host. */\nconst MARKUP_PATTERN = /<[A-Za-z/!]/;\n/**\n * A template version, declared as `version` by a prompt entry and as\n * `setup.bundle.version` by a bundle one. Sent to the service as template\n * provenance, so it is checked at admission. Full semver, as the spec at\n * semver.org states it: a catalog entry published with a pre-release or build\n * suffix is still a version this host may forward, and refusing one would drop\n * the entry from the registry outright.\n */\nconst TEMPLATE_VERSION_PATTERN =\n /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(?:\\+[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*)?$/;\n// The characters a command of plain words and paths is made of. No shell\n// metacharacters, which the service rejects anyway and a bundle has no reason\n// to need; where those words may point is `isPlainCommand`'s to say.\nconst BUNDLE_COMMAND_PATTERN = /^[A-Za-z0-9 ._/-]+$/;\nconst BUNDLE_PATH_PATTERN = /^[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*$/;\nconst BUNDLE_SOURCE_PATTERN =\n /^(skills|automations|plugins)\\/[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*$/;\n/** Every `{{` must open a known namespace and close immediately. */\nconst UNKNOWN_PLACEHOLDER_PATTERN = new RegExp(\n `\\\\{\\\\{(?!(?:${SETUP_PLACEHOLDER_NAMESPACES.join(\"|\")})\\\\.[A-Za-z0-9_.]+\\\\}\\\\})`,\n);\n\nconst SETUP_MODES = [\"direct\", \"assisted\"] as const;\nconst FIELD_TYPES = [\n \"text\",\n \"textarea\",\n \"select\",\n \"number\",\n \"cron\",\n \"timezone\",\n \"repo-picker\",\n \"llm-profile\",\n \"event-source\",\n \"event-type\",\n \"plugin-sources\",\n \"tarball-upload\",\n] as const;\nconst GIT_PROVIDERS = [\"github\", \"gitlab\", \"bitbucket\"] as const;\nconst TRIGGER_KINDS = [\"cron\", \"event\"] as const;\nconst CONSTRAINT_FORMATS = [\"safeExpressionLiteral\"] as const;\n\n/** Setup context only, so this can never become a channel for runtime instructions. */\nconst MAX_MESSAGE_LENGTH = 2000;\n\nexport interface SetupValidationResult {\n valid: boolean;\n errors: string[];\n}\n\ntype Rec = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Rec {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOneOf<T extends readonly string[]>(\n value: unknown,\n allowed: T,\n): value is T[number] {\n return (\n typeof value === \"string\" && (allowed as readonly string[]).includes(value)\n );\n}\n\nfunction isInteger(value: unknown, minimum: number): boolean {\n return (\n typeof value === \"number\" && Number.isInteger(value) && value >= minimum\n );\n}\n\nclass SetupChecker {\n readonly errors: string[] = [];\n\n fail(path: string, reason: string): false {\n this.errors.push(`${path}: ${reason}`);\n return false;\n }\n\n /** Literal user-visible copy. Carries no markup. */\n copy(value: unknown, path: string): boolean {\n if (typeof value !== \"string\" || value.length === 0) {\n return this.fail(path, \"must be a non-empty string\");\n }\n if (MARKUP_PATTERN.test(value)) {\n return this.fail(path, \"must not contain markup\");\n }\n return true;\n }\n\n placeholders(value: string, path: string): boolean {\n if (UNKNOWN_PLACEHOLDER_PATTERN.test(value)) {\n return this.fail(path, \"uses an unknown placeholder namespace\");\n }\n return true;\n }\n\n /** Copy that may embed `{{namespace.key}}` placeholders. */\n templateCopy(value: unknown, path: string): boolean {\n return this.copy(value, path) && this.placeholders(value as string, path);\n }\n\n /**\n * A request-body string that may embed placeholders. Never rendered, so\n * expression syntax such as a JMESPath filter is allowed through.\n */\n templateValue(value: unknown, path: string): boolean {\n if (typeof value !== \"string\" || value.length === 0) {\n return this.fail(path, \"must be a non-empty string\");\n }\n return this.placeholders(value, path);\n }\n\n absent(container: Rec, key: string, path: string, reason: string): boolean {\n if (key in container) return this.fail(`${path}.${key}`, reason);\n return true;\n }\n}\n\n/**\n * A relative path that stays inside the archive it names.\n *\n * The character class alone is not enough: `.` and `..` are made of allowed\n * characters, so a segment check is what actually keeps a packed file from\n * climbing out of the directory it is extracted into.\n */\nfunction isRelativePath(value: unknown, pattern: RegExp): value is string {\n return (\n typeof value === \"string\" &&\n pattern.test(value) &&\n !value.split(\"/\").some((segment) => segment === \".\" || segment === \"..\")\n );\n}\n\n/**\n * A command whose every word stays inside the archive it is run in.\n *\n * The character class is not what keeps it there: `/` and `.` are allowed\n * characters, so `/bin/sh setup.sh` and `python3 ../../etc/x.py` are made of\n * them and each names something outside the extracted directory. The segment\n * rule packed paths are held to is what refuses those, and requiring a word at\n * all is what refuses an entrypoint of nothing but spaces.\n */\nfunction isPlainCommand(value: unknown): value is string {\n if (typeof value !== \"string\" || !BUNDLE_COMMAND_PATTERN.test(value)) {\n return false;\n }\n const words = value.split(\" \").filter((word) => word.length > 0);\n return (\n words.length > 0 &&\n words.every(\n (word) =>\n !word.startsWith(\"/\") &&\n !word.split(\"/\").some((segment) => segment === \"..\"),\n )\n );\n}\n\nfunction checkRequires(check: SetupChecker, requires: unknown): void {\n if (!isRecord(requires)) {\n check.fail(\"requires\", \"must be an object\");\n return;\n }\n\n const { integrations, features } = requires;\n // Empty is meaningful rather than malformed: an automation that needs no\n // credential connects to nothing, and the key stays required so that saying\n // so is a deliberate statement instead of an omission.\n if (!isRecord(integrations)) {\n check.fail(\"requires.integrations\", \"must be an object\");\n } else {\n Object.entries(integrations).forEach(([id, requirement]) => {\n const path = `requires.integrations.${id}`;\n if (!isRecord(requirement)) {\n check.fail(path, \"must be an object\");\n return;\n }\n check.copy(requirement.message, `${path}.message`);\n if (\"required\" in requirement && requirement.required !== false) {\n check.fail(`${path}.required`, \"may only be false\");\n }\n const allowed = [\"message\", \"required\"];\n Object.keys(requirement)\n .filter((key) => !allowed.includes(key))\n .forEach((key) => check.fail(`${path}.${key}`, \"is not allowed\"));\n });\n }\n\n if (features !== undefined) {\n if (!Array.isArray(features) || features.length === 0) {\n check.fail(\"requires.features\", \"must be a non-empty array\");\n } else {\n features.forEach((feature, index) => {\n if (typeof feature !== \"string\" || feature.length === 0) {\n check.fail(\n `requires.features[${index}]`,\n \"must be a non-empty string\",\n );\n }\n });\n }\n }\n}\n\nfunction checkConstraints(\n check: SetupChecker,\n constraints: unknown,\n path: string,\n): void {\n if (!isRecord(constraints) || Object.keys(constraints).length === 0) {\n check.fail(path, \"must be a non-empty object\");\n return;\n }\n\n const { minLength, maxLength, min, max, format } = constraints;\n if (minLength !== undefined && !isInteger(minLength, 0)) {\n check.fail(`${path}.minLength`, \"must be a non-negative integer\");\n }\n if (maxLength !== undefined && !isInteger(maxLength, 1)) {\n check.fail(`${path}.maxLength`, \"must be a positive integer\");\n }\n if (min !== undefined && !isInteger(min, 0)) {\n check.fail(`${path}.min`, \"must be a non-negative integer\");\n }\n if (max !== undefined && !isInteger(max, 1)) {\n check.fail(`${path}.max`, \"must be a positive integer\");\n }\n if (format !== undefined && !isOneOf(format, CONSTRAINT_FORMATS)) {\n check.fail(`${path}.format`, \"is not a supported format\");\n }\n}\n\nfunction checkField(check: SetupChecker, field: unknown, path: string): void {\n if (!isRecord(field)) {\n check.fail(path, \"must be an object\");\n return;\n }\n\n const { type, label, help, placeholder, required, provider, options } = field;\n\n if (!isOneOf(type, FIELD_TYPES)) {\n check.fail(`${path}.type`, \"is not a supported field type\");\n }\n check.copy(label, `${path}.label`);\n check.copy(help, `${path}.help`);\n if (placeholder !== undefined) check.copy(placeholder, `${path}.placeholder`);\n if (\n field.default !== undefined &&\n typeof field.default !== \"string\" &&\n typeof field.default !== \"number\" &&\n typeof field.default !== \"boolean\" &&\n field.default !== null\n ) {\n check.fail(`${path}.default`, \"must be a string, number, boolean or null\");\n }\n if (typeof required !== \"boolean\") {\n check.fail(`${path}.required`, \"must be a boolean\");\n }\n if (provider !== undefined && !isOneOf(provider, GIT_PROVIDERS)) {\n check.fail(`${path}.provider`, \"is not a supported provider\");\n }\n if (type === \"repo-picker\" && provider === undefined) {\n check.fail(`${path}.provider`, \"is required for a repository field\");\n }\n // The host branches on this key to decide whether a field's value is a list,\n // so a field declaring it anywhere else would be seeded with a list and\n // rendered as a string.\n if (\n field.multiple !== undefined &&\n (field.multiple !== true || type !== \"repo-picker\")\n ) {\n check.fail(\n `${path}.multiple`,\n \"may only be true, and only on a repository field\",\n );\n }\n\n if (options !== undefined) {\n if (type !== \"select\") {\n check.fail(`${path}.options`, \"is only allowed on a select field\");\n } else if (!Array.isArray(options) || options.length === 0) {\n check.fail(`${path}.options`, \"must be a non-empty array\");\n } else {\n options.forEach((option, index) => {\n const optionPath = `${path}.options[${index}]`;\n if (!isRecord(option)) {\n check.fail(optionPath, \"must be an object\");\n return;\n }\n if (typeof option.value !== \"string\" || option.value.length === 0) {\n check.fail(`${optionPath}.value`, \"must be a non-empty string\");\n }\n check.copy(option.label, `${optionPath}.label`);\n });\n }\n }\n\n if (field.constraints !== undefined) {\n checkConstraints(check, field.constraints, `${path}.constraints`);\n }\n}\n\n/** Returns the declared field names, so the caller can check them for collisions. */\nfunction checkFields(\n check: SetupChecker,\n fields: unknown,\n path: string,\n): string[] {\n if (!isRecord(fields) || Object.keys(fields).length === 0) {\n check.fail(path, \"must be a non-empty object\");\n return [];\n }\n\n return Object.entries(fields).map(([name, field]) => {\n if (!FIELD_NAME_PATTERN.test(name)) {\n check.fail(`${path}.${name}`, \"is not a valid field name\");\n }\n checkField(check, field, `${path}.${name}`);\n return name;\n });\n}\n\n/** Returns the trigger kinds declared, in order. */\nfunction checkForm(\n check: SetupChecker,\n form: unknown,\n): { kinds: string[]; fieldNames: string[] } {\n if (!isRecord(form)) {\n check.fail(\"setup.form\", \"must be an object\");\n return { kinds: [], fieldNames: [] };\n }\n\n if (form.note !== undefined) check.copy(form.note, \"setup.form.note\");\n\n const names = checkFields(check, form.args, \"setup.form.args\");\n const kinds: string[] = [];\n\n if (form.triggers !== undefined) {\n if (!isRecord(form.triggers) || Object.keys(form.triggers).length === 0) {\n check.fail(\"setup.form.triggers\", \"must be a non-empty object\");\n } else {\n Object.entries(form.triggers).forEach(([kind, fields]) => {\n if (!isOneOf(kind, TRIGGER_KINDS)) {\n check.fail(`setup.form.triggers.${kind}`, \"is not a trigger kind\");\n return;\n }\n kinds.push(kind);\n names.push(\n ...checkFields(check, fields, `setup.form.triggers.${kind}`),\n );\n });\n }\n }\n\n // The host merges both halves into one value map, so a repeated name would\n // silently shadow a field and misaddress every error reported against it.\n const duplicates = names.filter(\n (name, index) => names.indexOf(name) !== index,\n );\n Array.from(new Set(duplicates)).forEach((name) =>\n check.fail(`setup.form.${name}`, \"is declared more than once\"),\n );\n\n return { kinds, fieldNames: names };\n}\n\nfunction checkActionFeatures(\n check: SetupChecker,\n features: unknown,\n path: string,\n): void {\n if (!Array.isArray(features) || features.length === 0) {\n check.fail(path, \"must be a non-empty array\");\n return;\n }\n features.forEach((feature, index) => {\n if (typeof feature !== \"string\" || feature.length === 0) {\n check.fail(`${path}[${index}]`, \"must be a non-empty string\");\n }\n });\n}\n\nfunction checkAction(\n check: SetupChecker,\n kind: string,\n action: unknown,\n commonFieldNames: string[],\n): void {\n const path = `setup.actions.${kind}`;\n if (!isRecord(action)) {\n check.fail(path, \"must be an object\");\n return;\n }\n\n check.copy(action.label, `${path}.label`);\n check.copy(action.help, `${path}.help`);\n checkActionFeatures(check, action.features, `${path}.features`);\n const actionFieldNames = checkFields(check, action.args, `${path}.args`);\n actionFieldNames\n .filter((name) => commonFieldNames.includes(name))\n .forEach((name) =>\n check.fail(`${path}.args.${name}`, \"is already declared by the form\"),\n );\n\n if (kind === \"prompt\") {\n check.templateValue(action.prompt, `${path}.prompt`);\n } else if (kind === \"plugin\") {\n check.templateValue(action.prompt, `${path}.prompt`);\n check.templateValue(action.plugins, `${path}.plugins`);\n } else if (kind === \"upload\") {\n check.templateValue(action.tarballPath, `${path}.tarballPath`);\n check.templateValue(action.entrypoint, `${path}.entrypoint`);\n if (action.setupScript !== undefined) {\n check.templateValue(action.setupScript, `${path}.setupScript`);\n }\n } else {\n check.fail(path, \"is not a supported action kind\");\n }\n\n const allowedByKind: Record<string, string[]> = {\n prompt: [\"label\", \"help\", \"features\", \"args\", \"prompt\"],\n plugin: [\"label\", \"help\", \"features\", \"args\", \"prompt\", \"plugins\"],\n upload: [\n \"label\",\n \"help\",\n \"features\",\n \"args\",\n \"tarballPath\",\n \"entrypoint\",\n \"setupScript\",\n ],\n };\n const allowed = allowedByKind[kind] ?? [];\n Object.keys(action)\n .filter((key) => !allowed.includes(key))\n .forEach((key) => check.fail(`${path}.${key}`, \"is not allowed\"));\n}\n\nfunction checkActions(\n check: SetupChecker,\n actions: unknown,\n commonFieldNames: string[],\n): void {\n if (!isRecord(actions) || Object.keys(actions).length === 0) {\n check.fail(\"setup.actions\", \"must be a non-empty object\");\n return;\n }\n Object.entries(actions).forEach(([kind, action]) =>\n checkAction(check, kind, action, commonFieldNames),\n );\n}\n\nfunction fieldsContainType(fields: unknown, type: string): boolean {\n if (!isRecord(fields)) return false;\n return Object.values(fields).some(\n (field) => isRecord(field) && field.type === type,\n );\n}\n\nfunction actionHasRepoPicker(action: unknown): boolean {\n return isRecord(action) && fieldsContainType(action.args, \"repo-picker\");\n}\n\n/**\n * Whether an event trigger's `source` is derivable for every selectable action.\n *\n * `buildTrigger` fills `source` from a field named `source` in the event\n * trigger, or failing that from the selected action's repo-picker provider. A\n * picker in another trigger group (such as `cron`) is never collected for the\n * event trigger, and a picker in only some actions is invisible when one of the\n * others is selected — so neither may satisfy this check, or the user can end\n * up with an empty `source` no form field can fix.\n */\nfunction setupSuppliesEventSource(setup: Rec): boolean {\n const form = isRecord(setup.form) ? setup.form : {};\n const triggers = isRecord(form.triggers) ? form.triggers : {};\n const eventFields = triggers.event;\n\n // An explicit event-source field fills `source` directly, regardless of which\n // action is selected.\n if (fieldsContainType(eventFields, \"event-source\")) return true;\n\n // A repo-picker in the event trigger is only collected when `event` is the\n // sole trigger kind; with a sibling trigger the derivation reads no trigger\n // fields for the picker. `form.args` is shared across every selection, so a\n // picker there is always available.\n const singleEventTrigger =\n \"event\" in triggers && Object.keys(triggers).length === 1;\n if (\n (singleEventTrigger && fieldsContainType(eventFields, \"repo-picker\")) ||\n fieldsContainType(form.args, \"repo-picker\")\n ) {\n return true;\n }\n\n // Without a shared or event-trigger picker, every selectable action must\n // carry its own repo-picker; otherwise selecting an action without one\n // derives `source: \"\"`.\n if (!isRecord(setup.actions) || Object.keys(setup.actions).length === 0) {\n return false;\n }\n return Object.values(setup.actions).every(actionHasRepoPicker);\n}\n\nfunction checkMessage(check: SetupChecker, message: unknown): void {\n if (check.templateCopy(message, \"setup.message\")) {\n if ((message as string).length > MAX_MESSAGE_LENGTH) {\n check.fail(\n \"setup.message\",\n `must be at most ${MAX_MESSAGE_LENGTH} characters`,\n );\n }\n }\n}\n\n/**\n * The script tarball a direct entry may ship.\n *\n * The strings here are commands and paths this host acts on, so they are held\n * to a closed character set rather than the placeholder rules copy uses: an\n * entrypoint with a shell metacharacter, or a packed path that escapes the\n * archive, is refused here rather than by the service.\n */\nfunction checkBundle(check: SetupChecker, bundle: unknown): void {\n if (!isRecord(bundle)) {\n check.fail(\"setup.bundle\", \"must be an object\");\n return;\n }\n\n if (\n typeof bundle.version !== \"string\" ||\n !TEMPLATE_VERSION_PATTERN.test(bundle.version)\n ) {\n check.fail(\"setup.bundle.version\", \"must be a semantic version\");\n }\n if (!isPlainCommand(bundle.entrypoint)) {\n check.fail(\n \"setup.bundle.entrypoint\",\n \"must be a plain command that stays inside the archive\",\n );\n }\n if (\n bundle.setupScript !== undefined &&\n !isRelativePath(bundle.setupScript, BUNDLE_PATH_PATTERN)\n ) {\n check.fail(\"setup.bundle.setupScript\", \"must be a relative path\");\n }\n if (bundle.timeout !== undefined && !isInteger(bundle.timeout, 1)) {\n check.fail(\"setup.bundle.timeout\", \"must be a positive integer\");\n }\n\n if (!isRecord(bundle.files) || Object.keys(bundle.files).length === 0) {\n check.fail(\"setup.bundle.files\", \"must be a non-empty object\");\n } else {\n Object.entries(bundle.files).forEach(([packedPath, source]) => {\n if (!isRelativePath(packedPath, BUNDLE_PATH_PATTERN)) {\n check.fail(`setup.bundle.files.${packedPath}`, \"is not a packed path\");\n }\n // The rendered config is packed under this name too, and a tar carrying\n // the name twice leaves which one the script reads to whichever\n // extractor unpacks it.\n if (packedPath === BUNDLE_CONFIG_FILENAME) {\n check.fail(\n `setup.bundle.files.${packedPath}`,\n \"is the name the rendered config is packed under\",\n );\n }\n if (!isRelativePath(source, BUNDLE_SOURCE_PATTERN)) {\n check.fail(\n `setup.bundle.files.${packedPath}`,\n \"must name a file under skills/, automations/, or plugins/\",\n );\n }\n });\n\n // A setup script the archive does not carry is a create request the\n // service accepts and the first run fails on, and it is also the only\n // thing packed executable - naming an unpacked file makes that rule\n // unreachable.\n if (\n typeof bundle.setupScript === \"string\" &&\n !(bundle.setupScript in bundle.files)\n ) {\n check.fail(\"setup.bundle.setupScript\", \"must name a packed file\");\n }\n }\n\n if (!isRecord(bundle.config) || Object.keys(bundle.config).length === 0) {\n check.fail(\"setup.bundle.config\", \"must be a non-empty object\");\n } else {\n checkBundleConfig(check, bundle.config, \"setup.bundle.config\");\n }\n}\n\n/** Every string leaf of the config is a payload value: placeholders, no markup rule. */\nfunction checkBundleConfig(\n check: SetupChecker,\n node: unknown,\n path: string,\n): void {\n if (typeof node === \"string\") {\n check.templateValue(node, path);\n return;\n }\n if (Array.isArray(node)) {\n node.forEach((item, index) =>\n checkBundleConfig(check, item, `${path}[${index}]`),\n );\n return;\n }\n if (isRecord(node)) {\n Object.entries(node).forEach(([key, value]) =>\n checkBundleConfig(check, value, `${path}.${key}`),\n );\n return;\n }\n if (node !== null && typeof node !== \"number\" && typeof node !== \"boolean\") {\n check.fail(\n path,\n \"must be a string, number, boolean, null, array or object\",\n );\n }\n}\n\nfunction checkMode(\n check: SetupChecker,\n setup: Rec,\n kinds: string[],\n commonFieldNames: string[],\n): void {\n if (!isOneOf(setup.mode, SETUP_MODES)) {\n check.fail(\"setup.mode\", \"is not a supported mode\");\n return;\n }\n\n if (setup.mode === \"direct\") {\n // A direct entry produces one of three things: a prompt, a script bundle\n // the host packs and uploads, or a selectable set of action variants.\n // More than one would be ambiguous, and none is nothing to create.\n const hasPrompt = setup.prompt !== undefined;\n const hasBundle = setup.bundle !== undefined;\n const hasActions = setup.actions !== undefined;\n const variants = [hasPrompt, hasBundle, hasActions].filter(Boolean);\n if (variants.length !== 1) {\n check.fail(\n \"setup\",\n \"must declare exactly one of prompt, bundle or actions for direct setup\",\n );\n } else if (hasBundle) {\n checkBundle(check, setup.bundle);\n } else if (hasActions) {\n checkActions(check, setup.actions, commonFieldNames);\n } else {\n check.templateValue(setup.prompt, \"setup.prompt\");\n }\n // A direct entry may carry a fallback-conversation seed for deployments\n // that cannot run the direct path, held to the same rules as an assisted\n // message.\n if (setup.message !== undefined) checkMessage(check, setup.message);\n\n if (kinds.length === 0) {\n check.fail(\n \"setup.form.triggers\",\n \"must declare at least one trigger kind\",\n );\n }\n if (kinds.includes(\"event\") && !setupSuppliesEventSource(setup)) {\n check.fail(\n \"setup.form.triggers.event\",\n \"must declare an event source field or repository picker\",\n );\n }\n if (setup.filter !== undefined) {\n if (!kinds.includes(\"event\")) {\n check.fail(\"setup.filter\", \"is only allowed for an event trigger\");\n } else {\n check.templateValue(setup.filter, \"setup.filter\");\n }\n }\n return;\n }\n\n checkMessage(check, setup.message);\n check.absent(setup, \"prompt\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"bundle\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"actions\", \"setup\", \"is only allowed for direct setup\");\n check.absent(setup, \"filter\", \"setup\", \"is only allowed for direct setup\");\n}\n\n/** Whether a catalog entry ships a setup experience at all. It is optional. */\nexport function hasSetupBlock(candidate: unknown): boolean {\n return isRecord(candidate) && candidate.setup !== undefined;\n}\n\n/**\n * Decide whether this host will act on a catalog manifest.\n *\n * The version is checked first and fails closed: a format this host does not\n * recognise is refused rather than interpreted with today's rules.\n */\nexport function validateSetupEntry(candidate: unknown): SetupValidationResult {\n const check = new SetupChecker();\n\n if (!isRecord(candidate)) {\n return { valid: false, errors: [\"manifest: must be an object\"] };\n }\n\n const { setup } = candidate;\n if (!isRecord(setup)) {\n return { valid: false, errors: [\"setup: must be an object\"] };\n }\n if (setup.version !== SETUP_VERSION) {\n return {\n valid: false,\n errors: [`setup.version: must be \"${SETUP_VERSION}\"`],\n };\n }\n\n if (\n typeof candidate.id !== \"string\" ||\n !ENTRY_ID_PATTERN.test(candidate.id)\n ) {\n check.fail(\"id\", \"must be a lowercase slug\");\n }\n check.copy(candidate.name, \"name\");\n check.copy(candidate.description, \"description\");\n if (\n candidate.version !== undefined &&\n (typeof candidate.version !== \"string\" ||\n !TEMPLATE_VERSION_PATTERN.test(candidate.version))\n ) {\n check.fail(\"version\", \"must be a semantic version\");\n }\n if (\n candidate.skill !== undefined &&\n (typeof candidate.skill !== \"string\" ||\n !ENTRY_ID_PATTERN.test(candidate.skill))\n ) {\n check.fail(\"skill\", \"must be a lowercase slug\");\n }\n\n checkRequires(check, candidate.requires);\n const { kinds, fieldNames } = checkForm(check, setup.form);\n checkMode(check, setup, kinds, fieldNames);\n\n return { valid: check.errors.length === 0, errors: check.errors };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- require("../../../../../_virtual/_rolldown/runtime.cjs");var e=`AGENT_SERVER_VERSION_TOO_OLD`,t={workspaces:{feature:`workspaces`,displayName:`Workspaces`,minVersion:`1.23.0`},hooks:{feature:`hooks`,displayName:`Hooks API`,minVersion:`1.23.0`},mcpTest:{feature:`mcp-test`,displayName:`MCP test API`,minVersion:`1.23.0`},mcpOAuth:{feature:`mcp-oauth`,displayName:`MCP OAuth API`,minVersion:`1.31.0`}},n=class t extends Error{constructor({requirement:n,actualVersion:r}){super(`${n.displayName} requires agent-server ${n.minVersion} or newer; this backend is running ${r}. Please upgrade your agent-server backend.`),this.code=e,this.name=`AgentServerVersionError`,this.feature=n.feature,this.displayName=n.displayName,this.requiredVersion=n.minVersion,this.actualVersion=r,Object.setPrototypeOf(this,t.prototype)}},r=new WeakMap;function i(e){return e instanceof n||typeof e==`object`&&!!e&&`code`in e&&e.code===`AGENT_SERVER_VERSION_TOO_OLD`}async function a(e){let t=r.get(e);if(t)return t;let n=e.get(`/server_info`).then(e=>e.data);return r.set(e,n),n}async function o(e,t){let r=await a(e),i=typeof r.version==`string`&&r.version.trim()?r.version.trim():`unknown`,o=s(i,t.minVersion);if(o===null||o<0)throw new n({requirement:t,actualVersion:i});return r}function s(e,t){let n=c(e),r=c(t);if(!n||!r)return null;for(let e of[`major`,`minor`,`patch`]){if(n[e]>r[e])return 1;if(n[e]<r[e])return-1}return n.prerelease&&!r.prerelease?-1:!n.prerelease&&r.prerelease?1:n.prerelease&&r.prerelease?n.prerelease.localeCompare(r.prerelease):0}function c(e){let[t]=e.trim().replace(/^v/,``).split(`+`),[n,r]=t.split(`-`,2),i=n.split(`.`);if(i.length!==3)return null;let[a,o,s]=i.map(e=>Number(e));return[a,o,s].every(e=>Number.isInteger(e)&&e>=0)?{major:a,minor:o,patch:s,prerelease:r}:null}exports.AGENT_SERVER_VERSION_ERROR_CODE=e,exports.AgentServerFeatureRequirements=t,exports.AgentServerVersionError=n,exports.assertAgentServerSupports=o,exports.compareAgentServerVersions=s,exports.getCachedAgentServerInfo=a,exports.isAgentServerVersionError=i;
1
+ require("../../../../../_virtual/_rolldown/runtime.cjs");var e=`AGENT_SERVER_VERSION_TOO_OLD`,t={workspaces:{feature:`workspaces`,displayName:`Workspaces`,minVersion:`1.23.0`},hooks:{feature:`hooks`,displayName:`Hooks API`,minVersion:`1.23.0`},mcpTest:{feature:`mcp-test`,displayName:`MCP test API`,minVersion:`1.23.0`},mcpOAuth:{feature:`mcp-oauth`,displayName:`MCP OAuth API`,minVersion:`1.31.0`}},n=class t extends Error{constructor({requirement:n,actualVersion:r}){super(`${n.displayName} requires agent-server ${n.minVersion} or newer; this backend is running ${r}. Please upgrade your agent-server backend.`),this.code=e,this.name=`AgentServerVersionError`,this.feature=n.feature,this.displayName=n.displayName,this.requiredVersion=n.minVersion,this.actualVersion=r,Object.setPrototypeOf(this,t.prototype)}},r=new WeakMap;function i(e){return e instanceof n||typeof e==`object`&&!!e&&`code`in e&&e.code===`AGENT_SERVER_VERSION_TOO_OLD`}function a(e){if(e){r.delete(e);return}r=new WeakMap}async function o(e){let t=r.get(e);if(t)return t;let n=e.get(`/server_info`).then(e=>e.data);return r.set(e,n),n}async function s(e,t){let r=await o(e),i=typeof r.version==`string`&&r.version.trim()?r.version.trim():`unknown`,a=c(i,t.minVersion);if(a===null||a<0)throw new n({requirement:t,actualVersion:i});return r}function c(e,t){let n=l(e),r=l(t);if(!n||!r)return null;for(let e of[`major`,`minor`,`patch`]){if(n[e]>r[e])return 1;if(n[e]<r[e])return-1}return n.prerelease&&!r.prerelease?-1:!n.prerelease&&r.prerelease?1:n.prerelease&&r.prerelease?n.prerelease.localeCompare(r.prerelease):0}function l(e){let[t]=e.trim().replace(/^v/,``).split(`+`),[n,r]=t.split(`-`,2),i=n.split(`.`);if(i.length!==3)return null;let[a,o,s]=i.map(e=>Number(e));return[a,o,s].every(e=>Number.isInteger(e)&&e>=0)?{major:a,minor:o,patch:s,prerelease:r}:null}exports.AGENT_SERVER_VERSION_ERROR_CODE=e,exports.AgentServerFeatureRequirements=t,exports.AgentServerVersionError=n,exports.assertAgentServerSupports=s,exports.clearAgentServerInfoCache=a,exports.compareAgentServerVersions=c,exports.getCachedAgentServerInfo=o,exports.isAgentServerVersionError=i;
2
2
  //# sourceMappingURL=agent-server-compatibility.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-server-compatibility.cjs","names":[],"sources":["../../../../../../node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js"],"sourcesContent":["export const AGENT_SERVER_VERSION_ERROR_CODE = 'AGENT_SERVER_VERSION_TOO_OLD';\nexport const AgentServerFeatureRequirements = {\n workspaces: {\n feature: 'workspaces',\n displayName: 'Workspaces',\n minVersion: '1.23.0',\n },\n hooks: {\n feature: 'hooks',\n displayName: 'Hooks API',\n minVersion: '1.23.0',\n },\n mcpTest: {\n feature: 'mcp-test',\n displayName: 'MCP test API',\n minVersion: '1.23.0',\n },\n mcpOAuth: {\n feature: 'mcp-oauth',\n displayName: 'MCP OAuth API',\n minVersion: '1.31.0',\n },\n};\nexport class AgentServerVersionError extends Error {\n constructor({ requirement, actualVersion, }) {\n super(`${requirement.displayName} requires agent-server ${requirement.minVersion} or newer; this backend is running ${actualVersion}. Please upgrade your agent-server backend.`);\n this.code = AGENT_SERVER_VERSION_ERROR_CODE;\n this.name = 'AgentServerVersionError';\n this.feature = requirement.feature;\n this.displayName = requirement.displayName;\n this.requiredVersion = requirement.minVersion;\n this.actualVersion = actualVersion;\n Object.setPrototypeOf(this, AgentServerVersionError.prototype);\n }\n}\nlet serverInfoCache = new WeakMap();\nexport function isAgentServerVersionError(error) {\n return (error instanceof AgentServerVersionError ||\n (typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === AGENT_SERVER_VERSION_ERROR_CODE));\n}\nexport function clearAgentServerInfoCache(client) {\n if (client) {\n serverInfoCache.delete(client);\n return;\n }\n serverInfoCache = new WeakMap();\n}\nexport async function getCachedAgentServerInfo(client) {\n const cached = serverInfoCache.get(client);\n if (cached) {\n return cached;\n }\n const request = client.get('/server_info').then((response) => response.data);\n serverInfoCache.set(client, request);\n return request;\n}\nexport async function assertAgentServerSupports(client, requirement) {\n const serverInfo = await getCachedAgentServerInfo(client);\n const actualVersion = typeof serverInfo.version === 'string' && serverInfo.version.trim()\n ? serverInfo.version.trim()\n : 'unknown';\n const comparison = compareAgentServerVersions(actualVersion, requirement.minVersion);\n if (comparison === null || comparison < 0) {\n throw new AgentServerVersionError({ requirement, actualVersion });\n }\n return serverInfo;\n}\nexport function compareAgentServerVersions(actual, required) {\n const parsedActual = parseAgentServerVersion(actual);\n const parsedRequired = parseAgentServerVersion(required);\n if (!parsedActual || !parsedRequired) {\n return null;\n }\n for (const key of ['major', 'minor', 'patch']) {\n if (parsedActual[key] > parsedRequired[key]) {\n return 1;\n }\n if (parsedActual[key] < parsedRequired[key]) {\n return -1;\n }\n }\n if (parsedActual.prerelease && !parsedRequired.prerelease) {\n return -1;\n }\n if (!parsedActual.prerelease && parsedRequired.prerelease) {\n return 1;\n }\n if (parsedActual.prerelease && parsedRequired.prerelease) {\n return parsedActual.prerelease.localeCompare(parsedRequired.prerelease);\n }\n return 0;\n}\nfunction parseAgentServerVersion(version) {\n const trimmed = version.trim().replace(/^v/, '');\n const [withoutBuild] = trimmed.split('+');\n const [core, prerelease] = withoutBuild.split('-', 2);\n const parts = core.split('.');\n if (parts.length !== 3) {\n return null;\n }\n const [major, minor, patch] = parts.map((part) => Number(part));\n if (![major, minor, patch].every((part) => Number.isInteger(part) && part >= 0)) {\n return null;\n }\n return { major, minor, patch, prerelease };\n}\n//# sourceMappingURL=agent-server-compatibility.js.map"],"x_google_ignoreList":[0],"mappings":"yDAAA,IAAa,EAAkC,+BAClC,EAAiC,CAC1C,WAAY,CACR,QAAS,aACT,YAAa,aACb,WAAY,QAChB,EACA,MAAO,CACH,QAAS,QACT,YAAa,YACb,WAAY,QAChB,EACA,QAAS,CACL,QAAS,WACT,YAAa,eACb,WAAY,QAChB,EACA,SAAU,CACN,QAAS,YACT,YAAa,gBACb,WAAY,QAChB,CACJ,EACa,EAAb,MAAa,UAAgC,KAAM,CAC/C,YAAY,CAAE,cAAa,iBAAkB,CACzC,MAAM,GAAG,EAAY,YAAY,yBAAyB,EAAY,WAAW,qCAAqC,EAAc,4CAA4C,EAChL,KAAK,KAAO,EACZ,KAAK,KAAO,0BACZ,KAAK,QAAU,EAAY,QAC3B,KAAK,YAAc,EAAY,YAC/B,KAAK,gBAAkB,EAAY,WACnC,KAAK,cAAgB,EACrB,OAAO,eAAe,KAAM,EAAwB,SAAS,CACjE,CACJ,EACI,EAAkB,IAAI,QAC1B,SAAgB,EAA0B,EAAO,CAC7C,OAAQ,aAAiB,GACpB,OAAO,GAAU,YACd,GACA,SAAU,GACV,EAAM,OAAA,8BAClB,CAQA,eAAsB,EAAyB,EAAQ,CACnD,IAAM,EAAS,EAAgB,IAAI,CAAM,EACzC,GAAI,EACA,OAAO,EAEX,IAAM,EAAU,EAAO,IAAI,cAAc,EAAE,KAAM,GAAa,EAAS,IAAI,EAE3E,OADA,EAAgB,IAAI,EAAQ,CAAO,EAC5B,CACX,CACA,eAAsB,EAA0B,EAAQ,EAAa,CACjE,IAAM,EAAa,MAAM,EAAyB,CAAM,EAClD,EAAgB,OAAO,EAAW,SAAY,UAAY,EAAW,QAAQ,KAAK,EAClF,EAAW,QAAQ,KAAK,EACxB,UACA,EAAa,EAA2B,EAAe,EAAY,UAAU,EACnF,GAAI,IAAe,MAAQ,EAAa,EACpC,MAAM,IAAI,EAAwB,CAAE,cAAa,eAAc,CAAC,EAEpE,OAAO,CACX,CACA,SAAgB,EAA2B,EAAQ,EAAU,CACzD,IAAM,EAAe,EAAwB,CAAM,EAC7C,EAAiB,EAAwB,CAAQ,EACvD,GAAI,CAAC,GAAgB,CAAC,EAClB,OAAO,KAEX,IAAK,IAAM,IAAO,CAAC,QAAS,QAAS,OAAO,EAAG,CAC3C,GAAI,EAAa,GAAO,EAAe,GACnC,MAAO,GAEX,GAAI,EAAa,GAAO,EAAe,GACnC,MAAO,EAEf,CAUA,OATI,EAAa,YAAc,CAAC,EAAe,WACpC,GAEP,CAAC,EAAa,YAAc,EAAe,WACpC,EAEP,EAAa,YAAc,EAAe,WACnC,EAAa,WAAW,cAAc,EAAe,UAAU,EAEnE,CACX,CACA,SAAS,EAAwB,EAAS,CAEtC,GAAM,CAAC,GADS,EAAQ,KAAK,EAAE,QAAQ,KAAM,EAChB,EAAE,MAAM,GAAG,EAClC,CAAC,EAAM,GAAc,EAAa,MAAM,IAAK,CAAC,EAC9C,EAAQ,EAAK,MAAM,GAAG,EAC5B,GAAI,EAAM,SAAW,EACjB,OAAO,KAEX,GAAM,CAAC,EAAO,EAAO,GAAS,EAAM,IAAK,GAAS,OAAO,CAAI,CAAC,EAI9D,MAHK,CAAC,EAAO,EAAO,CAAK,EAAE,MAAO,GAAS,OAAO,UAAU,CAAI,GAAK,GAAQ,CAAC,EAGvE,CAAE,QAAO,QAAO,QAAO,YAAW,EAF9B,IAGf"}
1
+ {"version":3,"file":"agent-server-compatibility.cjs","names":[],"sources":["../../../../../../node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js"],"sourcesContent":["export const AGENT_SERVER_VERSION_ERROR_CODE = 'AGENT_SERVER_VERSION_TOO_OLD';\nexport const AgentServerFeatureRequirements = {\n workspaces: {\n feature: 'workspaces',\n displayName: 'Workspaces',\n minVersion: '1.23.0',\n },\n hooks: {\n feature: 'hooks',\n displayName: 'Hooks API',\n minVersion: '1.23.0',\n },\n mcpTest: {\n feature: 'mcp-test',\n displayName: 'MCP test API',\n minVersion: '1.23.0',\n },\n mcpOAuth: {\n feature: 'mcp-oauth',\n displayName: 'MCP OAuth API',\n minVersion: '1.31.0',\n },\n};\nexport class AgentServerVersionError extends Error {\n constructor({ requirement, actualVersion, }) {\n super(`${requirement.displayName} requires agent-server ${requirement.minVersion} or newer; this backend is running ${actualVersion}. Please upgrade your agent-server backend.`);\n this.code = AGENT_SERVER_VERSION_ERROR_CODE;\n this.name = 'AgentServerVersionError';\n this.feature = requirement.feature;\n this.displayName = requirement.displayName;\n this.requiredVersion = requirement.minVersion;\n this.actualVersion = actualVersion;\n Object.setPrototypeOf(this, AgentServerVersionError.prototype);\n }\n}\nlet serverInfoCache = new WeakMap();\nexport function isAgentServerVersionError(error) {\n return (error instanceof AgentServerVersionError ||\n (typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === AGENT_SERVER_VERSION_ERROR_CODE));\n}\nexport function clearAgentServerInfoCache(client) {\n if (client) {\n serverInfoCache.delete(client);\n return;\n }\n serverInfoCache = new WeakMap();\n}\nexport async function getCachedAgentServerInfo(client) {\n const cached = serverInfoCache.get(client);\n if (cached) {\n return cached;\n }\n const request = client.get('/server_info').then((response) => response.data);\n serverInfoCache.set(client, request);\n return request;\n}\nexport async function assertAgentServerSupports(client, requirement) {\n const serverInfo = await getCachedAgentServerInfo(client);\n const actualVersion = typeof serverInfo.version === 'string' && serverInfo.version.trim()\n ? serverInfo.version.trim()\n : 'unknown';\n const comparison = compareAgentServerVersions(actualVersion, requirement.minVersion);\n if (comparison === null || comparison < 0) {\n throw new AgentServerVersionError({ requirement, actualVersion });\n }\n return serverInfo;\n}\nexport function compareAgentServerVersions(actual, required) {\n const parsedActual = parseAgentServerVersion(actual);\n const parsedRequired = parseAgentServerVersion(required);\n if (!parsedActual || !parsedRequired) {\n return null;\n }\n for (const key of ['major', 'minor', 'patch']) {\n if (parsedActual[key] > parsedRequired[key]) {\n return 1;\n }\n if (parsedActual[key] < parsedRequired[key]) {\n return -1;\n }\n }\n if (parsedActual.prerelease && !parsedRequired.prerelease) {\n return -1;\n }\n if (!parsedActual.prerelease && parsedRequired.prerelease) {\n return 1;\n }\n if (parsedActual.prerelease && parsedRequired.prerelease) {\n return parsedActual.prerelease.localeCompare(parsedRequired.prerelease);\n }\n return 0;\n}\nfunction parseAgentServerVersion(version) {\n const trimmed = version.trim().replace(/^v/, '');\n const [withoutBuild] = trimmed.split('+');\n const [core, prerelease] = withoutBuild.split('-', 2);\n const parts = core.split('.');\n if (parts.length !== 3) {\n return null;\n }\n const [major, minor, patch] = parts.map((part) => Number(part));\n if (![major, minor, patch].every((part) => Number.isInteger(part) && part >= 0)) {\n return null;\n }\n return { major, minor, patch, prerelease };\n}\n//# sourceMappingURL=agent-server-compatibility.js.map"],"x_google_ignoreList":[0],"mappings":"yDAAA,IAAa,EAAkC,+BAClC,EAAiC,CAC1C,WAAY,CACR,QAAS,aACT,YAAa,aACb,WAAY,QAChB,EACA,MAAO,CACH,QAAS,QACT,YAAa,YACb,WAAY,QAChB,EACA,QAAS,CACL,QAAS,WACT,YAAa,eACb,WAAY,QAChB,EACA,SAAU,CACN,QAAS,YACT,YAAa,gBACb,WAAY,QAChB,CACJ,EACa,EAAb,MAAa,UAAgC,KAAM,CAC/C,YAAY,CAAE,cAAa,iBAAkB,CACzC,MAAM,GAAG,EAAY,YAAY,yBAAyB,EAAY,WAAW,qCAAqC,EAAc,4CAA4C,EAChL,KAAK,KAAO,EACZ,KAAK,KAAO,0BACZ,KAAK,QAAU,EAAY,QAC3B,KAAK,YAAc,EAAY,YAC/B,KAAK,gBAAkB,EAAY,WACnC,KAAK,cAAgB,EACrB,OAAO,eAAe,KAAM,EAAwB,SAAS,CACjE,CACJ,EACI,EAAkB,IAAI,QAC1B,SAAgB,EAA0B,EAAO,CAC7C,OAAQ,aAAiB,GACpB,OAAO,GAAU,YACd,GACA,SAAU,GACV,EAAM,OAAA,8BAClB,CACA,SAAgB,EAA0B,EAAQ,CAC9C,GAAI,EAAQ,CACR,EAAgB,OAAO,CAAM,EAC7B,MACJ,CACA,EAAkB,IAAI,OAC1B,CACA,eAAsB,EAAyB,EAAQ,CACnD,IAAM,EAAS,EAAgB,IAAI,CAAM,EACzC,GAAI,EACA,OAAO,EAEX,IAAM,EAAU,EAAO,IAAI,cAAc,EAAE,KAAM,GAAa,EAAS,IAAI,EAE3E,OADA,EAAgB,IAAI,EAAQ,CAAO,EAC5B,CACX,CACA,eAAsB,EAA0B,EAAQ,EAAa,CACjE,IAAM,EAAa,MAAM,EAAyB,CAAM,EAClD,EAAgB,OAAO,EAAW,SAAY,UAAY,EAAW,QAAQ,KAAK,EAClF,EAAW,QAAQ,KAAK,EACxB,UACA,EAAa,EAA2B,EAAe,EAAY,UAAU,EACnF,GAAI,IAAe,MAAQ,EAAa,EACpC,MAAM,IAAI,EAAwB,CAAE,cAAa,eAAc,CAAC,EAEpE,OAAO,CACX,CACA,SAAgB,EAA2B,EAAQ,EAAU,CACzD,IAAM,EAAe,EAAwB,CAAM,EAC7C,EAAiB,EAAwB,CAAQ,EACvD,GAAI,CAAC,GAAgB,CAAC,EAClB,OAAO,KAEX,IAAK,IAAM,IAAO,CAAC,QAAS,QAAS,OAAO,EAAG,CAC3C,GAAI,EAAa,GAAO,EAAe,GACnC,MAAO,GAEX,GAAI,EAAa,GAAO,EAAe,GACnC,MAAO,EAEf,CAUA,OATI,EAAa,YAAc,CAAC,EAAe,WACpC,GAEP,CAAC,EAAa,YAAc,EAAe,WACpC,EAEP,EAAa,YAAc,EAAe,WACnC,EAAa,WAAW,cAAc,EAAe,UAAU,EAEnE,CACX,CACA,SAAS,EAAwB,EAAS,CAEtC,GAAM,CAAC,GADS,EAAQ,KAAK,EAAE,QAAQ,KAAM,EAChB,EAAE,MAAM,GAAG,EAClC,CAAC,EAAM,GAAc,EAAa,MAAM,IAAK,CAAC,EAC9C,EAAQ,EAAK,MAAM,GAAG,EAC5B,GAAI,EAAM,SAAW,EACjB,OAAO,KAEX,GAAM,CAAC,EAAO,EAAO,GAAS,EAAM,IAAK,GAAS,OAAO,CAAI,CAAC,EAI9D,MAHK,CAAC,EAAO,EAAO,CAAK,EAAE,MAAO,GAAS,OAAO,UAAU,CAAI,GAAK,GAAQ,CAAC,EAGvE,CAAE,QAAO,QAAO,QAAO,YAAW,EAF9B,IAGf"}
@@ -28,22 +28,29 @@ var e = "AGENT_SERVER_VERSION_TOO_OLD", t = {
28
28
  function i(e) {
29
29
  return e instanceof n || typeof e == "object" && !!e && "code" in e && e.code === "AGENT_SERVER_VERSION_TOO_OLD";
30
30
  }
31
- async function a(e) {
31
+ function a(e) {
32
+ if (e) {
33
+ r.delete(e);
34
+ return;
35
+ }
36
+ r = /* @__PURE__ */ new WeakMap();
37
+ }
38
+ async function o(e) {
32
39
  let t = r.get(e);
33
40
  if (t) return t;
34
41
  let n = e.get("/server_info").then((e) => e.data);
35
42
  return r.set(e, n), n;
36
43
  }
37
- async function o(e, t) {
38
- let r = await a(e), i = typeof r.version == "string" && r.version.trim() ? r.version.trim() : "unknown", o = s(i, t.minVersion);
39
- if (o === null || o < 0) throw new n({
44
+ async function s(e, t) {
45
+ let r = await o(e), i = typeof r.version == "string" && r.version.trim() ? r.version.trim() : "unknown", a = c(i, t.minVersion);
46
+ if (a === null || a < 0) throw new n({
40
47
  requirement: t,
41
48
  actualVersion: i
42
49
  });
43
50
  return r;
44
51
  }
45
- function s(e, t) {
46
- let n = c(e), r = c(t);
52
+ function c(e, t) {
53
+ let n = l(e), r = l(t);
47
54
  if (!n || !r) return null;
48
55
  for (let e of [
49
56
  "major",
@@ -55,7 +62,7 @@ function s(e, t) {
55
62
  }
56
63
  return n.prerelease && !r.prerelease ? -1 : !n.prerelease && r.prerelease ? 1 : n.prerelease && r.prerelease ? n.prerelease.localeCompare(r.prerelease) : 0;
57
64
  }
58
- function c(e) {
65
+ function l(e) {
59
66
  let [t] = e.trim().replace(/^v/, "").split("+"), [n, r] = t.split("-", 2), i = n.split(".");
60
67
  if (i.length !== 3) return null;
61
68
  let [a, o, s] = i.map((e) => Number(e));
@@ -71,6 +78,6 @@ function c(e) {
71
78
  } : null;
72
79
  }
73
80
  //#endregion
74
- export { e as AGENT_SERVER_VERSION_ERROR_CODE, t as AgentServerFeatureRequirements, n as AgentServerVersionError, o as assertAgentServerSupports, s as compareAgentServerVersions, a as getCachedAgentServerInfo, i as isAgentServerVersionError };
81
+ export { e as AGENT_SERVER_VERSION_ERROR_CODE, t as AgentServerFeatureRequirements, n as AgentServerVersionError, s as assertAgentServerSupports, a as clearAgentServerInfoCache, c as compareAgentServerVersions, o as getCachedAgentServerInfo, i as isAgentServerVersionError };
75
82
 
76
83
  //# sourceMappingURL=agent-server-compatibility.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-server-compatibility.js","names":[],"sources":["../../../../../../node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js"],"sourcesContent":["export const AGENT_SERVER_VERSION_ERROR_CODE = 'AGENT_SERVER_VERSION_TOO_OLD';\nexport const AgentServerFeatureRequirements = {\n workspaces: {\n feature: 'workspaces',\n displayName: 'Workspaces',\n minVersion: '1.23.0',\n },\n hooks: {\n feature: 'hooks',\n displayName: 'Hooks API',\n minVersion: '1.23.0',\n },\n mcpTest: {\n feature: 'mcp-test',\n displayName: 'MCP test API',\n minVersion: '1.23.0',\n },\n mcpOAuth: {\n feature: 'mcp-oauth',\n displayName: 'MCP OAuth API',\n minVersion: '1.31.0',\n },\n};\nexport class AgentServerVersionError extends Error {\n constructor({ requirement, actualVersion, }) {\n super(`${requirement.displayName} requires agent-server ${requirement.minVersion} or newer; this backend is running ${actualVersion}. Please upgrade your agent-server backend.`);\n this.code = AGENT_SERVER_VERSION_ERROR_CODE;\n this.name = 'AgentServerVersionError';\n this.feature = requirement.feature;\n this.displayName = requirement.displayName;\n this.requiredVersion = requirement.minVersion;\n this.actualVersion = actualVersion;\n Object.setPrototypeOf(this, AgentServerVersionError.prototype);\n }\n}\nlet serverInfoCache = new WeakMap();\nexport function isAgentServerVersionError(error) {\n return (error instanceof AgentServerVersionError ||\n (typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === AGENT_SERVER_VERSION_ERROR_CODE));\n}\nexport function clearAgentServerInfoCache(client) {\n if (client) {\n serverInfoCache.delete(client);\n return;\n }\n serverInfoCache = new WeakMap();\n}\nexport async function getCachedAgentServerInfo(client) {\n const cached = serverInfoCache.get(client);\n if (cached) {\n return cached;\n }\n const request = client.get('/server_info').then((response) => response.data);\n serverInfoCache.set(client, request);\n return request;\n}\nexport async function assertAgentServerSupports(client, requirement) {\n const serverInfo = await getCachedAgentServerInfo(client);\n const actualVersion = typeof serverInfo.version === 'string' && serverInfo.version.trim()\n ? serverInfo.version.trim()\n : 'unknown';\n const comparison = compareAgentServerVersions(actualVersion, requirement.minVersion);\n if (comparison === null || comparison < 0) {\n throw new AgentServerVersionError({ requirement, actualVersion });\n }\n return serverInfo;\n}\nexport function compareAgentServerVersions(actual, required) {\n const parsedActual = parseAgentServerVersion(actual);\n const parsedRequired = parseAgentServerVersion(required);\n if (!parsedActual || !parsedRequired) {\n return null;\n }\n for (const key of ['major', 'minor', 'patch']) {\n if (parsedActual[key] > parsedRequired[key]) {\n return 1;\n }\n if (parsedActual[key] < parsedRequired[key]) {\n return -1;\n }\n }\n if (parsedActual.prerelease && !parsedRequired.prerelease) {\n return -1;\n }\n if (!parsedActual.prerelease && parsedRequired.prerelease) {\n return 1;\n }\n if (parsedActual.prerelease && parsedRequired.prerelease) {\n return parsedActual.prerelease.localeCompare(parsedRequired.prerelease);\n }\n return 0;\n}\nfunction parseAgentServerVersion(version) {\n const trimmed = version.trim().replace(/^v/, '');\n const [withoutBuild] = trimmed.split('+');\n const [core, prerelease] = withoutBuild.split('-', 2);\n const parts = core.split('.');\n if (parts.length !== 3) {\n return null;\n }\n const [major, minor, patch] = parts.map((part) => Number(part));\n if (![major, minor, patch].every((part) => Number.isInteger(part) && part >= 0)) {\n return null;\n }\n return { major, minor, patch, prerelease };\n}\n//# sourceMappingURL=agent-server-compatibility.js.map"],"x_google_ignoreList":[0],"mappings":";AAAA,IAAa,IAAkC,gCAClC,IAAiC;CAC1C,YAAY;EACR,SAAS;EACT,aAAa;EACb,YAAY;CAChB;CACA,OAAO;EACH,SAAS;EACT,aAAa;EACb,YAAY;CAChB;CACA,SAAS;EACL,SAAS;EACT,aAAa;EACb,YAAY;CAChB;CACA,UAAU;EACN,SAAS;EACT,aAAa;EACb,YAAY;CAChB;AACJ,GACa,IAAb,MAAa,UAAgC,MAAM;CAC/C,YAAY,EAAE,gBAAa,oBAAkB;EAQzC,AAPA,MAAM,GAAG,EAAY,YAAY,yBAAyB,EAAY,WAAW,qCAAqC,EAAc,4CAA4C,GAChL,KAAK,OAAO,GACZ,KAAK,OAAO,2BACZ,KAAK,UAAU,EAAY,SAC3B,KAAK,cAAc,EAAY,aAC/B,KAAK,kBAAkB,EAAY,YACnC,KAAK,gBAAgB,GACrB,OAAO,eAAe,MAAM,EAAwB,SAAS;CACjE;AACJ,GACI,oBAAkB,IAAI,QAAQ;AAClC,SAAgB,EAA0B,GAAO;CAC7C,OAAQ,aAAiB,KACpB,OAAO,KAAU,cACd,KACA,UAAU,KACV,EAAM,SAAA;AAClB;AAQA,eAAsB,EAAyB,GAAQ;CACnD,IAAM,IAAS,EAAgB,IAAI,CAAM;CACzC,IAAI,GACA,OAAO;CAEX,IAAM,IAAU,EAAO,IAAI,cAAc,EAAE,MAAM,MAAa,EAAS,IAAI;CAE3E,OADA,EAAgB,IAAI,GAAQ,CAAO,GAC5B;AACX;AACA,eAAsB,EAA0B,GAAQ,GAAa;CACjE,IAAM,IAAa,MAAM,EAAyB,CAAM,GAClD,IAAgB,OAAO,EAAW,WAAY,YAAY,EAAW,QAAQ,KAAK,IAClF,EAAW,QAAQ,KAAK,IACxB,WACA,IAAa,EAA2B,GAAe,EAAY,UAAU;CACnF,IAAI,MAAe,QAAQ,IAAa,GACpC,MAAM,IAAI,EAAwB;EAAE;EAAa;CAAc,CAAC;CAEpE,OAAO;AACX;AACA,SAAgB,EAA2B,GAAQ,GAAU;CACzD,IAAM,IAAe,EAAwB,CAAM,GAC7C,IAAiB,EAAwB,CAAQ;CACvD,IAAI,CAAC,KAAgB,CAAC,GAClB,OAAO;CAEX,KAAK,IAAM,KAAO;EAAC;EAAS;EAAS;CAAO,GAAG;EAC3C,IAAI,EAAa,KAAO,EAAe,IACnC,OAAO;EAEX,IAAI,EAAa,KAAO,EAAe,IACnC,OAAO;CAEf;CAUA,OATI,EAAa,cAAc,CAAC,EAAe,aACpC,KAEP,CAAC,EAAa,cAAc,EAAe,aACpC,IAEP,EAAa,cAAc,EAAe,aACnC,EAAa,WAAW,cAAc,EAAe,UAAU,IAEnE;AACX;AACA,SAAS,EAAwB,GAAS;CAEtC,IAAM,CAAC,KADS,EAAQ,KAAK,EAAE,QAAQ,MAAM,EAChB,EAAE,MAAM,GAAG,GAClC,CAAC,GAAM,KAAc,EAAa,MAAM,KAAK,CAAC,GAC9C,IAAQ,EAAK,MAAM,GAAG;CAC5B,IAAI,EAAM,WAAW,GACjB,OAAO;CAEX,IAAM,CAAC,GAAO,GAAO,KAAS,EAAM,KAAK,MAAS,OAAO,CAAI,CAAC;CAI9D,OAHK;EAAC;EAAO;EAAO;CAAK,EAAE,OAAO,MAAS,OAAO,UAAU,CAAI,KAAK,KAAQ,CAAC,IAGvE;EAAE;EAAO;EAAO;EAAO;CAAW,IAF9B;AAGf"}
1
+ {"version":3,"file":"agent-server-compatibility.js","names":[],"sources":["../../../../../../node_modules/@openhands/typescript-client/dist/client/agent-server-compatibility.js"],"sourcesContent":["export const AGENT_SERVER_VERSION_ERROR_CODE = 'AGENT_SERVER_VERSION_TOO_OLD';\nexport const AgentServerFeatureRequirements = {\n workspaces: {\n feature: 'workspaces',\n displayName: 'Workspaces',\n minVersion: '1.23.0',\n },\n hooks: {\n feature: 'hooks',\n displayName: 'Hooks API',\n minVersion: '1.23.0',\n },\n mcpTest: {\n feature: 'mcp-test',\n displayName: 'MCP test API',\n minVersion: '1.23.0',\n },\n mcpOAuth: {\n feature: 'mcp-oauth',\n displayName: 'MCP OAuth API',\n minVersion: '1.31.0',\n },\n};\nexport class AgentServerVersionError extends Error {\n constructor({ requirement, actualVersion, }) {\n super(`${requirement.displayName} requires agent-server ${requirement.minVersion} or newer; this backend is running ${actualVersion}. Please upgrade your agent-server backend.`);\n this.code = AGENT_SERVER_VERSION_ERROR_CODE;\n this.name = 'AgentServerVersionError';\n this.feature = requirement.feature;\n this.displayName = requirement.displayName;\n this.requiredVersion = requirement.minVersion;\n this.actualVersion = actualVersion;\n Object.setPrototypeOf(this, AgentServerVersionError.prototype);\n }\n}\nlet serverInfoCache = new WeakMap();\nexport function isAgentServerVersionError(error) {\n return (error instanceof AgentServerVersionError ||\n (typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === AGENT_SERVER_VERSION_ERROR_CODE));\n}\nexport function clearAgentServerInfoCache(client) {\n if (client) {\n serverInfoCache.delete(client);\n return;\n }\n serverInfoCache = new WeakMap();\n}\nexport async function getCachedAgentServerInfo(client) {\n const cached = serverInfoCache.get(client);\n if (cached) {\n return cached;\n }\n const request = client.get('/server_info').then((response) => response.data);\n serverInfoCache.set(client, request);\n return request;\n}\nexport async function assertAgentServerSupports(client, requirement) {\n const serverInfo = await getCachedAgentServerInfo(client);\n const actualVersion = typeof serverInfo.version === 'string' && serverInfo.version.trim()\n ? serverInfo.version.trim()\n : 'unknown';\n const comparison = compareAgentServerVersions(actualVersion, requirement.minVersion);\n if (comparison === null || comparison < 0) {\n throw new AgentServerVersionError({ requirement, actualVersion });\n }\n return serverInfo;\n}\nexport function compareAgentServerVersions(actual, required) {\n const parsedActual = parseAgentServerVersion(actual);\n const parsedRequired = parseAgentServerVersion(required);\n if (!parsedActual || !parsedRequired) {\n return null;\n }\n for (const key of ['major', 'minor', 'patch']) {\n if (parsedActual[key] > parsedRequired[key]) {\n return 1;\n }\n if (parsedActual[key] < parsedRequired[key]) {\n return -1;\n }\n }\n if (parsedActual.prerelease && !parsedRequired.prerelease) {\n return -1;\n }\n if (!parsedActual.prerelease && parsedRequired.prerelease) {\n return 1;\n }\n if (parsedActual.prerelease && parsedRequired.prerelease) {\n return parsedActual.prerelease.localeCompare(parsedRequired.prerelease);\n }\n return 0;\n}\nfunction parseAgentServerVersion(version) {\n const trimmed = version.trim().replace(/^v/, '');\n const [withoutBuild] = trimmed.split('+');\n const [core, prerelease] = withoutBuild.split('-', 2);\n const parts = core.split('.');\n if (parts.length !== 3) {\n return null;\n }\n const [major, minor, patch] = parts.map((part) => Number(part));\n if (![major, minor, patch].every((part) => Number.isInteger(part) && part >= 0)) {\n return null;\n }\n return { major, minor, patch, prerelease };\n}\n//# sourceMappingURL=agent-server-compatibility.js.map"],"x_google_ignoreList":[0],"mappings":";AAAA,IAAa,IAAkC,gCAClC,IAAiC;CAC1C,YAAY;EACR,SAAS;EACT,aAAa;EACb,YAAY;CAChB;CACA,OAAO;EACH,SAAS;EACT,aAAa;EACb,YAAY;CAChB;CACA,SAAS;EACL,SAAS;EACT,aAAa;EACb,YAAY;CAChB;CACA,UAAU;EACN,SAAS;EACT,aAAa;EACb,YAAY;CAChB;AACJ,GACa,IAAb,MAAa,UAAgC,MAAM;CAC/C,YAAY,EAAE,gBAAa,oBAAkB;EAQzC,AAPA,MAAM,GAAG,EAAY,YAAY,yBAAyB,EAAY,WAAW,qCAAqC,EAAc,4CAA4C,GAChL,KAAK,OAAO,GACZ,KAAK,OAAO,2BACZ,KAAK,UAAU,EAAY,SAC3B,KAAK,cAAc,EAAY,aAC/B,KAAK,kBAAkB,EAAY,YACnC,KAAK,gBAAgB,GACrB,OAAO,eAAe,MAAM,EAAwB,SAAS;CACjE;AACJ,GACI,oBAAkB,IAAI,QAAQ;AAClC,SAAgB,EAA0B,GAAO;CAC7C,OAAQ,aAAiB,KACpB,OAAO,KAAU,cACd,KACA,UAAU,KACV,EAAM,SAAA;AAClB;AACA,SAAgB,EAA0B,GAAQ;CAC9C,IAAI,GAAQ;EACR,EAAgB,OAAO,CAAM;EAC7B;CACJ;CACA,oBAAkB,IAAI,QAAQ;AAClC;AACA,eAAsB,EAAyB,GAAQ;CACnD,IAAM,IAAS,EAAgB,IAAI,CAAM;CACzC,IAAI,GACA,OAAO;CAEX,IAAM,IAAU,EAAO,IAAI,cAAc,EAAE,MAAM,MAAa,EAAS,IAAI;CAE3E,OADA,EAAgB,IAAI,GAAQ,CAAO,GAC5B;AACX;AACA,eAAsB,EAA0B,GAAQ,GAAa;CACjE,IAAM,IAAa,MAAM,EAAyB,CAAM,GAClD,IAAgB,OAAO,EAAW,WAAY,YAAY,EAAW,QAAQ,KAAK,IAClF,EAAW,QAAQ,KAAK,IACxB,WACA,IAAa,EAA2B,GAAe,EAAY,UAAU;CACnF,IAAI,MAAe,QAAQ,IAAa,GACpC,MAAM,IAAI,EAAwB;EAAE;EAAa;CAAc,CAAC;CAEpE,OAAO;AACX;AACA,SAAgB,EAA2B,GAAQ,GAAU;CACzD,IAAM,IAAe,EAAwB,CAAM,GAC7C,IAAiB,EAAwB,CAAQ;CACvD,IAAI,CAAC,KAAgB,CAAC,GAClB,OAAO;CAEX,KAAK,IAAM,KAAO;EAAC;EAAS;EAAS;CAAO,GAAG;EAC3C,IAAI,EAAa,KAAO,EAAe,IACnC,OAAO;EAEX,IAAI,EAAa,KAAO,EAAe,IACnC,OAAO;CAEf;CAUA,OATI,EAAa,cAAc,CAAC,EAAe,aACpC,KAEP,CAAC,EAAa,cAAc,EAAe,aACpC,IAEP,EAAa,cAAc,EAAe,aACnC,EAAa,WAAW,cAAc,EAAe,UAAU,IAEnE;AACX;AACA,SAAS,EAAwB,GAAS;CAEtC,IAAM,CAAC,KADS,EAAQ,KAAK,EAAE,QAAQ,MAAM,EAChB,EAAE,MAAM,GAAG,GAClC,CAAC,GAAM,KAAc,EAAa,MAAM,KAAK,CAAC,GAC9C,IAAQ,EAAK,MAAM,GAAG;CAC5B,IAAI,EAAM,WAAW,GACjB,OAAO;CAEX,IAAM,CAAC,GAAO,GAAO,KAAS,EAAM,KAAK,MAAS,OAAO,CAAI,CAAC;CAI9D,OAHK;EAAC;EAAO;EAAO;CAAK,EAAE,OAAO,MAAS,OAAO,UAAU,CAAI,KAAK,KAAQ,CAAC,IAGvE;EAAE;EAAO;EAAO;EAAO;CAAW,IAF9B;AAGf"}
@@ -1,2 +1,2 @@
1
- require("../../../../../_virtual/_rolldown/runtime.cjs");const e=require("./http-client.cjs");var t=class{constructor(t){this.host=t.host.replace(/\/$/,``),this.apiKey=t.apiKey,this.client=new e.HttpClient({baseUrl:this.host,apiKey:this.apiKey,timeout:t.timeout||6e4})}async searchEvents(e={}){return(await this.client.get(`/api/bash/bash_events/search`,{params:e})).data}async getEvent(e){return(await this.client.get(`/api/bash/bash_events/${e}`)).data}async getEvents(t){return Promise.all(t.map(async t=>{try{return await this.getEvent(t)}catch(t){if(t instanceof e.HttpError&&t.status===404)return null;throw t}}))}async batchGetEvents(e){return(await this.client.get(`/api/bash/bash_events/`,{data:e})).data}async startCommand(e,t,n){let r=this.normalizeRequest(e,t,n);return(await this.client.post(`/api/bash/start_bash_command`,r)).data}async executeCommand(e,t,n){let r=this.normalizeRequest(e,t,n);return(await this.client.post(`/api/bash/execute_bash_command`,r,{timeout:((r.timeout||30)+10)*1e3})).data}async clearEvents(){return(await this.client.delete(`/api/bash/bash_events`)).data}close(){this.client.close()}normalizeRequest(e,t,n){return typeof e==`string`?{command:e,...t?{cwd:t}:{},...n===void 0?{}:{timeout:Math.floor(n)}}:{...e,...e.timeout===void 0?{}:{timeout:Math.floor(e.timeout)}}}};exports.BashClient=t;
1
+ require("../../../../../_virtual/_rolldown/runtime.cjs");const e=require("./http-client.cjs"),t=require("./runtime-transport.cjs");var n=class{constructor(e){let{runtimeClient:n}=t.createRuntimeHttpClients(e);this.host=e.host.replace(/\/$/,``),this.apiKey=e.apiKey,this.client=n}async searchEvents(e={}){return(await this.client.get(`/api/bash/bash_events/search`,{params:e})).data}async getEvent(e){return(await this.client.get(`/api/bash/bash_events/${e}`)).data}async getEvents(t){return Promise.all(t.map(async t=>{try{return await this.getEvent(t)}catch(t){if(t instanceof e.HttpError&&t.status===404)return null;throw t}}))}async batchGetEvents(e){return(await this.client.get(`/api/bash/bash_events/`,{data:e})).data}async startCommand(e,t,n){let r=this.normalizeRequest(e,t,n);return(await this.client.post(`/api/bash/start_bash_command`,r)).data}async executeCommand(e,t,n){let r=this.normalizeRequest(e,t,n);return(await this.client.post(`/api/bash/execute_bash_command`,r,{timeout:((r.timeout||30)+10)*1e3})).data}async clearEvents(){return(await this.client.delete(`/api/bash/bash_events`)).data}close(){this.client.close()}normalizeRequest(e,t,n){return typeof e==`string`?{command:e,...t?{cwd:t}:{},...n===void 0?{}:{timeout:Math.floor(n)}}:{...e,...e.timeout===void 0?{}:{timeout:Math.floor(e.timeout)}}}};exports.BashClient=n;
2
2
  //# sourceMappingURL=bash-client.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"bash-client.cjs","names":["HttpClient","HttpError"],"sources":["../../../../../../node_modules/@openhands/typescript-client/dist/client/bash-client.js"],"sourcesContent":["import { HttpClient, HttpError } from './http-client.js';\nexport class BashClient {\n constructor(options) {\n this.host = options.host.replace(/\\/$/, '');\n this.apiKey = options.apiKey;\n this.client = new HttpClient({\n baseUrl: this.host,\n apiKey: this.apiKey,\n timeout: options.timeout || 60000,\n });\n }\n async searchEvents(options = {}) {\n const response = await this.client.get('/api/bash/bash_events/search', {\n params: options,\n });\n return response.data;\n }\n async getEvent(eventId) {\n const response = await this.client.get(`/api/bash/bash_events/${eventId}`);\n return response.data;\n }\n async getEvents(eventIds) {\n return Promise.all(eventIds.map(async (eventId) => {\n try {\n return await this.getEvent(eventId);\n }\n catch (error) {\n if (error instanceof HttpError && error.status === 404) {\n return null;\n }\n throw error;\n }\n }));\n }\n /**\n * Batch-fetch bash events in a single request via `GET /api/bash/bash_events/`.\n *\n * Unlike {@link getEvents} (which fans out one request per id), this calls the\n * server-side batch endpoint and returns one entry per requested id, with\n * `null` in the slots of any missing event — preserving input order.\n */\n async batchGetEvents(eventIds) {\n const response = await this.client.get('/api/bash/bash_events/', {\n data: eventIds,\n });\n return response.data;\n }\n async startCommand(request, cwd, timeout) {\n const payload = this.normalizeRequest(request, cwd, timeout);\n const response = await this.client.post('/api/bash/start_bash_command', payload);\n return response.data;\n }\n async executeCommand(request, cwd, timeout) {\n const payload = this.normalizeRequest(request, cwd, timeout);\n const response = await this.client.post('/api/bash/execute_bash_command', payload, {\n timeout: ((payload.timeout || 30) + 10) * 1000,\n });\n return response.data;\n }\n async clearEvents() {\n const response = await this.client.delete('/api/bash/bash_events');\n return response.data;\n }\n close() {\n this.client.close();\n }\n normalizeRequest(request, cwd, timeout) {\n if (typeof request === 'string') {\n return {\n command: request,\n ...(cwd ? { cwd } : {}),\n ...(timeout !== undefined ? { timeout: Math.floor(timeout) } : {}),\n };\n }\n return {\n ...request,\n ...(request.timeout !== undefined ? { timeout: Math.floor(request.timeout) } : {}),\n };\n }\n}\n//# sourceMappingURL=bash-client.js.map"],"x_google_ignoreList":[0],"mappings":"8FACA,IAAa,EAAb,KAAwB,CACpB,YAAY,EAAS,CACjB,KAAK,KAAO,EAAQ,KAAK,QAAQ,MAAO,EAAE,EAC1C,KAAK,OAAS,EAAQ,OACtB,KAAK,OAAS,IAAIA,EAAAA,WAAW,CACzB,QAAS,KAAK,KACd,OAAQ,KAAK,OACb,QAAS,EAAQ,SAAW,GAChC,CAAC,CACL,CACA,MAAM,aAAa,EAAU,CAAC,EAAG,CAI7B,OAAO,MAHgB,KAAK,OAAO,IAAI,+BAAgC,CACnE,OAAQ,CACZ,CAAC,GACe,IACpB,CACA,MAAM,SAAS,EAAS,CAEpB,OAAO,MADgB,KAAK,OAAO,IAAI,yBAAyB,GAAS,GACzD,IACpB,CACA,MAAM,UAAU,EAAU,CACtB,OAAO,QAAQ,IAAI,EAAS,IAAI,KAAO,IAAY,CAC/C,GAAI,CACA,OAAO,MAAM,KAAK,SAAS,CAAO,CACtC,OACO,EAAO,CACV,GAAI,aAAiBC,EAAAA,WAAa,EAAM,SAAW,IAC/C,OAAO,KAEX,MAAM,CACV,CACJ,CAAC,CAAC,CACN,CAQA,MAAM,eAAe,EAAU,CAI3B,OAAO,MAHgB,KAAK,OAAO,IAAI,yBAA0B,CAC7D,KAAM,CACV,CAAC,GACe,IACpB,CACA,MAAM,aAAa,EAAS,EAAK,EAAS,CACtC,IAAM,EAAU,KAAK,iBAAiB,EAAS,EAAK,CAAO,EAE3D,OAAO,MADgB,KAAK,OAAO,KAAK,+BAAgC,CAAO,GAC/D,IACpB,CACA,MAAM,eAAe,EAAS,EAAK,EAAS,CACxC,IAAM,EAAU,KAAK,iBAAiB,EAAS,EAAK,CAAO,EAI3D,OAAO,MAHgB,KAAK,OAAO,KAAK,iCAAkC,EAAS,CAC/E,UAAW,EAAQ,SAAW,IAAM,IAAM,GAC9C,CAAC,GACe,IACpB,CACA,MAAM,aAAc,CAEhB,OAAO,MADgB,KAAK,OAAO,OAAO,uBAAuB,GACjD,IACpB,CACA,OAAQ,CACJ,KAAK,OAAO,MAAM,CACtB,CACA,iBAAiB,EAAS,EAAK,EAAS,CAQpC,OAPI,OAAO,GAAY,SACZ,CACH,QAAS,EACT,GAAI,EAAM,CAAE,KAAI,EAAI,CAAC,EACrB,GAAI,IAAY,IAAA,GAA+C,CAAC,EAApC,CAAE,QAAS,KAAK,MAAM,CAAO,CAAE,CAC/D,EAEG,CACH,GAAG,EACH,GAAI,EAAQ,UAAY,IAAA,GAAuD,CAAC,EAA5C,CAAE,QAAS,KAAK,MAAM,EAAQ,OAAO,CAAE,CAC/E,CACJ,CACJ"}
1
+ {"version":3,"file":"bash-client.cjs","names":["createRuntimeHttpClients","HttpError"],"sources":["../../../../../../node_modules/@openhands/typescript-client/dist/client/bash-client.js"],"sourcesContent":["import { HttpError } from './http-client.js';\nimport { createRuntimeHttpClients } from './runtime-transport.js';\nexport class BashClient {\n constructor(options) {\n const { runtimeClient } = createRuntimeHttpClients(options);\n this.host = options.host.replace(/\\/$/, '');\n this.apiKey = options.apiKey;\n this.client = runtimeClient;\n }\n async searchEvents(options = {}) {\n const response = await this.client.get('/api/bash/bash_events/search', {\n params: options,\n });\n return response.data;\n }\n async getEvent(eventId) {\n const response = await this.client.get(`/api/bash/bash_events/${eventId}`);\n return response.data;\n }\n async getEvents(eventIds) {\n return Promise.all(eventIds.map(async (eventId) => {\n try {\n return await this.getEvent(eventId);\n }\n catch (error) {\n if (error instanceof HttpError && error.status === 404) {\n return null;\n }\n throw error;\n }\n }));\n }\n /**\n * Batch-fetch bash events in a single request via `GET /api/bash/bash_events/`.\n *\n * Unlike {@link getEvents} (which fans out one request per id), this calls the\n * server-side batch endpoint and returns one entry per requested id, with\n * `null` in the slots of any missing event — preserving input order.\n */\n async batchGetEvents(eventIds) {\n const response = await this.client.get('/api/bash/bash_events/', {\n data: eventIds,\n });\n return response.data;\n }\n async startCommand(request, cwd, timeout) {\n const payload = this.normalizeRequest(request, cwd, timeout);\n const response = await this.client.post('/api/bash/start_bash_command', payload);\n return response.data;\n }\n async executeCommand(request, cwd, timeout) {\n const payload = this.normalizeRequest(request, cwd, timeout);\n const response = await this.client.post('/api/bash/execute_bash_command', payload, {\n timeout: ((payload.timeout || 30) + 10) * 1000,\n });\n return response.data;\n }\n async clearEvents() {\n const response = await this.client.delete('/api/bash/bash_events');\n return response.data;\n }\n close() {\n this.client.close();\n }\n normalizeRequest(request, cwd, timeout) {\n if (typeof request === 'string') {\n return {\n command: request,\n ...(cwd ? { cwd } : {}),\n ...(timeout !== undefined ? { timeout: Math.floor(timeout) } : {}),\n };\n }\n return {\n ...request,\n ...(request.timeout !== undefined ? { timeout: Math.floor(request.timeout) } : {}),\n };\n }\n}\n//# sourceMappingURL=bash-client.js.map"],"x_google_ignoreList":[0],"mappings":"mIAEA,IAAa,EAAb,KAAwB,CACpB,YAAY,EAAS,CACjB,GAAM,CAAE,iBAAkBA,EAAAA,yBAAyB,CAAO,EAC1D,KAAK,KAAO,EAAQ,KAAK,QAAQ,MAAO,EAAE,EAC1C,KAAK,OAAS,EAAQ,OACtB,KAAK,OAAS,CAClB,CACA,MAAM,aAAa,EAAU,CAAC,EAAG,CAI7B,OAAO,MAHgB,KAAK,OAAO,IAAI,+BAAgC,CACnE,OAAQ,CACZ,CAAC,GACe,IACpB,CACA,MAAM,SAAS,EAAS,CAEpB,OAAO,MADgB,KAAK,OAAO,IAAI,yBAAyB,GAAS,GACzD,IACpB,CACA,MAAM,UAAU,EAAU,CACtB,OAAO,QAAQ,IAAI,EAAS,IAAI,KAAO,IAAY,CAC/C,GAAI,CACA,OAAO,MAAM,KAAK,SAAS,CAAO,CACtC,OACO,EAAO,CACV,GAAI,aAAiBC,EAAAA,WAAa,EAAM,SAAW,IAC/C,OAAO,KAEX,MAAM,CACV,CACJ,CAAC,CAAC,CACN,CAQA,MAAM,eAAe,EAAU,CAI3B,OAAO,MAHgB,KAAK,OAAO,IAAI,yBAA0B,CAC7D,KAAM,CACV,CAAC,GACe,IACpB,CACA,MAAM,aAAa,EAAS,EAAK,EAAS,CACtC,IAAM,EAAU,KAAK,iBAAiB,EAAS,EAAK,CAAO,EAE3D,OAAO,MADgB,KAAK,OAAO,KAAK,+BAAgC,CAAO,GAC/D,IACpB,CACA,MAAM,eAAe,EAAS,EAAK,EAAS,CACxC,IAAM,EAAU,KAAK,iBAAiB,EAAS,EAAK,CAAO,EAI3D,OAAO,MAHgB,KAAK,OAAO,KAAK,iCAAkC,EAAS,CAC/E,UAAW,EAAQ,SAAW,IAAM,IAAM,GAC9C,CAAC,GACe,IACpB,CACA,MAAM,aAAc,CAEhB,OAAO,MADgB,KAAK,OAAO,OAAO,uBAAuB,GACjD,IACpB,CACA,OAAQ,CACJ,KAAK,OAAO,MAAM,CACtB,CACA,iBAAiB,EAAS,EAAK,EAAS,CAQpC,OAPI,OAAO,GAAY,SACZ,CACH,QAAS,EACT,GAAI,EAAM,CAAE,KAAI,EAAI,CAAC,EACrB,GAAI,IAAY,IAAA,GAA+C,CAAC,EAApC,CAAE,QAAS,KAAK,MAAM,CAAO,CAAE,CAC/D,EAEG,CACH,GAAG,EACH,GAAI,EAAQ,UAAY,IAAA,GAAuD,CAAC,EAA5C,CAAE,QAAS,KAAK,MAAM,EAAQ,OAAO,CAAE,CAC/E,CACJ,CACJ"}