happy2 0.0.9 → 0.0.12

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 (286) hide show
  1. package/README.md +29 -0
  2. package/package.json +7 -3
  3. package/packages/happy2-server/PLUGINS.md +402 -0
  4. package/packages/happy2-server/README.md +39 -0
  5. package/packages/happy2-server/dist/daemon.d.ts +39 -0
  6. package/packages/happy2-server/dist/daemon.d.ts.map +1 -0
  7. package/packages/happy2-server/dist/daemon.js +302 -0
  8. package/packages/happy2-server/dist/daemon.js.map +1 -0
  9. package/packages/happy2-server/dist/daemon.test.d.ts +2 -0
  10. package/packages/happy2-server/dist/daemon.test.d.ts.map +1 -0
  11. package/packages/happy2-server/dist/daemon.test.js +245 -0
  12. package/packages/happy2-server/dist/daemon.test.js.map +1 -0
  13. package/packages/happy2-server/dist/index.d.ts +7 -1
  14. package/packages/happy2-server/dist/index.d.ts.map +1 -1
  15. package/packages/happy2-server/dist/index.js +5 -1
  16. package/packages/happy2-server/dist/index.js.map +1 -1
  17. package/packages/happy2-server/dist/modules/agents/daemon.d.ts +10 -13
  18. package/packages/happy2-server/dist/modules/agents/daemon.d.ts.map +1 -1
  19. package/packages/happy2-server/dist/modules/agents/daemon.js +19 -5
  20. package/packages/happy2-server/dist/modules/agents/daemon.js.map +1 -1
  21. package/packages/happy2-server/dist/modules/agents/service.d.ts +9 -1
  22. package/packages/happy2-server/dist/modules/agents/service.d.ts.map +1 -1
  23. package/packages/happy2-server/dist/modules/agents/service.js +59 -2
  24. package/packages/happy2-server/dist/modules/agents/service.js.map +1 -1
  25. package/packages/happy2-server/dist/modules/auth/tokens.d.ts +7 -0
  26. package/packages/happy2-server/dist/modules/auth/tokens.d.ts.map +1 -1
  27. package/packages/happy2-server/dist/modules/auth/tokens.js +33 -0
  28. package/packages/happy2-server/dist/modules/auth/tokens.js.map +1 -1
  29. package/packages/happy2-server/dist/modules/auth/tokens.test.d.ts +2 -0
  30. package/packages/happy2-server/dist/modules/auth/tokens.test.d.ts.map +1 -0
  31. package/packages/happy2-server/dist/modules/auth/tokens.test.js +28 -0
  32. package/packages/happy2-server/dist/modules/auth/tokens.test.js.map +1 -0
  33. package/packages/happy2-server/dist/modules/chat/types.d.ts +1 -1
  34. package/packages/happy2-server/dist/modules/chat/types.d.ts.map +1 -1
  35. package/packages/happy2-server/dist/modules/config/defaults.d.ts.map +1 -1
  36. package/packages/happy2-server/dist/modules/config/defaults.js +5 -0
  37. package/packages/happy2-server/dist/modules/config/defaults.js.map +1 -1
  38. package/packages/happy2-server/dist/modules/config/loader.d.ts.map +1 -1
  39. package/packages/happy2-server/dist/modules/config/loader.js +9 -0
  40. package/packages/happy2-server/dist/modules/config/loader.js.map +1 -1
  41. package/packages/happy2-server/dist/modules/config/loader.test.js +15 -0
  42. package/packages/happy2-server/dist/modules/config/loader.test.js.map +1 -1
  43. package/packages/happy2-server/dist/modules/config/paths.d.ts +1 -0
  44. package/packages/happy2-server/dist/modules/config/paths.d.ts.map +1 -1
  45. package/packages/happy2-server/dist/modules/config/paths.js +1 -0
  46. package/packages/happy2-server/dist/modules/config/paths.js.map +1 -1
  47. package/packages/happy2-server/dist/modules/config/paths.test.js +1 -0
  48. package/packages/happy2-server/dist/modules/config/paths.test.js.map +1 -1
  49. package/packages/happy2-server/dist/modules/config/type.d.ts +5 -0
  50. package/packages/happy2-server/dist/modules/config/type.d.ts.map +1 -1
  51. package/packages/happy2-server/dist/modules/integrations/transport.d.ts.map +1 -1
  52. package/packages/happy2-server/dist/modules/integrations/transport.js +8 -1
  53. package/packages/happy2-server/dist/modules/integrations/transport.js.map +1 -1
  54. package/packages/happy2-server/dist/modules/integrations/types.d.ts +2 -0
  55. package/packages/happy2-server/dist/modules/integrations/types.d.ts.map +1 -1
  56. package/packages/happy2-server/dist/modules/integrations/types.js.map +1 -1
  57. package/packages/happy2-server/dist/modules/plugin/catalog.d.ts +13 -0
  58. package/packages/happy2-server/dist/modules/plugin/catalog.d.ts.map +1 -0
  59. package/packages/happy2-server/dist/modules/plugin/catalog.js +400 -0
  60. package/packages/happy2-server/dist/modules/plugin/catalog.js.map +1 -0
  61. package/packages/happy2-server/dist/modules/plugin/catalog.test.d.ts +2 -0
  62. package/packages/happy2-server/dist/modules/plugin/catalog.test.d.ts.map +1 -0
  63. package/packages/happy2-server/dist/modules/plugin/catalog.test.js +172 -0
  64. package/packages/happy2-server/dist/modules/plugin/catalog.test.js.map +1 -0
  65. package/packages/happy2-server/dist/modules/plugin/functions.test.d.ts +2 -0
  66. package/packages/happy2-server/dist/modules/plugin/functions.test.d.ts.map +1 -0
  67. package/packages/happy2-server/dist/modules/plugin/functions.test.js +123 -0
  68. package/packages/happy2-server/dist/modules/plugin/functions.test.js.map +1 -0
  69. package/packages/happy2-server/dist/modules/plugin/httpBridge.d.ts +19 -0
  70. package/packages/happy2-server/dist/modules/plugin/httpBridge.d.ts.map +1 -0
  71. package/packages/happy2-server/dist/modules/plugin/httpBridge.js +206 -0
  72. package/packages/happy2-server/dist/modules/plugin/httpBridge.js.map +1 -0
  73. package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.d.ts +3 -0
  74. package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.d.ts.map +1 -0
  75. package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.js +47 -0
  76. package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.js.map +1 -0
  77. package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.d.ts +3 -0
  78. package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.d.ts.map +1 -0
  79. package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.js +82 -0
  80. package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.js.map +1 -0
  81. package/packages/happy2-server/dist/modules/plugin/impl/effectiveContainer.d.ts +3 -0
  82. package/packages/happy2-server/dist/modules/plugin/impl/effectiveContainer.d.ts.map +1 -0
  83. package/packages/happy2-server/dist/modules/plugin/impl/effectiveContainer.js +12 -0
  84. package/packages/happy2-server/dist/modules/plugin/impl/effectiveContainer.js.map +1 -0
  85. package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.d.ts +288 -0
  86. package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.d.ts.map +1 -0
  87. package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.js +19 -0
  88. package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.js.map +1 -0
  89. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.d.ts +3 -0
  90. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.d.ts.map +1 -0
  91. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.js +63 -0
  92. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.js.map +1 -0
  93. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.d.ts +2 -0
  94. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.d.ts.map +1 -0
  95. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.js +17 -0
  96. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.js.map +1 -0
  97. package/packages/happy2-server/dist/modules/plugin/impl/pluginFunctionResult.d.ts +3 -0
  98. package/packages/happy2-server/dist/modules/plugin/impl/pluginFunctionResult.d.ts.map +1 -0
  99. package/packages/happy2-server/dist/modules/plugin/impl/pluginFunctionResult.js +16 -0
  100. package/packages/happy2-server/dist/modules/plugin/impl/pluginFunctionResult.js.map +1 -0
  101. package/packages/happy2-server/dist/modules/plugin/impl/pluginSelection.d.ts +339 -0
  102. package/packages/happy2-server/dist/modules/plugin/impl/pluginSelection.d.ts.map +1 -0
  103. package/packages/happy2-server/dist/modules/plugin/impl/pluginSelection.js +22 -0
  104. package/packages/happy2-server/dist/modules/plugin/impl/pluginSelection.js.map +1 -0
  105. package/packages/happy2-server/dist/modules/plugin/index.d.ts +3 -0
  106. package/packages/happy2-server/dist/modules/plugin/index.d.ts.map +1 -0
  107. package/packages/happy2-server/dist/modules/plugin/index.js +3 -0
  108. package/packages/happy2-server/dist/modules/plugin/index.js.map +1 -0
  109. package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts +15 -0
  110. package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts.map +1 -0
  111. package/packages/happy2-server/dist/modules/plugin/packageStore.js +90 -0
  112. package/packages/happy2-server/dist/modules/plugin/packageStore.js.map +1 -0
  113. package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.d.ts +7 -0
  114. package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.d.ts.map +1 -0
  115. package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.js +9 -0
  116. package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.js.map +1 -0
  117. package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.d.ts +9 -0
  118. package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.d.ts.map +1 -0
  119. package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.js +64 -0
  120. package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.js.map +1 -0
  121. package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceAuthorize.d.ts +10 -0
  122. package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceAuthorize.d.ts.map +1 -0
  123. package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceAuthorize.js +20 -0
  124. package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceAuthorize.js.map +1 -0
  125. package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceInvalidate.d.ts +12 -0
  126. package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceInvalidate.d.ts.map +1 -0
  127. package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceInvalidate.js +44 -0
  128. package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceInvalidate.js.map +1 -0
  129. package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.d.ts +9 -0
  130. package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.d.ts.map +1 -0
  131. package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.js +15 -0
  132. package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.js.map +1 -0
  133. package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultAcquire.d.ts +23 -0
  134. package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultAcquire.d.ts.map +1 -0
  135. package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultAcquire.js +54 -0
  136. package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultAcquire.js.map +1 -0
  137. package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultComplete.d.ts +13 -0
  138. package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultComplete.d.ts.map +1 -0
  139. package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultComplete.js +37 -0
  140. package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultComplete.js.map +1 -0
  141. package/packages/happy2-server/dist/modules/plugin/pluginGetImage.d.ts +17 -0
  142. package/packages/happy2-server/dist/modules/plugin/pluginGetImage.d.ts.map +1 -0
  143. package/packages/happy2-server/dist/modules/plugin/pluginGetImage.js +29 -0
  144. package/packages/happy2-server/dist/modules/plugin/pluginGetImage.js.map +1 -0
  145. package/packages/happy2-server/dist/modules/plugin/pluginInstall.d.ts +27 -0
  146. package/packages/happy2-server/dist/modules/plugin/pluginInstall.d.ts.map +1 -0
  147. package/packages/happy2-server/dist/modules/plugin/pluginInstall.js +180 -0
  148. package/packages/happy2-server/dist/modules/plugin/pluginInstall.js.map +1 -0
  149. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.d.ts +9 -0
  150. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.d.ts.map +1 -0
  151. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.js +122 -0
  152. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.js.map +1 -0
  153. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetStatus.d.ts +11 -0
  154. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetStatus.d.ts.map +1 -0
  155. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetStatus.js +18 -0
  156. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetStatus.js.map +1 -0
  157. package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.d.ts +8 -0
  158. package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.d.ts.map +1 -0
  159. package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.js +19 -0
  160. package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.js.map +1 -0
  161. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListForHost.d.ts +14 -0
  162. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListForHost.d.ts.map +1 -0
  163. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListForHost.js +20 -0
  164. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListForHost.js.map +1 -0
  165. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListIds.d.ts +7 -0
  166. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListIds.d.ts.map +1 -0
  167. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListIds.js +13 -0
  168. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListIds.js.map +1 -0
  169. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListReadyMcpIds.d.ts +7 -0
  170. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListReadyMcpIds.d.ts.map +1 -0
  171. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListReadyMcpIds.js +16 -0
  172. package/packages/happy2-server/dist/modules/plugin/pluginInstallationListReadyMcpIds.js.map +1 -0
  173. package/packages/happy2-server/dist/modules/plugin/pluginInstallationUpdateStatus.d.ts +16 -0
  174. package/packages/happy2-server/dist/modules/plugin/pluginInstallationUpdateStatus.d.ts.map +1 -0
  175. package/packages/happy2-server/dist/modules/plugin/pluginInstallationUpdateStatus.js +38 -0
  176. package/packages/happy2-server/dist/modules/plugin/pluginInstallationUpdateStatus.js.map +1 -0
  177. package/packages/happy2-server/dist/modules/plugin/pluginList.d.ts +8 -0
  178. package/packages/happy2-server/dist/modules/plugin/pluginList.d.ts.map +1 -0
  179. package/packages/happy2-server/dist/modules/plugin/pluginList.js +17 -0
  180. package/packages/happy2-server/dist/modules/plugin/pluginList.js.map +1 -0
  181. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsList.d.ts +11 -0
  182. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsList.d.ts.map +1 -0
  183. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsList.js +43 -0
  184. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsList.js.map +1 -0
  185. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsListReady.d.ts +15 -0
  186. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsListReady.d.ts.map +1 -0
  187. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsListReady.js +37 -0
  188. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsListReady.js.map +1 -0
  189. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsReplace.d.ts +16 -0
  190. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsReplace.d.ts.map +1 -0
  191. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsReplace.js +71 -0
  192. package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsReplace.js.map +1 -0
  193. package/packages/happy2-server/dist/modules/plugin/pluginRemoveMissingBuiltins.d.ts +14 -0
  194. package/packages/happy2-server/dist/modules/plugin/pluginRemoveMissingBuiltins.d.ts.map +1 -0
  195. package/packages/happy2-server/dist/modules/plugin/pluginRemoveMissingBuiltins.js +51 -0
  196. package/packages/happy2-server/dist/modules/plugin/pluginRemoveMissingBuiltins.js.map +1 -0
  197. package/packages/happy2-server/dist/modules/plugin/runtime.d.ts +56 -0
  198. package/packages/happy2-server/dist/modules/plugin/runtime.d.ts.map +1 -0
  199. package/packages/happy2-server/dist/modules/plugin/runtime.js +147 -0
  200. package/packages/happy2-server/dist/modules/plugin/runtime.js.map +1 -0
  201. package/packages/happy2-server/dist/modules/plugin/secrets.d.ts +17 -0
  202. package/packages/happy2-server/dist/modules/plugin/secrets.d.ts.map +1 -0
  203. package/packages/happy2-server/dist/modules/plugin/secrets.js +56 -0
  204. package/packages/happy2-server/dist/modules/plugin/secrets.js.map +1 -0
  205. package/packages/happy2-server/dist/modules/plugin/secrets.test.d.ts +2 -0
  206. package/packages/happy2-server/dist/modules/plugin/secrets.test.d.ts.map +1 -0
  207. package/packages/happy2-server/dist/modules/plugin/secrets.test.js +14 -0
  208. package/packages/happy2-server/dist/modules/plugin/secrets.test.js.map +1 -0
  209. package/packages/happy2-server/dist/modules/plugin/service.d.ts +60 -0
  210. package/packages/happy2-server/dist/modules/plugin/service.d.ts.map +1 -0
  211. package/packages/happy2-server/dist/modules/plugin/service.js +584 -0
  212. package/packages/happy2-server/dist/modules/plugin/service.js.map +1 -0
  213. package/packages/happy2-server/dist/modules/plugin/types.d.ts +194 -0
  214. package/packages/happy2-server/dist/modules/plugin/types.d.ts.map +1 -0
  215. package/packages/happy2-server/dist/modules/plugin/types.js +10 -0
  216. package/packages/happy2-server/dist/modules/plugin/types.js.map +1 -0
  217. package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.d.ts +19 -0
  218. package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.d.ts.map +1 -0
  219. package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.js +97 -0
  220. package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.js.map +1 -0
  221. package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.test.d.ts +2 -0
  222. package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.test.d.ts.map +1 -0
  223. package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.test.js +74 -0
  224. package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.test.js.map +1 -0
  225. package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.d.ts +29 -0
  226. package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.d.ts.map +1 -0
  227. package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.js +126 -0
  228. package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.js.map +1 -0
  229. package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.test.d.ts +2 -0
  230. package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.test.d.ts.map +1 -0
  231. package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.test.js +75 -0
  232. package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.test.js.map +1 -0
  233. package/packages/happy2-server/dist/modules/sandbox/index.d.ts +1 -1
  234. package/packages/happy2-server/dist/modules/sandbox/index.d.ts.map +1 -1
  235. package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.d.ts +9 -1
  236. package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.d.ts.map +1 -1
  237. package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.js +218 -4
  238. package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.js.map +1 -1
  239. package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.test.js +157 -2
  240. package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.test.js.map +1 -1
  241. package/packages/happy2-server/dist/modules/sandbox/types.d.ts +24 -0
  242. package/packages/happy2-server/dist/modules/sandbox/types.d.ts.map +1 -1
  243. package/packages/happy2-server/dist/modules/schema.d.ts +7781 -5489
  244. package/packages/happy2-server/dist/modules/schema.d.ts.map +1 -1
  245. package/packages/happy2-server/dist/modules/schema.js +87 -1
  246. package/packages/happy2-server/dist/modules/schema.js.map +1 -1
  247. package/packages/happy2-server/dist/modules/sync/syncGetDifference.d.ts.map +1 -1
  248. package/packages/happy2-server/dist/modules/sync/syncGetDifference.js +2 -0
  249. package/packages/happy2-server/dist/modules/sync/syncGetDifference.js.map +1 -1
  250. package/packages/happy2-server/dist/routes/pluginHost.d.ts +6 -0
  251. package/packages/happy2-server/dist/routes/pluginHost.d.ts.map +1 -0
  252. package/packages/happy2-server/dist/routes/pluginHost.js +37 -0
  253. package/packages/happy2-server/dist/routes/pluginHost.js.map +1 -0
  254. package/packages/happy2-server/dist/routes/plugins.d.ts +8 -0
  255. package/packages/happy2-server/dist/routes/plugins.d.ts.map +1 -0
  256. package/packages/happy2-server/dist/routes/plugins.js +198 -0
  257. package/packages/happy2-server/dist/routes/plugins.js.map +1 -0
  258. package/packages/happy2-server/dist/runner.js +64 -19
  259. package/packages/happy2-server/dist/runner.js.map +1 -1
  260. package/packages/happy2-server/dist/server.d.ts +8 -0
  261. package/packages/happy2-server/dist/server.d.ts.map +1 -1
  262. package/packages/happy2-server/dist/server.js +65 -3
  263. package/packages/happy2-server/dist/server.js.map +1 -1
  264. package/packages/happy2-server/dist/systemService.d.ts +48 -0
  265. package/packages/happy2-server/dist/systemService.d.ts.map +1 -0
  266. package/packages/happy2-server/dist/systemService.js +323 -0
  267. package/packages/happy2-server/dist/systemService.js.map +1 -0
  268. package/packages/happy2-server/dist/systemService.test.d.ts +2 -0
  269. package/packages/happy2-server/dist/systemService.test.d.ts.map +1 -0
  270. package/packages/happy2-server/dist/systemService.test.js +280 -0
  271. package/packages/happy2-server/dist/systemService.test.js.map +1 -0
  272. package/packages/happy2-server/dist/web/assets/index-9SGCQLg7.js +46 -0
  273. package/packages/happy2-server/dist/web/assets/{index-DZ1uRLgV.css → index-DWXBQDJB.css} +1 -1
  274. package/packages/happy2-server/dist/web/index.html +2 -2
  275. package/packages/happy2-server/drizzle/0020_plugins.sql +61 -0
  276. package/packages/happy2-server/drizzle/0021_plugin_function_results.sql +11 -0
  277. package/packages/happy2-server/drizzle/0022_plugin_container_runtime_tools.sql +16 -0
  278. package/packages/happy2-server/drizzle/meta/_journal.json +21 -0
  279. package/packages/happy2-server/happy2.example.toml +13 -0
  280. package/packages/happy2-server/plugins/README.md +7 -0
  281. package/packages/happy2-server/plugins/hello/container/Dockerfile +6 -0
  282. package/packages/happy2-server/plugins/hello/plugin.json +16 -0
  283. package/packages/happy2-server/plugins/hello/plugin.png +0 -0
  284. package/packages/happy2-server/plugins/hello/server.mjs +75 -0
  285. package/packages/happy2-server/plugins/hello/skills/hello/SKILL.md +11 -0
  286. package/packages/happy2-server/dist/web/assets/index-DH1SOwNV.js +0 -46
@@ -0,0 +1,400 @@
1
+ import { createHash } from "node:crypto";
2
+ import { lstat, readFile, readdir, realpath } from "node:fs/promises";
3
+ import { basename, join, relative, resolve, sep } from "node:path";
4
+ import sharp from "sharp";
5
+ import { rgbaToThumbHash } from "thumbhash";
6
+ import { parseDocument } from "yaml";
7
+ import { StrictWebhookUrlPolicy } from "../integrations/ssrf.js";
8
+ const MAX_PACKAGE_FILES = 1_000;
9
+ const MAX_PACKAGE_BYTES = 20 * 1024 * 1024;
10
+ const MAX_FILE_BYTES = 5 * 1024 * 1024;
11
+ const MAX_ICON_DIMENSION = 4_096;
12
+ const SHORT_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
13
+ const ENV_KEY = /^[A-Z_][A-Z0-9_]*$/;
14
+ const SKILL_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
15
+ const VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
16
+ const HEADER_NAME = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
17
+ const RESERVED_REMOTE_HEADERS = new Set([
18
+ "__proto__",
19
+ "accept",
20
+ "connection",
21
+ "constructor",
22
+ "content-length",
23
+ "content-type",
24
+ "host",
25
+ "mcp-protocol-version",
26
+ "proxy-authorization",
27
+ "prototype",
28
+ "te",
29
+ "trailer",
30
+ "transfer-encoding",
31
+ "upgrade",
32
+ "user-agent",
33
+ ]);
34
+ const HOST_PERMISSIONS = new Set(["plugins:list"]);
35
+ /** Immutable lookup over validated plugin packages supplied by the built-in catalog. */
36
+ export class PluginCatalog {
37
+ packages;
38
+ constructor(packages) {
39
+ const indexed = new Map();
40
+ for (const plugin of packages) {
41
+ if (indexed.has(plugin.manifest.shortName))
42
+ throw new Error(`Duplicate plugin shortName ${plugin.manifest.shortName}`);
43
+ indexed.set(plugin.manifest.shortName, plugin);
44
+ }
45
+ this.packages = indexed;
46
+ }
47
+ list() {
48
+ return [...this.packages.values()].sort((left, right) => left.manifest.displayName.localeCompare(right.manifest.displayName));
49
+ }
50
+ get(shortName) {
51
+ return this.packages.get(shortName);
52
+ }
53
+ }
54
+ /** Loads and fully validates every child package in a built-in plugins directory. */
55
+ export async function pluginCatalogLoad(root) {
56
+ let entries;
57
+ try {
58
+ entries = await readdir(root, { withFileTypes: true });
59
+ }
60
+ catch (error) {
61
+ if (error.code === "ENOENT")
62
+ return new PluginCatalog([]);
63
+ throw error;
64
+ }
65
+ const packages = await Promise.all(entries
66
+ .filter((entry) => entry.isDirectory())
67
+ .map((entry) => pluginPackageLoad(join(root, entry.name), entry.name)));
68
+ return new PluginCatalog(packages);
69
+ }
70
+ /** Loads one built-in package while rejecting unsafe paths, malformed manifests, invalid skills, and non-square icons. */
71
+ export async function pluginPackageLoad(directory, sourceReference = basename(directory)) {
72
+ const canonicalDirectory = await realpath(directory);
73
+ const files = await packageFiles(canonicalDirectory);
74
+ const manifestBuffer = files.get("plugin.json");
75
+ const iconBuffer = files.get("plugin.png");
76
+ if (!manifestBuffer)
77
+ throw new Error(`${sourceReference}: plugin.json is required`);
78
+ if (!iconBuffer)
79
+ throw new Error(`${sourceReference}: plugin.png is required`);
80
+ const manifest = manifestParse(manifestBuffer.toString("utf8"), sourceReference);
81
+ if (manifest.shortName !== sourceReference)
82
+ throw new Error(`${sourceReference}: shortName must match the package directory name`);
83
+ const iconImage = sharp(iconBuffer, { limitInputPixels: 16_777_216 });
84
+ const icon = await iconImage.metadata();
85
+ if (icon.format !== "png" ||
86
+ !icon.width ||
87
+ icon.width !== icon.height ||
88
+ icon.width > MAX_ICON_DIMENSION)
89
+ throw new Error(`${sourceReference}: plugin.png must be a square PNG up to 4096 pixels`);
90
+ const skills = await skillsParse(files, sourceReference);
91
+ if (!manifest.container && !manifest.mcp && skills.length === 0)
92
+ throw new Error(`${sourceReference}: a plugin must contain a container, skill, or MCP server`);
93
+ if (manifest.container?.dockerfile)
94
+ requirePackageFile(files, manifest.container.dockerfile, sourceReference);
95
+ if (manifest.mcp?.type === "stdio" && manifest.mcp.container)
96
+ requirePackageFile(files, manifest.mcp.container.dockerfile, sourceReference);
97
+ const thumbhashInput = await iconImage
98
+ .clone()
99
+ .resize(100, 100, { fit: "inside", withoutEnlargement: true })
100
+ .ensureAlpha()
101
+ .raw()
102
+ .toBuffer({ resolveWithObject: true });
103
+ return {
104
+ manifest,
105
+ skills,
106
+ directory: canonicalDirectory,
107
+ iconPath: join(canonicalDirectory, "plugin.png"),
108
+ image: {
109
+ contentType: "image/png",
110
+ size: iconBuffer.byteLength,
111
+ width: icon.width,
112
+ height: icon.height,
113
+ thumbhash: Buffer.from(rgbaToThumbHash(thumbhashInput.info.width, thumbhashInput.info.height, thumbhashInput.data)).toString("base64url"),
114
+ checksumSha256: createHash("sha256").update(iconBuffer).digest("hex"),
115
+ },
116
+ packageDigest: digest(files),
117
+ source: { kind: "builtin", reference: sourceReference },
118
+ };
119
+ }
120
+ async function packageFiles(directory) {
121
+ const result = new Map();
122
+ let totalBytes = 0;
123
+ const visit = async (current) => {
124
+ const entries = await readdir(current, { withFileTypes: true });
125
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
126
+ const path = join(current, entry.name);
127
+ const info = await lstat(path);
128
+ if (info.isSymbolicLink())
129
+ throw new Error(`Plugin packages may not contain symlinks: ${path}`);
130
+ if (info.isDirectory()) {
131
+ await visit(path);
132
+ continue;
133
+ }
134
+ if (!info.isFile())
135
+ throw new Error(`Plugin packages may contain only files: ${path}`);
136
+ if (info.size > MAX_FILE_BYTES)
137
+ throw new Error(`Plugin package file is too large: ${path}`);
138
+ if (result.size >= MAX_PACKAGE_FILES)
139
+ throw new Error("Plugin package has too many files");
140
+ totalBytes += info.size;
141
+ if (totalBytes > MAX_PACKAGE_BYTES)
142
+ throw new Error("Plugin package is too large");
143
+ const name = relative(directory, path).split(sep).join("/");
144
+ result.set(name, await readFile(path));
145
+ }
146
+ };
147
+ await visit(directory);
148
+ return result;
149
+ }
150
+ function manifestParse(source, label) {
151
+ let value;
152
+ try {
153
+ value = JSON.parse(source);
154
+ }
155
+ catch {
156
+ throw new Error(`${label}: plugin.json must contain valid JSON`);
157
+ }
158
+ const record = object(value, `${label}: plugin.json`);
159
+ only(record, [
160
+ "schemaVersion",
161
+ "version",
162
+ "displayName",
163
+ "shortName",
164
+ "description",
165
+ "variables",
166
+ "container",
167
+ "mcp",
168
+ ]);
169
+ if (record.schemaVersion !== 1)
170
+ throw new Error(`${label}: schemaVersion must be 1`);
171
+ const version = string(record.version, "version", 64);
172
+ const versionMatch = VERSION.exec(version);
173
+ if (!versionMatch ||
174
+ versionMatch[4]
175
+ ?.split(".")
176
+ .some((identifier) => /^\d+$/.test(identifier) && identifier.length > 1 && identifier.startsWith("0")))
177
+ throw new Error(`${label}: version must be a valid SemVer version`);
178
+ const shortName = string(record.shortName, "shortName", 64);
179
+ if (!SHORT_NAME.test(shortName))
180
+ throw new Error(`${label}: shortName is invalid`);
181
+ const variables = variableDefinitions(record.variables, label);
182
+ const parsedContainer = record.container === undefined ? undefined : container(record.container, label);
183
+ const parsedMcp = record.mcp === undefined ? undefined : mcp(record.mcp, variables, label);
184
+ if (parsedContainer && parsedMcp?.type === "stdio" && parsedMcp.container)
185
+ throw new Error(`${label}: use container.dockerfile instead of mcp.container.dockerfile`);
186
+ if (parsedContainer && parsedMcp?.type === "remote")
187
+ throw new Error(`${label}: a remote MCP cannot share a local plugin container`);
188
+ if (!parsedContainer && !parsedMcp && variables.length)
189
+ throw new Error(`${label}: variables require a container or MCP server definition`);
190
+ if (parsedContainer && !parsedContainer.command && parsedMcp?.type !== "stdio")
191
+ throw new Error(`${label}: a container without a stdio MCP requires a command`);
192
+ return {
193
+ schemaVersion: 1,
194
+ version,
195
+ displayName: string(record.displayName, "displayName", 100),
196
+ shortName,
197
+ description: string(record.description, "description", 1_000),
198
+ variables,
199
+ ...(parsedContainer ? { container: parsedContainer } : {}),
200
+ ...(parsedMcp ? { mcp: parsedMcp } : {}),
201
+ };
202
+ }
203
+ function container(value, label) {
204
+ const record = object(value, "container");
205
+ only(record, ["dockerfile", "command", "args", "permissions"]);
206
+ const command = record.command === undefined
207
+ ? undefined
208
+ : string(record.command, "container.command", 1_000);
209
+ if (!command && record.args !== undefined)
210
+ throw new Error(`${label}: container.args requires container.command`);
211
+ const rawPermissions = record.permissions ?? [];
212
+ if (!Array.isArray(rawPermissions) || rawPermissions.length > HOST_PERMISSIONS.size)
213
+ throw new Error(`${label}: container.permissions is invalid`);
214
+ const permissions = [];
215
+ for (const [index, raw] of rawPermissions.entries()) {
216
+ const permission = string(raw, `container.permissions[${index}]`, 100);
217
+ if (!HOST_PERMISSIONS.has(permission))
218
+ throw new Error(`${label}: unknown container permission ${permission}`);
219
+ if (permissions.includes(permission))
220
+ throw new Error(`${label}: duplicate container permission ${permission}`);
221
+ permissions.push(permission);
222
+ }
223
+ return {
224
+ ...(record.dockerfile === undefined
225
+ ? {}
226
+ : { dockerfile: relativePath(record.dockerfile, "container.dockerfile") }),
227
+ ...(command ? { command } : {}),
228
+ args: command ? stringArray(record.args, "container.args", 128, 4_096) : [],
229
+ permissions,
230
+ };
231
+ }
232
+ function variableDefinitions(value, label) {
233
+ if (value === undefined)
234
+ return [];
235
+ if (!Array.isArray(value) || value.length > 64)
236
+ throw new Error(`${label}: variables must be an array with at most 64 entries`);
237
+ const seen = new Set();
238
+ return value.map((item, index) => {
239
+ const record = object(item, `variables[${index}]`);
240
+ only(record, ["key", "displayName", "description", "kind"]);
241
+ const key = string(record.key, `variables[${index}].key`, 128);
242
+ if (!ENV_KEY.test(key))
243
+ throw new Error(`${label}: variable key ${key} is invalid`);
244
+ if (seen.has(key))
245
+ throw new Error(`${label}: duplicate variable key ${key}`);
246
+ seen.add(key);
247
+ if (record.kind !== "text" && record.kind !== "secret")
248
+ throw new Error(`${label}: variable ${key} kind must be text or secret`);
249
+ return {
250
+ key,
251
+ displayName: string(record.displayName, `${key}.displayName`, 100),
252
+ description: string(record.description, `${key}.description`, 1_000),
253
+ kind: record.kind,
254
+ };
255
+ });
256
+ }
257
+ function mcp(value, variables, label) {
258
+ const record = object(value, "mcp");
259
+ if (record.type === "stdio") {
260
+ only(record, ["type", "command", "args", "container"]);
261
+ const container = record.container === undefined ? undefined : object(record.container, "mcp.container");
262
+ if (container)
263
+ only(container, ["dockerfile"]);
264
+ return {
265
+ type: "stdio",
266
+ command: string(record.command, "mcp.command", 1_000),
267
+ args: stringArray(record.args, "mcp.args", 128, 4_096),
268
+ ...(container
269
+ ? {
270
+ container: {
271
+ dockerfile: relativePath(container.dockerfile, "mcp.container.dockerfile"),
272
+ },
273
+ }
274
+ : {}),
275
+ };
276
+ }
277
+ if (record.type === "remote") {
278
+ only(record, ["type", "url", "headers"]);
279
+ const url = string(record.url, "mcp.url", 4_096);
280
+ let normalizedUrl;
281
+ try {
282
+ normalizedUrl = new StrictWebhookUrlPolicy().validateForStorage(url);
283
+ }
284
+ catch (error) {
285
+ throw new Error(`${label}: ${error instanceof Error ? error.message : "remote MCP URL is invalid"}`);
286
+ }
287
+ const headersRecord = record.headers === undefined ? {} : object(record.headers, "mcp.headers");
288
+ const headers = Object.create(null);
289
+ const headerNames = new Set();
290
+ const declared = new Set(variables.map(({ key }) => key));
291
+ const referenced = new Set();
292
+ for (const [key, raw] of Object.entries(headersRecord)) {
293
+ if (!HEADER_NAME.test(key))
294
+ throw new Error(`${label}: invalid MCP header name ${key}`);
295
+ const normalizedKey = key.toLowerCase();
296
+ if (RESERVED_REMOTE_HEADERS.has(normalizedKey))
297
+ throw new Error(`${label}: MCP header ${key} is managed by Happy`);
298
+ if (headerNames.has(normalizedKey))
299
+ throw new Error(`${label}: duplicate MCP header name ${key}`);
300
+ headerNames.add(normalizedKey);
301
+ const template = string(raw, `mcp.headers.${key}`, 8_192, false);
302
+ if (/\r|\n/.test(template))
303
+ throw new Error(`${label}: MCP header values may not contain newlines`);
304
+ for (const match of template.matchAll(/\$\{([^}]+)\}/g))
305
+ if (!declared.has(match[1]))
306
+ throw new Error(`${label}: MCP header ${key} references undeclared variable ${match[1]}`);
307
+ else
308
+ referenced.add(match[1]);
309
+ headers[key] = template;
310
+ }
311
+ const unused = variables.find(({ key }) => !referenced.has(key));
312
+ if (unused)
313
+ throw new Error(`${label}: remote MCP variable ${unused.key} is not used by a header template`);
314
+ return { type: "remote", url: normalizedUrl, headers };
315
+ }
316
+ throw new Error(`${label}: mcp.type must be stdio or remote`);
317
+ }
318
+ async function skillsParse(files, label) {
319
+ const skillFiles = [...files.keys()].filter((name) => /^skills\/[^/]+\/SKILL\.md$/.test(name));
320
+ const unexpected = [...files.keys()].find((name) => name.startsWith("skills/") && name.split("/").length < 3);
321
+ if (unexpected)
322
+ throw new Error(`${label}: skill files must live below skills/<name>/`);
323
+ const skillDirectories = new Set([...files.keys()]
324
+ .filter((name) => name.startsWith("skills/"))
325
+ .map((name) => name.split("/")[1])
326
+ .filter(Boolean));
327
+ for (const directory of skillDirectories)
328
+ if (!skillFiles.includes(`skills/${directory}/SKILL.md`))
329
+ throw new Error(`${label}: skills/${directory}/SKILL.md is required`);
330
+ return skillFiles.sort().map((path) => {
331
+ const directory = path.split("/")[1];
332
+ if (!SKILL_NAME.test(directory))
333
+ throw new Error(`${label}: invalid skill directory ${directory}`);
334
+ const source = files.get(path).toString("utf8");
335
+ const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
336
+ if (!match)
337
+ throw new Error(`${label}: ${path} requires YAML frontmatter`);
338
+ const document = parseDocument(match[1], { uniqueKeys: true });
339
+ if (document.errors.length)
340
+ throw new Error(`${label}: ${path} has invalid YAML frontmatter`);
341
+ const frontmatter = object(document.toJSON(), `${path} frontmatter`);
342
+ const name = string(frontmatter.name, `${path} name`, 64);
343
+ const description = string(frontmatter.description, `${path} description`, 1_024);
344
+ if (name !== directory)
345
+ throw new Error(`${label}: ${path} name must match its parent directory`);
346
+ if (!SKILL_NAME.test(name))
347
+ throw new Error(`${label}: ${path} has an invalid skill name`);
348
+ return { name, description, directory: `skills/${directory}` };
349
+ });
350
+ }
351
+ function requirePackageFile(files, path, label) {
352
+ if (!files.has(path))
353
+ throw new Error(`${label}: referenced package file ${path} does not exist`);
354
+ }
355
+ function relativePath(value, name) {
356
+ const path = string(value, name, 1_000);
357
+ const normalized = path.replaceAll("\\", "/");
358
+ if (normalized.startsWith("/") ||
359
+ normalized.split("/").some((part) => !part || part === "." || part === "..") ||
360
+ resolve("/plugin", normalized).split(sep).join("/").startsWith("/plugin/") === false)
361
+ throw new Error(`${name} must be a safe package-relative path`);
362
+ return normalized;
363
+ }
364
+ function digest(files) {
365
+ const hash = createHash("sha256");
366
+ for (const [name, contents] of [...files.entries()].sort(([a], [b]) => a.localeCompare(b))) {
367
+ hash.update(name, "utf8");
368
+ hash.update("\0");
369
+ hash.update(String(contents.byteLength), "utf8");
370
+ hash.update("\0");
371
+ hash.update(contents);
372
+ }
373
+ return `sha256:${hash.digest("hex")}`;
374
+ }
375
+ function object(value, name) {
376
+ if (!value || typeof value !== "object" || Array.isArray(value))
377
+ throw new Error(`${name} must be an object`);
378
+ return value;
379
+ }
380
+ function only(value, allowed) {
381
+ const unexpected = Object.keys(value).find((key) => !allowed.includes(key));
382
+ if (unexpected)
383
+ throw new Error(`Unexpected field ${unexpected}`);
384
+ }
385
+ function string(value, name, maximum, trim = true) {
386
+ if (typeof value !== "string")
387
+ throw new Error(`${name} must be a string`);
388
+ const normalized = trim ? value.trim() : value;
389
+ if (!normalized || normalized.length > maximum || normalized.includes("\u0000"))
390
+ throw new Error(`${name} must contain between 1 and ${maximum} characters`);
391
+ return normalized;
392
+ }
393
+ function stringArray(value, name, maximumItems, maximumLength) {
394
+ if (value === undefined)
395
+ return [];
396
+ if (!Array.isArray(value) || value.length > maximumItems)
397
+ throw new Error(`${name} must be an array with at most ${maximumItems} entries`);
398
+ return value.map((item, index) => string(item, `${name}[${index}]`, maximumLength, false));
399
+ }
400
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../sources/modules/plugin/catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=catalog.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.test.d.ts","sourceRoot":"","sources":["../../../sources/modules/plugin/catalog.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,172 @@
1
+ import { mkdtemp, mkdir, readFile, realpath, rm, symlink, writeFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { basename, join } from "node:path";
4
+ import { afterEach, describe, expect, it } from "vitest";
5
+ import { pluginCatalogLoad, pluginPackageLoad } from "./catalog.js";
6
+ import { PluginPackageStore } from "./packageStore.js";
7
+ const SQUARE_PNG = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=", "base64");
8
+ const directories = [];
9
+ afterEach(async () => {
10
+ await Promise.all(directories.splice(0).map((directory) => rm(directory, { force: true, recursive: true })));
11
+ });
12
+ describe("plugin package catalog", () => {
13
+ it("loads a spec-shaped skill and verifies an immutable installed snapshot", async () => {
14
+ const root = await temporaryDirectory();
15
+ const plugin = await packageDirectory(root, "search-tools");
16
+ await mkdir(join(plugin, "skills", "project-search", "references"), { recursive: true });
17
+ await writeFile(join(plugin, "skills", "project-search", "SKILL.md"), "---\nname: project-search\ndescription: Search the current project and its documentation.\n---\n\nSearch carefully.\n");
18
+ await writeFile(join(plugin, "skills", "project-search", "references", "syntax.md"), "# Syntax\n");
19
+ await manifest(plugin, { variables: [], version: "1.0.0+unit.1" });
20
+ const catalog = await pluginCatalogLoad(root);
21
+ const loaded = catalog.get("search-tools");
22
+ expect(loaded.skills).toEqual([
23
+ {
24
+ name: "project-search",
25
+ description: "Search the current project and its documentation.",
26
+ directory: "skills/project-search",
27
+ },
28
+ ]);
29
+ expect(loaded.packageDigest).toMatch(/^sha256:[a-f0-9]{64}$/);
30
+ expect(loaded.image).toMatchObject({
31
+ contentType: "image/png",
32
+ width: 1,
33
+ height: 1,
34
+ size: SQUARE_PNG.byteLength,
35
+ thumbhash: expect.any(String),
36
+ checksumSha256: expect.stringMatching(/^[a-f0-9]{64}$/),
37
+ });
38
+ const installedRoot = await temporaryDirectory();
39
+ const store = new PluginPackageStore(installedRoot);
40
+ const installed = await store.install(loaded, "cmockplugin");
41
+ const snapshot = installed.packageDirectory;
42
+ expect(snapshot).toBe(join(await realpath(installedRoot), "cmockplugin"));
43
+ expect(installed.imageStorageKey).toBe("cmockplugin/plugin.png");
44
+ const copied = await pluginPackageLoad(snapshot, "search-tools");
45
+ expect(copied.packageDigest).toBe(loaded.packageDigest);
46
+ const copiedManifest = JSON.parse(await readFile(join(snapshot, "plugin.json"), "utf8"));
47
+ expect(copiedManifest.shortName).toBe("search-tools");
48
+ await expect(store.verify("cmockplugin", snapshot, "search-tools", loaded.packageDigest)).resolves.toBeUndefined();
49
+ await expect(store.readImage("cmockplugin", snapshot, installed.imageStorageKey, "search-tools", loaded.packageDigest)).resolves.toEqual(SQUARE_PNG);
50
+ await expect(store.install(loaded, "cmockplugin")).resolves.toEqual(installed);
51
+ await writeFile(join(snapshot, "unexpected.txt"), "tampered");
52
+ await expect(store.install(loaded, "cmockplugin")).rejects.toThrow("no longer matches its recorded digest");
53
+ await expect(store.verify("cmockplugin", snapshot, "search-tools", loaded.packageDigest)).rejects.toThrow("no longer matches its recorded digest");
54
+ await rm(snapshot, { force: true, recursive: true });
55
+ await symlink(loaded.directory, snapshot);
56
+ await expect(store.verify("cmockplugin", snapshot, "search-tools", loaded.packageDigest)).rejects.toThrow("outside the plugin package store");
57
+ });
58
+ it("rejects skill directories without SKILL.md, undeclared header variables, and symlinks", async () => {
59
+ const missingSkillRoot = await temporaryDirectory();
60
+ const missingSkill = await packageDirectory(missingSkillRoot, "missing-skill");
61
+ await mkdir(join(missingSkill, "skills", "orphan", "references"), { recursive: true });
62
+ await writeFile(join(missingSkill, "skills", "orphan", "references", "notes.md"), "x");
63
+ await manifest(missingSkill, { variables: [] });
64
+ await expect(pluginCatalogLoad(missingSkillRoot)).rejects.toThrow("skills/orphan/SKILL.md is required");
65
+ const headerRoot = await temporaryDirectory();
66
+ const header = await packageDirectory(headerRoot, "bad-header");
67
+ await manifest(header, {
68
+ variables: [],
69
+ mcp: {
70
+ type: "remote",
71
+ url: "https://mcp.example.com/mcp",
72
+ headers: { authorization: "Bearer ${UNDECLARED}" },
73
+ },
74
+ });
75
+ await expect(pluginCatalogLoad(headerRoot)).rejects.toThrow("references undeclared variable UNDECLARED");
76
+ const unusedVariableRoot = await temporaryDirectory();
77
+ const unusedVariable = await packageDirectory(unusedVariableRoot, "unused-variable");
78
+ await manifest(unusedVariable, {
79
+ variables: [variable("REMOTE_TOKEN")],
80
+ mcp: {
81
+ type: "remote",
82
+ url: "https://mcp.example.com/mcp",
83
+ headers: { authorization: "Static value" },
84
+ },
85
+ });
86
+ await expect(pluginCatalogLoad(unusedVariableRoot)).rejects.toThrow("remote MCP variable REMOTE_TOKEN is not used");
87
+ const privateRemoteRoot = await temporaryDirectory();
88
+ const privateRemote = await packageDirectory(privateRemoteRoot, "private-remote");
89
+ await manifest(privateRemote, {
90
+ variables: [],
91
+ mcp: { type: "remote", url: "https://localhost/mcp", headers: {} },
92
+ });
93
+ await expect(pluginCatalogLoad(privateRemoteRoot)).rejects.toThrow("hostname is not public");
94
+ const symlinkRoot = await temporaryDirectory();
95
+ const linked = await packageDirectory(symlinkRoot, "linked-package");
96
+ await writeFile(join(symlinkRoot, "outside.txt"), "outside");
97
+ await symlink(join(symlinkRoot, "outside.txt"), join(linked, "linked.txt"));
98
+ await manifest(linked, { variables: [], mcp: stdioMcp() });
99
+ await expect(pluginCatalogLoad(symlinkRoot)).rejects.toThrow("Plugin packages may not contain symlinks");
100
+ const versionRoot = await temporaryDirectory();
101
+ const versioned = await packageDirectory(versionRoot, "bad-version");
102
+ await manifest(versioned, { variables: [], version: "1.0.0-01", mcp: stdioMcp() });
103
+ await expect(pluginCatalogLoad(versionRoot)).rejects.toThrow("version must be a valid SemVer version");
104
+ });
105
+ it("loads container-only commands and rejects unrecognized host capabilities", async () => {
106
+ const root = await temporaryDirectory();
107
+ const command = await packageDirectory(root, "command-runtime");
108
+ await mkdir(join(command, "container"));
109
+ await writeFile(join(command, "container", "Dockerfile"), "FROM scratch\n");
110
+ await manifest(command, {
111
+ variables: [variable("COMMAND_TOKEN")],
112
+ container: {
113
+ dockerfile: "container/Dockerfile",
114
+ command: "/plugin/worker",
115
+ args: ["--serve"],
116
+ permissions: ["plugins:list"],
117
+ },
118
+ });
119
+ await expect(pluginCatalogLoad(root)).resolves.toMatchObject({});
120
+ expect((await pluginCatalogLoad(root)).get("command-runtime")?.manifest.container).toEqual({
121
+ dockerfile: "container/Dockerfile",
122
+ command: "/plugin/worker",
123
+ args: ["--serve"],
124
+ permissions: ["plugins:list"],
125
+ });
126
+ const deniedRoot = await temporaryDirectory();
127
+ const denied = await packageDirectory(deniedRoot, "denied-runtime");
128
+ await manifest(denied, {
129
+ variables: [],
130
+ container: {
131
+ command: "/plugin/worker",
132
+ args: [],
133
+ permissions: ["users:list"],
134
+ },
135
+ });
136
+ await expect(pluginCatalogLoad(deniedRoot)).rejects.toThrow("unknown container permission users:list");
137
+ });
138
+ });
139
+ async function temporaryDirectory() {
140
+ const directory = await mkdtemp(join(tmpdir(), "happy2-plugin-unit-"));
141
+ directories.push(directory);
142
+ return directory;
143
+ }
144
+ async function packageDirectory(root, shortName) {
145
+ const directory = join(root, shortName);
146
+ await mkdir(directory, { recursive: true });
147
+ await writeFile(join(directory, "plugin.png"), SQUARE_PNG);
148
+ return directory;
149
+ }
150
+ async function manifest(directory, additions) {
151
+ const shortName = basename(directory);
152
+ await writeFile(join(directory, "plugin.json"), JSON.stringify({
153
+ schemaVersion: 1,
154
+ version: "1.0.0",
155
+ displayName: shortName,
156
+ shortName,
157
+ description: `Plugin package ${shortName}.`,
158
+ ...additions,
159
+ }));
160
+ }
161
+ function stdioMcp() {
162
+ return { type: "stdio", command: "server", args: [] };
163
+ }
164
+ function variable(key) {
165
+ return {
166
+ key,
167
+ displayName: key,
168
+ description: `Configuration for ${key}.`,
169
+ kind: "secret",
170
+ };
171
+ }
172
+ //# sourceMappingURL=catalog.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.test.js","sourceRoot":"","sources":["../../../sources/modules/plugin/catalog.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=functions.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functions.test.d.ts","sourceRoot":"","sources":["../../../sources/modules/plugin/functions.test.ts"],"names":[],"mappings":""}