@openhands/agent-canvas 1.9.0 → 1.10.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 (1105) hide show
  1. package/README.md +1 -1
  2. package/README.windows.md +2 -2
  3. package/build/assets/{acp-providers-C921BlYB.js → acp-providers-DLe_gVDY.js} +1 -1
  4. package/build/assets/active-backend-context-B0wI7OzM.js +2 -0
  5. package/build/assets/agent-context-settings-CaQtdNA-.js +1 -0
  6. package/build/assets/{agent-profiles-settings-BymJf3EP.js → agent-profiles-settings-CvuErjp6.js} +1 -1
  7. package/build/assets/agent-server-conversation-service.api-km_8sOVf.js +41 -0
  8. package/build/assets/{agent-settings-WzqXk6B4.js → agent-settings-UE-U4Xii.js} +2 -2
  9. package/build/assets/agent-settings-nmO-KSXr.js +1 -0
  10. package/build/assets/alert-banner-BMaOtTCG.js +1 -0
  11. package/build/assets/{api-key-entry-screen-DI0I04O3.js → api-key-entry-screen-Cy66vT4D.js} +1 -1
  12. package/build/assets/{app-settings-DGistSFV.js → app-settings-9ok42bV6.js} +1 -1
  13. package/build/assets/automation-detail-fuITm6i3.js +3 -0
  14. package/build/assets/automation-export-CRq40mux.js +2 -0
  15. package/build/assets/automation-setup-route-EXDazOHW.js +1 -0
  16. package/build/assets/automation-templates-BArZsaxP.js +1 -0
  17. package/build/assets/automations-list-CG4HKOTn.js +1 -0
  18. package/build/assets/{back-nav-button-D4ngzpSh.js → back-nav-button-BZB6H7xz.js} +1 -1
  19. package/build/assets/{backend-form-modal-B8D5hBzK.js → backend-form-modal-B_lXjOGa.js} +1 -1
  20. package/build/assets/{backend-synced-settings-badge-BnzI8Ysj.js → backend-synced-settings-badge-B_NXJ3u1.js} +1 -1
  21. package/build/assets/{badge-1Mf1iPcX.js → badge-C64c-7PO.js} +1 -1
  22. package/build/assets/{base-modal-BBuy0WQQ.js → base-modal-C0RQPug5.js} +1 -1
  23. package/build/assets/bot-DuN83i3p.js +1 -0
  24. package/build/assets/{brand-button-DGN6Y9o6.js → brand-button-DJmFCyMK.js} +1 -1
  25. package/build/assets/{browser-D_ekTlTS.js → browser-D3gd2n83.js} +2 -2
  26. package/build/assets/{browser-tab-D4a4Ou_w.js → browser-tab-BicAWuJ1.js} +1 -1
  27. package/build/assets/{chat-send-button-CgbcjD97.js → chat-send-button-CCrH1E8u.js} +1 -1
  28. package/build/assets/check-DLOKoFU9.js +1 -0
  29. package/build/assets/{checkmark-CxdXtM3b.js → checkmark-XZyokq_Y.js} +1 -1
  30. package/build/assets/chevron-down-CnIbtM6i.js +1 -0
  31. package/build/assets/circle-check-CxCYJrpZ.js +1 -0
  32. package/build/assets/{circle-plus-check-toggle-yTAS-nX3.js → circle-plus-check-toggle-CB_sNERY.js} +1 -1
  33. package/build/assets/{close-CDAVqnTn.js → close-ScPlnwyq.js} +1 -1
  34. package/build/assets/{cloud-funnel-analytics-CEOl5Gxr.js → cloud-funnel-analytics-XynamQGU.js} +1 -1
  35. package/build/assets/{combobox-caret-Bd2yySnF.js → combobox-caret-Bwiifgjs.js} +1 -1
  36. package/build/assets/command-menu-CA3IjGNc.js +1 -0
  37. package/build/assets/condenser-settings-cNGy75gq.js +1 -0
  38. package/build/assets/{confirmation-modal-NCUPr2-O.js → confirmation-modal-BATFmFyP.js} +1 -1
  39. package/build/assets/context-menu-list-item-DhJCcBA0.js +1 -0
  40. package/build/assets/conversation-B6t6EiVp.js +1 -0
  41. package/build/assets/{conversation-CUJ0Vo8g.js → conversation-Csdxh9Xt.js} +7 -7
  42. package/build/assets/conversation-panel-B6t6EiVp.js +1 -0
  43. package/build/assets/{conversation-state-store-F62HvuI1.js → conversation-state-store-C2QzhPaK.js} +1 -1
  44. package/build/assets/{conversation-store-C6hSXHw0.js → conversation-store-B8Eahyeg.js} +1 -1
  45. package/build/assets/{conversation-tab-empty-state-BCZ7rUMH.js → conversation-tab-empty-state-D3fb5xIA.js} +1 -1
  46. package/build/assets/{copy-DCmZtz6n.js → copy-DaHuDtG4.js} +1 -1
  47. package/build/assets/{copy-z7idLzWO.js → copy-Drmhc2jD.js} +1 -1
  48. package/build/assets/{copy-to-clipboard-button-D_Lp6-Fl.js → copy-to-clipboard-button-c4MQwKGj.js} +1 -1
  49. package/build/assets/{device-verify-DLmolX8Q.js → device-verify-oFpQoLgm.js} +1 -1
  50. package/build/assets/{dist-hOnv1nn2.js → dist-Bl64nBZL.js} +1 -1
  51. package/build/assets/{dropdown-classes-BB8rzqXL.js → dropdown-classes-f91ARMV1.js} +1 -1
  52. package/build/assets/entry.client-BCzY2Bf3.js +2 -0
  53. package/build/assets/enum-filter-dropdown-HG3q3rkV.js +1 -0
  54. package/build/assets/{environment-switch-overlay-BepBBX66.js → environment-switch-overlay-CquZXolz.js} +1 -1
  55. package/build/assets/{extensions-hub-R3KNv-5V.js → extensions-hub-BeweE0PW.js} +1 -1
  56. package/build/assets/{extensions-navigation-CfWFmI1I.js → extensions-navigation-Dd58NlUF.js} +1 -1
  57. package/build/assets/{external-link-BdBSg8rk.js → external-link-zWbg5KXS.js} +1 -1
  58. package/build/assets/file-text-RecuaId_.js +1 -0
  59. package/build/assets/files-tab-CLLG55-q.js +1 -0
  60. package/build/assets/{folder-C86qXV7M.js → folder-C1ou4_DT.js} +1 -1
  61. package/build/assets/{form-control-classes-DAfsCJTe.js → form-control-classes-pHtZUI6K.js} +1 -1
  62. package/build/assets/format-relative-time-6-3uvOXe.js +1 -0
  63. package/build/assets/format-time-delta-BIR5Os7T.js +1 -0
  64. package/build/assets/{git-provider-icon-BZqqUPlm.js → git-provider-icon-wg7ShB98.js} +1 -1
  65. package/build/assets/{git-repo-dropdown-DEpOwUez.js → git-repo-dropdown-CWnaUyxL.js} +1 -1
  66. package/build/assets/git-repo-dropdown-TzOuG5Ef.js +1 -0
  67. package/build/assets/{highlighted-source-view-CX9oIoVT.js → highlighted-source-view-DBtI3por.js} +1 -1
  68. package/build/assets/home-BpZQkDWM.js +1 -0
  69. package/build/assets/home-OEx0XtfP.js +1 -0
  70. package/build/assets/{home-store-Ch1ErdBc.js → home-store-DM4qw1lF.js} +1 -1
  71. package/build/assets/{iconBase-B2rQun3J.js → iconBase-C2sR-uAp.js} +1 -1
  72. package/build/assets/index-home-OEx0XtfP.js +1 -0
  73. package/build/assets/info-C9lpK5pw.js +1 -0
  74. package/build/assets/install-server-modal-DnjZrJUy.js +1 -0
  75. package/build/assets/kebab-menu-item-content-By16Tm_0.js +1 -0
  76. package/build/assets/{launch-B1POpHuP.js → launch-C9uijypN.js} +1 -1
  77. package/build/assets/{link-external-BDBCz-_z.js → link-external-BNZzCM1I.js} +1 -1
  78. package/build/assets/list-filter-C86CBRDE.js +1 -0
  79. package/build/assets/{list-todo-DtiL3lTp.js → list-todo-CheUtB7F.js} +1 -1
  80. package/build/assets/llm-not-configured-banner-DrBrhfN0.js +27 -0
  81. package/build/assets/{llm-settings-CXo8iPNW.js → llm-settings-CRsLqxgu.js} +1 -1
  82. package/build/assets/llm-settings-RBm_3kNm.js +1 -0
  83. package/build/assets/{llm-subscription-service-DBJbfd8Z.js → llm-subscription-service-DwjJ8-_X.js} +1 -1
  84. package/build/assets/loader-circle-C5AnEN8r.js +1 -0
  85. package/build/assets/{loading-spinner-DfZ_bhV7.js → loading-spinner-6Yj-YyoS.js} +1 -1
  86. package/build/assets/{manage-backends-modal-CwyWsiag.js → manage-backends-modal-DrwErS0N.js} +1 -1
  87. package/build/assets/manifest-c352d453.js +1 -0
  88. package/build/assets/manifest-subpage-layout-CtqVwIvJ.js +1 -0
  89. package/build/assets/{markdown-renderer-DgiLLhW6.js → markdown-renderer-lsvsp7jn.js} +4 -4
  90. package/build/assets/mcp-DD4hPTRE.js +9 -0
  91. package/build/assets/mcp-marketplace-utils-BMnYz0Gc.js +1 -0
  92. package/build/assets/messages-Dt77e0qi.js +40 -0
  93. package/build/assets/{modal-backdrop-X-vKo61e.js → modal-backdrop-BSzNhM4r.js} +1 -1
  94. package/build/assets/{modal-body-CMsDpalT.js → modal-body-BHGCSAtj.js} +1 -1
  95. package/build/assets/{modal-classes-B6PDrxXo.js → modal-classes-DSTLuxkA.js} +1 -1
  96. package/build/assets/{modal-close-button-DyxBZaAb.js → modal-close-button-dheWZ2ys.js} +1 -1
  97. package/build/assets/mouse-pointer-click-Px-dXWcS.js +1 -0
  98. package/build/assets/{navigation-context-BOGzIng3.js → navigation-context-CQZwH_tC.js} +1 -1
  99. package/build/assets/navigation-link-Bxo3-4vo.js +1 -0
  100. package/build/assets/onboarding-5CZvRBbh.js +1 -0
  101. package/build/assets/onboarding-modal-CD2ehuxt.js +1 -0
  102. package/build/assets/{openhands-logo-CmYvJXBa.js → openhands-logo-BS-Epajy.js} +1 -1
  103. package/build/assets/{organization-service.api-UDy63-oC.js → organization-service.api-Dsuoep0g.js} +1 -1
  104. package/build/assets/{pencil-BjgtZmWp.js → pencil-Bl3GWhgq.js} +1 -1
  105. package/build/assets/{planner-tab-BWk8885v.js → planner-tab-DeO7Thb0.js} +1 -1
  106. package/build/assets/{plugins-management-service-CjkgF2dd.js → plugins-management-service-C9f75R6X.js} +1 -1
  107. package/build/assets/plus-CtzlyAoF.js +1 -0
  108. package/build/assets/{profiles-service.api-CukSFLzz.js → profiles-service.api-Dl20_2IM.js} +1 -1
  109. package/build/assets/{providers-CqUWC85T.js → providers-CeuhK46N.js} +1 -1
  110. package/build/assets/{proxy-BBUG3sd2.js → proxy-CIGI9zQC.js} +1 -1
  111. package/build/assets/{puzzle-BoNc6zZ8.js → puzzle-B3v361yY.js} +1 -1
  112. package/build/assets/recommended-automations-launcher-6xmbf7lh.js +1 -0
  113. package/build/assets/{refresh-cw-BrM5ZAZD.js → refresh-cw-B9GhC3QC.js} +1 -1
  114. package/build/assets/root-BQPNqNvD.js +2 -0
  115. package/build/assets/root-BeuHFY2s.css +1 -0
  116. package/build/assets/root-layout-Dl_2CDoq.js +3 -0
  117. package/build/assets/{schema-field-nImDoY6-.js → schema-field-z2vSLuLo.js} +1 -1
  118. package/build/assets/{sdk-section-page-BxMrtUNV.js → sdk-section-page-BnCXAytf.js} +1 -1
  119. package/build/assets/{search-7DRiGm4Z.js → search-BatSpWed.js} +1 -1
  120. package/build/assets/search-CYaiKHRp.js +1 -0
  121. package/build/assets/{secrets-service-Dhjh3HhH.js → secrets-service-DGUNlwQd.js} +1 -1
  122. package/build/assets/{secrets-settings-CPdxceT_.js → secrets-settings-DUmML_dK.js} +1 -1
  123. package/build/assets/{segmented-toggle-Do6oyepX.js → segmented-toggle-eSofF7gn.js} +1 -1
  124. package/build/assets/settings-CWFxymAf.js +1 -0
  125. package/build/assets/{settings-BRbnfKEm.js → settings-Co-M5bK9.js} +1 -1
  126. package/build/assets/{settings-dropdown-input-DYCULKpp.js → settings-dropdown-input-Cx4g7Xfl.js} +1 -1
  127. package/build/assets/{settings-gear-TYXnELES.js → settings-gear-DaJj6Pde.js} +1 -1
  128. package/build/assets/{settings-index-C9o2NBO0.js → settings-index-BECdgecg.js} +1 -1
  129. package/build/assets/{settings-input-B-q2gkVy.js → settings-input-BQY115xH.js} +1 -1
  130. package/build/assets/settings-like-page-layout-classes-Cw4Yzv_P.js +1 -0
  131. package/build/assets/{settings-list-classes-WpQi0q1L.js → settings-list-classes-C9cLrrcc.js} +1 -1
  132. package/build/assets/{settings-modal-CEK0AIx6.js → settings-modal-ChBJNTdd.js} +1 -1
  133. package/build/assets/{settings-section-header-context-CnIIQAUn.js → settings-section-header-context-BOJ_Fbak.js} +1 -1
  134. package/build/assets/settings-service.api-Dz9cZyvx.js +1 -0
  135. package/build/assets/{settings-switch-LqKdGxHL.js → settings-switch-BIodMVz9.js} +1 -1
  136. package/build/assets/{shared-conversation-Bu-dQlgp.js → shared-conversation-CSF0aTuE.js} +1 -1
  137. package/build/assets/{sidebar-layout-oHBGQmLh.js → sidebar-layout-DEycoFd_.js} +1 -1
  138. package/build/assets/sidebar-mobile-menu-toggle-DeRvTupV.js +1 -0
  139. package/build/assets/{sidebar-nav-link-CrujNA09.js → sidebar-nav-link-BjpQ-NVc.js} +1 -1
  140. package/build/assets/{sidebar-store-Bui-WNEr.js → sidebar-store-B04sX8aP.js} +1 -1
  141. package/build/assets/{skill-card-pill-row-CZBI7OqH.js → skill-card-pill-row-BH6fPGba.js} +1 -1
  142. package/build/assets/{skill-icon-badge-BOov_phZ.js → skill-icon-badge-D4uznfjU.js} +1 -1
  143. package/build/assets/skill-scope-DH_AUUUP.js +1 -0
  144. package/build/assets/{skills-CYFLsN5U.js → skills-B0IliMxw.js} +1 -1
  145. package/build/assets/{skills-plugins-D0PiHWAD.js → skills-plugins-vfvOk34h.js} +1 -1
  146. package/build/assets/skills-settings-DnbIu2eO.js +2 -0
  147. package/build/assets/sparkles-g7y3r-Ut.js +1 -0
  148. package/build/assets/{styled-tooltip-C7grwnOX.js → styled-tooltip-CQ9JEFiO.js} +1 -1
  149. package/build/assets/{switch-skeleton-BQoOhQTB.js → switch-skeleton-DwOoCqaL.js} +1 -1
  150. package/build/assets/{syntax-highlighter-B92AFGMy.js → syntax-highlighter-BGDg_7w9.js} +1 -1
  151. package/build/assets/{task-list-tab-R3ac6m7O.js → task-list-tab-DeF_uXdw.js} +1 -1
  152. package/build/assets/{terminal-cMS3RgVE.js → terminal-BUpID2wS.js} +1 -1
  153. package/build/assets/{terminal-yqkNdEAx.js → terminal-DRc4rup7.js} +1 -1
  154. package/build/assets/{toggle-switch-BeSrbgCg.js → toggle-switch--8n8NeV_.js} +1 -1
  155. package/build/assets/{trash-2-wW5TWcdN.js → trash-2-CzDVN-Iw.js} +1 -1
  156. package/build/assets/{typography-iYhzLlHO.js → typography-BSbUhJPn.js} +1 -1
  157. package/build/assets/{u-check-circle-DBEvndTS.js → u-check-circle-BKn1spCL.js} +1 -1
  158. package/build/assets/{u-edit-809W9D9T.js → u-edit-DAkcF52u.js} +1 -1
  159. package/build/assets/{u-robot-CJtSzy5X.js → u-robot-BvAOA2ZD.js} +1 -1
  160. package/build/assets/{use-acp-credential-form-DUxbxmbq.js → use-acp-credential-form-BGKFi1VL.js} +1 -1
  161. package/build/assets/{use-activate-agent-profile-CDHA52tC.js → use-activate-agent-profile-2nvALjC-.js} +1 -1
  162. package/build/assets/{use-agent-profiles-TsOdIyw5.js → use-agent-profiles-BlQA67MW.js} +1 -1
  163. package/build/assets/{use-breakpoint-DA7JqsRN.js → use-breakpoint-DWtihr9g.js} +1 -1
  164. package/build/assets/{use-can-manage-org-profiles-Bt1M71u5.js → use-can-manage-org-profiles-Clw5Dh1s.js} +1 -1
  165. package/build/assets/{use-click-outside-element-DKqpqEEm.js → use-click-outside-element-W6Os4Nlb.js} +1 -1
  166. package/build/assets/{use-cloud-current-user-id-DWt7HCgf.js → use-cloud-current-user-id-B8AQSQFM.js} +1 -1
  167. package/build/assets/{use-config-CxlEdf_v.js → use-config-C3zGuUQI.js} +1 -1
  168. package/build/assets/{use-create-conversation-nOJ6Um5h.js → use-create-conversation-FaP0kUpg.js} +1 -1
  169. package/build/assets/{use-create-secret-Dj5ang9x.js → use-create-secret-CgQ3pXd6.js} +1 -1
  170. package/build/assets/use-is-authed-Bka89Xmm.js +1 -0
  171. package/build/assets/{use-is-creating-conversation-CAggrM75.js → use-is-creating-conversation-CVefC9Ns.js} +1 -1
  172. package/build/assets/{use-launch-skill-in-chat-DKzCTMt0.js → use-launch-skill-in-chat-BcKNjxxd.js} +1 -1
  173. package/build/assets/use-llm-profiles-C-tDO6UB.js +1 -0
  174. package/build/assets/use-manifest-capabilities-DLP5wCxp.js +1 -0
  175. package/build/assets/{use-onboarding-completion-gxQlcEy2.js → use-onboarding-completion-BiCdXvlU.js} +1 -1
  176. package/build/assets/{use-plugins-marketplace-CVO7sXYR.js → use-plugins-marketplace-DRFNLBlr.js} +1 -1
  177. package/build/assets/use-save-agent-profile-CaGVAudI.js +1 -0
  178. package/build/assets/{use-save-settings-L3aMaDeS.js → use-save-settings-C9B8Y-h3.js} +1 -1
  179. package/build/assets/{use-settings-8nt3DGxW.js → use-settings-3RcgdUuZ.js} +1 -1
  180. package/build/assets/{use-settings-nav-items-DHAAD-zk.js → use-settings-nav-items-y-Oyc93G.js} +2 -2
  181. package/build/assets/use-tracking-CTtkLAmx.js +3 -0
  182. package/build/assets/{use-user-conversation-BIIpGUgM.js → use-user-conversation-Bei82QsZ.js} +1 -1
  183. package/build/assets/{useInfiniteQuery-BLRVmVPU.js → useInfiniteQuery-DbCv0Jzd.js} +1 -1
  184. package/build/assets/{useMutation-CaSHLnX0.js → useMutation-ChpkYxI5.js} +1 -1
  185. package/build/assets/{useQueries--d_WWAzc.js → useQueries-Cjv3E8_1.js} +1 -1
  186. package/build/assets/useQuery-BCnzy4LX.js +1 -0
  187. package/build/assets/utils-BX9XJ0IE.js +1 -0
  188. package/build/assets/{vendor-markdown-BML7QbqS.js → vendor-markdown-j0kYzV48.js} +1 -1
  189. package/build/assets/{vendor-styling-Bcgpimp9.js → vendor-styling-Ck5D_A2Q.js} +6 -6
  190. package/build/assets/{vendor~browser-jaN4ilxM.js → vendor~browser-C6uXH-dw.js} +2 -2
  191. package/build/assets/vendor~browser-DJ1pl_wn.js +47 -0
  192. package/build/assets/{vendor~browser-tab-_-VCXq8n.js → vendor~browser-tab-C5uuAxZX.js} +1 -1
  193. package/build/assets/vendor~entry.client-CgNUwtQL.js +1 -0
  194. package/build/assets/{vendor~entry.client-BcYIVQvB.js → vendor~entry.client-zSIea5EO.js} +2 -2
  195. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~cy4jtuc2-rfV8mQ9m.js +1 -0
  196. package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0bpqexo-CbTboogo.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kv3pap4j-oGvLV0dO.js} +4 -4
  197. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~lq5hicxx-cHFhpUBq.js +26 -0
  198. package/build/assets/{vendor~files-tab-C7RmQJwN.js → vendor~files-tab-C87pjSpi.js} +1 -1
  199. package/build/assets/{vendor~index-home~home~conversation-panel~conversation-Bqp1ZqJM.js → vendor~index-home~home~conversation-panel~conversation-DiXf0dkj.js} +1 -1
  200. package/build/assets/{vendor~conversation-panel~conversation~alert-banner-BNzz5FuZ.js → vendor~index-home~home~conversation-panel~conversation~alert-banner-B3qC_oj8.js} +1 -1
  201. package/build/assets/{vendor~launch-ChXCOGw8.js → vendor~launch-CHwEQG6e.js} +1 -1
  202. package/build/assets/vendor~module-DyG7x7JT.js +2 -0
  203. package/build/assets/{vendor~root-layout~conversation-panel~conversation-BCn8lzeG.js → vendor~root-layout~conversation-panel~conversation-DEzjR4K7.js} +1 -1
  204. package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-DRblkyXD.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-DOuig0C0.js} +1 -1
  205. package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-U-xdsAEx.js +1 -0
  206. package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~automation-setup-route-B_L-gcOG.js → vendor~root-layout~index-home~home~conversation-panel~conversation~automation-setup-route-CjECvSl5.js} +1 -1
  207. package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-sjx0x5ac.js → vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-CQR5Sa0H.js} +1 -1
  208. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gy8zbn65-CGt6bWRT.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gxu4j2ea-Cwhh3zLe.js} +1 -1
  209. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~dfc8ddxy-tTyxnjXT.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-CuQhkiS7.js} +1 -1
  210. package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~9pstowjp-BOVIFA_g.js +73 -0
  211. package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~dufan6ng-Dtdw8H0q.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~ht43enc2-C0JXQb_q.js} +162 -54
  212. package/build/assets/{verification-settings-DBsnSXC3.js → verification-settings-nD61Ijph.js} +1 -1
  213. package/build/assets/wrench-DRitTfwe.js +1 -0
  214. package/build/assets/x-RYDBg-e2.js +1 -0
  215. package/build/assets/{x-mark-jcTkPiOB.js → x-mark-BopmFoBq.js} +1 -1
  216. package/build/assets/zap-tbKDzCe3.js +1 -0
  217. package/build/index.html +4 -4
  218. package/build/locales/ar/openhands.json +70 -4
  219. package/build/locales/ca/openhands.json +70 -4
  220. package/build/locales/de/openhands.json +70 -4
  221. package/build/locales/en/openhands.json +70 -4
  222. package/build/locales/es/openhands.json +70 -4
  223. package/build/locales/fr/openhands.json +70 -4
  224. package/build/locales/it/openhands.json +70 -4
  225. package/build/locales/ja/openhands.json +70 -4
  226. package/build/locales/ko-KR/openhands.json +70 -4
  227. package/build/locales/no/openhands.json +70 -4
  228. package/build/locales/pt/openhands.json +70 -4
  229. package/build/locales/tr/openhands.json +70 -4
  230. package/build/locales/uk/openhands.json +70 -4
  231. package/build/locales/zh-CN/openhands.json +70 -4
  232. package/build/locales/zh-TW/openhands.json +70 -4
  233. package/build/mockServiceWorker.js +21 -9
  234. package/config/defaults.json +3 -3
  235. package/dist/api/automation-service/automation-service.api.cjs +1 -1
  236. package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
  237. package/dist/api/automation-service/automation-service.api.d.ts +5 -0
  238. package/dist/api/automation-service/automation-service.api.js +11 -0
  239. package/dist/api/automation-service/automation-service.api.js.map +1 -1
  240. package/dist/api/backend-registry/active-store.cjs +1 -1
  241. package/dist/api/backend-registry/active-store.cjs.map +1 -1
  242. package/dist/api/backend-registry/active-store.js +36 -31
  243. package/dist/api/backend-registry/active-store.js.map +1 -1
  244. package/dist/api/backend-registry/url-selection.cjs +2 -0
  245. package/dist/api/backend-registry/url-selection.cjs.map +1 -0
  246. package/dist/api/backend-registry/url-selection.d.ts +31 -0
  247. package/dist/api/backend-registry/url-selection.js +29 -0
  248. package/dist/api/backend-registry/url-selection.js.map +1 -0
  249. package/dist/api/mcp-service/mcp-redacted-credentials.cjs +1 -1
  250. package/dist/api/mcp-service/mcp-redacted-credentials.cjs.map +1 -1
  251. package/dist/api/mcp-service/mcp-redacted-credentials.d.ts +3 -2
  252. package/dist/api/mcp-service/mcp-redacted-credentials.js +32 -27
  253. package/dist/api/mcp-service/mcp-redacted-credentials.js.map +1 -1
  254. package/dist/api/mcp-service/mcp-service.api.cjs +1 -1
  255. package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -1
  256. package/dist/api/mcp-service/mcp-service.api.js +19 -19
  257. package/dist/api/mcp-service/mcp-service.api.js.map +1 -1
  258. package/dist/api/settings-service/settings-service.api.cjs +1 -1
  259. package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
  260. package/dist/api/settings-service/settings-service.api.d.ts +10 -0
  261. package/dist/api/settings-service/settings-service.api.js +90 -100
  262. package/dist/api/settings-service/settings-service.api.js.map +1 -1
  263. package/dist/api/skills-service.cjs +1 -1
  264. package/dist/api/skills-service.cjs.map +1 -1
  265. package/dist/api/skills-service.js +1 -0
  266. package/dist/api/skills-service.js.map +1 -1
  267. package/dist/assets/chevron-left.d.ts +1 -1
  268. package/dist/assets/chevron-right.d.ts +1 -1
  269. package/dist/components/conversation-events/chat/event-message-components/collapsible-thinking.d.ts +2 -1
  270. package/dist/components/conversation-events/chat/event-message-components/critic-result-display.d.ts +2 -1
  271. package/dist/components/conversation-events/chat/event-message-components/error-event-message.d.ts +2 -1
  272. package/dist/components/conversation-events/chat/event-message-components/event-group.d.ts +1 -1
  273. package/dist/components/conversation-events/chat/event-message-components/finish-event-message.d.ts +1 -1
  274. package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.d.ts +1 -1
  275. package/dist/components/conversation-events/chat/event-message-components/observation-pair-event-message.d.ts +2 -1
  276. package/dist/components/conversation-events/chat/event-message-components/skill-item-expanded.d.ts +1 -1
  277. package/dist/components/conversation-events/chat/event-message-components/skill-ready-content-list.d.ts +2 -1
  278. package/dist/components/conversation-events/chat/event-message-components/thought-event-message.d.ts +1 -1
  279. package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.d.ts +2 -1
  280. package/dist/components/conversation-events/chat/event-message.d.ts +2 -1
  281. package/dist/components/conversation-events/chat/task-tracking/task-item.d.ts +1 -1
  282. package/dist/components/conversation-events/chat/task-tracking/task-list-section.d.ts +1 -1
  283. package/dist/components/features/alerts/alert-banner.d.ts +1 -1
  284. package/dist/components/features/analytics/telemetry-consent-banner.d.ts +2 -1
  285. package/dist/components/features/automations/add-automation-modal.d.ts +1 -1
  286. package/dist/components/features/automations/automation-card-skeleton.d.ts +1 -1
  287. package/dist/components/features/automations/automation-card.d.ts +9 -1
  288. package/dist/components/features/automations/automation-group.d.ts +9 -1
  289. package/dist/components/features/automations/automation-health-badge.d.ts +8 -0
  290. package/dist/components/features/automations/automation-list-row.d.ts +3 -1
  291. package/dist/components/features/automations/automation-run-insights.d.ts +17 -0
  292. package/dist/components/features/automations/automation-view-toggle.d.ts +1 -1
  293. package/dist/components/features/automations/backend-not-configured.d.ts +1 -1
  294. package/dist/components/features/automations/create-instructions.d.ts +2 -2
  295. package/dist/components/features/automations/dashboard/automations-dashboard-controls.d.ts +18 -0
  296. package/dist/components/features/automations/dashboard/automations-filtered-empty-state.d.ts +9 -0
  297. package/dist/components/features/automations/dashboard/use-automation-sub-page-nav.d.ts +12 -0
  298. package/dist/components/features/automations/delete-confirmation-modal.d.ts +1 -1
  299. package/dist/components/features/automations/detail/active-status-badge.d.ts +1 -1
  300. package/dist/components/features/automations/detail/activity-log-item.d.ts +1 -1
  301. package/dist/components/features/automations/detail/activity-log-section.d.ts +3 -1
  302. package/dist/components/features/automations/detail/activity-section.d.ts +1 -1
  303. package/dist/components/features/automations/detail/back-link.d.ts +1 -1
  304. package/dist/components/features/automations/detail/branch-badge.d.ts +1 -1
  305. package/dist/components/features/automations/detail/config-field.d.ts +1 -1
  306. package/dist/components/features/automations/detail/configuration-section.d.ts +1 -1
  307. package/dist/components/features/automations/detail/debug-automation-button.d.ts +1 -1
  308. package/dist/components/features/automations/detail/detail-header.d.ts +1 -1
  309. package/dist/components/features/automations/detail/detail-skeleton.d.ts +1 -1
  310. package/dist/components/features/automations/detail/edit-automation-modal.d.ts +1 -1
  311. package/dist/components/features/automations/detail/not-found-state.d.ts +1 -1
  312. package/dist/components/features/automations/detail/plugin-chip.d.ts +1 -1
  313. package/dist/components/features/automations/detail/plugins-section.d.ts +1 -1
  314. package/dist/components/features/automations/detail/prompt-section.d.ts +2 -1
  315. package/dist/components/features/automations/detail/run-logs-modal.d.ts +1 -1
  316. package/dist/components/features/automations/detail/run-status-badge.d.ts +10 -1
  317. package/dist/components/features/automations/detail/section-card.d.ts +1 -1
  318. package/dist/components/features/automations/empty-state.d.ts +1 -1
  319. package/dist/components/features/automations/error-state.d.ts +1 -1
  320. package/dist/components/features/automations/import-automation-modal.d.ts +1 -1
  321. package/dist/components/features/automations/kebab-menu-item-content.d.ts +1 -1
  322. package/dist/components/features/automations/kebab-menu.d.ts +1 -1
  323. package/dist/components/features/automations/metadata-chip.d.ts +1 -1
  324. package/dist/components/features/automations/recommended-automations-launcher.d.ts +1 -1
  325. package/dist/components/features/automations/recommended-automations-section.d.ts +1 -1
  326. package/dist/components/features/automations/responder-deployment-modal.d.ts +1 -1
  327. package/dist/components/features/automations/search-input.d.ts +1 -1
  328. package/dist/components/features/automations/status-badge.d.ts +1 -1
  329. package/dist/components/features/automations/turn-off-confirmation-modal.d.ts +8 -0
  330. package/dist/components/features/automations/view-menu-item-content.d.ts +1 -1
  331. package/dist/components/features/backends/add-backend-modal.d.ts +1 -1
  332. package/dist/components/features/backends/api-key-entry-screen.d.ts +2 -1
  333. package/dist/components/features/backends/backend-form-modal.d.ts +3 -3
  334. package/dist/components/features/backends/backend-row.d.ts +1 -1
  335. package/dist/components/features/backends/backend-selector.d.ts +2 -1
  336. package/dist/components/features/backends/backend-status-dot.d.ts +2 -1
  337. package/dist/components/features/backends/backend-version.d.ts +1 -1
  338. package/dist/components/features/backends/device-flow-auth.d.ts +1 -1
  339. package/dist/components/features/backends/manage-backends-modal.d.ts +2 -1
  340. package/dist/components/features/browser/browser-chrome-bar.d.ts +1 -1
  341. package/dist/components/features/browser/browser-snapshot.d.ts +1 -1
  342. package/dist/components/features/browser/browser.d.ts +1 -1
  343. package/dist/components/features/browser/empty-browser-message.d.ts +1 -1
  344. package/dist/components/features/chat/btw-messages.d.ts +1 -1
  345. package/dist/components/features/chat/change-agent-button.d.ts +2 -1
  346. package/dist/components/features/chat/change-agent-context-menu.d.ts +1 -1
  347. package/dist/components/features/chat/chat-action-tooltip.d.ts +1 -1
  348. package/dist/components/features/chat/chat-add-file-button.d.ts +2 -1
  349. package/dist/components/features/chat/chat-interface.d.ts +2 -1
  350. package/dist/components/features/chat/chat-message.d.ts +1 -1
  351. package/dist/components/features/chat/chat-messages-skeleton.d.ts +2 -1
  352. package/dist/components/features/chat/chat-play-button.d.ts +1 -1
  353. package/dist/components/features/chat/chat-send-button.d.ts +1 -1
  354. package/dist/components/features/chat/chat-status-indicator.d.ts +1 -1
  355. package/dist/components/features/chat/chat-stop-button.d.ts +1 -1
  356. package/dist/components/features/chat/chat-suggestions.d.ts +1 -1
  357. package/dist/components/features/chat/components/chat-input-actions.d.ts +2 -1
  358. package/dist/components/features/chat/components/chat-input-container.d.ts +1 -1
  359. package/dist/components/features/chat/components/chat-input-field.d.ts +1 -1
  360. package/dist/components/features/chat/components/chat-input-grip.d.ts +1 -1
  361. package/dist/components/features/chat/components/chat-input-llm-profile-picker.d.ts +3 -2
  362. package/dist/components/features/chat/components/chat-input-model.d.ts +3 -2
  363. package/dist/components/features/chat/components/chat-input-profile-picker.d.ts +1 -1
  364. package/dist/components/features/chat/components/chat-input-row.d.ts +1 -1
  365. package/dist/components/features/chat/components/hidden-file-input.d.ts +1 -1
  366. package/dist/components/features/chat/components/slash-command-menu.d.ts +2 -1
  367. package/dist/components/features/chat/confirmation-mode-enabled.d.ts +1 -1
  368. package/dist/components/features/chat/custom-chat-input.d.ts +1 -1
  369. package/dist/components/features/chat/drag-over.d.ts +1 -1
  370. package/dist/components/features/chat/error-message-banner.d.ts +2 -1
  371. package/dist/components/features/chat/error-message.d.ts +2 -1
  372. package/dist/components/features/chat/generic-event-message.d.ts +1 -1
  373. package/dist/components/features/chat/git-control-bar-branch-button.d.ts +1 -1
  374. package/dist/components/features/chat/git-control-bar-pr-button.d.ts +1 -1
  375. package/dist/components/features/chat/git-control-bar-pull-button.d.ts +1 -1
  376. package/dist/components/features/chat/git-control-bar-push-button.d.ts +1 -1
  377. package/dist/components/features/chat/git-control-bar-repo-button.d.ts +1 -1
  378. package/dist/components/features/chat/git-control-bar-tooltip-wrapper.d.ts +1 -1
  379. package/dist/components/features/chat/git-control-bar.d.ts +1 -1
  380. package/dist/components/features/chat/git-external-link-icon.d.ts +1 -1
  381. package/dist/components/features/chat/goal-status-banner.d.ts +1 -1
  382. package/dist/components/features/chat/goal-status-content.d.ts +1 -1
  383. package/dist/components/features/chat/got-it-button.d.ts +1 -1
  384. package/dist/components/features/chat/interactive-chat-box.d.ts +1 -1
  385. package/dist/components/features/chat/model-messages.d.ts +2 -1
  386. package/dist/components/features/chat/mono-component.d.ts +1 -1
  387. package/dist/components/features/chat/open-repository-modal.d.ts +2 -1
  388. package/dist/components/features/chat/pasted-image-upload-as-file-button.d.ts +1 -1
  389. package/dist/components/features/chat/path-component.d.ts +1 -1
  390. package/dist/components/features/chat/pending-stop-icon.d.ts +1 -1
  391. package/dist/components/features/chat/pending-user-messages.d.ts +2 -1
  392. package/dist/components/features/chat/plan-preview.d.ts +1 -1
  393. package/dist/components/features/chat/remove-file-button.d.ts +1 -1
  394. package/dist/components/features/chat/skill-install-restart-banner.d.ts +1 -1
  395. package/dist/components/features/chat/success-indicator.d.ts +1 -1
  396. package/dist/components/features/chat/task-tracking/status-badge.d.ts +1 -1
  397. package/dist/components/features/chat/task-tracking/status-icon.d.ts +1 -1
  398. package/dist/components/features/chat/task-tracking/task-item.d.ts +1 -1
  399. package/dist/components/features/chat/task-tracking/task-list-section.d.ts +1 -1
  400. package/dist/components/features/chat/tool-visualizers/primitives/code-block.d.ts +2 -1
  401. package/dist/components/features/chat/tool-visualizers/primitives/diff-view.d.ts +2 -1
  402. package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.d.ts +2 -1
  403. package/dist/components/features/chat/tool-visualizers/primitives/key-value-grid.d.ts +1 -1
  404. package/dist/components/features/chat/tool-visualizers/primitives/output-pane.d.ts +2 -1
  405. package/dist/components/features/chat/typing-indicator.d.ts +1 -1
  406. package/dist/components/features/chat/uploaded-file.d.ts +1 -1
  407. package/dist/components/features/chat/uploaded-files.d.ts +1 -1
  408. package/dist/components/features/chat/uploaded-image.d.ts +2 -1
  409. package/dist/components/features/chat/user-message-body.d.ts +2 -2
  410. package/dist/components/features/chat/waiting-for-runtime-message.d.ts +1 -1
  411. package/dist/components/features/chat/workspace-mode-icon.d.ts +1 -1
  412. package/dist/components/features/chat/workspace-mode-selector.d.ts +1 -1
  413. package/dist/components/features/command-menu/command-menu-trigger.d.ts +2 -1
  414. package/dist/components/features/context-menu/archived-disabled-tooltip.d.ts +1 -1
  415. package/dist/components/features/context-menu/context-menu-icon-text-with-description.d.ts +1 -1
  416. package/dist/components/features/context-menu/context-menu-icon-text.d.ts +1 -1
  417. package/dist/components/features/context-menu/context-menu-list-item.cjs +1 -1
  418. package/dist/components/features/context-menu/context-menu-list-item.cjs.map +1 -1
  419. package/dist/components/features/context-menu/context-menu-list-item.d.ts +2 -1
  420. package/dist/components/features/context-menu/context-menu-list-item.js +2 -1
  421. package/dist/components/features/context-menu/context-menu-list-item.js.map +1 -1
  422. package/dist/components/features/controls/agent-loading.d.ts +1 -1
  423. package/dist/components/features/controls/agent-status.d.ts +1 -1
  424. package/dist/components/features/controls/git-tools-submenu.d.ts +1 -1
  425. package/dist/components/features/controls/macros-submenu.d.ts +1 -1
  426. package/dist/components/features/controls/server-status-context-menu-icon-text.d.ts +1 -1
  427. package/dist/components/features/controls/server-status-context-menu.d.ts +1 -1
  428. package/dist/components/features/controls/server-status.d.ts +1 -1
  429. package/dist/components/features/controls/tools-context-menu-icon-text.d.ts +1 -1
  430. package/dist/components/features/controls/tools-context-menu.d.ts +1 -1
  431. package/dist/components/features/controls/tools.d.ts +2 -1
  432. package/dist/components/features/conversation/conversation-loading.d.ts +1 -1
  433. package/dist/components/features/conversation/conversation-main/chat-interface-wrapper.d.ts +1 -1
  434. package/dist/components/features/conversation/conversation-main/conversation-main.d.ts +1 -1
  435. package/dist/components/features/conversation/conversation-main/conversation-mobile-panel-page.d.ts +2 -1
  436. package/dist/components/features/conversation/conversation-name-context-menu-icon-text.d.ts +1 -1
  437. package/dist/components/features/conversation/conversation-name-context-menu.d.ts +1 -1
  438. package/dist/components/features/conversation/conversation-name-with-status.d.ts +2 -1
  439. package/dist/components/features/conversation/conversation-name.d.ts +2 -1
  440. package/dist/components/features/conversation/conversation-tab-empty-state.d.ts +1 -1
  441. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content-crossfade.d.ts +1 -1
  442. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.d.ts +1 -1
  443. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/suspense-pending-fallback.d.ts +1 -1
  444. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/tab-container.d.ts +1 -1
  445. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/tab-content-area.d.ts +1 -1
  446. package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/tab-wrapper.d.ts +1 -1
  447. package/dist/components/features/conversation/conversation-tabs/conversation-tab-nav.d.ts +1 -1
  448. package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.d.ts +1 -1
  449. package/dist/components/features/conversation/conversation-tabs/conversation-tabs.d.ts +1 -1
  450. package/dist/components/features/conversation/conversation-tabs/drawer-vscode-link.d.ts +1 -1
  451. package/dist/components/features/conversation/metrics-modal/context-window-section.d.ts +1 -1
  452. package/dist/components/features/conversation/metrics-modal/cost-section.d.ts +1 -1
  453. package/dist/components/features/conversation/metrics-modal/empty-state.d.ts +1 -1
  454. package/dist/components/features/conversation/metrics-modal/metric-row.d.ts +1 -1
  455. package/dist/components/features/conversation/metrics-modal/metrics-modal-header.d.ts +1 -1
  456. package/dist/components/features/conversation/metrics-modal/metrics-modal.d.ts +1 -1
  457. package/dist/components/features/conversation/metrics-modal/usage-section.d.ts +1 -1
  458. package/dist/components/features/conversation/right-panel-toggle.d.ts +1 -1
  459. package/dist/components/features/conversation/transcript-export-modal.d.ts +2 -1
  460. package/dist/components/features/conversation-panel/budget-display.d.ts +2 -1
  461. package/dist/components/features/conversation-panel/budget-progress-bar.d.ts +1 -1
  462. package/dist/components/features/conversation-panel/budget-usage-text.d.ts +2 -1
  463. package/dist/components/features/conversation-panel/cloud-new-conversation-menu.d.ts +1 -1
  464. package/dist/components/features/conversation-panel/compact-conversation-row.cjs +1 -1
  465. package/dist/components/features/conversation-panel/compact-conversation-row.cjs.map +1 -1
  466. package/dist/components/features/conversation-panel/compact-conversation-row.d.ts +2 -1
  467. package/dist/components/features/conversation-panel/compact-conversation-row.js +38 -37
  468. package/dist/components/features/conversation-panel/compact-conversation-row.js.map +1 -1
  469. package/dist/components/features/conversation-panel/confirm-delete-modal.d.ts +1 -1
  470. package/dist/components/features/conversation-panel/confirm-stop-modal.d.ts +1 -1
  471. package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.d.ts +1 -1
  472. package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.d.ts +1 -1
  473. package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.d.ts +1 -1
  474. package/dist/components/features/conversation-panel/conversation-card/conversation-card-header.d.ts +1 -1
  475. package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.d.ts +1 -1
  476. package/dist/components/features/conversation-panel/conversation-card/conversation-card-skeleton.d.ts +1 -1
  477. package/dist/components/features/conversation-panel/conversation-card/conversation-card-title.d.ts +1 -1
  478. package/dist/components/features/conversation-panel/conversation-card/conversation-card.d.ts +2 -1
  479. package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.d.ts +1 -1
  480. package/dist/components/features/conversation-panel/conversation-card/conversation-status-badges.d.ts +1 -1
  481. package/dist/components/features/conversation-panel/conversation-card/no-repository.d.ts +1 -1
  482. package/dist/components/features/conversation-panel/conversation-group-folder-list.d.ts +1 -1
  483. package/dist/components/features/conversation-panel/conversation-group-folder-row.d.ts +1 -1
  484. package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +1 -1
  485. package/dist/components/features/conversation-panel/conversation-panel-new-thread-picker.d.ts +1 -1
  486. package/dist/components/features/conversation-panel/conversation-panel-pinned-section.d.ts +1 -1
  487. package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
  488. package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
  489. package/dist/components/features/conversation-panel/conversation-panel.d.ts +2 -1
  490. package/dist/components/features/conversation-panel/conversation-panel.js +221 -220
  491. package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
  492. package/dist/components/features/conversation-panel/conversation-status-dot.d.ts +1 -1
  493. package/dist/components/features/conversation-panel/exit-conversation-modal.d.ts +1 -1
  494. package/dist/components/features/conversation-panel/hook-event-item.d.ts +1 -1
  495. package/dist/components/features/conversation-panel/hook-matcher-content.d.ts +1 -1
  496. package/dist/components/features/conversation-panel/hooks-empty-state.d.ts +1 -1
  497. package/dist/components/features/conversation-panel/hooks-loading-state.d.ts +1 -1
  498. package/dist/components/features/conversation-panel/hooks-modal-header.d.ts +1 -1
  499. package/dist/components/features/conversation-panel/hooks-modal.d.ts +1 -1
  500. package/dist/components/features/conversation-panel/local-new-conversation-menu.d.ts +1 -1
  501. package/dist/components/features/conversation-panel/menu-heading.d.ts +1 -1
  502. package/dist/components/features/conversation-panel/menu-row.d.ts +1 -1
  503. package/dist/components/features/conversation-panel/menu-separator.d.ts +1 -1
  504. package/dist/components/features/conversation-panel/new-conversation-button.d.ts +2 -1
  505. package/dist/components/features/conversation-panel/plugins-modal.d.ts +1 -1
  506. package/dist/components/features/conversation-panel/runtime-waiting-state.d.ts +1 -1
  507. package/dist/components/features/conversation-panel/skill-content.d.ts +1 -1
  508. package/dist/components/features/conversation-panel/skill-item.d.ts +1 -1
  509. package/dist/components/features/conversation-panel/skill-triggers.d.ts +1 -1
  510. package/dist/components/features/conversation-panel/skills-empty-state.d.ts +1 -1
  511. package/dist/components/features/conversation-panel/skills-loading-state.d.ts +1 -1
  512. package/dist/components/features/conversation-panel/skills-modal-header.d.ts +1 -1
  513. package/dist/components/features/conversation-panel/skills-modal-section.d.ts +1 -1
  514. package/dist/components/features/conversation-panel/skills-modal.d.ts +1 -1
  515. package/dist/components/features/conversation-panel/start-task-card/start-task-card-footer.d.ts +1 -1
  516. package/dist/components/features/conversation-panel/start-task-card/start-task-card-header.d.ts +1 -1
  517. package/dist/components/features/conversation-panel/start-task-card/start-task-card.d.ts +1 -1
  518. package/dist/components/features/conversation-panel/start-task-card/start-task-status-badge.d.ts +1 -1
  519. package/dist/components/features/conversation-panel/start-task-card/start-task-status-indicator.d.ts +1 -1
  520. package/dist/components/features/conversation-panel/system-message-modal/empty-tools-state.d.ts +1 -1
  521. package/dist/components/features/conversation-panel/system-message-modal/system-message-content.d.ts +1 -1
  522. package/dist/components/features/conversation-panel/system-message-modal/system-message-header.d.ts +1 -1
  523. package/dist/components/features/conversation-panel/system-message-modal/tab-button.d.ts +1 -1
  524. package/dist/components/features/conversation-panel/system-message-modal/tab-content.d.ts +1 -1
  525. package/dist/components/features/conversation-panel/system-message-modal/tab-navigation.d.ts +1 -1
  526. package/dist/components/features/conversation-panel/system-message-modal/toggle-button.d.ts +1 -1
  527. package/dist/components/features/conversation-panel/system-message-modal/tool-item.d.ts +1 -1
  528. package/dist/components/features/conversation-panel/system-message-modal/tool-parameters.d.ts +1 -1
  529. package/dist/components/features/conversation-panel/system-message-modal/tools-list.d.ts +1 -1
  530. package/dist/components/features/conversation-panel/system-message-modal.d.ts +1 -1
  531. package/dist/components/features/diff-viewer/commit-list.d.ts +2 -1
  532. package/dist/components/features/diff-viewer/commit-row.d.ts +2 -1
  533. package/dist/components/features/diff-viewer/diff-drawer-icon.d.ts +1 -1
  534. package/dist/components/features/diff-viewer/editor-container.d.ts +1 -1
  535. package/dist/components/features/diff-viewer/empty-changes-message.d.ts +1 -1
  536. package/dist/components/features/diff-viewer/file-diff-viewer.d.ts +2 -1
  537. package/dist/components/features/diff-viewer/loading-spinner.d.ts +1 -1
  538. package/dist/components/features/files/file-item.d.ts +1 -1
  539. package/dist/components/features/files/file-list.d.ts +2 -1
  540. package/dist/components/features/files-tab/file-content-viewer.d.ts +1 -1
  541. package/dist/components/features/files-tab/file-quick-row.d.ts +1 -1
  542. package/dist/components/features/files-tab/file-tree-view.d.ts +1 -1
  543. package/dist/components/features/files-tab/highlighted-source-view.d.ts +1 -1
  544. package/dist/components/features/files-tab/no-file-selected-message.d.ts +1 -1
  545. package/dist/components/features/files-tab/segmented-toggle.d.ts +1 -1
  546. package/dist/components/features/files-tab/tree-node.d.ts +1 -1
  547. package/dist/components/features/home/featured-automations/automation-health-indicator.d.ts +11 -0
  548. package/dist/components/features/home/featured-automations/automation-run-activity-metrics.d.ts +18 -0
  549. package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.d.ts +14 -0
  550. package/dist/components/features/home/featured-automations/automation-run-health.d.ts +25 -0
  551. package/dist/components/features/home/featured-automations/build-home-automation-menu-items.d.ts +39 -0
  552. package/dist/components/features/home/featured-automations/build-pinned-automation-menu-items.d.ts +22 -0
  553. package/dist/components/features/home/featured-automations/home-automation-activity.d.ts +23 -0
  554. package/dist/components/features/home/featured-automations/home-automation-menu.d.ts +13 -0
  555. package/dist/components/features/home/featured-automations/home-automation-run-tooltip.d.ts +12 -0
  556. package/dist/components/features/home/featured-automations/pinned-automation-card.d.ts +21 -0
  557. package/dist/components/features/home/featured-automations/pinned-automations-dashboard.d.ts +6 -0
  558. package/dist/components/features/home/featured-automations/running-automations-list.d.ts +6 -0
  559. package/dist/components/features/home/git-branch-dropdown/branch-dropdown-menu.d.ts +1 -1
  560. package/dist/components/features/home/git-branch-dropdown/git-branch-dropdown.d.ts +2 -1
  561. package/dist/components/features/home/git-provider-dropdown/git-provider-dropdown.d.ts +2 -1
  562. package/dist/components/features/home/git-repo-dropdown/git-repo-dropdown.d.ts +2 -1
  563. package/dist/components/features/home/home-chat-launcher.d.ts +1 -1
  564. package/dist/components/features/home/home-git-control-bar-preview.d.ts +1 -1
  565. package/dist/components/features/home/home-header/guide-message.d.ts +1 -1
  566. package/dist/components/features/home/home-header/home-header-title.d.ts +1 -1
  567. package/dist/components/features/home/home-header/home-header.d.ts +1 -1
  568. package/dist/components/features/home/llm-not-configured-banner.d.ts +1 -1
  569. package/dist/components/features/home/new-conversation/create-conversation-button.d.ts +1 -1
  570. package/dist/components/features/home/new-conversation/new-conversation.d.ts +1 -1
  571. package/dist/components/features/home/new-conversation.d.ts +1 -1
  572. package/dist/components/features/home/open-launcher-button.d.ts +1 -1
  573. package/dist/components/features/home/open-repository-dialog.d.ts +1 -1
  574. package/dist/components/features/home/open-workspace-dialog.d.ts +1 -1
  575. package/dist/components/features/home/repo-selection-form.d.ts +2 -1
  576. package/dist/components/features/home/shared/clear-button.d.ts +2 -1
  577. package/dist/components/features/home/shared/dropdown-item.d.ts +1 -1
  578. package/dist/components/features/home/shared/empty-state.d.ts +2 -1
  579. package/dist/components/features/home/shared/error-message.d.ts +2 -1
  580. package/dist/components/features/home/shared/generic-dropdown-menu.d.ts +1 -1
  581. package/dist/components/features/home/shared/loading-spinner.d.ts +2 -1
  582. package/dist/components/features/home/shared/toggle-button.d.ts +1 -1
  583. package/dist/components/features/home/tasks/task-card.d.ts +1 -1
  584. package/dist/components/features/home/tasks/task-group.d.ts +1 -1
  585. package/dist/components/features/home/tasks/task-issue-number.d.ts +1 -1
  586. package/dist/components/features/home/tasks/task-item-title.d.ts +1 -1
  587. package/dist/components/features/home/tasks/task-suggestions-skeleton.d.ts +1 -1
  588. package/dist/components/features/home/tasks/task-suggestions.d.ts +1 -1
  589. package/dist/components/features/home/workspace-dropdown/folder-browser-modal.d.ts +2 -1
  590. package/dist/components/features/home/workspace-dropdown/manage-workspaces-modal.d.ts +2 -1
  591. package/dist/components/features/home/workspace-dropdown/workspace-dropdown.d.ts +2 -1
  592. package/dist/components/features/home/workspace-selection-form.d.ts +2 -1
  593. package/dist/components/features/images/image-carousel.d.ts +2 -1
  594. package/dist/components/features/images/image-preview.d.ts +1 -1
  595. package/dist/components/features/images/thumbnail.d.ts +1 -1
  596. package/dist/components/features/launch/plugin-launch-modal.d.ts +2 -1
  597. package/dist/components/features/launch/plugin-launch-parameter-input.d.ts +1 -1
  598. package/dist/components/features/launch/plugin-launch-plugin-section.d.ts +1 -1
  599. package/dist/components/features/manifest/manifest-form-field.d.ts +1 -1
  600. package/dist/components/features/manifest/manifest-icons.d.ts +13 -0
  601. package/dist/components/features/manifest/manifest-overview-tiles.d.ts +19 -0
  602. package/dist/components/features/manifest/manifest-prerequisites-step.d.ts +1 -1
  603. package/dist/components/features/manifest/manifest-review-step.d.ts +1 -1
  604. package/dist/components/features/manifest/manifest-setup-dialog.d.ts +1 -1
  605. package/dist/components/features/manifest/manifest-subpage-layout.d.ts +23 -0
  606. package/dist/components/features/markdown/anchor.d.ts +1 -1
  607. package/dist/components/features/markdown/blockquote.d.ts +1 -1
  608. package/dist/components/features/markdown/code.d.ts +1 -1
  609. package/dist/components/features/markdown/headings.d.ts +6 -6
  610. package/dist/components/features/markdown/horizontal-rule.d.ts +1 -1
  611. package/dist/components/features/markdown/list.d.ts +3 -3
  612. package/dist/components/features/markdown/markdown-renderer.d.ts +1 -1
  613. package/dist/components/features/markdown/markdown-table-scroll.d.ts +1 -1
  614. package/dist/components/features/markdown/paragraph.d.ts +1 -1
  615. package/dist/components/features/markdown/plan-components.d.ts +36 -36
  616. package/dist/components/features/markdown/table.d.ts +3 -3
  617. package/dist/components/features/mcp-logo-badge.d.ts +1 -1
  618. package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
  619. package/dist/components/features/mcp-page/custom-server-editor.cjs.map +1 -1
  620. package/dist/components/features/mcp-page/custom-server-editor.d.ts +2 -1
  621. package/dist/components/features/mcp-page/custom-server-editor.js +5 -0
  622. package/dist/components/features/mcp-page/custom-server-editor.js.map +1 -1
  623. package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
  624. package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
  625. package/dist/components/features/mcp-page/install-server-modal.d.ts +2 -1
  626. package/dist/components/features/mcp-page/install-server-modal.js +117 -118
  627. package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
  628. package/dist/components/features/mcp-page/installed-server-card.d.ts +2 -1
  629. package/dist/components/features/mcp-page/installed-servers-section.d.ts +1 -1
  630. package/dist/components/features/mcp-page/marketplace-card.d.ts +1 -1
  631. package/dist/components/features/mcp-page/marketplace-section.d.ts +1 -1
  632. package/dist/components/features/mcp-page/mcp-logo-stack-badge.d.ts +1 -1
  633. package/dist/components/features/mcp-page/mcp-section-filter-dropdown.d.ts +1 -1
  634. package/dist/components/features/mcp-page/mcp-server-health.d.ts +2 -1
  635. package/dist/components/features/mcp-page/mcp-toolbar.d.ts +1 -1
  636. package/dist/components/features/mcp-page/save-as-secret-toggle.d.ts +1 -1
  637. package/dist/components/features/onboarding/onboarding-host.d.ts +1 -1
  638. package/dist/components/features/onboarding/onboarding-modal.d.ts +2 -1
  639. package/dist/components/features/onboarding/onboarding-progress-bar.d.ts +1 -1
  640. package/dist/components/features/onboarding/steps/check-backend-step.d.ts +2 -1
  641. package/dist/components/features/onboarding/steps/choose-agent-step.d.ts +3 -2
  642. package/dist/components/features/onboarding/steps/say-hello-step.d.ts +2 -1
  643. package/dist/components/features/onboarding/steps/setup-acp-secrets-step.d.ts +2 -1
  644. package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +2 -1
  645. package/dist/components/features/plugins/add-plugin-modal.d.ts +2 -1
  646. package/dist/components/features/plugins/plugin-card.d.ts +2 -1
  647. package/dist/components/features/plugins/plugin-detail-modal.d.ts +1 -1
  648. package/dist/components/features/plugins/plugin-files-section.d.ts +2 -1
  649. package/dist/components/features/plugins/plugin-picker-card.d.ts +1 -1
  650. package/dist/components/features/plugins/plugin-picker-modal.d.ts +1 -1
  651. package/dist/components/features/plugins/plugin-picker-trigger.d.ts +1 -1
  652. package/dist/components/features/plugins/plugin-picker.d.ts +1 -1
  653. package/dist/components/features/plugins/plugins-toolbar.d.ts +1 -1
  654. package/dist/components/features/settings/acp-auth-status-banner.d.ts +1 -1
  655. package/dist/components/features/settings/acp-conflict-warnings.d.ts +2 -1
  656. package/dist/components/features/settings/acp-credentials-section.d.ts +1 -1
  657. package/dist/components/features/settings/acp-secret-field.d.ts +2 -1
  658. package/dist/components/features/settings/agent-canvas-update-card.d.ts +1 -1
  659. package/dist/components/features/settings/agent-profiles/agent-profile-actions-menu.d.ts +1 -1
  660. package/dist/components/features/settings/agent-profiles/agent-profile-row.d.ts +1 -1
  661. package/dist/components/features/settings/agent-profiles/agent-profiles-body.d.ts +1 -1
  662. package/dist/components/features/settings/agent-profiles/agent-profiles-local-view.d.ts +1 -1
  663. package/dist/components/features/settings/agent-profiles/agent-profiles-manager.d.ts +1 -1
  664. package/dist/components/features/settings/agent-profiles/delete-agent-profile-modal.d.ts +1 -1
  665. package/dist/components/features/settings/agent-server-onboarding.d.ts +2 -1
  666. package/dist/components/features/settings/api-key-modal-base.d.ts +1 -1
  667. package/dist/components/features/settings/app-settings/app-settings-inputs-skeleton.d.ts +1 -1
  668. package/dist/components/features/settings/app-settings/language-input.d.ts +1 -1
  669. package/dist/components/features/settings/app-settings/theme-input.d.ts +2 -1
  670. package/dist/components/features/settings/backend-synced-settings-badge.d.ts +1 -1
  671. package/dist/components/features/settings/banner-message.d.ts +1 -1
  672. package/dist/components/features/settings/cloud-settings-link.d.ts +1 -1
  673. package/dist/components/features/settings/input-skeleton.d.ts +1 -1
  674. package/dist/components/features/settings/integrations-settings-link.d.ts +1 -1
  675. package/dist/components/features/settings/key-status-icon.d.ts +1 -1
  676. package/dist/components/features/settings/llm-profiles/delete-profile-modal.d.ts +1 -1
  677. package/dist/components/features/settings/llm-profiles/llm-profiles-manager.d.ts +1 -1
  678. package/dist/components/features/settings/llm-profiles/llm-settings-local-view.d.ts +2 -1
  679. package/dist/components/features/settings/llm-profiles/profile-actions-menu-item.d.ts +1 -1
  680. package/dist/components/features/settings/llm-profiles/profile-actions-menu.d.ts +1 -1
  681. package/dist/components/features/settings/llm-profiles/profile-row.d.ts +1 -1
  682. package/dist/components/features/settings/llm-profiles/profiles-body.d.ts +1 -1
  683. package/dist/components/features/settings/llm-profiles/rename-profile-modal.d.ts +1 -1
  684. package/dist/components/features/settings/llm-settings/llm-settings-inputs-skeleton.d.ts +1 -1
  685. package/dist/components/features/settings/llm-settings/openai-subscription-auth-card.d.ts +2 -1
  686. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +1 -1
  687. package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
  688. package/dist/components/features/settings/mcp-settings/mcp-server-form.d.ts +2 -1
  689. package/dist/components/features/settings/mcp-settings/mcp-server-form.js +2 -1
  690. package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
  691. package/dist/components/features/settings/mcp-settings/mcp-server-list-item.d.ts +1 -1
  692. package/dist/components/features/settings/mcp-settings/mcp-server-list.d.ts +1 -1
  693. package/dist/components/features/settings/mobile-header.d.ts +1 -1
  694. package/dist/components/features/settings/optional-tag.d.ts +1 -1
  695. package/dist/components/features/settings/sdk-settings/field-help.d.ts +1 -1
  696. package/dist/components/features/settings/sdk-settings/schema-field.d.ts +2 -1
  697. package/dist/components/features/settings/sdk-settings/sdk-section-page.d.ts +1 -1
  698. package/dist/components/features/settings/sdk-settings/view-toggle.d.ts +1 -1
  699. package/dist/components/features/settings/secrets-settings/secret-form.d.ts +2 -1
  700. package/dist/components/features/settings/secrets-settings/secret-list-item.d.ts +2 -2
  701. package/dist/components/features/settings/settings-desktop-sidebar.d.ts +1 -1
  702. package/dist/components/features/settings/settings-dropdown-input.d.ts +1 -1
  703. package/dist/components/features/settings/settings-layout.d.ts +1 -1
  704. package/dist/components/features/settings/settings-mobile-drawer.d.ts +1 -1
  705. package/dist/components/features/settings/settings-mobile-hub.d.ts +1 -1
  706. package/dist/components/features/settings/settings-nav-divider.d.ts +1 -1
  707. package/dist/components/features/settings/settings-nav-header.d.ts +1 -1
  708. package/dist/components/features/settings/settings-nav-link.d.ts +1 -1
  709. package/dist/components/features/settings/settings-navigation.d.ts +1 -1
  710. package/dist/components/features/settings/settings-switch.d.ts +1 -1
  711. package/dist/components/features/settings/subtext-skeleton.d.ts +1 -1
  712. package/dist/components/features/settings/switch-skeleton.d.ts +1 -1
  713. package/dist/components/features/settings/upgrade-banner.d.ts +1 -1
  714. package/dist/components/features/settings/upgrade-button.d.ts +1 -1
  715. package/dist/components/features/sidebar/avatar.d.ts +1 -1
  716. package/dist/components/features/sidebar/sidebar-collapsed-icon-slot.d.ts +1 -1
  717. package/dist/components/features/sidebar/sidebar-conversation-list.d.ts +1 -1
  718. package/dist/components/features/sidebar/sidebar-mobile-menu-bar.d.ts +1 -1
  719. package/dist/components/features/sidebar/sidebar-mobile-menu-toggle.d.ts +1 -1
  720. package/dist/components/features/sidebar/sidebar-mobile-nav-context.d.ts +1 -1
  721. package/dist/components/features/sidebar/sidebar-nav-link.d.ts +1 -1
  722. package/dist/components/features/sidebar/sidebar-rail-body.d.ts +1 -1
  723. package/dist/components/features/sidebar/sidebar.d.ts +2 -1
  724. package/dist/components/features/sidebar/user-avatar.d.ts +1 -1
  725. package/dist/components/features/skills/add-skill-modal.d.ts +2 -1
  726. package/dist/components/features/skills/extensions-mobile-hub.d.ts +1 -1
  727. package/dist/components/features/skills/extensions-navigation.d.ts +1 -1
  728. package/dist/components/features/skills/skill-card-pill-row.d.ts +1 -1
  729. package/dist/components/features/skills/skill-card.d.ts +2 -1
  730. package/dist/components/features/skills/skill-detail-modal.d.ts +2 -1
  731. package/dist/components/features/skills/skill-facet-rail.d.ts +8 -0
  732. package/dist/components/features/skills/skill-facet-row.d.ts +13 -0
  733. package/dist/components/features/skills/skill-filter.d.ts +34 -0
  734. package/dist/components/features/skills/skill-filters-modal.d.ts +10 -0
  735. package/dist/components/features/skills/skill-icon-badge.d.ts +1 -1
  736. package/dist/components/features/skills/skill-type-badge.d.ts +1 -1
  737. package/dist/components/features/skills/skills-toolbar.d.ts +3 -4
  738. package/dist/components/features/suggestions/suggestion-item.d.ts +1 -1
  739. package/dist/components/features/suggestions/suggestions.d.ts +1 -1
  740. package/dist/components/features/terminal/empty-terminal-message.d.ts +1 -1
  741. package/dist/components/features/terminal/terminal.d.ts +1 -1
  742. package/dist/components/features/tips/random-tip.d.ts +2 -1
  743. package/dist/components/providers/agent-server-ui-providers.d.ts +1 -1
  744. package/dist/components/providers/agent-server-ui-root.d.ts +1 -1
  745. package/dist/components/providers/telemetry-provider.d.ts +1 -1
  746. package/dist/components/shared/action-tooltip.d.ts +1 -1
  747. package/dist/components/shared/agent-brand-icon.d.ts +1 -1
  748. package/dist/components/shared/badge.d.ts +1 -1
  749. package/dist/components/shared/buttons/back-nav-button-content.d.ts +1 -1
  750. package/dist/components/shared/buttons/circle-plus-check-toggle.d.ts +3 -2
  751. package/dist/components/shared/buttons/conversation-confirmation-buttons.d.ts +1 -1
  752. package/dist/components/shared/buttons/copy-to-clipboard-button.d.ts +1 -1
  753. package/dist/components/shared/buttons/copyable-content-wrapper.d.ts +1 -1
  754. package/dist/components/shared/buttons/modal-button.d.ts +1 -1
  755. package/dist/components/shared/buttons/openhands-logo-button.d.ts +1 -1
  756. package/dist/components/shared/buttons/remove-button.d.ts +1 -1
  757. package/dist/components/shared/buttons/scroll-to-bottom-button.d.ts +1 -1
  758. package/dist/components/shared/buttons/styled-tooltip.d.ts +1 -1
  759. package/dist/components/shared/filters/enum-filter-dropdown.cjs +1 -1
  760. package/dist/components/shared/filters/enum-filter-dropdown.cjs.map +1 -1
  761. package/dist/components/shared/filters/enum-filter-dropdown.d.ts +6 -2
  762. package/dist/components/shared/filters/enum-filter-dropdown.js +13 -13
  763. package/dist/components/shared/filters/enum-filter-dropdown.js.map +1 -1
  764. package/dist/components/shared/git-provider-icon.d.ts +1 -1
  765. package/dist/components/shared/hook-execution-event-message.d.ts +2 -1
  766. package/dist/components/shared/loading-spinner.d.ts +1 -1
  767. package/dist/components/shared/modals/confirmation-modal.d.ts +1 -1
  768. package/dist/components/shared/modals/confirmation-modals/base-modal.d.ts +3 -3
  769. package/dist/components/shared/modals/confirmation-modals/danger-modal.d.ts +1 -1
  770. package/dist/components/shared/modals/modal-body.d.ts +1 -1
  771. package/dist/components/shared/modals/modal-close-button.d.ts +1 -1
  772. package/dist/components/shared/modals/settings/model-selector.d.ts +2 -1
  773. package/dist/components/shared/modals/settings/settings-form.d.ts +2 -1
  774. package/dist/components/shared/modals/settings/settings-modal.d.ts +1 -1
  775. package/dist/components/shared/navigation-link.cjs +1 -1
  776. package/dist/components/shared/navigation-link.cjs.map +1 -1
  777. package/dist/components/shared/navigation-link.js +11 -7
  778. package/dist/components/shared/navigation-link.js.map +1 -1
  779. package/dist/components/shared/risk-alert.d.ts +1 -1
  780. package/dist/components/shared/text-shimmer.d.ts +1 -1
  781. package/dist/components/ui/resize-handle.d.ts +1 -1
  782. package/dist/config/defaults.cjs +1 -1
  783. package/dist/config/defaults.cjs.map +1 -1
  784. package/dist/config/defaults.js +3 -3
  785. package/dist/config/defaults.js.map +1 -1
  786. package/dist/context/navigation-context.d.ts +1 -1
  787. package/dist/context/scroll-context.d.ts +1 -1
  788. package/dist/contexts/active-backend-context.d.ts +1 -1
  789. package/dist/contexts/conversation-websocket-context.d.ts +1 -1
  790. package/dist/contexts/settings-section-header-context.d.ts +1 -1
  791. package/dist/contexts/websocket-provider-wrapper.d.ts +1 -1
  792. package/dist/fixtures/home-automations-demo.d.ts +19 -0
  793. package/dist/hooks/mutation/use-add-mcp-server.cjs +1 -1
  794. package/dist/hooks/mutation/use-add-mcp-server.cjs.map +1 -1
  795. package/dist/hooks/mutation/use-add-mcp-server.js +10 -14
  796. package/dist/hooks/mutation/use-add-mcp-server.js.map +1 -1
  797. package/dist/hooks/mutation/use-delete-mcp-server.cjs +1 -1
  798. package/dist/hooks/mutation/use-delete-mcp-server.cjs.map +1 -1
  799. package/dist/hooks/mutation/use-delete-mcp-server.d.ts +2 -7
  800. package/dist/hooks/mutation/use-delete-mcp-server.js +8 -34
  801. package/dist/hooks/mutation/use-delete-mcp-server.js.map +1 -1
  802. package/dist/hooks/mutation/use-save-settings.cjs +1 -1
  803. package/dist/hooks/mutation/use-save-settings.cjs.map +1 -1
  804. package/dist/hooks/mutation/use-save-settings.js +8 -4
  805. package/dist/hooks/mutation/use-save-settings.js.map +1 -1
  806. package/dist/hooks/mutation/use-update-mcp-server.cjs +1 -1
  807. package/dist/hooks/mutation/use-update-mcp-server.cjs.map +1 -1
  808. package/dist/hooks/mutation/use-update-mcp-server.d.ts +1 -1
  809. package/dist/hooks/mutation/use-update-mcp-server.js +31 -16
  810. package/dist/hooks/mutation/use-update-mcp-server.js.map +1 -1
  811. package/dist/hooks/query/use-active-conversation.d.ts +1 -1
  812. package/dist/hooks/query/use-agent-profiles.d.ts +1 -1
  813. package/dist/hooks/query/use-app-installations.d.ts +1 -1
  814. package/dist/hooks/query/use-automation-detail.d.ts +2 -2
  815. package/dist/hooks/query/use-automation-health.d.ts +2 -0
  816. package/dist/hooks/query/use-automations.d.ts +5 -1
  817. package/dist/hooks/query/use-bash-command-logs.d.ts +1 -1
  818. package/dist/hooks/query/use-cloud-sandbox.d.ts +1 -1
  819. package/dist/hooks/query/use-commit-changes.d.ts +1 -1
  820. package/dist/hooks/query/use-config.d.ts +1 -1
  821. package/dist/hooks/query/use-conversation-history.d.ts +1 -1
  822. package/dist/hooks/query/use-conversation-hooks.d.ts +1 -1
  823. package/dist/hooks/query/use-conversation-skills.d.ts +1 -1
  824. package/dist/hooks/query/use-get-secrets.d.ts +1 -1
  825. package/dist/hooks/query/use-home-automations.d.ts +20 -0
  826. package/dist/hooks/query/use-latest-automation-runs.d.ts +19 -0
  827. package/dist/hooks/query/use-llm-profiles.d.ts +1 -1
  828. package/dist/hooks/query/use-llm-subscription-models.d.ts +1 -1
  829. package/dist/hooks/query/use-llm-subscription-status.d.ts +1 -1
  830. package/dist/hooks/query/use-local-git-info.d.ts +1 -1
  831. package/dist/hooks/query/use-local-workspaces.d.ts +1 -1
  832. package/dist/hooks/query/use-manifest-capabilities.d.ts +2 -0
  833. package/dist/hooks/query/use-plugin-file-content.d.ts +1 -1
  834. package/dist/hooks/query/use-plugins-marketplace.d.ts +1 -1
  835. package/dist/hooks/query/use-provider-models.d.ts +1 -1
  836. package/dist/hooks/query/use-search-branches.d.ts +1 -1
  837. package/dist/hooks/query/use-search-providers.d.ts +1 -1
  838. package/dist/hooks/query/use-search-repositories.d.ts +1 -1
  839. package/dist/hooks/query/use-search-subdirs.d.ts +2 -2
  840. package/dist/hooks/query/use-settings.d.ts +2 -2
  841. package/dist/hooks/query/use-skills.d.ts +1 -1
  842. package/dist/hooks/query/use-start-tasks.d.ts +1 -1
  843. package/dist/hooks/query/use-sub-conversation-task-polling.d.ts +1 -1
  844. package/dist/hooks/query/use-sub-conversations.d.ts +1 -1
  845. package/dist/hooks/query/use-suggested-tasks.d.ts +1 -1
  846. package/dist/hooks/query/use-task-polling.d.ts +2 -2
  847. package/dist/hooks/query/use-unified-get-git-changes.d.ts +1 -1
  848. package/dist/hooks/query/use-unified-git-diff.d.ts +1 -1
  849. package/dist/hooks/query/use-user-conversation.d.ts +1 -1
  850. package/dist/hooks/query/use-workspace-file-content.d.ts +1 -1
  851. package/dist/hooks/use-backend-scoped-path.cjs +2 -0
  852. package/dist/hooks/use-backend-scoped-path.cjs.map +1 -0
  853. package/dist/hooks/use-backend-scoped-path.d.ts +10 -0
  854. package/dist/hooks/use-backend-scoped-path.js +13 -0
  855. package/dist/hooks/use-backend-scoped-path.js.map +1 -0
  856. package/dist/hooks/use-home-automation-actions.d.ts +23 -0
  857. package/dist/hooks/use-home-pinned-automations.d.ts +26 -0
  858. package/dist/hooks/use-tracking.cjs +1 -1
  859. package/dist/hooks/use-tracking.cjs.map +1 -1
  860. package/dist/hooks/use-tracking.d.ts +4 -0
  861. package/dist/hooks/use-tracking.js +6 -0
  862. package/dist/hooks/use-tracking.js.map +1 -1
  863. package/dist/i18n/declaration.cjs +1 -1
  864. package/dist/i18n/declaration.cjs.map +1 -1
  865. package/dist/i18n/declaration.d.ts +68 -2
  866. package/dist/i18n/declaration.js +1 -1
  867. package/dist/i18n/declaration.js.map +1 -1
  868. package/dist/i18n/translation.cjs +2 -2
  869. package/dist/i18n/translation.cjs.map +1 -1
  870. package/dist/i18n/translation.js +1169 -47
  871. package/dist/i18n/translation.js.map +1 -1
  872. package/dist/icons/code-pill.d.ts +1 -1
  873. package/dist/locales/ar/openhands.json +70 -4
  874. package/dist/locales/ca/openhands.json +70 -4
  875. package/dist/locales/de/openhands.json +70 -4
  876. package/dist/locales/en/openhands.json +70 -4
  877. package/dist/locales/es/openhands.json +70 -4
  878. package/dist/locales/fr/openhands.json +70 -4
  879. package/dist/locales/it/openhands.json +70 -4
  880. package/dist/locales/ja/openhands.json +70 -4
  881. package/dist/locales/ko-KR/openhands.json +70 -4
  882. package/dist/locales/no/openhands.json +70 -4
  883. package/dist/locales/pt/openhands.json +70 -4
  884. package/dist/locales/tr/openhands.json +70 -4
  885. package/dist/locales/uk/openhands.json +70 -4
  886. package/dist/locales/zh-CN/openhands.json +70 -4
  887. package/dist/locales/zh-TW/openhands.json +70 -4
  888. package/dist/manifests/automation-insights.d.ts +64 -0
  889. package/dist/manifests/automation-interface.cjs +1 -1
  890. package/dist/manifests/automation-interface.cjs.map +1 -1
  891. package/dist/manifests/automation-interface.d.ts +33 -1
  892. package/dist/manifests/automation-interface.js +2 -1
  893. package/dist/manifests/automation-interface.js.map +1 -1
  894. package/dist/manifests/interface-validation.cjs +1 -1
  895. package/dist/manifests/interface-validation.cjs.map +1 -1
  896. package/dist/manifests/interface-validation.js +228 -50
  897. package/dist/manifests/interface-validation.js.map +1 -1
  898. package/dist/manifests/manifest-template.d.ts +2 -0
  899. package/dist/manifests/manifest-validation.cjs.map +1 -1
  900. package/dist/manifests/manifest-validation.js.map +1 -1
  901. package/dist/manifests/types.cjs +1 -1
  902. package/dist/manifests/types.cjs.map +1 -1
  903. package/dist/manifests/types.d.ts +128 -0
  904. package/dist/manifests/types.js +35 -2
  905. package/dist/manifests/types.js.map +1 -1
  906. package/dist/mockServiceWorker.js +21 -9
  907. package/dist/node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.cjs +9 -0
  908. package/dist/node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.cjs.map +1 -0
  909. package/dist/node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.js +74 -0
  910. package/dist/node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.js.map +1 -0
  911. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +1 -1
  912. package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -1
  913. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +6 -4
  914. package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -1
  915. package/dist/node_modules/@openhands/extensions/automations/interface.cjs +1 -1
  916. package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -1
  917. package/dist/node_modules/@openhands/extensions/automations/interface.js +126 -5
  918. package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -1
  919. package/dist/node_modules/@openhands/extensions/skills/index.cjs +161 -53
  920. package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
  921. package/dist/node_modules/@openhands/extensions/skills/index.js +112 -50
  922. package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
  923. package/dist/node_modules/@tanstack/query-core/build/modern/utils.cjs +1 -1
  924. package/dist/node_modules/@tanstack/query-core/build/modern/utils.cjs.map +1 -1
  925. package/dist/node_modules/@tanstack/query-core/build/modern/utils.js +12 -1
  926. package/dist/node_modules/@tanstack/query-core/build/modern/utils.js.map +1 -1
  927. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.cjs +1 -1
  928. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.cjs.map +1 -1
  929. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js +14 -12
  930. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js.map +1 -1
  931. package/dist/node_modules/html-parse-stringify/dist/esm/html-parse-stringify.cjs +2 -0
  932. package/dist/node_modules/html-parse-stringify/dist/esm/html-parse-stringify.cjs.map +1 -0
  933. package/dist/node_modules/html-parse-stringify/dist/esm/html-parse-stringify.js +177 -0
  934. package/dist/node_modules/html-parse-stringify/dist/esm/html-parse-stringify.js.map +1 -0
  935. package/dist/node_modules/i18next/dist/esm/i18next.cjs +1 -1
  936. package/dist/node_modules/i18next/dist/esm/i18next.cjs.map +1 -1
  937. package/dist/node_modules/i18next/dist/esm/i18next.js +31 -24
  938. package/dist/node_modules/i18next/dist/esm/i18next.js.map +1 -1
  939. package/dist/node_modules/posthog-js/dist/module.cjs +2 -2
  940. package/dist/node_modules/posthog-js/dist/module.cjs.map +1 -1
  941. package/dist/node_modules/posthog-js/dist/module.js +2055 -1929
  942. package/dist/node_modules/posthog-js/dist/module.js.map +1 -1
  943. package/dist/node_modules/react-i18next/dist/es/TransWithoutContext.cjs +1 -1
  944. package/dist/node_modules/react-i18next/dist/es/TransWithoutContext.cjs.map +1 -1
  945. package/dist/node_modules/react-i18next/dist/es/TransWithoutContext.js +43 -62
  946. package/dist/node_modules/react-i18next/dist/es/TransWithoutContext.js.map +1 -1
  947. package/dist/node_modules/react-i18next/dist/es/useTranslation.cjs +1 -1
  948. package/dist/node_modules/react-i18next/dist/es/useTranslation.cjs.map +1 -1
  949. package/dist/node_modules/react-i18next/dist/es/useTranslation.js +12 -6
  950. package/dist/node_modules/react-i18next/dist/es/useTranslation.js.map +1 -1
  951. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.cjs +1 -1
  952. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.cjs.map +1 -1
  953. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +352 -310
  954. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
  955. package/dist/package.cjs +1 -1
  956. package/dist/package.cjs.map +1 -1
  957. package/dist/package.js +34 -33
  958. package/dist/package.js.map +1 -1
  959. package/dist/routes/agent-settings.d.ts +3 -2
  960. package/dist/routes/app-settings.d.ts +2 -1
  961. package/dist/routes/browser-tab.d.ts +1 -1
  962. package/dist/routes/changes-tab.d.ts +2 -1
  963. package/dist/routes/commits-tab.d.ts +1 -1
  964. package/dist/routes/conversation.d.ts +2 -1
  965. package/dist/routes/files-tab.d.ts +1 -1
  966. package/dist/routes/llm-settings.d.ts +3 -2
  967. package/dist/routes/mcp.cjs +1 -1
  968. package/dist/routes/mcp.cjs.map +1 -1
  969. package/dist/routes/mcp.d.ts +2 -1
  970. package/dist/routes/mcp.js +1 -1
  971. package/dist/routes/mcp.js.map +1 -1
  972. package/dist/routes/planner-tab.d.ts +2 -1
  973. package/dist/routes/secrets-settings.d.ts +2 -1
  974. package/dist/routes/task-list-tab.d.ts +1 -1
  975. package/dist/services/settings.cjs +1 -1
  976. package/dist/services/settings.cjs.map +1 -1
  977. package/dist/services/settings.js +3 -7
  978. package/dist/services/settings.js.map +1 -1
  979. package/dist/types/automation.d.ts +16 -1
  980. package/dist/types/mcp-auth.cjs.map +1 -1
  981. package/dist/types/mcp-auth.d.ts +5 -41
  982. package/dist/types/mcp-auth.js.map +1 -1
  983. package/dist/types/mcp-server.d.ts +17 -32
  984. package/dist/types/settings.d.ts +8 -28
  985. package/dist/ui/card-title.d.ts +1 -1
  986. package/dist/ui/card.d.ts +1 -1
  987. package/dist/ui/combobox-caret.d.ts +3 -3
  988. package/dist/ui/context-menu.cjs +1 -1
  989. package/dist/ui/context-menu.cjs.map +1 -1
  990. package/dist/ui/context-menu.d.ts +3 -2
  991. package/dist/ui/context-menu.js +10 -9
  992. package/dist/ui/context-menu.js.map +1 -1
  993. package/dist/ui/divider.d.ts +1 -1
  994. package/dist/ui/dropdown/clear-button.d.ts +1 -1
  995. package/dist/ui/dropdown/dropdown-input.d.ts +1 -1
  996. package/dist/ui/dropdown/dropdown-menu.d.ts +1 -1
  997. package/dist/ui/dropdown/dropdown.d.ts +1 -1
  998. package/dist/ui/dropdown/loading-spinner.d.ts +1 -1
  999. package/dist/ui/dropdown/toggle-button.d.ts +1 -1
  1000. package/dist/ui/help-link.d.ts +1 -1
  1001. package/dist/ui/pre.d.ts +1 -1
  1002. package/dist/ui/toggle-switch.d.ts +2 -2
  1003. package/dist/ui/typography.d.ts +7 -7
  1004. package/dist/utils/automation-activity-log-export.d.ts +17 -0
  1005. package/dist/utils/automation-timeout.d.ts +4 -6
  1006. package/dist/utils/custom-toast-handlers.d.ts +2 -2
  1007. package/dist/utils/format-relative-time.d.ts +3 -0
  1008. package/dist/utils/mcp-config.cjs +1 -1
  1009. package/dist/utils/mcp-config.cjs.map +1 -1
  1010. package/dist/utils/mcp-config.d.ts +12 -29
  1011. package/dist/utils/mcp-config.js +161 -143
  1012. package/dist/utils/mcp-config.js.map +1 -1
  1013. package/dist/utils/mcp-installed-servers.cjs +1 -1
  1014. package/dist/utils/mcp-installed-servers.cjs.map +1 -1
  1015. package/dist/utils/mcp-installed-servers.d.ts +2 -2
  1016. package/dist/utils/mcp-installed-servers.js +21 -32
  1017. package/dist/utils/mcp-installed-servers.js.map +1 -1
  1018. package/dist/utils/mcp-server-health-key.cjs.map +1 -1
  1019. package/dist/utils/mcp-server-health-key.d.ts +2 -4
  1020. package/dist/utils/mcp-server-health-key.js.map +1 -1
  1021. package/dist/utils/settings-like-page-layout-classes.cjs +1 -1
  1022. package/dist/utils/settings-like-page-layout-classes.cjs.map +1 -1
  1023. package/dist/utils/settings-like-page-layout-classes.d.ts +6 -2
  1024. package/dist/utils/settings-like-page-layout-classes.js +1 -1
  1025. package/dist/utils/settings-like-page-layout-classes.js.map +1 -1
  1026. package/dist/utils/skill-category.d.ts +12 -0
  1027. package/package.json +36 -33
  1028. package/scripts/check-sdk-version-sync.mjs +6 -6
  1029. package/scripts/dev-safe.mjs +2 -2
  1030. package/scripts/dev-with-automation.mjs +3 -2
  1031. package/build/assets/Trans-Bwpzk1wT.js +0 -1
  1032. package/build/assets/active-backend-context-BiwzkzDy.js +0 -2
  1033. package/build/assets/agent-context-settings-DXNT_dcw.js +0 -1
  1034. package/build/assets/agent-server-conversation-service.api-CYSWw-2g.js +0 -41
  1035. package/build/assets/agent-settings-BjgQQe-_.js +0 -1
  1036. package/build/assets/alert-banner-DR8EVyZM.js +0 -1
  1037. package/build/assets/api-error-message-e16L1kwH.js +0 -1
  1038. package/build/assets/automation-detail-DY6x2FW1.js +0 -2
  1039. package/build/assets/automation-export-C09f-Lua.js +0 -2
  1040. package/build/assets/automation-setup-route-CqKp0717.js +0 -1
  1041. package/build/assets/automations-list-CqWJ7qXW.js +0 -1
  1042. package/build/assets/check-CPLXgluF.js +0 -1
  1043. package/build/assets/chevron-down-CP4QHvyc.js +0 -1
  1044. package/build/assets/circle-check-Dpy2_xSI.js +0 -1
  1045. package/build/assets/command-menu-Bj6X4ckE.js +0 -1
  1046. package/build/assets/condenser-settings-EAXQNR2E.js +0 -1
  1047. package/build/assets/context-menu-list-item-CrCrYuPF.js +0 -1
  1048. package/build/assets/conversation-BzyIcSwr.js +0 -1
  1049. package/build/assets/conversation-panel-BzyIcSwr.js +0 -1
  1050. package/build/assets/entry.client-BbIYOsIg.js +0 -2
  1051. package/build/assets/enum-filter-dropdown-C08-srev.js +0 -1
  1052. package/build/assets/files-tab-DEq8MbHu.js +0 -1
  1053. package/build/assets/format-time-delta-CxfPJpzC.js +0 -1
  1054. package/build/assets/git-repo-dropdown-9WKINV6J.js +0 -1
  1055. package/build/assets/home-CY0JaxiY.js +0 -1
  1056. package/build/assets/home-CaNWlVvB.js +0 -1
  1057. package/build/assets/index-home-CaNWlVvB.js +0 -1
  1058. package/build/assets/info-CmWQXtRQ.js +0 -1
  1059. package/build/assets/install-server-modal-BWrudmZU.js +0 -1
  1060. package/build/assets/llm-not-configured-banner-3tMsM4K6.js +0 -27
  1061. package/build/assets/llm-settings-D0W8mJDk.js +0 -1
  1062. package/build/assets/loader-circle-B4QDBARx.js +0 -1
  1063. package/build/assets/manifest-39f4789d.js +0 -1
  1064. package/build/assets/mcp-DXG9LWrI.js +0 -9
  1065. package/build/assets/mcp-marketplace-utils-DFmhKc5s.js +0 -1
  1066. package/build/assets/messages-kBjKaAeA.js +0 -40
  1067. package/build/assets/navigation-link-Bxmn-pCs.js +0 -1
  1068. package/build/assets/onboarding-47hh2IHA.js +0 -1
  1069. package/build/assets/onboarding-modal-9BuvvROo.js +0 -1
  1070. package/build/assets/plus-DrKuuvMe.js +0 -1
  1071. package/build/assets/recommended-automations-launcher-ejxy1P27.js +0 -1
  1072. package/build/assets/root-5S-M8SYa.js +0 -2
  1073. package/build/assets/root-DZ39lS5f.css +0 -1
  1074. package/build/assets/root-layout-BPqoa0gv.js +0 -3
  1075. package/build/assets/search-Dc2qR4O2.js +0 -1
  1076. package/build/assets/settings-Chfn5xTD.js +0 -1
  1077. package/build/assets/settings-like-page-layout-classes-DyxyJ0k4.js +0 -1
  1078. package/build/assets/settings-service.api-CZiPD8__.js +0 -1
  1079. package/build/assets/sidebar-mobile-menu-toggle-ND-hgygu.js +0 -1
  1080. package/build/assets/skills-settings-B43KArIz.js +0 -2
  1081. package/build/assets/use-is-authed-BT7Iud4U.js +0 -1
  1082. package/build/assets/use-llm-profiles-2Wc2db8u.js +0 -1
  1083. package/build/assets/use-save-agent-profile-D0wC5ExW.js +0 -1
  1084. package/build/assets/use-skills-CE6miQ3r.js +0 -1
  1085. package/build/assets/use-tracking-BGboadaZ.js +0 -68
  1086. package/build/assets/useQuery-DiPh8LRJ.js +0 -1
  1087. package/build/assets/utils-BgGG1znF.js +0 -1
  1088. package/build/assets/v4-DDdyfk2q.js +0 -1
  1089. package/build/assets/vendor~browser-IVYgIgG1.js +0 -47
  1090. package/build/assets/vendor~entry.client-CXM9oiAk.js +0 -1
  1091. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~d4by102p-C2f0ZhS-.js +0 -26
  1092. package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~emdr2jt4-BrmgjeOw.js +0 -1
  1093. package/build/assets/vendor~module-BZXjBMvd.js +0 -2
  1094. package/build/assets/x-omAzpXkl.js +0 -1
  1095. package/dist/components/features/skills/skill-type-filter.d.ts +0 -3
  1096. package/dist/components/features/skills/skills-type-filter-dropdown.d.ts +0 -7
  1097. package/dist/node_modules/html-parse-stringify/dist/html-parse-stringify.module.cjs +0 -2
  1098. package/dist/node_modules/html-parse-stringify/dist/html-parse-stringify.module.cjs.map +0 -1
  1099. package/dist/node_modules/html-parse-stringify/dist/html-parse-stringify.module.js +0 -81
  1100. package/dist/node_modules/html-parse-stringify/dist/html-parse-stringify.module.js.map +0 -1
  1101. package/dist/node_modules/void-elements/index.cjs +0 -2
  1102. package/dist/node_modules/void-elements/index.cjs.map +0 -1
  1103. package/dist/node_modules/void-elements/index.js +0 -25
  1104. package/dist/node_modules/void-elements/index.js.map +0 -1
  1105. /package/build/assets/{vendor~root-layout~index-home~home~mcp~automations-list~automation-setup-route~onboarding-modal-D7IDevqN.js → vendor~root-layout~index-home~home~mcp~automations-list~automation-templates~automation-set~bxsimjx0-D7IDevqN.js} +0 -0
@@ -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 { SETUP_PLACEHOLDER_NAMESPACES, SETUP_VERSION } 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/** 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 \"cron\",\n \"timezone\",\n \"repo-picker\",\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\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 if (!isRecord(integrations) || Object.keys(integrations).length === 0) {\n check.fail(\"requires.integrations\", \"must be a non-empty 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, 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 (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 (field.default !== undefined && typeof field.default !== \"string\") {\n check.fail(`${path}.default`, \"must be a string\");\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\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(check: SetupChecker, form: unknown): string[] {\n if (!isRecord(form)) {\n check.fail(\"setup.form\", \"must be an object\");\n return [];\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;\n}\n\nfunction hasRepoPicker(form: unknown): boolean {\n if (!isRecord(form)) return false;\n const groups = [\n form.args,\n ...Object.values(isRecord(form.triggers) ? form.triggers : {}),\n ];\n return groups.some(\n (group) =>\n isRecord(group) &&\n Object.values(group).some(\n (field) => isRecord(field) && field.type === \"repo-picker\",\n ),\n );\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\nfunction checkMode(check: SetupChecker, setup: Rec, kinds: string[]): 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 check.templateValue(setup.prompt, \"setup.prompt\");\n // Optional here: it seeds the fallback conversation offered when the\n // deployment cannot run the direct path.\n if (setup.message !== undefined) checkMessage(check, setup.message);\n\n // The derivation reads a single trigger kind, and an event trigger takes\n // its source from the repository field's provider.\n if (kinds.length !== 1) {\n check.fail(\n \"setup.form.triggers\",\n \"must declare exactly one trigger kind\",\n );\n }\n if (kinds.includes(\"event\") && !hasRepoPicker(setup.form)) {\n check.fail(\n \"setup.form\",\n \"must declare a repository field for an event trigger\",\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, \"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.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 = checkForm(check, setup.form);\n checkMode(check, setup, kinds);\n\n return { valid: check.errors.length === 0, errors: check.errors };\n}\n"],"mappings":"4EAoBA,IAAM,EAAmB,2BACnB,EAAqB,sBAErB,EAAiB,cAEjB,EAAkC,OACtC,eAAe,EAAA,6BAA6B,KAAK,GAAG,EAAE,0BACxD,EAEM,EAAc,CAAC,SAAU,UAAU,EACnC,EAAc,CAClB,OACA,WACA,SACA,OACA,WACA,aACF,EACM,EAAgB,CAAC,SAAU,SAAU,WAAW,EAChD,EAAgB,CAAC,OAAQ,OAAO,EAChC,EAAqB,CAAC,uBAAuB,EAG7C,EAAqB,IAS3B,SAAS,EAAS,EAA8B,CAC9C,OAAO,OAAO,GAAU,YAAY,GAAkB,CAAC,MAAM,QAAQ,CAAK,CAC5E,CAEA,SAAS,EACP,EACA,EACoB,CACpB,OACE,OAAO,GAAU,UAAa,EAA8B,SAAS,CAAK,CAE9E,CAEA,SAAS,EAAU,EAAgB,EAA0B,CAC3D,OACE,OAAO,GAAU,UAAY,OAAO,UAAU,CAAK,GAAK,GAAS,CAErE,CAEA,IAAM,EAAN,KAAmB,CACjB,OAA4B,CAAC,EAE7B,KAAK,EAAc,EAAuB,CAExC,OADA,KAAK,OAAO,KAAK,GAAG,EAAK,IAAI,GAAQ,EAC9B,EACT,CAGA,KAAK,EAAgB,EAAuB,CAO1C,OANI,OAAO,GAAU,UAAY,EAAM,SAAW,EACzC,KAAK,KAAK,EAAM,4BAA4B,EAEjD,EAAe,KAAK,CAAK,EACpB,KAAK,KAAK,EAAM,yBAAyB,EAE3C,EACT,CAEA,aAAa,EAAe,EAAuB,CAIjD,OAHI,EAA4B,KAAK,CAAK,EACjC,KAAK,KAAK,EAAM,uCAAuC,EAEzD,EACT,CAGA,aAAa,EAAgB,EAAuB,CAClD,OAAO,KAAK,KAAK,EAAO,CAAI,GAAK,KAAK,aAAa,EAAiB,CAAI,CAC1E,CAMA,cAAc,EAAgB,EAAuB,CAInD,OAHI,OAAO,GAAU,UAAY,EAAM,SAAW,EACzC,KAAK,KAAK,EAAM,4BAA4B,EAE9C,KAAK,aAAa,EAAO,CAAI,CACtC,CAEA,OAAO,EAAgB,EAAa,EAAc,EAAyB,CAEzE,OADI,KAAO,EAAkB,KAAK,KAAK,GAAG,EAAK,GAAG,IAAO,CAAM,EACxD,EACT,CACF,EAEA,SAAS,EAAc,EAAqB,EAAyB,CACnE,GAAI,CAAC,EAAS,CAAQ,EAAG,CACvB,EAAM,KAAK,WAAY,mBAAmB,EAC1C,MACF,CAEA,GAAM,CAAE,eAAc,YAAa,EAC/B,CAAC,EAAS,CAAY,GAAK,OAAO,KAAK,CAAY,EAAE,SAAW,EAClE,EAAM,KAAK,wBAAyB,4BAA4B,EAEhE,OAAO,QAAQ,CAAY,EAAE,SAAS,CAAC,EAAI,KAAiB,CAC1D,IAAM,EAAO,yBAAyB,IACtC,GAAI,CAAC,EAAS,CAAW,EAAG,CAC1B,EAAM,KAAK,EAAM,mBAAmB,EACpC,MACF,CACA,EAAM,KAAK,EAAY,QAAS,GAAG,EAAK,SAAS,EAC7C,aAAc,GAAe,EAAY,WAAa,IACxD,EAAM,KAAK,GAAG,EAAK,WAAY,mBAAmB,EAEpD,IAAM,EAAU,CAAC,UAAW,UAAU,EACtC,OAAO,KAAK,CAAW,EACpB,OAAQ,GAAQ,CAAC,EAAQ,SAAS,CAAG,CAAC,EACtC,QAAS,GAAQ,EAAM,KAAK,GAAG,EAAK,GAAG,IAAO,gBAAgB,CAAC,CACpE,CAAC,EAGC,IAAa,IAAA,KACX,CAAC,MAAM,QAAQ,CAAQ,GAAK,EAAS,SAAW,EAClD,EAAM,KAAK,oBAAqB,2BAA2B,EAE3D,EAAS,SAAS,EAAS,IAAU,EAC/B,OAAO,GAAY,UAAY,EAAQ,SAAW,IACpD,EAAM,KACJ,qBAAqB,EAAM,GAC3B,4BACF,CAEJ,CAAC,EAGP,CAEA,SAAS,EACP,EACA,EACA,EACM,CACN,GAAI,CAAC,EAAS,CAAW,GAAK,OAAO,KAAK,CAAW,EAAE,SAAW,EAAG,CACnE,EAAM,KAAK,EAAM,4BAA4B,EAC7C,MACF,CAEA,GAAM,CAAE,YAAW,YAAW,UAAW,EACrC,IAAc,IAAA,IAAa,CAAC,EAAU,EAAW,CAAC,GACpD,EAAM,KAAK,GAAG,EAAK,YAAa,gCAAgC,EAE9D,IAAc,IAAA,IAAa,CAAC,EAAU,EAAW,CAAC,GACpD,EAAM,KAAK,GAAG,EAAK,YAAa,4BAA4B,EAE1D,IAAW,IAAA,IAAa,CAAC,EAAQ,EAAQ,CAAkB,GAC7D,EAAM,KAAK,GAAG,EAAK,SAAU,2BAA2B,CAE5D,CAEA,SAAS,EAAW,EAAqB,EAAgB,EAAoB,CAC3E,GAAI,CAAC,EAAS,CAAK,EAAG,CACpB,EAAM,KAAK,EAAM,mBAAmB,EACpC,MACF,CAEA,GAAM,CAAE,OAAM,QAAO,OAAM,cAAa,WAAU,WAAU,WAAY,EAEnE,EAAQ,EAAM,CAAW,GAC5B,EAAM,KAAK,GAAG,EAAK,OAAQ,+BAA+B,EAE5D,EAAM,KAAK,EAAO,GAAG,EAAK,OAAO,EACjC,EAAM,KAAK,EAAM,GAAG,EAAK,MAAM,EAC3B,IAAgB,IAAA,IAAW,EAAM,KAAK,EAAa,GAAG,EAAK,aAAa,EACxE,EAAM,UAAY,IAAA,IAAa,OAAO,EAAM,SAAY,UAC1D,EAAM,KAAK,GAAG,EAAK,UAAW,kBAAkB,EAE9C,OAAO,GAAa,WACtB,EAAM,KAAK,GAAG,EAAK,WAAY,mBAAmB,EAEhD,IAAa,IAAA,IAAa,CAAC,EAAQ,EAAU,CAAa,GAC5D,EAAM,KAAK,GAAG,EAAK,WAAY,6BAA6B,EAE1D,IAAS,eAAiB,IAAa,IAAA,IACzC,EAAM,KAAK,GAAG,EAAK,WAAY,oCAAoC,EAGjE,IAAY,IAAA,KACV,IAAS,SAEF,CAAC,MAAM,QAAQ,CAAO,GAAK,EAAQ,SAAW,EACvD,EAAM,KAAK,GAAG,EAAK,UAAW,2BAA2B,EAEzD,EAAQ,SAAS,EAAQ,IAAU,CACjC,IAAM,EAAa,GAAG,EAAK,WAAW,EAAM,GAC5C,GAAI,CAAC,EAAS,CAAM,EAAG,CACrB,EAAM,KAAK,EAAY,mBAAmB,EAC1C,MACF,EACI,OAAO,EAAO,OAAU,UAAY,EAAO,MAAM,SAAW,IAC9D,EAAM,KAAK,GAAG,EAAW,QAAS,4BAA4B,EAEhE,EAAM,KAAK,EAAO,MAAO,GAAG,EAAW,OAAO,CAChD,CAAC,EAdD,EAAM,KAAK,GAAG,EAAK,UAAW,mCAAmC,GAkBjE,EAAM,cAAgB,IAAA,IACxB,EAAiB,EAAO,EAAM,YAAa,GAAG,EAAK,aAAa,CAEpE,CAGA,SAAS,EACP,EACA,EACA,EACU,CAMV,MALI,CAAC,EAAS,CAAM,GAAK,OAAO,KAAK,CAAM,EAAE,SAAW,GACtD,EAAM,KAAK,EAAM,4BAA4B,EACtC,CAAC,GAGH,OAAO,QAAQ,CAAM,EAAE,KAAK,CAAC,EAAM,MACnC,EAAmB,KAAK,CAAI,GAC/B,EAAM,KAAK,GAAG,EAAK,GAAG,IAAQ,2BAA2B,EAE3D,EAAW,EAAO,EAAO,GAAG,EAAK,GAAG,GAAM,EACnC,EACR,CACH,CAGA,SAAS,EAAU,EAAqB,EAAyB,CAC/D,GAAI,CAAC,EAAS,CAAI,EAEhB,OADA,EAAM,KAAK,aAAc,mBAAmB,EACrC,CAAC,EAGN,EAAK,OAAS,IAAA,IAAW,EAAM,KAAK,EAAK,KAAM,iBAAiB,EAEpE,IAAM,EAAQ,EAAY,EAAO,EAAK,KAAM,iBAAiB,EACvD,EAAkB,CAAC,EAErB,EAAK,WAAa,IAAA,KAChB,CAAC,EAAS,EAAK,QAAQ,GAAK,OAAO,KAAK,EAAK,QAAQ,EAAE,SAAW,EACpE,EAAM,KAAK,sBAAuB,4BAA4B,EAE9D,OAAO,QAAQ,EAAK,QAAQ,EAAE,SAAS,CAAC,EAAM,KAAY,CACxD,GAAI,CAAC,EAAQ,EAAM,CAAa,EAAG,CACjC,EAAM,KAAK,uBAAuB,IAAQ,uBAAuB,EACjE,MACF,CACA,EAAM,KAAK,CAAI,EACf,EAAM,KACJ,GAAG,EAAY,EAAO,EAAQ,uBAAuB,GAAM,CAC7D,CACF,CAAC,GAML,IAAM,EAAa,EAAM,QACtB,EAAM,IAAU,EAAM,QAAQ,CAAI,IAAM,CAC3C,EAKA,OAJA,MAAM,KAAK,IAAI,IAAI,CAAU,CAAC,EAAE,QAAS,GACvC,EAAM,KAAK,cAAc,IAAQ,4BAA4B,CAC/D,EAEO,CACT,CAEA,SAAS,EAAc,EAAwB,CAM7C,OALK,EAAS,CAAI,EAKX,CAHL,EAAK,KACL,GAAG,OAAO,OAAO,EAAS,EAAK,QAAQ,EAAI,EAAK,SAAW,CAAC,CAAC,CAExD,EAAO,KACX,GACC,EAAS,CAAK,GACd,OAAO,OAAO,CAAK,EAAE,KAClB,GAAU,EAAS,CAAK,GAAK,EAAM,OAAS,aAC/C,CACJ,EAX4B,EAY9B,CAEA,SAAS,EAAa,EAAqB,EAAwB,CAC7D,EAAM,aAAa,EAAS,eAAe,GACxC,EAAmB,OAAS,GAC/B,EAAM,KACJ,gBACA,mBAAmB,EAAmB,YACxC,CAGN,CAEA,SAAS,EAAU,EAAqB,EAAY,EAAuB,CACzE,GAAI,CAAC,EAAQ,EAAM,KAAM,CAAW,EAAG,CACrC,EAAM,KAAK,aAAc,yBAAyB,EAClD,MACF,CAEA,GAAI,EAAM,OAAS,SAAU,CAC3B,EAAM,cAAc,EAAM,OAAQ,cAAc,EAG5C,EAAM,UAAY,IAAA,IAAW,EAAa,EAAO,EAAM,OAAO,EAI9D,EAAM,SAAW,GACnB,EAAM,KACJ,sBACA,uCACF,EAEE,EAAM,SAAS,OAAO,GAAK,CAAC,EAAc,EAAM,IAAI,GACtD,EAAM,KACJ,aACA,sDACF,EAEE,EAAM,SAAW,IAAA,KACd,EAAM,SAAS,OAAO,EAGzB,EAAM,cAAc,EAAM,OAAQ,cAAc,EAFhD,EAAM,KAAK,eAAgB,sCAAsC,GAKrE,MACF,CAEA,EAAa,EAAO,EAAM,OAAO,EACjC,EAAM,OAAO,EAAO,SAAU,QAAS,kCAAkC,EACzE,EAAM,OAAO,EAAO,SAAU,QAAS,kCAAkC,CAC3E,CAGA,SAAgB,EAAc,EAA6B,CACzD,OAAO,EAAS,CAAS,GAAK,EAAU,QAAU,IAAA,EACpD,CAQA,SAAgB,EAAmB,EAA2C,CAC5E,IAAM,EAAQ,IAAI,EAElB,GAAI,CAAC,EAAS,CAAS,EACrB,MAAO,CAAE,MAAO,GAAO,OAAQ,CAAC,6BAA6B,CAAE,EAGjE,GAAM,CAAE,SAAU,EA+BlB,OA9BK,EAAS,CAAK,EAGf,EAAM,UAAA,QAQR,OAAO,EAAU,IAAO,UACxB,CAAC,EAAiB,KAAK,EAAU,EAAE,IAEnC,EAAM,KAAK,KAAM,0BAA0B,EAE7C,EAAM,KAAK,EAAU,KAAM,MAAM,EACjC,EAAM,KAAK,EAAU,YAAa,aAAa,EAE7C,EAAU,QAAU,IAAA,KACnB,OAAO,EAAU,OAAU,UAC1B,CAAC,EAAiB,KAAK,EAAU,KAAK,IAExC,EAAM,KAAK,QAAS,0BAA0B,EAGhD,EAAc,EAAO,EAAU,QAAQ,EAEvC,EAAU,EAAO,EADH,EAAU,EAAO,EAAM,IACb,CAAK,EAEtB,CAAE,MAAO,EAAM,OAAO,SAAW,EAAG,OAAQ,EAAM,MAAO,GA1BvD,CACL,MAAO,GACP,OAAQ,CAAC,8BAA2C,CACtD,EANO,CAAE,MAAO,GAAO,OAAQ,CAAC,0BAA0B,CAAE,CA8BhE"}
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 { SETUP_PLACEHOLDER_NAMESPACES, SETUP_VERSION } 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/** 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 \"cron\",\n \"timezone\",\n \"repo-picker\",\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\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 if (!isRecord(integrations) || Object.keys(integrations).length === 0) {\n check.fail(\"requires.integrations\", \"must be a non-empty 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, 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 (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 (field.default !== undefined && typeof field.default !== \"string\") {\n check.fail(`${path}.default`, \"must be a string\");\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\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(check: SetupChecker, form: unknown): string[] {\n if (!isRecord(form)) {\n check.fail(\"setup.form\", \"must be an object\");\n return [];\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;\n}\n\nfunction hasRepoPicker(form: unknown): boolean {\n if (!isRecord(form)) return false;\n const groups = [\n form.args,\n ...Object.values(isRecord(form.triggers) ? form.triggers : {}),\n ];\n return groups.some(\n (group) =>\n isRecord(group) &&\n Object.values(group).some(\n (field) => isRecord(field) && field.type === \"repo-picker\",\n ),\n );\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\nfunction checkMode(check: SetupChecker, setup: Rec, kinds: string[]): 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 check.templateValue(setup.prompt, \"setup.prompt\");\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 // The derivation reads a single trigger kind, and an event trigger takes\n // its source from the repository field's provider.\n if (kinds.length !== 1) {\n check.fail(\n \"setup.form.triggers\",\n \"must declare exactly one trigger kind\",\n );\n }\n if (kinds.includes(\"event\") && !hasRepoPicker(setup.form)) {\n check.fail(\n \"setup.form\",\n \"must declare a repository field for an event trigger\",\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, \"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.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 = checkForm(check, setup.form);\n checkMode(check, setup, kinds);\n\n return { valid: check.errors.length === 0, errors: check.errors };\n}\n"],"mappings":"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"}
@@ -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 { SETUP_PLACEHOLDER_NAMESPACES, SETUP_VERSION } 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/** 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 \"cron\",\n \"timezone\",\n \"repo-picker\",\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\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 if (!isRecord(integrations) || Object.keys(integrations).length === 0) {\n check.fail(\"requires.integrations\", \"must be a non-empty 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, 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 (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 (field.default !== undefined && typeof field.default !== \"string\") {\n check.fail(`${path}.default`, \"must be a string\");\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\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(check: SetupChecker, form: unknown): string[] {\n if (!isRecord(form)) {\n check.fail(\"setup.form\", \"must be an object\");\n return [];\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;\n}\n\nfunction hasRepoPicker(form: unknown): boolean {\n if (!isRecord(form)) return false;\n const groups = [\n form.args,\n ...Object.values(isRecord(form.triggers) ? form.triggers : {}),\n ];\n return groups.some(\n (group) =>\n isRecord(group) &&\n Object.values(group).some(\n (field) => isRecord(field) && field.type === \"repo-picker\",\n ),\n );\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\nfunction checkMode(check: SetupChecker, setup: Rec, kinds: string[]): 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 check.templateValue(setup.prompt, \"setup.prompt\");\n // Optional here: it seeds the fallback conversation offered when the\n // deployment cannot run the direct path.\n if (setup.message !== undefined) checkMessage(check, setup.message);\n\n // The derivation reads a single trigger kind, and an event trigger takes\n // its source from the repository field's provider.\n if (kinds.length !== 1) {\n check.fail(\n \"setup.form.triggers\",\n \"must declare exactly one trigger kind\",\n );\n }\n if (kinds.includes(\"event\") && !hasRepoPicker(setup.form)) {\n check.fail(\n \"setup.form\",\n \"must declare a repository field for an event trigger\",\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, \"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.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 = checkForm(check, setup.form);\n checkMode(check, setup, kinds);\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 { SETUP_PLACEHOLDER_NAMESPACES, SETUP_VERSION } 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/** 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 \"cron\",\n \"timezone\",\n \"repo-picker\",\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\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 if (!isRecord(integrations) || Object.keys(integrations).length === 0) {\n check.fail(\"requires.integrations\", \"must be a non-empty 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, 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 (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 (field.default !== undefined && typeof field.default !== \"string\") {\n check.fail(`${path}.default`, \"must be a string\");\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\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(check: SetupChecker, form: unknown): string[] {\n if (!isRecord(form)) {\n check.fail(\"setup.form\", \"must be an object\");\n return [];\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;\n}\n\nfunction hasRepoPicker(form: unknown): boolean {\n if (!isRecord(form)) return false;\n const groups = [\n form.args,\n ...Object.values(isRecord(form.triggers) ? form.triggers : {}),\n ];\n return groups.some(\n (group) =>\n isRecord(group) &&\n Object.values(group).some(\n (field) => isRecord(field) && field.type === \"repo-picker\",\n ),\n );\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\nfunction checkMode(check: SetupChecker, setup: Rec, kinds: string[]): 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 check.templateValue(setup.prompt, \"setup.prompt\");\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 // The derivation reads a single trigger kind, and an event trigger takes\n // its source from the repository field's provider.\n if (kinds.length !== 1) {\n check.fail(\n \"setup.form.triggers\",\n \"must declare exactly one trigger kind\",\n );\n }\n if (kinds.includes(\"event\") && !hasRepoPicker(setup.form)) {\n check.fail(\n \"setup.form\",\n \"must declare a repository field for an event trigger\",\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, \"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.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 = checkForm(check, setup.form);\n checkMode(check, setup, kinds);\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=[`form`,`automation`];exports.SETUP_PLACEHOLDER_NAMESPACES=e;
1
+ require("../_virtual/_rolldown/runtime.cjs");var e=[`form`,`automation`],t=[`list`,`templates`],n=[`layout-dashboard`,`sparkles`,`bot`,`circle-alert`,`activity`,`timer`],r=[`automations`,`needs-attention`,`total-runs`,`average-duration`],i={automations:[`active`],"needs-attention":[],"total-runs":[],"average-duration":[]},a={status:[`all`,`active`,`failing`,`disabled`],trigger:[`all`,`schedule`,`event`]},o=Object.keys(a),s=[`last-run`,`runs`,`name`];exports.DASHBOARD_FILTER_IDS=o,exports.DASHBOARD_FILTER_VALUES=a,exports.DASHBOARD_SORT_VALUES=s,exports.INTERFACE_ICON_SLUGS=n,exports.INTERFACE_SUB_PAGE_IDS=t,exports.OVERVIEW_METRICS=r,exports.OVERVIEW_TILE_PLACEHOLDERS=i,exports.SETUP_PLACEHOLDER_NAMESPACES=e;
2
2
  //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","names":[],"sources":["../../src/manifests/types.ts"],"sourcesContent":["/**\n * Host-owned shape of an extension-authored setup experience.\n *\n * A catalog entry is declarative data published by `@openhands/extensions`. Its\n * optional `setup` block says what to ask a user for; everything derivable from\n * that — the request to send, the route, the review screen, the analytics — is\n * this host's to generate, so none of it appears here.\n *\n * The names mirror `@openhands/extensions/automations`' own declarations, so an\n * entry from the published package assigns without an adapter.\n */\n\nexport const SETUP_VERSION = \"1.0\";\n\nexport type SetupMode = \"direct\" | \"assisted\";\n\nexport type SetupFieldType =\n | \"text\"\n | \"textarea\"\n | \"select\"\n | \"cron\"\n | \"timezone\"\n | \"repo-picker\";\n\nexport type SetupGitProvider = \"github\" | \"gitlab\" | \"bitbucket\";\n\nexport type SetupTriggerKind = \"cron\" | \"event\";\n\n/** Placeholder namespaces a setup block may reference inside `{{...}}`. */\nexport const SETUP_PLACEHOLDER_NAMESPACES = [\"form\", \"automation\"] as const;\n\nexport interface SetupFieldOption {\n value: string;\n label: string;\n}\n\nexport interface SetupFieldConstraints {\n minLength?: number;\n maxLength?: number;\n /**\n * A host-implemented check named from a closed set. Entries supply no regex\n * of their own, so they cannot hand the host a pathological pattern.\n */\n format?: \"safeExpressionLiteral\";\n}\n\nexport interface SetupFormField {\n type: SetupFieldType;\n label: string;\n help: string;\n placeholder?: string;\n default?: string;\n required: boolean;\n provider?: SetupGitProvider;\n options?: SetupFieldOption[];\n constraints?: SetupFieldConstraints;\n}\n\n/** Keyed by field name, which is what `{{form.<name>}}` resolves against. */\nexport type SetupFormFields = Record<string, SetupFormField>;\n\nexport interface SetupForm {\n note?: string;\n /** Inputs that decide when the automation runs, keyed by trigger kind. */\n triggers?: Partial<Record<SetupTriggerKind, SetupFormFields>>;\n /** Every other input: the arguments to the automation itself. */\n args: SetupFormFields;\n}\n\nexport interface SetupBlock {\n version: typeof SETUP_VERSION;\n mode: SetupMode;\n form: SetupForm;\n /** direct only. What the automation is told to do. */\n prompt?: string;\n /** direct only, event trigger only. Which delivered events belong to it. */\n filter?: string;\n /**\n * Setup context for the conversation that finishes setup. Required for\n * assisted mode. Optional for direct mode, where it seeds the fallback\n * conversation offered when the deployment cannot run the direct path.\n */\n message?: string;\n}\n\nexport interface SetupIntegrationRequirement {\n /** Why this entry needs the integration. */\n message: string;\n /** Defaults to true. `false` lets setup continue while it is unconnected. */\n required?: false;\n}\n\nexport interface SetupPrerequisites {\n /** Keyed by integration catalog id. */\n integrations: Record<string, SetupIntegrationRequirement>;\n /** Deployment capabilities this entry cannot run without. */\n features?: string[];\n}\n\n/**\n * The part of a catalog entry this host reads. An admitted entry always has a\n * `setup` block; entries without one are simply not setup entries.\n */\nexport interface SetupEntry {\n id: string;\n name: string;\n description: string;\n requires: SetupPrerequisites;\n /** The skill that owns the launch command. Defaults to `id`. */\n skill?: string;\n setup: SetupBlock;\n}\n\nexport type SetupPayloadValue =\n | string\n | number\n | boolean\n | null\n | SetupPayloadValue[]\n | { [key: string]: SetupPayloadValue };\n\nexport interface SetupRequestBody {\n [key: string]: SetupPayloadValue;\n}\n\n/** Form values are collected as strings; the payload mapping shapes them. */\nexport type SetupFormValues = Record<string, string>;\n\n/** `GET /v1/capabilities` — what this deployment supports. */\nexport interface DeploymentCapabilities {\n ready: boolean;\n triggerKinds: string[];\n eventSources: string[];\n eventTypes: string[];\n triggers: {\n cron?: { minIntervalSeconds: number; timezones: string[] };\n event?: { filterLanguage: string; filterFunctions: string[] };\n };\n features: string[];\n}\n\n/** A single problem with a draft, addressed to the field that caused it. */\nexport interface DraftValidationError {\n /** Dotted path into the draft. Null when the problem spans the whole draft. */\n field: string | null;\n code: string;\n message: string;\n}\n\n/** `POST /v1/validate` — an invalid draft is still a 200. */\nexport interface ValidateDraftResponse {\n valid: boolean;\n errors: DraftValidationError[];\n sampleEventMatched?: boolean | null;\n}\n\n/**\n * Host-owned shape of the production Automation interface manifest, published\n * by `@openhands/extensions/automations` as `AUTOMATION_INTERFACE`.\n *\n * The catalog states what varies per automation; this states the domain-level\n * facts of the interface itself. As with setup entries, the published data is\n * validated at admission rather than trusted, and a package that predates the\n * manifest simply leaves the host on its own defaults.\n */\n\nexport const INTERFACE_VERSION = \"1.0\";\n\n/** The closed set of runtime-model properties a client may offer for setting. */\nexport type AutomationAttributeName =\n | \"name\"\n | \"prompt\"\n | \"model\"\n | \"timeout\"\n | \"schedule\";\n\nexport type InterfaceAttributeType =\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"llm-profile\"\n | \"schedule\";\n\n/** How one settable attribute of an existing Automation is offered. */\nexport interface InterfaceAttribute {\n type: InterfaceAttributeType;\n label: string;\n help?: string;\n required: boolean;\n /** Only a `number` attribute carries constraints. */\n constraints?: { min?: number; max?: number };\n}\n\nexport interface InterfaceRoutes {\n list: string;\n /** Carries the `:automationId` segment the host substitutes. */\n setup: string;\n /** Carries the `:automationId` segment the host substitutes. */\n detail: string;\n}\n\n/**\n * Service-relative paths the host calls. The base path, methods, headers, and\n * auth remain the host's. `{id}` marks where the automation id is substituted.\n */\nexport interface InterfaceEndpoints {\n list: string;\n detail: string;\n dispatch: string;\n runs: string;\n tarball: string;\n health: string;\n capabilities: string;\n validate: string;\n createPrompt: string;\n createPlugin: string;\n}\n\nexport type InterfaceEndpointName = keyof InterfaceEndpoints;\n\nexport interface InterfaceImportExport {\n fileKind: string;\n fileVersion: number;\n filenameSuffix: string;\n importDefaults: {\n /** Provider inferred for short owner/repo repository URLs on import. */\n repoProvider: SetupGitProvider;\n /** Event source of the placeholder trigger that keeps an import inert. */\n placeholderEventSource: string;\n };\n}\n\nexport interface InterfaceManifest {\n version: typeof INTERFACE_VERSION;\n routes: InterfaceRoutes;\n navigation: {\n sidebar: { label: string };\n commandMenu: { title: string; description: string; keywords: string };\n };\n pages: {\n list: { title: string; subtitle: string };\n detail: { backLabel: string };\n edit: { title: string };\n };\n docsUrl: string;\n /**\n * The input surface of an existing Automation, keyed by the runtime-model\n * property the host sends. Rendering it as an edit dialog is this host's\n * choice, not stated here.\n */\n attributes: Partial<Record<AutomationAttributeName, InterfaceAttribute>>;\n importExport: InterfaceImportExport;\n endpoints: InterfaceEndpoints;\n featuredAutomationIds: string[];\n responderIntegrationIds: string[];\n}\n"],"mappings":"6CA6BA,IAAa,EAA+B,CAAC,OAAQ,YAAY"}
1
+ {"version":3,"file":"types.cjs","names":[],"sources":["../../src/manifests/types.ts"],"sourcesContent":["/**\n * Host-owned shape of an extension-authored setup experience.\n *\n * A catalog entry is declarative data published by `@openhands/extensions`. Its\n * optional `setup` block says what to ask a user for; everything derivable from\n * that — the request to send, the route, the review screen, the analytics — is\n * this host's to generate, so none of it appears here.\n *\n * The names mirror `@openhands/extensions/automations`' own declarations, so an\n * entry from the published package assigns without an adapter.\n */\n\nexport const SETUP_VERSION = \"1.0\";\n\nexport type SetupMode = \"direct\" | \"assisted\";\n\nexport type SetupFieldType =\n | \"text\"\n | \"textarea\"\n | \"select\"\n | \"cron\"\n | \"timezone\"\n | \"repo-picker\";\n\nexport type SetupGitProvider = \"github\" | \"gitlab\" | \"bitbucket\";\n\nexport type SetupTriggerKind = \"cron\" | \"event\";\n\n/** Placeholder namespaces a setup block may reference inside `{{...}}`. */\nexport const SETUP_PLACEHOLDER_NAMESPACES = [\"form\", \"automation\"] as const;\n\nexport interface SetupFieldOption {\n value: string;\n label: string;\n}\n\nexport interface SetupFieldConstraints {\n minLength?: number;\n maxLength?: number;\n /**\n * A host-implemented check named from a closed set. Entries supply no regex\n * of their own, so they cannot hand the host a pathological pattern.\n */\n format?: \"safeExpressionLiteral\";\n}\n\nexport interface SetupFormField {\n type: SetupFieldType;\n label: string;\n help: string;\n placeholder?: string;\n default?: string;\n required: boolean;\n provider?: SetupGitProvider;\n options?: SetupFieldOption[];\n constraints?: SetupFieldConstraints;\n}\n\n/** Keyed by field name, which is what `{{form.<name>}}` resolves against. */\nexport type SetupFormFields = Record<string, SetupFormField>;\n\nexport interface SetupForm {\n note?: string;\n /** Inputs that decide when the automation runs, keyed by trigger kind. */\n triggers?: Partial<Record<SetupTriggerKind, SetupFormFields>>;\n /** Every other input: the arguments to the automation itself. */\n args: SetupFormFields;\n}\n\nexport interface SetupBlock {\n version: typeof SETUP_VERSION;\n mode: SetupMode;\n form: SetupForm;\n /** direct only. What the automation is told to do. */\n prompt?: string;\n /** direct only, event trigger only. Which delivered events belong to it. */\n filter?: string;\n /**\n * Setup context for the conversation that finishes setup. Required for\n * assisted mode. Optional for direct mode, where it seeds the fallback\n * conversation offered when the deployment cannot run the direct path.\n */\n message?: string;\n}\n\nexport interface SetupIntegrationRequirement {\n /** Why this entry needs the integration. */\n message: string;\n /** Defaults to true. `false` lets setup continue while it is unconnected. */\n required?: false;\n}\n\nexport interface SetupPrerequisites {\n /** Keyed by integration catalog id. */\n integrations: Record<string, SetupIntegrationRequirement>;\n /** Deployment capabilities this entry cannot run without. */\n features?: string[];\n}\n\n/**\n * The part of a catalog entry this host reads. An admitted entry always has a\n * `setup` block; entries without one are simply not setup entries.\n */\nexport interface SetupEntry {\n id: string;\n name: string;\n description: string;\n requires: SetupPrerequisites;\n /** The skill that owns the launch command. Defaults to `id`. */\n skill?: string;\n setup: SetupBlock;\n}\n\nexport type SetupPayloadValue =\n | string\n | number\n | boolean\n | null\n | SetupPayloadValue[]\n | { [key: string]: SetupPayloadValue };\n\nexport interface SetupRequestBody {\n [key: string]: SetupPayloadValue;\n}\n\n/** Form values are collected as strings; the payload mapping shapes them. */\nexport type SetupFormValues = Record<string, string>;\n\n/** `GET /v1/capabilities` — what this deployment supports. */\nexport interface DeploymentCapabilities {\n ready: boolean;\n /** Absolute timeout ceiling enforced by this deployment's automation API. */\n maxAutomationTimeoutSeconds?: number;\n triggerKinds: string[];\n eventSources: string[];\n eventTypes: string[];\n triggers: {\n cron?: { minIntervalSeconds: number; timezones: string[] };\n event?: { filterLanguage: string; filterFunctions: string[] };\n };\n features: string[];\n}\n\n/** A single problem with a draft, addressed to the field that caused it. */\nexport interface DraftValidationError {\n /** Dotted path into the draft. Null when the problem spans the whole draft. */\n field: string | null;\n code: string;\n message: string;\n}\n\n/** `POST /v1/validate` — an invalid draft is still a 200. */\nexport interface ValidateDraftResponse {\n valid: boolean;\n errors: DraftValidationError[];\n sampleEventMatched?: boolean | null;\n}\n\n/**\n * Host-owned shape of the production Automation interface manifest, published\n * by `@openhands/extensions/automations` as `AUTOMATION_INTERFACE`.\n *\n * The catalog states what varies per automation; this states the domain-level\n * facts of the interface itself. As with setup entries, the published data is\n * validated at admission rather than trusted, and a package that predates the\n * manifest simply leaves the host on its own defaults.\n */\n\nexport const INTERFACE_VERSION = \"1.0\";\n\n/** The closed set of runtime-model properties a client may offer for setting. */\nexport type AutomationAttributeName =\n | \"name\"\n | \"prompt\"\n | \"model\"\n | \"timeout\"\n | \"schedule\";\n\nexport type InterfaceAttributeType =\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"llm-profile\"\n | \"schedule\";\n\n/** How one settable attribute of an existing Automation is offered. */\nexport interface InterfaceAttribute {\n type: InterfaceAttributeType;\n label: string;\n help?: string;\n required: boolean;\n /** Only a `number` attribute carries constraints. */\n constraints?: { min?: number; max?: number };\n}\n\nexport interface InterfaceRoutes {\n list: string;\n /** Carries the `:automationId` segment the host substitutes. */\n setup: string;\n /** Carries the `:automationId` segment the host substitutes. */\n detail: string;\n /** The templates sub-page. Static: there is no parameter to substitute. */\n templates?: string;\n}\n\n/**\n * Service-relative paths the host calls. The base path, methods, headers, and\n * auth remain the host's. `{id}` marks where the automation id is substituted.\n */\nexport interface InterfaceEndpoints {\n list: string;\n detail: string;\n dispatch: string;\n runs: string;\n tarball: string;\n health: string;\n capabilities: string;\n validate: string;\n createPrompt: string;\n createPlugin: string;\n}\n\nexport type InterfaceEndpointName = keyof InterfaceEndpoints;\n\nexport interface InterfaceImportExport {\n fileKind: string;\n fileVersion: number;\n filenameSuffix: string;\n importDefaults: {\n /** Provider inferred for short owner/repo repository URLs on import. */\n repoProvider: SetupGitProvider;\n /** Event source of the placeholder trigger that keeps an import inert. */\n placeholderEventSource: string;\n };\n}\n\n/**\n * The sub-page surface: navigation, overview tiles, filters, sort, and run\n * insights for the list page, and a templates page. Every value below names\n * something this host implements from a closed set — a metric it computes, a\n * predicate it applies, a comparator it runs, an icon it ships — and the\n * manifest picks and captions it, never defines it. The host carries no\n * definitions of its own for this surface, so a manifest without it simply\n * leaves the sub-pages unrendered.\n */\n\nexport const INTERFACE_SUB_PAGE_IDS = [\"list\", \"templates\"] as const;\n\nexport type InterfaceSubPageId = (typeof INTERFACE_SUB_PAGE_IDS)[number];\n\n/** Icon names this host maps to artwork. A manifest cannot supply its own. */\nexport const INTERFACE_ICON_SLUGS = [\n \"layout-dashboard\",\n \"sparkles\",\n \"bot\",\n \"circle-alert\",\n \"activity\",\n \"timer\",\n] as const;\n\nexport type InterfaceIconSlug = (typeof INTERFACE_ICON_SLUGS)[number];\n\nexport interface InterfaceSubPageNavItem {\n /** The `pages` entry this item navigates to; its route comes from `routes`. */\n page: InterfaceSubPageId;\n label: string;\n icon: InterfaceIconSlug;\n}\n\n/** Values this host computes over the loaded automations and their runs. */\nexport const OVERVIEW_METRICS = [\n \"automations\",\n \"needs-attention\",\n \"total-runs\",\n \"average-duration\",\n] as const;\n\nexport type OverviewMetric = (typeof OVERVIEW_METRICS)[number];\n\n/**\n * Placeholder names a tile's `detail`/`zeroDetail` copy may reference inside\n * `{{...}}`, per metric. Plain substitution, like setup copy.\n */\nexport const OVERVIEW_TILE_PLACEHOLDERS: Record<\n OverviewMetric,\n readonly string[]\n> = {\n automations: [\"active\"],\n \"needs-attention\": [],\n \"total-runs\": [],\n \"average-duration\": [],\n};\n\nexport interface InterfaceOverviewTile {\n metric: OverviewMetric;\n label: string;\n /** Caption under the value. */\n detail: string;\n /** Replaces `detail` while the metric's value is zero. */\n zeroDetail?: string;\n icon: InterfaceIconSlug;\n}\n\nexport interface InterfaceOverview {\n /** Names the tiles section for assistive technology. */\n label: string;\n tiles: InterfaceOverviewTile[];\n}\n\n/** Filter values name predicates this host implements, per filter id. */\nexport const DASHBOARD_FILTER_VALUES = {\n status: [\"all\", \"active\", \"failing\", \"disabled\"],\n trigger: [\"all\", \"schedule\", \"event\"],\n} as const;\n\nexport type DashboardFilterId = keyof typeof DASHBOARD_FILTER_VALUES;\n\nexport const DASHBOARD_FILTER_IDS = Object.keys(\n DASHBOARD_FILTER_VALUES,\n) as readonly DashboardFilterId[];\n\nexport type DashboardStatusValue =\n (typeof DASHBOARD_FILTER_VALUES.status)[number];\n\nexport type DashboardTriggerValue =\n (typeof DASHBOARD_FILTER_VALUES.trigger)[number];\n\nexport interface InterfaceStatusFilter {\n id: \"status\";\n /** The control's accessible name. */\n label: string;\n options: { value: DashboardStatusValue; label: string }[];\n}\n\nexport interface InterfaceTriggerFilter {\n id: \"trigger\";\n /** The control's accessible name. */\n label: string;\n options: { value: DashboardTriggerValue; label: string }[];\n}\n\nexport type InterfaceDashboardFilter =\n | InterfaceStatusFilter\n | InterfaceTriggerFilter;\n\n/** Sort values name comparators this host implements. */\nexport const DASHBOARD_SORT_VALUES = [\"last-run\", \"runs\", \"name\"] as const;\n\nexport type DashboardSortValue = (typeof DASHBOARD_SORT_VALUES)[number];\n\nexport interface InterfaceDashboardSort {\n /** The control's accessible name. */\n label: string;\n options: { value: DashboardSortValue; label: string }[];\n /** One of the declared option values. */\n default: DashboardSortValue;\n}\n\n/**\n * Copy for the per-automation run insights on cards and rows. The states,\n * precedence, sampling, and value formatting are this host's; the manifest\n * names them.\n */\nexport interface InterfaceListInsights {\n health: {\n healthy: string;\n failing: string;\n running: string;\n disabled: string;\n neverRun: string;\n checking: string;\n };\n lastRun: { label: string; never: string; justNow: string };\n stats: { runs: string; recentSuccess: string; averageDuration: string };\n}\n\n/**\n * The templates sub-page identity. Its body — the catalog cards and their\n * launch behavior — is this host's existing catalog surface.\n */\nexport interface InterfaceTemplatesPage {\n title: string;\n description: string;\n}\n\nexport interface InterfaceManifest {\n version: typeof INTERFACE_VERSION;\n routes: InterfaceRoutes;\n navigation: {\n sidebar: { label: string };\n commandMenu: { title: string; description: string; keywords: string };\n /** The ordered sub-page navigation of the interface. */\n subPages?: InterfaceSubPageNavItem[];\n };\n pages: {\n list: {\n title: string;\n subtitle: string;\n overview?: InterfaceOverview;\n /** The filter dropdowns of the list page, in render order. */\n filters?: InterfaceDashboardFilter[];\n sort?: InterfaceDashboardSort;\n insights?: InterfaceListInsights;\n };\n detail: { backLabel: string };\n edit: { title: string };\n templates?: InterfaceTemplatesPage;\n };\n docsUrl: string;\n /**\n * The input surface of an existing Automation, keyed by the runtime-model\n * property the host sends. Rendering it as an edit dialog is this host's\n * choice, not stated here.\n */\n attributes: Partial<Record<AutomationAttributeName, InterfaceAttribute>>;\n importExport: InterfaceImportExport;\n endpoints: InterfaceEndpoints;\n featuredAutomationIds: string[];\n responderIntegrationIds: string[];\n}\n"],"mappings":"6CA6BA,IAAa,EAA+B,CAAC,OAAQ,YAAY,EAyNpD,EAAyB,CAAC,OAAQ,WAAW,EAK7C,EAAuB,CAClC,mBACA,WACA,MACA,eACA,WACA,OACF,EAYa,EAAmB,CAC9B,cACA,kBACA,aACA,kBACF,EAQa,EAGT,CACF,YAAa,CAAC,QAAQ,EACtB,kBAAmB,CAAC,EACpB,aAAc,CAAC,EACf,mBAAoB,CAAC,CACvB,EAmBa,EAA0B,CACrC,OAAQ,CAAC,MAAO,SAAU,UAAW,UAAU,EAC/C,QAAS,CAAC,MAAO,WAAY,OAAO,CACtC,EAIa,EAAuB,OAAO,KACzC,CACF,EA2Ba,EAAwB,CAAC,WAAY,OAAQ,MAAM"}
@@ -100,6 +100,8 @@ export type SetupFormValues = Record<string, string>;
100
100
  /** `GET /v1/capabilities` — what this deployment supports. */
101
101
  export interface DeploymentCapabilities {
102
102
  ready: boolean;
103
+ /** Absolute timeout ceiling enforced by this deployment's automation API. */
104
+ maxAutomationTimeoutSeconds?: number;
103
105
  triggerKinds: string[];
104
106
  eventSources: string[];
105
107
  eventTypes: string[];
@@ -159,6 +161,8 @@ export interface InterfaceRoutes {
159
161
  setup: string;
160
162
  /** Carries the `:automationId` segment the host substitutes. */
161
163
  detail: string;
164
+ /** The templates sub-page. Static: there is no parameter to substitute. */
165
+ templates?: string;
162
166
  }
163
167
  /**
164
168
  * Service-relative paths the host calls. The base path, methods, headers, and
@@ -188,6 +192,122 @@ export interface InterfaceImportExport {
188
192
  placeholderEventSource: string;
189
193
  };
190
194
  }
195
+ /**
196
+ * The sub-page surface: navigation, overview tiles, filters, sort, and run
197
+ * insights for the list page, and a templates page. Every value below names
198
+ * something this host implements from a closed set — a metric it computes, a
199
+ * predicate it applies, a comparator it runs, an icon it ships — and the
200
+ * manifest picks and captions it, never defines it. The host carries no
201
+ * definitions of its own for this surface, so a manifest without it simply
202
+ * leaves the sub-pages unrendered.
203
+ */
204
+ export declare const INTERFACE_SUB_PAGE_IDS: readonly ["list", "templates"];
205
+ export type InterfaceSubPageId = (typeof INTERFACE_SUB_PAGE_IDS)[number];
206
+ /** Icon names this host maps to artwork. A manifest cannot supply its own. */
207
+ export declare const INTERFACE_ICON_SLUGS: readonly ["layout-dashboard", "sparkles", "bot", "circle-alert", "activity", "timer"];
208
+ export type InterfaceIconSlug = (typeof INTERFACE_ICON_SLUGS)[number];
209
+ export interface InterfaceSubPageNavItem {
210
+ /** The `pages` entry this item navigates to; its route comes from `routes`. */
211
+ page: InterfaceSubPageId;
212
+ label: string;
213
+ icon: InterfaceIconSlug;
214
+ }
215
+ /** Values this host computes over the loaded automations and their runs. */
216
+ export declare const OVERVIEW_METRICS: readonly ["automations", "needs-attention", "total-runs", "average-duration"];
217
+ export type OverviewMetric = (typeof OVERVIEW_METRICS)[number];
218
+ /**
219
+ * Placeholder names a tile's `detail`/`zeroDetail` copy may reference inside
220
+ * `{{...}}`, per metric. Plain substitution, like setup copy.
221
+ */
222
+ export declare const OVERVIEW_TILE_PLACEHOLDERS: Record<OverviewMetric, readonly string[]>;
223
+ export interface InterfaceOverviewTile {
224
+ metric: OverviewMetric;
225
+ label: string;
226
+ /** Caption under the value. */
227
+ detail: string;
228
+ /** Replaces `detail` while the metric's value is zero. */
229
+ zeroDetail?: string;
230
+ icon: InterfaceIconSlug;
231
+ }
232
+ export interface InterfaceOverview {
233
+ /** Names the tiles section for assistive technology. */
234
+ label: string;
235
+ tiles: InterfaceOverviewTile[];
236
+ }
237
+ /** Filter values name predicates this host implements, per filter id. */
238
+ export declare const DASHBOARD_FILTER_VALUES: {
239
+ readonly status: readonly ["all", "active", "failing", "disabled"];
240
+ readonly trigger: readonly ["all", "schedule", "event"];
241
+ };
242
+ export type DashboardFilterId = keyof typeof DASHBOARD_FILTER_VALUES;
243
+ export declare const DASHBOARD_FILTER_IDS: readonly DashboardFilterId[];
244
+ export type DashboardStatusValue = (typeof DASHBOARD_FILTER_VALUES.status)[number];
245
+ export type DashboardTriggerValue = (typeof DASHBOARD_FILTER_VALUES.trigger)[number];
246
+ export interface InterfaceStatusFilter {
247
+ id: "status";
248
+ /** The control's accessible name. */
249
+ label: string;
250
+ options: {
251
+ value: DashboardStatusValue;
252
+ label: string;
253
+ }[];
254
+ }
255
+ export interface InterfaceTriggerFilter {
256
+ id: "trigger";
257
+ /** The control's accessible name. */
258
+ label: string;
259
+ options: {
260
+ value: DashboardTriggerValue;
261
+ label: string;
262
+ }[];
263
+ }
264
+ export type InterfaceDashboardFilter = InterfaceStatusFilter | InterfaceTriggerFilter;
265
+ /** Sort values name comparators this host implements. */
266
+ export declare const DASHBOARD_SORT_VALUES: readonly ["last-run", "runs", "name"];
267
+ export type DashboardSortValue = (typeof DASHBOARD_SORT_VALUES)[number];
268
+ export interface InterfaceDashboardSort {
269
+ /** The control's accessible name. */
270
+ label: string;
271
+ options: {
272
+ value: DashboardSortValue;
273
+ label: string;
274
+ }[];
275
+ /** One of the declared option values. */
276
+ default: DashboardSortValue;
277
+ }
278
+ /**
279
+ * Copy for the per-automation run insights on cards and rows. The states,
280
+ * precedence, sampling, and value formatting are this host's; the manifest
281
+ * names them.
282
+ */
283
+ export interface InterfaceListInsights {
284
+ health: {
285
+ healthy: string;
286
+ failing: string;
287
+ running: string;
288
+ disabled: string;
289
+ neverRun: string;
290
+ checking: string;
291
+ };
292
+ lastRun: {
293
+ label: string;
294
+ never: string;
295
+ justNow: string;
296
+ };
297
+ stats: {
298
+ runs: string;
299
+ recentSuccess: string;
300
+ averageDuration: string;
301
+ };
302
+ }
303
+ /**
304
+ * The templates sub-page identity. Its body — the catalog cards and their
305
+ * launch behavior — is this host's existing catalog surface.
306
+ */
307
+ export interface InterfaceTemplatesPage {
308
+ title: string;
309
+ description: string;
310
+ }
191
311
  export interface InterfaceManifest {
192
312
  version: typeof INTERFACE_VERSION;
193
313
  routes: InterfaceRoutes;
@@ -200,11 +320,18 @@ export interface InterfaceManifest {
200
320
  description: string;
201
321
  keywords: string;
202
322
  };
323
+ /** The ordered sub-page navigation of the interface. */
324
+ subPages?: InterfaceSubPageNavItem[];
203
325
  };
204
326
  pages: {
205
327
  list: {
206
328
  title: string;
207
329
  subtitle: string;
330
+ overview?: InterfaceOverview;
331
+ /** The filter dropdowns of the list page, in render order. */
332
+ filters?: InterfaceDashboardFilter[];
333
+ sort?: InterfaceDashboardSort;
334
+ insights?: InterfaceListInsights;
208
335
  };
209
336
  detail: {
210
337
  backLabel: string;
@@ -212,6 +339,7 @@ export interface InterfaceManifest {
212
339
  edit: {
213
340
  title: string;
214
341
  };
342
+ templates?: InterfaceTemplatesPage;
215
343
  };
216
344
  docsUrl: string;
217
345
  /**
@@ -1,6 +1,39 @@
1
1
  //#region src/manifests/types.ts
2
- var e = ["form", "automation"];
2
+ var e = ["form", "automation"], t = ["list", "templates"], n = [
3
+ "layout-dashboard",
4
+ "sparkles",
5
+ "bot",
6
+ "circle-alert",
7
+ "activity",
8
+ "timer"
9
+ ], r = [
10
+ "automations",
11
+ "needs-attention",
12
+ "total-runs",
13
+ "average-duration"
14
+ ], i = {
15
+ automations: ["active"],
16
+ "needs-attention": [],
17
+ "total-runs": [],
18
+ "average-duration": []
19
+ }, a = {
20
+ status: [
21
+ "all",
22
+ "active",
23
+ "failing",
24
+ "disabled"
25
+ ],
26
+ trigger: [
27
+ "all",
28
+ "schedule",
29
+ "event"
30
+ ]
31
+ }, o = Object.keys(a), s = [
32
+ "last-run",
33
+ "runs",
34
+ "name"
35
+ ];
3
36
  //#endregion
4
- export { e as SETUP_PLACEHOLDER_NAMESPACES };
37
+ export { o as DASHBOARD_FILTER_IDS, a as DASHBOARD_FILTER_VALUES, s as DASHBOARD_SORT_VALUES, n as INTERFACE_ICON_SLUGS, t as INTERFACE_SUB_PAGE_IDS, r as OVERVIEW_METRICS, i as OVERVIEW_TILE_PLACEHOLDERS, e as SETUP_PLACEHOLDER_NAMESPACES };
5
38
 
6
39
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../src/manifests/types.ts"],"sourcesContent":["/**\n * Host-owned shape of an extension-authored setup experience.\n *\n * A catalog entry is declarative data published by `@openhands/extensions`. Its\n * optional `setup` block says what to ask a user for; everything derivable from\n * that — the request to send, the route, the review screen, the analytics — is\n * this host's to generate, so none of it appears here.\n *\n * The names mirror `@openhands/extensions/automations`' own declarations, so an\n * entry from the published package assigns without an adapter.\n */\n\nexport const SETUP_VERSION = \"1.0\";\n\nexport type SetupMode = \"direct\" | \"assisted\";\n\nexport type SetupFieldType =\n | \"text\"\n | \"textarea\"\n | \"select\"\n | \"cron\"\n | \"timezone\"\n | \"repo-picker\";\n\nexport type SetupGitProvider = \"github\" | \"gitlab\" | \"bitbucket\";\n\nexport type SetupTriggerKind = \"cron\" | \"event\";\n\n/** Placeholder namespaces a setup block may reference inside `{{...}}`. */\nexport const SETUP_PLACEHOLDER_NAMESPACES = [\"form\", \"automation\"] as const;\n\nexport interface SetupFieldOption {\n value: string;\n label: string;\n}\n\nexport interface SetupFieldConstraints {\n minLength?: number;\n maxLength?: number;\n /**\n * A host-implemented check named from a closed set. Entries supply no regex\n * of their own, so they cannot hand the host a pathological pattern.\n */\n format?: \"safeExpressionLiteral\";\n}\n\nexport interface SetupFormField {\n type: SetupFieldType;\n label: string;\n help: string;\n placeholder?: string;\n default?: string;\n required: boolean;\n provider?: SetupGitProvider;\n options?: SetupFieldOption[];\n constraints?: SetupFieldConstraints;\n}\n\n/** Keyed by field name, which is what `{{form.<name>}}` resolves against. */\nexport type SetupFormFields = Record<string, SetupFormField>;\n\nexport interface SetupForm {\n note?: string;\n /** Inputs that decide when the automation runs, keyed by trigger kind. */\n triggers?: Partial<Record<SetupTriggerKind, SetupFormFields>>;\n /** Every other input: the arguments to the automation itself. */\n args: SetupFormFields;\n}\n\nexport interface SetupBlock {\n version: typeof SETUP_VERSION;\n mode: SetupMode;\n form: SetupForm;\n /** direct only. What the automation is told to do. */\n prompt?: string;\n /** direct only, event trigger only. Which delivered events belong to it. */\n filter?: string;\n /**\n * Setup context for the conversation that finishes setup. Required for\n * assisted mode. Optional for direct mode, where it seeds the fallback\n * conversation offered when the deployment cannot run the direct path.\n */\n message?: string;\n}\n\nexport interface SetupIntegrationRequirement {\n /** Why this entry needs the integration. */\n message: string;\n /** Defaults to true. `false` lets setup continue while it is unconnected. */\n required?: false;\n}\n\nexport interface SetupPrerequisites {\n /** Keyed by integration catalog id. */\n integrations: Record<string, SetupIntegrationRequirement>;\n /** Deployment capabilities this entry cannot run without. */\n features?: string[];\n}\n\n/**\n * The part of a catalog entry this host reads. An admitted entry always has a\n * `setup` block; entries without one are simply not setup entries.\n */\nexport interface SetupEntry {\n id: string;\n name: string;\n description: string;\n requires: SetupPrerequisites;\n /** The skill that owns the launch command. Defaults to `id`. */\n skill?: string;\n setup: SetupBlock;\n}\n\nexport type SetupPayloadValue =\n | string\n | number\n | boolean\n | null\n | SetupPayloadValue[]\n | { [key: string]: SetupPayloadValue };\n\nexport interface SetupRequestBody {\n [key: string]: SetupPayloadValue;\n}\n\n/** Form values are collected as strings; the payload mapping shapes them. */\nexport type SetupFormValues = Record<string, string>;\n\n/** `GET /v1/capabilities` — what this deployment supports. */\nexport interface DeploymentCapabilities {\n ready: boolean;\n triggerKinds: string[];\n eventSources: string[];\n eventTypes: string[];\n triggers: {\n cron?: { minIntervalSeconds: number; timezones: string[] };\n event?: { filterLanguage: string; filterFunctions: string[] };\n };\n features: string[];\n}\n\n/** A single problem with a draft, addressed to the field that caused it. */\nexport interface DraftValidationError {\n /** Dotted path into the draft. Null when the problem spans the whole draft. */\n field: string | null;\n code: string;\n message: string;\n}\n\n/** `POST /v1/validate` — an invalid draft is still a 200. */\nexport interface ValidateDraftResponse {\n valid: boolean;\n errors: DraftValidationError[];\n sampleEventMatched?: boolean | null;\n}\n\n/**\n * Host-owned shape of the production Automation interface manifest, published\n * by `@openhands/extensions/automations` as `AUTOMATION_INTERFACE`.\n *\n * The catalog states what varies per automation; this states the domain-level\n * facts of the interface itself. As with setup entries, the published data is\n * validated at admission rather than trusted, and a package that predates the\n * manifest simply leaves the host on its own defaults.\n */\n\nexport const INTERFACE_VERSION = \"1.0\";\n\n/** The closed set of runtime-model properties a client may offer for setting. */\nexport type AutomationAttributeName =\n | \"name\"\n | \"prompt\"\n | \"model\"\n | \"timeout\"\n | \"schedule\";\n\nexport type InterfaceAttributeType =\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"llm-profile\"\n | \"schedule\";\n\n/** How one settable attribute of an existing Automation is offered. */\nexport interface InterfaceAttribute {\n type: InterfaceAttributeType;\n label: string;\n help?: string;\n required: boolean;\n /** Only a `number` attribute carries constraints. */\n constraints?: { min?: number; max?: number };\n}\n\nexport interface InterfaceRoutes {\n list: string;\n /** Carries the `:automationId` segment the host substitutes. */\n setup: string;\n /** Carries the `:automationId` segment the host substitutes. */\n detail: string;\n}\n\n/**\n * Service-relative paths the host calls. The base path, methods, headers, and\n * auth remain the host's. `{id}` marks where the automation id is substituted.\n */\nexport interface InterfaceEndpoints {\n list: string;\n detail: string;\n dispatch: string;\n runs: string;\n tarball: string;\n health: string;\n capabilities: string;\n validate: string;\n createPrompt: string;\n createPlugin: string;\n}\n\nexport type InterfaceEndpointName = keyof InterfaceEndpoints;\n\nexport interface InterfaceImportExport {\n fileKind: string;\n fileVersion: number;\n filenameSuffix: string;\n importDefaults: {\n /** Provider inferred for short owner/repo repository URLs on import. */\n repoProvider: SetupGitProvider;\n /** Event source of the placeholder trigger that keeps an import inert. */\n placeholderEventSource: string;\n };\n}\n\nexport interface InterfaceManifest {\n version: typeof INTERFACE_VERSION;\n routes: InterfaceRoutes;\n navigation: {\n sidebar: { label: string };\n commandMenu: { title: string; description: string; keywords: string };\n };\n pages: {\n list: { title: string; subtitle: string };\n detail: { backLabel: string };\n edit: { title: string };\n };\n docsUrl: string;\n /**\n * The input surface of an existing Automation, keyed by the runtime-model\n * property the host sends. Rendering it as an edit dialog is this host's\n * choice, not stated here.\n */\n attributes: Partial<Record<AutomationAttributeName, InterfaceAttribute>>;\n importExport: InterfaceImportExport;\n endpoints: InterfaceEndpoints;\n featuredAutomationIds: string[];\n responderIntegrationIds: string[];\n}\n"],"mappings":";AA6BA,IAAa,IAA+B,CAAC,QAAQ,YAAY"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../src/manifests/types.ts"],"sourcesContent":["/**\n * Host-owned shape of an extension-authored setup experience.\n *\n * A catalog entry is declarative data published by `@openhands/extensions`. Its\n * optional `setup` block says what to ask a user for; everything derivable from\n * that — the request to send, the route, the review screen, the analytics — is\n * this host's to generate, so none of it appears here.\n *\n * The names mirror `@openhands/extensions/automations`' own declarations, so an\n * entry from the published package assigns without an adapter.\n */\n\nexport const SETUP_VERSION = \"1.0\";\n\nexport type SetupMode = \"direct\" | \"assisted\";\n\nexport type SetupFieldType =\n | \"text\"\n | \"textarea\"\n | \"select\"\n | \"cron\"\n | \"timezone\"\n | \"repo-picker\";\n\nexport type SetupGitProvider = \"github\" | \"gitlab\" | \"bitbucket\";\n\nexport type SetupTriggerKind = \"cron\" | \"event\";\n\n/** Placeholder namespaces a setup block may reference inside `{{...}}`. */\nexport const SETUP_PLACEHOLDER_NAMESPACES = [\"form\", \"automation\"] as const;\n\nexport interface SetupFieldOption {\n value: string;\n label: string;\n}\n\nexport interface SetupFieldConstraints {\n minLength?: number;\n maxLength?: number;\n /**\n * A host-implemented check named from a closed set. Entries supply no regex\n * of their own, so they cannot hand the host a pathological pattern.\n */\n format?: \"safeExpressionLiteral\";\n}\n\nexport interface SetupFormField {\n type: SetupFieldType;\n label: string;\n help: string;\n placeholder?: string;\n default?: string;\n required: boolean;\n provider?: SetupGitProvider;\n options?: SetupFieldOption[];\n constraints?: SetupFieldConstraints;\n}\n\n/** Keyed by field name, which is what `{{form.<name>}}` resolves against. */\nexport type SetupFormFields = Record<string, SetupFormField>;\n\nexport interface SetupForm {\n note?: string;\n /** Inputs that decide when the automation runs, keyed by trigger kind. */\n triggers?: Partial<Record<SetupTriggerKind, SetupFormFields>>;\n /** Every other input: the arguments to the automation itself. */\n args: SetupFormFields;\n}\n\nexport interface SetupBlock {\n version: typeof SETUP_VERSION;\n mode: SetupMode;\n form: SetupForm;\n /** direct only. What the automation is told to do. */\n prompt?: string;\n /** direct only, event trigger only. Which delivered events belong to it. */\n filter?: string;\n /**\n * Setup context for the conversation that finishes setup. Required for\n * assisted mode. Optional for direct mode, where it seeds the fallback\n * conversation offered when the deployment cannot run the direct path.\n */\n message?: string;\n}\n\nexport interface SetupIntegrationRequirement {\n /** Why this entry needs the integration. */\n message: string;\n /** Defaults to true. `false` lets setup continue while it is unconnected. */\n required?: false;\n}\n\nexport interface SetupPrerequisites {\n /** Keyed by integration catalog id. */\n integrations: Record<string, SetupIntegrationRequirement>;\n /** Deployment capabilities this entry cannot run without. */\n features?: string[];\n}\n\n/**\n * The part of a catalog entry this host reads. An admitted entry always has a\n * `setup` block; entries without one are simply not setup entries.\n */\nexport interface SetupEntry {\n id: string;\n name: string;\n description: string;\n requires: SetupPrerequisites;\n /** The skill that owns the launch command. Defaults to `id`. */\n skill?: string;\n setup: SetupBlock;\n}\n\nexport type SetupPayloadValue =\n | string\n | number\n | boolean\n | null\n | SetupPayloadValue[]\n | { [key: string]: SetupPayloadValue };\n\nexport interface SetupRequestBody {\n [key: string]: SetupPayloadValue;\n}\n\n/** Form values are collected as strings; the payload mapping shapes them. */\nexport type SetupFormValues = Record<string, string>;\n\n/** `GET /v1/capabilities` — what this deployment supports. */\nexport interface DeploymentCapabilities {\n ready: boolean;\n /** Absolute timeout ceiling enforced by this deployment's automation API. */\n maxAutomationTimeoutSeconds?: number;\n triggerKinds: string[];\n eventSources: string[];\n eventTypes: string[];\n triggers: {\n cron?: { minIntervalSeconds: number; timezones: string[] };\n event?: { filterLanguage: string; filterFunctions: string[] };\n };\n features: string[];\n}\n\n/** A single problem with a draft, addressed to the field that caused it. */\nexport interface DraftValidationError {\n /** Dotted path into the draft. Null when the problem spans the whole draft. */\n field: string | null;\n code: string;\n message: string;\n}\n\n/** `POST /v1/validate` — an invalid draft is still a 200. */\nexport interface ValidateDraftResponse {\n valid: boolean;\n errors: DraftValidationError[];\n sampleEventMatched?: boolean | null;\n}\n\n/**\n * Host-owned shape of the production Automation interface manifest, published\n * by `@openhands/extensions/automations` as `AUTOMATION_INTERFACE`.\n *\n * The catalog states what varies per automation; this states the domain-level\n * facts of the interface itself. As with setup entries, the published data is\n * validated at admission rather than trusted, and a package that predates the\n * manifest simply leaves the host on its own defaults.\n */\n\nexport const INTERFACE_VERSION = \"1.0\";\n\n/** The closed set of runtime-model properties a client may offer for setting. */\nexport type AutomationAttributeName =\n | \"name\"\n | \"prompt\"\n | \"model\"\n | \"timeout\"\n | \"schedule\";\n\nexport type InterfaceAttributeType =\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"llm-profile\"\n | \"schedule\";\n\n/** How one settable attribute of an existing Automation is offered. */\nexport interface InterfaceAttribute {\n type: InterfaceAttributeType;\n label: string;\n help?: string;\n required: boolean;\n /** Only a `number` attribute carries constraints. */\n constraints?: { min?: number; max?: number };\n}\n\nexport interface InterfaceRoutes {\n list: string;\n /** Carries the `:automationId` segment the host substitutes. */\n setup: string;\n /** Carries the `:automationId` segment the host substitutes. */\n detail: string;\n /** The templates sub-page. Static: there is no parameter to substitute. */\n templates?: string;\n}\n\n/**\n * Service-relative paths the host calls. The base path, methods, headers, and\n * auth remain the host's. `{id}` marks where the automation id is substituted.\n */\nexport interface InterfaceEndpoints {\n list: string;\n detail: string;\n dispatch: string;\n runs: string;\n tarball: string;\n health: string;\n capabilities: string;\n validate: string;\n createPrompt: string;\n createPlugin: string;\n}\n\nexport type InterfaceEndpointName = keyof InterfaceEndpoints;\n\nexport interface InterfaceImportExport {\n fileKind: string;\n fileVersion: number;\n filenameSuffix: string;\n importDefaults: {\n /** Provider inferred for short owner/repo repository URLs on import. */\n repoProvider: SetupGitProvider;\n /** Event source of the placeholder trigger that keeps an import inert. */\n placeholderEventSource: string;\n };\n}\n\n/**\n * The sub-page surface: navigation, overview tiles, filters, sort, and run\n * insights for the list page, and a templates page. Every value below names\n * something this host implements from a closed set — a metric it computes, a\n * predicate it applies, a comparator it runs, an icon it ships — and the\n * manifest picks and captions it, never defines it. The host carries no\n * definitions of its own for this surface, so a manifest without it simply\n * leaves the sub-pages unrendered.\n */\n\nexport const INTERFACE_SUB_PAGE_IDS = [\"list\", \"templates\"] as const;\n\nexport type InterfaceSubPageId = (typeof INTERFACE_SUB_PAGE_IDS)[number];\n\n/** Icon names this host maps to artwork. A manifest cannot supply its own. */\nexport const INTERFACE_ICON_SLUGS = [\n \"layout-dashboard\",\n \"sparkles\",\n \"bot\",\n \"circle-alert\",\n \"activity\",\n \"timer\",\n] as const;\n\nexport type InterfaceIconSlug = (typeof INTERFACE_ICON_SLUGS)[number];\n\nexport interface InterfaceSubPageNavItem {\n /** The `pages` entry this item navigates to; its route comes from `routes`. */\n page: InterfaceSubPageId;\n label: string;\n icon: InterfaceIconSlug;\n}\n\n/** Values this host computes over the loaded automations and their runs. */\nexport const OVERVIEW_METRICS = [\n \"automations\",\n \"needs-attention\",\n \"total-runs\",\n \"average-duration\",\n] as const;\n\nexport type OverviewMetric = (typeof OVERVIEW_METRICS)[number];\n\n/**\n * Placeholder names a tile's `detail`/`zeroDetail` copy may reference inside\n * `{{...}}`, per metric. Plain substitution, like setup copy.\n */\nexport const OVERVIEW_TILE_PLACEHOLDERS: Record<\n OverviewMetric,\n readonly string[]\n> = {\n automations: [\"active\"],\n \"needs-attention\": [],\n \"total-runs\": [],\n \"average-duration\": [],\n};\n\nexport interface InterfaceOverviewTile {\n metric: OverviewMetric;\n label: string;\n /** Caption under the value. */\n detail: string;\n /** Replaces `detail` while the metric's value is zero. */\n zeroDetail?: string;\n icon: InterfaceIconSlug;\n}\n\nexport interface InterfaceOverview {\n /** Names the tiles section for assistive technology. */\n label: string;\n tiles: InterfaceOverviewTile[];\n}\n\n/** Filter values name predicates this host implements, per filter id. */\nexport const DASHBOARD_FILTER_VALUES = {\n status: [\"all\", \"active\", \"failing\", \"disabled\"],\n trigger: [\"all\", \"schedule\", \"event\"],\n} as const;\n\nexport type DashboardFilterId = keyof typeof DASHBOARD_FILTER_VALUES;\n\nexport const DASHBOARD_FILTER_IDS = Object.keys(\n DASHBOARD_FILTER_VALUES,\n) as readonly DashboardFilterId[];\n\nexport type DashboardStatusValue =\n (typeof DASHBOARD_FILTER_VALUES.status)[number];\n\nexport type DashboardTriggerValue =\n (typeof DASHBOARD_FILTER_VALUES.trigger)[number];\n\nexport interface InterfaceStatusFilter {\n id: \"status\";\n /** The control's accessible name. */\n label: string;\n options: { value: DashboardStatusValue; label: string }[];\n}\n\nexport interface InterfaceTriggerFilter {\n id: \"trigger\";\n /** The control's accessible name. */\n label: string;\n options: { value: DashboardTriggerValue; label: string }[];\n}\n\nexport type InterfaceDashboardFilter =\n | InterfaceStatusFilter\n | InterfaceTriggerFilter;\n\n/** Sort values name comparators this host implements. */\nexport const DASHBOARD_SORT_VALUES = [\"last-run\", \"runs\", \"name\"] as const;\n\nexport type DashboardSortValue = (typeof DASHBOARD_SORT_VALUES)[number];\n\nexport interface InterfaceDashboardSort {\n /** The control's accessible name. */\n label: string;\n options: { value: DashboardSortValue; label: string }[];\n /** One of the declared option values. */\n default: DashboardSortValue;\n}\n\n/**\n * Copy for the per-automation run insights on cards and rows. The states,\n * precedence, sampling, and value formatting are this host's; the manifest\n * names them.\n */\nexport interface InterfaceListInsights {\n health: {\n healthy: string;\n failing: string;\n running: string;\n disabled: string;\n neverRun: string;\n checking: string;\n };\n lastRun: { label: string; never: string; justNow: string };\n stats: { runs: string; recentSuccess: string; averageDuration: string };\n}\n\n/**\n * The templates sub-page identity. Its body — the catalog cards and their\n * launch behavior — is this host's existing catalog surface.\n */\nexport interface InterfaceTemplatesPage {\n title: string;\n description: string;\n}\n\nexport interface InterfaceManifest {\n version: typeof INTERFACE_VERSION;\n routes: InterfaceRoutes;\n navigation: {\n sidebar: { label: string };\n commandMenu: { title: string; description: string; keywords: string };\n /** The ordered sub-page navigation of the interface. */\n subPages?: InterfaceSubPageNavItem[];\n };\n pages: {\n list: {\n title: string;\n subtitle: string;\n overview?: InterfaceOverview;\n /** The filter dropdowns of the list page, in render order. */\n filters?: InterfaceDashboardFilter[];\n sort?: InterfaceDashboardSort;\n insights?: InterfaceListInsights;\n };\n detail: { backLabel: string };\n edit: { title: string };\n templates?: InterfaceTemplatesPage;\n };\n docsUrl: string;\n /**\n * The input surface of an existing Automation, keyed by the runtime-model\n * property the host sends. Rendering it as an edit dialog is this host's\n * choice, not stated here.\n */\n attributes: Partial<Record<AutomationAttributeName, InterfaceAttribute>>;\n importExport: InterfaceImportExport;\n endpoints: InterfaceEndpoints;\n featuredAutomationIds: string[];\n responderIntegrationIds: string[];\n}\n"],"mappings":";AA6BA,IAAa,IAA+B,CAAC,QAAQ,YAAY,GAyNpD,IAAyB,CAAC,QAAQ,WAAW,GAK7C,IAAuB;CAClC;CACA;CACA;CACA;CACA;CACA;AACF,GAYa,IAAmB;CAC9B;CACA;CACA;CACA;AACF,GAQa,IAGT;CACF,aAAa,CAAC,QAAQ;CACtB,mBAAmB,CAAC;CACpB,cAAc,CAAC;CACf,oBAAoB,CAAC;AACvB,GAmBa,IAA0B;CACrC,QAAQ;EAAC;EAAO;EAAU;EAAW;CAAU;CAC/C,SAAS;EAAC;EAAO;EAAY;CAAO;AACtC,GAIa,IAAuB,OAAO,KACzC,CACF,GA2Ba,IAAwB;CAAC;CAAY;CAAQ;AAAM"}
@@ -7,8 +7,8 @@
7
7
  * - Please do NOT modify this file.
8
8
  */
9
9
 
10
- const PACKAGE_VERSION = '2.14.2'
11
- const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
10
+ const PACKAGE_VERSION = '2.15.0'
11
+ const INTEGRITY_CHECKSUM = '03cb67ac84128e63d7cd722a6e5b7f1e'
12
12
  const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
13
13
  const activeClientIds = new Set()
14
14
 
@@ -137,8 +137,18 @@ async function handleRequest(event, requestId, requestInterceptedAt) {
137
137
  if (client && activeClientIds.has(client.id)) {
138
138
  const serializedRequest = await serializeRequest(requestCloneForEvents)
139
139
 
140
+ // Omit the body of server-sent event stream responses.
141
+ // Cloning such responses would prevent client-side stream cancelations
142
+ // from reaching the original stream (a teed stream only cancels its
143
+ // source once both of its branches cancel) and would buffer the
144
+ // entire stream into the unconsumed clone indefinitely.
145
+ const isEventStreamResponse = response.headers
146
+ .get('content-type')
147
+ ?.toLowerCase()
148
+ .startsWith('text/event-stream')
149
+
140
150
  // Clone the response so both the client and the library could consume it.
141
- const responseClone = response.clone()
151
+ const responseClone = isEventStreamResponse ? null : response.clone()
142
152
 
143
153
  sendToClient(
144
154
  client,
@@ -151,15 +161,17 @@ async function handleRequest(event, requestId, requestInterceptedAt) {
151
161
  ...serializedRequest,
152
162
  },
153
163
  response: {
154
- type: responseClone.type,
155
- status: responseClone.status,
156
- statusText: responseClone.statusText,
157
- headers: Object.fromEntries(responseClone.headers.entries()),
158
- body: responseClone.body,
164
+ type: response.type,
165
+ status: response.status,
166
+ statusText: response.statusText,
167
+ headers: Object.fromEntries(response.headers.entries()),
168
+ body: responseClone ? responseClone.body : null,
159
169
  },
160
170
  },
161
171
  },
162
- responseClone.body ? [serializedRequest.body, responseClone.body] : [],
172
+ responseClone && responseClone.body
173
+ ? [serializedRequest.body, responseClone.body]
174
+ : [],
163
175
  )
164
176
  }
165
177
 
@@ -0,0 +1,9 @@
1
+ require("../../../../../../_virtual/_rolldown/runtime.cjs");var e={id:`upstream-fork-sync`,name:`Upstream fork sync`,category:`Developer tools`,description:`Keep a long-lived fork current with its upstream by re-running a nightly job that fetches upstream changes, rebases local customizations on top, verifies the software still works, and replaces the running version when it does.`,requires:{integrations:{github:{message:`Used to fetch upstream changes and push the rebased fork.`}},features:[`repoClone`,`presetPrompt`]},popularityRank:80,estimatedSetupMinutes:4,exampleImplementation:`Trigger: cron, nightly (configurable)
2
+ Required secret: GITHUB_PERSONAL_ACCESS_TOKEN
3
+
4
+ 1. Clone the fork repository and fetch the latest from its upstream remote.
5
+ 2. Rebase every local customization commit on top of the newest upstream HEAD.
6
+ 3. Run the configured verification command to confirm the software works as intended.
7
+ 4. If verification passes, force-push the rebased branch and replace the currently deployed version with the freshly built one.
8
+ 5. If verification fails, leave the running version untouched and report the conflict.`,setup:{version:`1.0`,mode:`direct`,form:{triggers:{cron:{schedule:{type:`cron`,label:`Sync schedule`,help:`How often to fetch upstream and rebase local changes. Nightly is the default.`,default:`0 3 * * *`,required:!0},timezone:{type:`timezone`,label:`Timezone`,help:`Timezone the schedule is interpreted in.`,default:`UTC`,required:!0}}},args:{repository:{type:`repo-picker`,label:`Repository`,help:`The long-lived fork to keep synchronized with upstream.`,provider:`github`,required:!0},upstreamRemote:{type:`text`,label:`Upstream remote`,help:`The remote (URL or owner/repo) the fork tracks. Defaults to the repository's parent.`,default:``,required:!1,constraints:{maxLength:255}},localChanges:{type:`text`,label:`Local changes`,help:`Plain-language description of the customizations to preserve across rebase.`,default:``,required:!1,constraints:{maxLength:2e3}},verifyCommand:{type:`text`,label:`Verify command`,help:"The command that confirms the software works as intended (e.g. `make test`). If blank, the agent infers a sensible check.",default:``,required:!1,constraints:{maxLength:500}}}},prompt:`Fetch the latest upstream changes for the fork {{form.repository}} and rebase all local changes on top of upstream. Local changes to preserve: {{form.localChanges}}. Check that the software works as intended; if it does, replace the current version, otherwise leave the running version untouched and report what failed.`,message:`This deployment cannot run the scheduled fork-sync automation directly. Set it up in this conversation instead: confirm the fork repository, the upstream remote, the local changes to preserve, the verification command, and the nightly schedule, then create the automation.`}};exports.default=e;
9
+ //# sourceMappingURL=manifest.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.cjs","names":[],"sources":["../../../../../../../node_modules/@openhands/extensions/automations/catalog/upstream-fork-sync/manifest.json"],"sourcesContent":["{\n \"id\": \"upstream-fork-sync\",\n \"name\": \"Upstream fork sync\",\n \"category\": \"Developer tools\",\n \"description\": \"Keep a long-lived fork current with its upstream by re-running a nightly job that fetches upstream changes, rebases local customizations on top, verifies the software still works, and replaces the running version when it does.\",\n \"requires\": {\n \"integrations\": {\n \"github\": {\n \"message\": \"Used to fetch upstream changes and push the rebased fork.\"\n }\n },\n \"features\": [\n \"repoClone\",\n \"presetPrompt\"\n ]\n },\n \"popularityRank\": 80,\n \"estimatedSetupMinutes\": 4,\n \"exampleImplementation\": \"Trigger: cron, nightly (configurable)\\nRequired secret: GITHUB_PERSONAL_ACCESS_TOKEN\\n\\n1. Clone the fork repository and fetch the latest from its upstream remote.\\n2. Rebase every local customization commit on top of the newest upstream HEAD.\\n3. Run the configured verification command to confirm the software works as intended.\\n4. If verification passes, force-push the rebased branch and replace the currently deployed version with the freshly built one.\\n5. If verification fails, leave the running version untouched and report the conflict.\",\n \"setup\": {\n \"version\": \"1.0\",\n \"mode\": \"direct\",\n \"form\": {\n \"triggers\": {\n \"cron\": {\n \"schedule\": {\n \"type\": \"cron\",\n \"label\": \"Sync schedule\",\n \"help\": \"How often to fetch upstream and rebase local changes. Nightly is the default.\",\n \"default\": \"0 3 * * *\",\n \"required\": true\n },\n \"timezone\": {\n \"type\": \"timezone\",\n \"label\": \"Timezone\",\n \"help\": \"Timezone the schedule is interpreted in.\",\n \"default\": \"UTC\",\n \"required\": true\n }\n }\n },\n \"args\": {\n \"repository\": {\n \"type\": \"repo-picker\",\n \"label\": \"Repository\",\n \"help\": \"The long-lived fork to keep synchronized with upstream.\",\n \"provider\": \"github\",\n \"required\": true\n },\n \"upstreamRemote\": {\n \"type\": \"text\",\n \"label\": \"Upstream remote\",\n \"help\": \"The remote (URL or owner/repo) the fork tracks. Defaults to the repository's parent.\",\n \"default\": \"\",\n \"required\": false,\n \"constraints\": {\n \"maxLength\": 255\n }\n },\n \"localChanges\": {\n \"type\": \"text\",\n \"label\": \"Local changes\",\n \"help\": \"Plain-language description of the customizations to preserve across rebase.\",\n \"default\": \"\",\n \"required\": false,\n \"constraints\": {\n \"maxLength\": 2000\n }\n },\n \"verifyCommand\": {\n \"type\": \"text\",\n \"label\": \"Verify command\",\n \"help\": \"The command that confirms the software works as intended (e.g. `make test`). If blank, the agent infers a sensible check.\",\n \"default\": \"\",\n \"required\": false,\n \"constraints\": {\n \"maxLength\": 500\n }\n }\n }\n },\n \"prompt\": \"Fetch the latest upstream changes for the fork {{form.repository}} and rebase all local changes on top of upstream. Local changes to preserve: {{form.localChanges}}. Check that the software works as intended; if it does, replace the current version, otherwise leave the running version untouched and report what failed.\",\n \"message\": \"This deployment cannot run the scheduled fork-sync automation directly. Set it up in this conversation instead: confirm the fork repository, the upstream remote, the local changes to preserve, the verification command, and the nightly schedule, then create the automation.\"\n }\n}\n"],"x_google_ignoreList":[0],"mappings":""}