happy2 0.0.13 → 0.0.15

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 (300) hide show
  1. package/package.json +1 -1
  2. package/packages/happy2-server/PLUGINS.md +202 -42
  3. package/packages/happy2-server/dist/index.d.ts +1 -0
  4. package/packages/happy2-server/dist/index.d.ts.map +1 -1
  5. package/packages/happy2-server/dist/index.js +1 -0
  6. package/packages/happy2-server/dist/index.js.map +1 -1
  7. package/packages/happy2-server/dist/modules/agent/agentChatGetContext.d.ts.map +1 -1
  8. package/packages/happy2-server/dist/modules/agent/agentChatGetContext.js +1 -1
  9. package/packages/happy2-server/dist/modules/agent/agentChatGetContext.js.map +1 -1
  10. package/packages/happy2-server/dist/modules/agent/agentConversationCreate.d.ts.map +1 -1
  11. package/packages/happy2-server/dist/modules/agent/agentConversationCreate.js +1 -1
  12. package/packages/happy2-server/dist/modules/agent/agentConversationCreate.js.map +1 -1
  13. package/packages/happy2-server/dist/modules/agent/agentCreate.d.ts.map +1 -1
  14. package/packages/happy2-server/dist/modules/agent/agentCreate.js +2 -2
  15. package/packages/happy2-server/dist/modules/agent/agentCreate.js.map +1 -1
  16. package/packages/happy2-server/dist/modules/agent/agentDefaultCreate.d.ts.map +1 -1
  17. package/packages/happy2-server/dist/modules/agent/agentDefaultCreate.js +1 -1
  18. package/packages/happy2-server/dist/modules/agent/agentDefaultCreate.js.map +1 -1
  19. package/packages/happy2-server/dist/modules/agent/agentImageCommitChange.js +1 -1
  20. package/packages/happy2-server/dist/modules/agent/agentImageCommitChange.js.map +1 -1
  21. package/packages/happy2-server/dist/modules/agent/agentImageCreate.d.ts +4 -3
  22. package/packages/happy2-server/dist/modules/agent/agentImageCreate.d.ts.map +1 -1
  23. package/packages/happy2-server/dist/modules/agent/agentImageCreate.js +73 -23
  24. package/packages/happy2-server/dist/modules/agent/agentImageCreate.js.map +1 -1
  25. package/packages/happy2-server/dist/modules/agent/agentImageDeactivate.d.ts +15 -0
  26. package/packages/happy2-server/dist/modules/agent/agentImageDeactivate.d.ts.map +1 -0
  27. package/packages/happy2-server/dist/modules/agent/agentImageDeactivate.js +92 -0
  28. package/packages/happy2-server/dist/modules/agent/agentImageDeactivate.js.map +1 -0
  29. package/packages/happy2-server/dist/modules/agent/agentImageDockerfileGetForHost.d.ts +12 -0
  30. package/packages/happy2-server/dist/modules/agent/agentImageDockerfileGetForHost.d.ts.map +1 -0
  31. package/packages/happy2-server/dist/modules/agent/agentImageDockerfileGetForHost.js +28 -0
  32. package/packages/happy2-server/dist/modules/agent/agentImageDockerfileGetForHost.js.map +1 -0
  33. package/packages/happy2-server/dist/modules/agent/agentImageFindDefinition.d.ts.map +1 -1
  34. package/packages/happy2-server/dist/modules/agent/agentImageFindDefinition.js +2 -2
  35. package/packages/happy2-server/dist/modules/agent/agentImageFindDefinition.js.map +1 -1
  36. package/packages/happy2-server/dist/modules/agent/agentImageGet.js +2 -2
  37. package/packages/happy2-server/dist/modules/agent/agentImageGet.js.map +1 -1
  38. package/packages/happy2-server/dist/modules/agent/agentImageGetChangeContext.js +1 -1
  39. package/packages/happy2-server/dist/modules/agent/agentImageGetChangeContext.js.map +1 -1
  40. package/packages/happy2-server/dist/modules/agent/agentImageGetReadyDefault.d.ts.map +1 -1
  41. package/packages/happy2-server/dist/modules/agent/agentImageGetReadyDefault.js +2 -2
  42. package/packages/happy2-server/dist/modules/agent/agentImageGetReadyDefault.js.map +1 -1
  43. package/packages/happy2-server/dist/modules/agent/agentImageList.d.ts.map +1 -1
  44. package/packages/happy2-server/dist/modules/agent/agentImageList.js +2 -1
  45. package/packages/happy2-server/dist/modules/agent/agentImageList.js.map +1 -1
  46. package/packages/happy2-server/dist/modules/agent/agentImageListForHost.d.ts +17 -0
  47. package/packages/happy2-server/dist/modules/agent/agentImageListForHost.d.ts.map +1 -0
  48. package/packages/happy2-server/dist/modules/agent/agentImageListForHost.js +38 -0
  49. package/packages/happy2-server/dist/modules/agent/agentImageListForHost.js.map +1 -0
  50. package/packages/happy2-server/dist/modules/agent/agentImageListRequestedBuildIds.d.ts.map +1 -1
  51. package/packages/happy2-server/dist/modules/agent/agentImageListRequestedBuildIds.js +2 -2
  52. package/packages/happy2-server/dist/modules/agent/agentImageListRequestedBuildIds.js.map +1 -1
  53. package/packages/happy2-server/dist/modules/agent/agentImageRequestBuild.js +3 -3
  54. package/packages/happy2-server/dist/modules/agent/agentImageRequestBuild.js.map +1 -1
  55. package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.d.ts +4 -3
  56. package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.d.ts.map +1 -1
  57. package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.js +10 -6
  58. package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.js.map +1 -1
  59. package/packages/happy2-server/dist/modules/agent/agentImageTakeBuild.js +2 -2
  60. package/packages/happy2-server/dist/modules/agent/agentImageTakeBuild.js.map +1 -1
  61. package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.d.ts +4 -0
  62. package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.d.ts.map +1 -0
  63. package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.js +15 -0
  64. package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.js.map +1 -0
  65. package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.test.d.ts +2 -0
  66. package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.test.d.ts.map +1 -0
  67. package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.test.js +17 -0
  68. package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.test.js.map +1 -0
  69. package/packages/happy2-server/dist/modules/agent/agentTurnGetPluginContext.d.ts +23 -0
  70. package/packages/happy2-server/dist/modules/agent/agentTurnGetPluginContext.d.ts.map +1 -0
  71. package/packages/happy2-server/dist/modules/agent/agentTurnGetPluginContext.js +70 -0
  72. package/packages/happy2-server/dist/modules/agent/agentTurnGetPluginContext.js.map +1 -0
  73. package/packages/happy2-server/dist/modules/agents/service.d.ts +23 -6
  74. package/packages/happy2-server/dist/modules/agents/service.d.ts.map +1 -1
  75. package/packages/happy2-server/dist/modules/agents/service.js +21 -7
  76. package/packages/happy2-server/dist/modules/agents/service.js.map +1 -1
  77. package/packages/happy2-server/dist/modules/auth/tokens.d.ts +15 -0
  78. package/packages/happy2-server/dist/modules/auth/tokens.d.ts.map +1 -1
  79. package/packages/happy2-server/dist/modules/auth/tokens.js +74 -6
  80. package/packages/happy2-server/dist/modules/auth/tokens.js.map +1 -1
  81. package/packages/happy2-server/dist/modules/auth/tokens.test.js +57 -0
  82. package/packages/happy2-server/dist/modules/auth/tokens.test.js.map +1 -1
  83. package/packages/happy2-server/dist/modules/chat/channelCreateWithMembers.d.ts +19 -0
  84. package/packages/happy2-server/dist/modules/chat/channelCreateWithMembers.d.ts.map +1 -0
  85. package/packages/happy2-server/dist/modules/chat/channelCreateWithMembers.js +87 -0
  86. package/packages/happy2-server/dist/modules/chat/channelCreateWithMembers.js.map +1 -0
  87. package/packages/happy2-server/dist/modules/chat/channelMembersUpdate.d.ts +15 -0
  88. package/packages/happy2-server/dist/modules/chat/channelMembersUpdate.d.ts.map +1 -0
  89. package/packages/happy2-server/dist/modules/chat/channelMembersUpdate.js +38 -0
  90. package/packages/happy2-server/dist/modules/chat/channelMembersUpdate.js.map +1 -0
  91. package/packages/happy2-server/dist/modules/chat/chatAppendAudit.d.ts +1 -1
  92. package/packages/happy2-server/dist/modules/chat/chatAppendAudit.d.ts.map +1 -1
  93. package/packages/happy2-server/dist/modules/draft/draftList.d.ts +8 -0
  94. package/packages/happy2-server/dist/modules/draft/draftList.d.ts.map +1 -0
  95. package/packages/happy2-server/dist/modules/draft/draftList.js +27 -0
  96. package/packages/happy2-server/dist/modules/draft/draftList.js.map +1 -0
  97. package/packages/happy2-server/dist/modules/draft/draftUpdate.d.ts +16 -0
  98. package/packages/happy2-server/dist/modules/draft/draftUpdate.d.ts.map +1 -0
  99. package/packages/happy2-server/dist/modules/draft/draftUpdate.js +64 -0
  100. package/packages/happy2-server/dist/modules/draft/draftUpdate.js.map +1 -0
  101. package/packages/happy2-server/dist/modules/draft/types.d.ts +7 -0
  102. package/packages/happy2-server/dist/modules/draft/types.d.ts.map +1 -0
  103. package/packages/happy2-server/dist/modules/draft/types.js +2 -0
  104. package/packages/happy2-server/dist/modules/draft/types.js.map +1 -0
  105. package/packages/happy2-server/dist/modules/plugin/catalog.d.ts.map +1 -1
  106. package/packages/happy2-server/dist/modules/plugin/catalog.js +3 -3
  107. package/packages/happy2-server/dist/modules/plugin/catalog.js.map +1 -1
  108. package/packages/happy2-server/dist/modules/plugin/catalog.test.js +2 -2
  109. package/packages/happy2-server/dist/modules/plugin/catalog.test.js.map +1 -1
  110. package/packages/happy2-server/dist/modules/plugin/environmentManagementServer.test.d.ts +2 -0
  111. package/packages/happy2-server/dist/modules/plugin/environmentManagementServer.test.d.ts.map +1 -0
  112. package/packages/happy2-server/dist/modules/plugin/environmentManagementServer.test.js +183 -0
  113. package/packages/happy2-server/dist/modules/plugin/environmentManagementServer.test.js.map +1 -0
  114. package/packages/happy2-server/dist/modules/plugin/impl/apiPermissions.d.ts +5 -0
  115. package/packages/happy2-server/dist/modules/plugin/impl/apiPermissions.d.ts.map +1 -0
  116. package/packages/happy2-server/dist/modules/plugin/impl/apiPermissions.js +128 -0
  117. package/packages/happy2-server/dist/modules/plugin/impl/apiPermissions.js.map +1 -0
  118. package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.d.ts.map +1 -1
  119. package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.js +10 -1
  120. package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.js.map +1 -1
  121. package/packages/happy2-server/dist/modules/plugin/impl/asManagementRequest.d.ts +3 -0
  122. package/packages/happy2-server/dist/modules/plugin/impl/asManagementRequest.d.ts.map +1 -0
  123. package/packages/happy2-server/dist/modules/plugin/impl/asManagementRequest.js +68 -0
  124. package/packages/happy2-server/dist/modules/plugin/impl/asManagementRequest.js.map +1 -0
  125. package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.d.ts.map +1 -1
  126. package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.js +10 -2
  127. package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.js.map +1 -1
  128. package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.d.ts +19 -0
  129. package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.d.ts.map +1 -1
  130. package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.js +1 -0
  131. package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.js.map +1 -1
  132. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.d.ts.map +1 -1
  133. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.js +4 -2
  134. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.js.map +1 -1
  135. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.js +14 -0
  136. package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.js.map +1 -1
  137. package/packages/happy2-server/dist/modules/plugin/impl/managementRequestSelection.d.ts +345 -0
  138. package/packages/happy2-server/dist/modules/plugin/impl/managementRequestSelection.d.ts.map +1 -0
  139. package/packages/happy2-server/dist/modules/plugin/impl/managementRequestSelection.js +22 -0
  140. package/packages/happy2-server/dist/modules/plugin/impl/managementRequestSelection.js.map +1 -0
  141. package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.d.ts +16 -0
  142. package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.d.ts.map +1 -0
  143. package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.js +73 -0
  144. package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.js.map +1 -0
  145. package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.test.d.ts +2 -0
  146. package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.test.d.ts.map +1 -0
  147. package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.test.js +37 -0
  148. package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.test.js.map +1 -0
  149. package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts +14 -1
  150. package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts.map +1 -1
  151. package/packages/happy2-server/dist/modules/plugin/packageStore.js +112 -1
  152. package/packages/happy2-server/dist/modules/plugin/packageStore.js.map +1 -1
  153. package/packages/happy2-server/dist/modules/plugin/packageStore.test.d.ts +2 -0
  154. package/packages/happy2-server/dist/modules/plugin/packageStore.test.d.ts.map +1 -0
  155. package/packages/happy2-server/dist/modules/plugin/packageStore.test.js +50 -0
  156. package/packages/happy2-server/dist/modules/plugin/packageStore.test.js.map +1 -0
  157. package/packages/happy2-server/dist/modules/plugin/pluginAgentCallContextGet.d.ts +5 -0
  158. package/packages/happy2-server/dist/modules/plugin/pluginAgentCallContextGet.d.ts.map +1 -0
  159. package/packages/happy2-server/dist/modules/plugin/pluginAgentCallContextGet.js +26 -0
  160. package/packages/happy2-server/dist/modules/plugin/pluginAgentCallContextGet.js.map +1 -0
  161. package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.d.ts.map +1 -1
  162. package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.js +7 -3
  163. package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.js.map +1 -1
  164. package/packages/happy2-server/dist/modules/plugin/pluginDeveloperServer.test.d.ts +2 -0
  165. package/packages/happy2-server/dist/modules/plugin/pluginDeveloperServer.test.d.ts.map +1 -0
  166. package/packages/happy2-server/dist/modules/plugin/pluginDeveloperServer.test.js +44 -0
  167. package/packages/happy2-server/dist/modules/plugin/pluginDeveloperServer.test.js.map +1 -0
  168. package/packages/happy2-server/dist/modules/plugin/pluginInstall.d.ts +4 -2
  169. package/packages/happy2-server/dist/modules/plugin/pluginInstall.d.ts.map +1 -1
  170. package/packages/happy2-server/dist/modules/plugin/pluginInstall.js +21 -4
  171. package/packages/happy2-server/dist/modules/plugin/pluginInstall.js.map +1 -1
  172. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetContainerName.d.ts +7 -0
  173. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetContainerName.d.ts.map +1 -0
  174. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetContainerName.js +18 -0
  175. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetContainerName.js.map +1 -0
  176. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRequestUninstallContext.d.ts +13 -0
  177. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRequestUninstallContext.d.ts.map +1 -0
  178. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRequestUninstallContext.js +35 -0
  179. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRequestUninstallContext.js.map +1 -0
  180. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.d.ts.map +1 -1
  181. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.js +8 -2
  182. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.js.map +1 -1
  183. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetUninstallContext.d.ts +6 -0
  184. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetUninstallContext.d.ts.map +1 -0
  185. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetUninstallContext.js +17 -0
  186. package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetUninstallContext.js.map +1 -0
  187. package/packages/happy2-server/dist/modules/plugin/pluginInstallationPermissionsUpdate.d.ts +18 -0
  188. package/packages/happy2-server/dist/modules/plugin/pluginInstallationPermissionsUpdate.d.ts.map +1 -0
  189. package/packages/happy2-server/dist/modules/plugin/pluginInstallationPermissionsUpdate.js +92 -0
  190. package/packages/happy2-server/dist/modules/plugin/pluginInstallationPermissionsUpdate.js.map +1 -0
  191. package/packages/happy2-server/dist/modules/plugin/pluginInstallationUninstall.d.ts +16 -0
  192. package/packages/happy2-server/dist/modules/plugin/pluginInstallationUninstall.d.ts.map +1 -0
  193. package/packages/happy2-server/dist/modules/plugin/pluginInstallationUninstall.js +71 -0
  194. package/packages/happy2-server/dist/modules/plugin/pluginInstallationUninstall.js.map +1 -0
  195. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginInstall.d.ts +21 -0
  196. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginInstall.d.ts.map +1 -0
  197. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginInstall.js +71 -0
  198. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginInstall.js.map +1 -0
  199. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginUninstall.d.ts +12 -0
  200. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginUninstall.d.ts.map +1 -0
  201. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginUninstall.js +56 -0
  202. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginUninstall.js.map +1 -0
  203. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteInstall.d.ts +11 -0
  204. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteInstall.d.ts.map +1 -0
  205. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteInstall.js +44 -0
  206. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteInstall.js.map +1 -0
  207. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteUninstall.d.ts +10 -0
  208. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteUninstall.d.ts.map +1 -0
  209. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteUninstall.js +41 -0
  210. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteUninstall.js.map +1 -0
  211. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateInstall.d.ts +26 -0
  212. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateInstall.d.ts.map +1 -0
  213. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateInstall.js +78 -0
  214. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateInstall.js.map +1 -0
  215. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateUninstall.d.ts +25 -0
  216. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateUninstall.d.ts.map +1 -0
  217. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateUninstall.js +76 -0
  218. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateUninstall.js.map +1 -0
  219. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestDeny.d.ts +11 -0
  220. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestDeny.d.ts.map +1 -0
  221. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestDeny.js +48 -0
  222. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestDeny.js.map +1 -0
  223. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestGetPackage.d.ts +12 -0
  224. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestGetPackage.d.ts.map +1 -0
  225. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestGetPackage.js +42 -0
  226. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestGetPackage.js.map +1 -0
  227. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestList.d.ts +5 -0
  228. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestList.d.ts.map +1 -0
  229. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestList.js +18 -0
  230. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestList.js.map +1 -0
  231. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestListTerminalIds.d.ts +4 -0
  232. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestListTerminalIds.d.ts.map +1 -0
  233. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestListTerminalIds.js +11 -0
  234. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestListTerminalIds.js.map +1 -0
  235. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestRecoverProcessing.d.ts +5 -0
  236. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestRecoverProcessing.d.ts.map +1 -0
  237. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestRecoverProcessing.js +75 -0
  238. package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestRecoverProcessing.js.map +1 -0
  239. package/packages/happy2-server/dist/modules/plugin/pluginSkillPackageListReady.d.ts +12 -0
  240. package/packages/happy2-server/dist/modules/plugin/pluginSkillPackageListReady.d.ts.map +1 -0
  241. package/packages/happy2-server/dist/modules/plugin/pluginSkillPackageListReady.js +33 -0
  242. package/packages/happy2-server/dist/modules/plugin/pluginSkillPackageListReady.js.map +1 -0
  243. package/packages/happy2-server/dist/modules/plugin/service.d.ts +108 -7
  244. package/packages/happy2-server/dist/modules/plugin/service.d.ts.map +1 -1
  245. package/packages/happy2-server/dist/modules/plugin/service.js +463 -26
  246. package/packages/happy2-server/dist/modules/plugin/service.js.map +1 -1
  247. package/packages/happy2-server/dist/modules/plugin/types.d.ts +75 -9
  248. package/packages/happy2-server/dist/modules/plugin/types.d.ts.map +1 -1
  249. package/packages/happy2-server/dist/modules/plugin/types.js +12 -0
  250. package/packages/happy2-server/dist/modules/plugin/types.js.map +1 -1
  251. package/packages/happy2-server/dist/modules/schema.d.ts +4526 -3290
  252. package/packages/happy2-server/dist/modules/schema.d.ts.map +1 -1
  253. package/packages/happy2-server/dist/modules/schema.js +49 -0
  254. package/packages/happy2-server/dist/modules/schema.js.map +1 -1
  255. package/packages/happy2-server/dist/modules/sync/syncGetDifference.d.ts.map +1 -1
  256. package/packages/happy2-server/dist/modules/sync/syncGetDifference.js +2 -0
  257. package/packages/happy2-server/dist/modules/sync/syncGetDifference.js.map +1 -1
  258. package/packages/happy2-server/dist/routes/collaboration.d.ts.map +1 -1
  259. package/packages/happy2-server/dist/routes/collaboration.js +38 -1
  260. package/packages/happy2-server/dist/routes/collaboration.js.map +1 -1
  261. package/packages/happy2-server/dist/routes/pluginHost.d.ts +4 -1
  262. package/packages/happy2-server/dist/routes/pluginHost.d.ts.map +1 -1
  263. package/packages/happy2-server/dist/routes/pluginHost.js +401 -6
  264. package/packages/happy2-server/dist/routes/pluginHost.js.map +1 -1
  265. package/packages/happy2-server/dist/routes/plugins.d.ts.map +1 -1
  266. package/packages/happy2-server/dist/routes/plugins.js +229 -3
  267. package/packages/happy2-server/dist/routes/plugins.js.map +1 -1
  268. package/packages/happy2-server/dist/server.d.ts +2 -0
  269. package/packages/happy2-server/dist/server.d.ts.map +1 -1
  270. package/packages/happy2-server/dist/server.js +9 -7
  271. package/packages/happy2-server/dist/server.js.map +1 -1
  272. package/packages/happy2-server/dist/web/assets/index-BT_VezYx.js +39 -0
  273. package/packages/happy2-server/dist/web/assets/{index-BaPUPGPe.css → index-Dys3sWv8.css} +1 -1
  274. package/packages/happy2-server/dist/web/index.html +2 -2
  275. package/packages/happy2-server/drizzle/0028_plugin_api_permissions.sql +1 -0
  276. package/packages/happy2-server/drizzle/0029_plugin_management_requests.sql +35 -0
  277. package/packages/happy2-server/drizzle/0030_personal_synced_drafts.sql +11 -0
  278. package/packages/happy2-server/drizzle/0031_agent_image_deactivation.sql +1 -0
  279. package/packages/happy2-server/drizzle/meta/_journal.json +28 -0
  280. package/packages/happy2-server/plugins/README.md +9 -3
  281. package/packages/happy2-server/plugins/chat-management/plugin.json +3 -3
  282. package/packages/happy2-server/plugins/chat-management/server.mjs +184 -17
  283. package/packages/happy2-server/plugins/environment-management/container/Dockerfile +6 -0
  284. package/packages/happy2-server/plugins/environment-management/plugin.json +17 -0
  285. package/packages/happy2-server/plugins/environment-management/plugin.png +0 -0
  286. package/packages/happy2-server/plugins/environment-management/server.mjs +234 -0
  287. package/packages/happy2-server/plugins/environment-management/skills/happy2-environment-management/SKILL.md +41 -0
  288. package/packages/happy2-server/plugins/plugin-developer/container/Dockerfile +6 -0
  289. package/packages/happy2-server/plugins/plugin-developer/plugin.json +17 -0
  290. package/packages/happy2-server/plugins/plugin-developer/plugin.png +0 -0
  291. package/packages/happy2-server/plugins/plugin-developer/server.mjs +155 -0
  292. package/packages/happy2-server/plugins/plugin-developer/skills/happy2-plugin-development/SKILL.md +59 -0
  293. package/packages/happy2-server/plugins/plugin-developer/skills/happy2-plugin-development/references/host-api.md +88 -0
  294. package/packages/happy2-server/plugins/plugin-developer/skills/happy2-plugin-development/references/installing.md +86 -0
  295. package/packages/happy2-server/plugins/plugin-developer/skills/happy2-plugin-development/references/package-format.md +140 -0
  296. package/packages/happy2-server/dist/modules/agent/agentChatGetIdBySession.d.ts +0 -7
  297. package/packages/happy2-server/dist/modules/agent/agentChatGetIdBySession.d.ts.map +0 -1
  298. package/packages/happy2-server/dist/modules/agent/agentChatGetIdBySession.js +0 -15
  299. package/packages/happy2-server/dist/modules/agent/agentChatGetIdBySession.js.map +0 -1
  300. package/packages/happy2-server/dist/web/assets/index-BnhFxR3U.js +0 -39
@@ -5,25 +5,46 @@ import { join } from "node:path";
5
5
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
6
6
  import { realtimeTopics } from "../realtime/index.js";
7
7
  import { chatUpdateMetadata } from "../chat/chatUpdateMetadata.js";
8
+ import { channelCreateWithMembers } from "../chat/channelCreateWithMembers.js";
9
+ import { channelMembersUpdate } from "../chat/channelMembersUpdate.js";
10
+ import { messageSend } from "../message/messageSend.js";
8
11
  import { pluginInstall } from "./pluginInstall.js";
9
12
  import { pluginFindBySource } from "./pluginFindBySource.js";
10
13
  import { pluginGetSource } from "./pluginGetSource.js";
11
14
  import { pluginGetImage } from "./pluginGetImage.js";
12
15
  import { pluginAuthorizeManagement } from "./pluginAuthorizeManagement.js";
13
16
  import { pluginInstallationGetRuntimeConfiguration } from "./pluginInstallationGetRuntimeConfiguration.js";
17
+ import { pluginInstallationGetRequestUninstallContext } from "./pluginInstallationGetRequestUninstallContext.js";
18
+ import { pluginInstallationUninstall } from "./pluginInstallationUninstall.js";
14
19
  import { pluginInstallationListIds } from "./pluginInstallationListIds.js";
15
20
  import { pluginInstallationListReadyMcpIds } from "./pluginInstallationListReadyMcpIds.js";
16
21
  import { pluginInstallationUpdateStatus } from "./pluginInstallationUpdateStatus.js";
22
+ import { pluginInstallationPermissionsUpdate } from "./pluginInstallationPermissionsUpdate.js";
23
+ import { pluginInstallationGetContainerName } from "./pluginInstallationGetContainerName.js";
24
+ import { pluginAgentCallContextGet } from "./pluginAgentCallContextGet.js";
17
25
  import { pluginRemoveMissingBuiltins } from "./pluginRemoveMissingBuiltins.js";
18
26
  import { pluginMcpToolsReplace } from "./pluginMcpToolsReplace.js";
19
27
  import { pluginMcpToolsListReady } from "./pluginMcpToolsListReady.js";
20
28
  import { pluginSkillsListReady } from "./pluginSkillsListReady.js";
21
29
  import { pluginSkillsListInstalled } from "./pluginSkillsListInstalled.js";
30
+ import { pluginApiPermissionSections } from "./impl/apiPermissions.js";
31
+ import { effectiveContainer } from "./impl/effectiveContainer.js";
22
32
  import { pluginContainerInstanceAuthorize } from "./pluginContainerInstanceAuthorize.js";
23
33
  import { pluginContainerInstanceInvalidate } from "./pluginContainerInstanceInvalidate.js";
24
34
  import { pluginUninstall } from "./pluginUninstall.js";
25
35
  import { pluginArchiveExtract } from "./archive.js";
26
36
  import { pluginPackageLoadSource } from "./catalog.js";
37
+ import { pluginManagementRequestBeginInstall } from "./pluginManagementRequestBeginInstall.js";
38
+ import { pluginManagementRequestBeginUninstall } from "./pluginManagementRequestBeginUninstall.js";
39
+ import { pluginManagementRequestCompleteInstall } from "./pluginManagementRequestCompleteInstall.js";
40
+ import { pluginManagementRequestCompleteUninstall } from "./pluginManagementRequestCompleteUninstall.js";
41
+ import { pluginManagementRequestCreateInstall } from "./pluginManagementRequestCreateInstall.js";
42
+ import { pluginManagementRequestCreateUninstall } from "./pluginManagementRequestCreateUninstall.js";
43
+ import { pluginManagementRequestDeny } from "./pluginManagementRequestDeny.js";
44
+ import { pluginManagementRequestGetPackage } from "./pluginManagementRequestGetPackage.js";
45
+ import { pluginManagementRequestList } from "./pluginManagementRequestList.js";
46
+ import { pluginManagementRequestListTerminalIds } from "./pluginManagementRequestListTerminalIds.js";
47
+ import { pluginManagementRequestRecoverProcessing } from "./pluginManagementRequestRecoverProcessing.js";
27
48
  import { RemotePluginMcpTransport } from "./utils/remoteMcpTransport.js";
28
49
  import { downloadedPluginSource, remotePluginSource, remotePluginSourceFromInstalled, uploadedPluginSource, } from "./source.js";
29
50
  import { PluginError, MAX_PLUGIN_MCP_TOOLS, } from "./types.js";
@@ -34,12 +55,14 @@ const MAX_RIG_PLUGIN_FUNCTIONS = 128;
34
55
  const MAX_RIG_PLUGIN_SKILLS = 128;
35
56
  const PREPARATION_TTL_MS = 15 * 60_000;
36
57
  const PLUGIN_CHAT_META_KEY = "happy2/chat";
58
+ const PLUGIN_USERS_META_KEY = "happy2/users";
37
59
  /** Coordinates durable plugin installs with asynchronous container preparation, MCP health probes, restart recovery, and local connection creation. */
38
60
  export class PluginService {
39
61
  executor;
40
62
  pubsub;
41
63
  catalog;
42
64
  packages;
65
+ packageLinks;
43
66
  secrets;
44
67
  runtime;
45
68
  tokens;
@@ -52,11 +75,12 @@ export class PluginService {
52
75
  commandHandles = new Map();
53
76
  preparations = new Map();
54
77
  closed = false;
55
- constructor(executor, pubsub, catalog, packages, secrets, runtime, tokens, urlPolicy, remoteTransport, hostApiUrl, archiveDownloader, onError) {
78
+ constructor(executor, pubsub, catalog, packages, packageLinks, secrets, runtime, tokens, urlPolicy, remoteTransport, hostApiUrl, archiveDownloader, onError) {
56
79
  this.executor = executor;
57
80
  this.pubsub = pubsub;
58
81
  this.catalog = catalog;
59
82
  this.packages = packages;
83
+ this.packageLinks = packageLinks;
60
84
  this.secrets = secrets;
61
85
  this.runtime = runtime;
62
86
  this.tokens = tokens;
@@ -68,6 +92,10 @@ export class PluginService {
68
92
  }
69
93
  async start() {
70
94
  await this.packages.cleanupTemporary();
95
+ for (const hint of await pluginManagementRequestRecoverProcessing(this.executor))
96
+ await this.publish(hint).catch(this.onError);
97
+ for (const requestId of await pluginManagementRequestListTerminalIds(this.executor))
98
+ await this.packages.removeRequest(requestId).catch(this.onError);
71
99
  const removed = await pluginRemoveMissingBuiltins(this.executor, this.catalog.list().map(({ source }) => source.reference));
72
100
  await Promise.all([
73
101
  ...removed.plugins.map(({ pluginId }) => this.packages.remove(pluginId).catch(this.onError)),
@@ -79,24 +107,70 @@ export class PluginService {
79
107
  this.activate(installationId);
80
108
  }
81
109
  async install(input) {
82
- await pluginAuthorizeManagement(this.executor, input.actorUserId);
110
+ if (input.actorUserId)
111
+ await pluginAuthorizeManagement(this.executor, input.actorUserId);
112
+ else if (!input.actorInstallationId)
113
+ throw new PluginError("forbidden", "Plugin installation authority is required");
83
114
  const plugin = this.catalog.get(input.shortName);
84
115
  if (!plugin)
85
116
  throw new PluginError("not_found", "Built-in plugin was not found");
86
- const installationId = createId();
87
- const existing = await pluginFindBySource(this.executor, plugin.source.kind, plugin.source.reference);
117
+ return this.installPackage({ ...input, plugin });
118
+ }
119
+ async installArchive(input) {
120
+ await pluginAuthorizeManagement(this.executor, input.actorUserId);
121
+ const prepared = await this.prepareRequestedArchive(input.archive, {
122
+ kind: "archive",
123
+ reference: "pending",
124
+ });
125
+ try {
126
+ return await this.installPackage({
127
+ ...input,
128
+ permissions: [],
129
+ plugin: prepared.plugin,
130
+ });
131
+ }
132
+ finally {
133
+ await prepared.cleanup();
134
+ }
135
+ }
136
+ async installLink(input) {
137
+ await pluginAuthorizeManagement(this.executor, input.actorUserId);
138
+ const downloaded = await this.downloadPackage(input.url);
139
+ const prepared = await this.prepareRequestedArchive(downloaded.body, {
140
+ kind: "link",
141
+ reference: downloaded.url,
142
+ });
143
+ try {
144
+ return await this.installPackage({
145
+ ...input,
146
+ permissions: [],
147
+ plugin: prepared.plugin,
148
+ });
149
+ }
150
+ finally {
151
+ await prepared.cleanup();
152
+ }
153
+ }
154
+ async installPackage(input) {
155
+ const installationId = input.installationId ?? createId();
156
+ const existing = await pluginFindBySource(this.executor, input.plugin.source.kind, input.plugin.source.reference);
88
157
  const candidateId = existing ? undefined : createId();
89
158
  const candidate = candidateId
90
- ? { pluginId: candidateId, ...(await this.packages.install(plugin, candidateId)) }
159
+ ? {
160
+ pluginId: candidateId,
161
+ ...(await this.packages.install(input.plugin, candidateId)),
162
+ }
91
163
  : undefined;
92
164
  let result;
93
165
  try {
94
166
  result = await pluginInstall(this.executor, this.secrets, {
95
167
  actorUserId: input.actorUserId,
168
+ actorInstallationId: input.actorInstallationId,
96
169
  installationId,
97
- plugin,
170
+ plugin: input.plugin,
98
171
  candidate,
99
172
  variables: input.variables,
173
+ permissions: input.permissions,
100
174
  containerImageId: input.containerImageId,
101
175
  });
102
176
  }
@@ -154,6 +228,7 @@ export class PluginService {
154
228
  plugin: prepared.plugin,
155
229
  candidate,
156
230
  variables: input.variables,
231
+ permissions: input.permissions,
157
232
  containerImageId: input.containerImageId,
158
233
  });
159
234
  }
@@ -242,6 +317,58 @@ export class PluginService {
242
317
  },
243
318
  };
244
319
  }
320
+ async updatePermissions(input) {
321
+ const result = await pluginInstallationPermissionsUpdate(this.executor, input);
322
+ if (!result.changed)
323
+ return result.installation;
324
+ if (result.hint)
325
+ await this.publish(result.hint).catch(this.onError);
326
+ await this.stopActivation(input.installationId);
327
+ if (result.containerName)
328
+ await this.runtime.removeLocal(result.containerName).catch(this.onError);
329
+ this.activate(input.installationId);
330
+ return result.installation;
331
+ }
332
+ async uninstallInstallation(input) {
333
+ if (input.actorUserId)
334
+ await pluginAuthorizeManagement(this.executor, input.actorUserId);
335
+ else if (!input.actorInstallationId)
336
+ throw new PluginError("forbidden", "Plugin installation authority is required");
337
+ const containerName = await pluginInstallationGetContainerName(this.executor, input.installationId);
338
+ await this.stopActivation(input.installationId);
339
+ try {
340
+ if (containerName)
341
+ await this.runtime.removeLocal(containerName);
342
+ const result = await pluginInstallationUninstall(this.executor, input);
343
+ if (result.pluginRemoved)
344
+ await this.packages.remove(result.pluginId);
345
+ await this.publish(result.hint).catch(this.onError);
346
+ }
347
+ catch (error) {
348
+ this.activate(input.installationId);
349
+ throw error;
350
+ }
351
+ }
352
+ async downloadPackage(url) {
353
+ try {
354
+ return await this.packageLinks.download(url);
355
+ }
356
+ catch (error) {
357
+ if (error instanceof PluginError)
358
+ throw error;
359
+ throw new PluginError("broken_configuration", errorMessage(error));
360
+ }
361
+ }
362
+ async prepareRequestedArchive(archive, source) {
363
+ try {
364
+ return await this.packages.prepareArchive(archive, source);
365
+ }
366
+ catch (error) {
367
+ if (error instanceof PluginError)
368
+ throw error;
369
+ throw new PluginError("broken_configuration", errorMessage(error));
370
+ }
371
+ }
245
372
  async image(actorUserId, pluginId) {
246
373
  const image = await pluginGetImage(this.executor, actorUserId, pluginId);
247
374
  const body = await this.packages.readImage(image.pluginId, image.packageDirectory, image.storageKey, image.shortName, image.packageDigest);
@@ -254,6 +381,165 @@ export class PluginService {
254
381
  checksumSha256: image.checksumSha256,
255
382
  };
256
383
  }
384
+ async requestInstallLink(input) {
385
+ const downloaded = await this.downloadPackage(input.url);
386
+ const prepared = await this.prepareRequestedArchive(downloaded.body, {
387
+ kind: "link",
388
+ reference: downloaded.url,
389
+ });
390
+ const requestId = createId();
391
+ try {
392
+ if (prepared.plugin.manifest.variables.length)
393
+ throw new PluginError("broken_configuration", "Plugins that require configuration must be installed directly by an administrator");
394
+ const container = effectiveContainer(prepared.plugin.manifest);
395
+ if (container && !container.dockerfile)
396
+ throw new PluginError("broken_configuration", "Plugins that require an administrator-selected image cannot be requested from chat");
397
+ const packageDirectory = await this.packages.stageRequest(prepared.plugin, requestId);
398
+ try {
399
+ const result = await pluginManagementRequestCreateInstall(this.executor, {
400
+ id: requestId,
401
+ actorUserId: input.agentCall.actorUserId,
402
+ agentUserId: input.agentCall.agentUserId,
403
+ callId: input.agentCall.callId,
404
+ chatId: input.agentCall.chatId,
405
+ requesterInstallationId: input.requesterInstallationId,
406
+ displayName: prepared.plugin.manifest.displayName,
407
+ shortName: prepared.plugin.manifest.shortName,
408
+ description: prepared.plugin.manifest.description,
409
+ reason: input.reason,
410
+ sourceKind: "link",
411
+ sourceReference: downloaded.url,
412
+ packageDigest: prepared.plugin.packageDigest,
413
+ packageDirectory,
414
+ installationId: createId(),
415
+ });
416
+ if (!result.created)
417
+ await this.packages.removeRequest(requestId);
418
+ if (result.hint)
419
+ await this.publish(result.hint).catch(this.onError);
420
+ return result.request;
421
+ }
422
+ catch (error) {
423
+ await this.packages.removeRequest(requestId);
424
+ throw error;
425
+ }
426
+ }
427
+ finally {
428
+ await prepared.cleanup();
429
+ }
430
+ }
431
+ async requestUninstall(input) {
432
+ const target = await pluginInstallationGetRequestUninstallContext(this.executor, input.targetInstallationId);
433
+ const plugin = await this.packages.loadInstalled(target.pluginId, target.packageDirectory, target.shortName, target.packageDigest, target.source);
434
+ const requestId = createId();
435
+ const packageDirectory = await this.packages.stageRequest(plugin, requestId);
436
+ try {
437
+ const result = await pluginManagementRequestCreateUninstall(this.executor, {
438
+ id: requestId,
439
+ actorUserId: input.agentCall.actorUserId,
440
+ agentUserId: input.agentCall.agentUserId,
441
+ callId: input.agentCall.callId,
442
+ chatId: input.agentCall.chatId,
443
+ requesterInstallationId: input.requesterInstallationId,
444
+ targetInstallationId: input.targetInstallationId,
445
+ displayName: target.displayName,
446
+ shortName: target.shortName,
447
+ description: target.description,
448
+ reason: input.reason,
449
+ source: target.source,
450
+ packageDigest: target.packageDigest,
451
+ packageDirectory,
452
+ });
453
+ if (!result.created)
454
+ await this.packages.removeRequest(requestId);
455
+ if (result.hint)
456
+ await this.publish(result.hint).catch(this.onError);
457
+ return result.request;
458
+ }
459
+ catch (error) {
460
+ await this.packages.removeRequest(requestId);
461
+ throw error;
462
+ }
463
+ }
464
+ listManagementRequests(actorUserId, chatId) {
465
+ return pluginManagementRequestList(this.executor, actorUserId, chatId);
466
+ }
467
+ async managementRequestImage(input) {
468
+ const request = await pluginManagementRequestGetPackage(this.executor, input.actorUserId, input.chatId, input.requestId);
469
+ return this.packages.readRequestImage(request.id, request.packageDirectory, request.source, request.packageDigest);
470
+ }
471
+ async approveManagementRequest(input) {
472
+ const work = await pluginManagementRequestBeginInstall(this.executor, input);
473
+ await this.publish(work.hint).catch(this.onError);
474
+ try {
475
+ const plugin = await this.packages.loadRequest(work.id, work.packageDirectory, work.source, work.packageDigest);
476
+ await this.installPackage({
477
+ actorUserId: input.actorUserId,
478
+ installationId: work.installationId,
479
+ plugin,
480
+ variables: {},
481
+ permissions: [],
482
+ });
483
+ }
484
+ catch (error) {
485
+ const hint = await pluginManagementRequestCompleteInstall(this.executor, {
486
+ ...input,
487
+ installationId: work.installationId,
488
+ error: errorMessage(error),
489
+ });
490
+ await this.publish(hint).catch(this.onError);
491
+ await this.packages.removeRequest(input.requestId).catch(this.onError);
492
+ throw error;
493
+ }
494
+ const hint = await pluginManagementRequestCompleteInstall(this.executor, {
495
+ ...input,
496
+ installationId: work.installationId,
497
+ });
498
+ await this.publish(hint).catch(this.onError);
499
+ await this.packages.removeRequest(input.requestId).catch(this.onError);
500
+ const requests = await pluginManagementRequestList(this.executor, input.actorUserId, input.chatId);
501
+ const request = requests.find(({ id }) => id === input.requestId);
502
+ if (!request)
503
+ throw new Error("Completed plugin management request was not found");
504
+ return request;
505
+ }
506
+ async denyManagementRequest(input) {
507
+ const hint = await pluginManagementRequestDeny(this.executor, input);
508
+ await this.publish(hint).catch(this.onError);
509
+ await this.packages.removeRequest(input.requestId).catch(this.onError);
510
+ const requests = await pluginManagementRequestList(this.executor, input.actorUserId, input.chatId);
511
+ const request = requests.find(({ id }) => id === input.requestId);
512
+ if (!request)
513
+ throw new Error("Denied plugin management request was not found");
514
+ return request;
515
+ }
516
+ async approveUninstallManagementRequest(input) {
517
+ const work = await pluginManagementRequestBeginUninstall(this.executor, input);
518
+ await this.publish(work.hint).catch(this.onError);
519
+ try {
520
+ await this.uninstallInstallation({
521
+ actorUserId: input.actorUserId,
522
+ installationId: work.targetInstallationId,
523
+ });
524
+ }
525
+ catch (error) {
526
+ const hint = await pluginManagementRequestCompleteUninstall(this.executor, {
527
+ ...input,
528
+ error: errorMessage(error),
529
+ });
530
+ await this.publish(hint).catch(this.onError);
531
+ await this.packages.removeRequest(input.requestId).catch(this.onError);
532
+ throw error;
533
+ }
534
+ const hint = await pluginManagementRequestCompleteUninstall(this.executor, input);
535
+ await this.publish(hint).catch(this.onError);
536
+ await this.packages.removeRequest(input.requestId).catch(this.onError);
537
+ const requests = await pluginManagementRequestList(this.executor, input.actorUserId, input.chatId);
538
+ const request = requests.find(({ id }) => id === input.requestId);
539
+ if (!request)
540
+ throw new Error("Completed plugin uninstall request was not found");
541
+ return request;
542
+ }
257
543
  async openLocal(installationId) {
258
544
  const configuration = await pluginInstallationGetRuntimeConfiguration(this.executor, this.secrets, installationId);
259
545
  if (configuration.type !== "local" || !configuration.mcp)
@@ -315,7 +601,8 @@ export class PluginService {
315
601
  }
316
602
  async callFunction(functionName, args, context, signal) {
317
603
  try {
318
- return await withOperationTimeout(FUNCTION_EXECUTION_TIMEOUT_MS, "Plugin MCP function execution", signal, (operationSignal) => this.callFunctionWithSignal(functionName, args, context, operationSignal));
604
+ const agentCall = await pluginAgentCallContextGet(this.executor, context.sessionId, context.callId);
605
+ return await withOperationTimeout(FUNCTION_EXECUTION_TIMEOUT_MS, "Plugin MCP function execution", signal, (operationSignal) => this.callFunctionWithSignal(functionName, args, context, agentCall, operationSignal));
319
606
  }
320
607
  catch (error) {
321
608
  if (signal?.aborted)
@@ -329,7 +616,7 @@ export class PluginService {
329
616
  };
330
617
  }
331
618
  }
332
- async callFunctionWithSignal(functionName, args, context, signal) {
619
+ async callFunctionWithSignal(functionName, args, context, agentCall, signal) {
333
620
  const installationId = pluginFunctionInstallationId(functionName);
334
621
  if (!installationId)
335
622
  throw new Error(`Unknown plugin function ${JSON.stringify(functionName)}`);
@@ -347,8 +634,17 @@ export class PluginService {
347
634
  const chatToken = await this.tokens.issuePluginChatToken({
348
635
  installationId,
349
636
  chatId: context.chatId,
637
+ actorUserId: context.triggeredByUserId,
638
+ agentUserId: context.agentUserId,
350
639
  });
351
- const result = await this.withClient(installationId, signal, async (client) => {
640
+ const referencedUsers = await Promise.all(context.users.map(async (user) => ({
641
+ ...user,
642
+ token: await this.tokens.issuePluginUserToken({
643
+ installationId,
644
+ userId: user.id,
645
+ }),
646
+ })));
647
+ const result = await this.withClient(installationId, signal, agentCall, async (client) => {
352
648
  const result = await client.callTool({
353
649
  name: cached.name,
354
650
  arguments: jsonArguments(args),
@@ -356,7 +652,9 @@ export class PluginService {
356
652
  [PLUGIN_CHAT_META_KEY]: {
357
653
  id: context.chatId,
358
654
  token: chatToken,
655
+ triggeredByUserId: context.triggeredByUserId,
359
656
  },
657
+ [PLUGIN_USERS_META_KEY]: referencedUsers,
360
658
  },
361
659
  });
362
660
  if (result.isError)
@@ -393,6 +691,14 @@ export class PluginService {
393
691
  catch {
394
692
  throw new PluginError("forbidden", "Plugin runtime token is invalid");
395
693
  }
694
+ if (claims.agentCall) {
695
+ const active = await pluginAgentCallContextGet(this.executor, claims.agentCall.sessionId, claims.agentCall.callId).catch(() => undefined);
696
+ if (!active ||
697
+ active.actorUserId !== claims.agentCall.actorUserId ||
698
+ active.agentUserId !== claims.agentCall.agentUserId ||
699
+ active.chatId !== claims.agentCall.chatId)
700
+ throw new PluginError("forbidden", "Plugin agent-call capability is no longer active");
701
+ }
396
702
  if (!claims.permissions.includes(permission))
397
703
  throw new PluginError("forbidden", `Plugin runtime lacks ${permission} permission`);
398
704
  const authorized = await pluginContainerInstanceAuthorize(this.executor, claims.installationId, claims.containerInstanceId);
@@ -409,19 +715,10 @@ export class PluginService {
409
715
  await this.publish(hint).catch(this.onError);
410
716
  throw new PluginError("forbidden", "Plugin container incarnation is not running");
411
717
  }
412
- return claims.installationId;
718
+ return claims;
413
719
  }
414
720
  async chatUpdate(runtimeToken, chatToken, input) {
415
- const installationId = await this.authorizeHost(runtimeToken, "chats:update");
416
- let claims;
417
- try {
418
- claims = await this.tokens.verifyPluginChatToken(chatToken);
419
- }
420
- catch {
421
- throw new PluginError("forbidden", "Plugin chat token is invalid");
422
- }
423
- if (claims.installationId !== installationId)
424
- throw new PluginError("forbidden", "Plugin chat token belongs to another installation");
721
+ const claims = await this.authorizeChat(runtimeToken, chatToken, "chats:update");
425
722
  const result = await chatUpdateMetadata(this.executor, {
426
723
  chatId: claims.chatId,
427
724
  ...input,
@@ -437,6 +734,122 @@ export class PluginService {
437
734
  });
438
735
  return { chat: result.chat, sync: result.hint };
439
736
  }
737
+ async channelMembersUpdate(runtimeToken, chatToken, input) {
738
+ const claims = await this.authorizeChat(runtimeToken, chatToken, "channels:manage");
739
+ const [addUserIds, removeUserIds] = await Promise.all([
740
+ this.authorizeUsers(claims.installationId, input.add),
741
+ this.authorizeUsers(claims.installationId, input.remove),
742
+ ]);
743
+ const result = await channelMembersUpdate(this.executor, {
744
+ actorUserId: claims.actorUserId,
745
+ chatId: claims.chatId,
746
+ addUserIds,
747
+ removeUserIds,
748
+ });
749
+ await this.publishHints(result.hints, [...addUserIds, ...removeUserIds]);
750
+ return {
751
+ chatId: claims.chatId,
752
+ addedUserIds: addUserIds,
753
+ removedUserIds: removeUserIds,
754
+ sync: result.hints,
755
+ };
756
+ }
757
+ async channelCreate(runtimeToken, chatToken, input, agents) {
758
+ const claims = await this.authorizeChat(runtimeToken, chatToken, "channels:manage");
759
+ const memberUserIds = await this.authorizeUsers(claims.installationId, input.members);
760
+ const clientMutationId = input.idempotencyKey
761
+ ? `${claims.installationId}:${input.idempotencyKey}`
762
+ : undefined;
763
+ if (input.initialMessage?.audience === "agents" && !agents)
764
+ throw new PluginError("not_ready", "AI agents are not enabled on this server");
765
+ const created = await channelCreateWithMembers(this.executor, {
766
+ actorUserId: claims.actorUserId,
767
+ name: input.name,
768
+ slug: pluginChannelSlug(input.name),
769
+ topic: input.description,
770
+ memberUserIds,
771
+ clientMutationId,
772
+ ...(input.initialMessage?.audience === "agents"
773
+ ? { defaultAgentUserId: claims.agentUserId }
774
+ : {}),
775
+ });
776
+ const hints = [...created.hints];
777
+ let initialMessage;
778
+ if (input.initialMessage) {
779
+ const agentTurns = input.initialMessage.audience === "agents"
780
+ ? await agents.prepareTurns({
781
+ actorUserId: claims.actorUserId,
782
+ agentUserIds: [],
783
+ chatId: created.chat.id,
784
+ })
785
+ : [];
786
+ const sent = await messageSend(this.executor, {
787
+ actorUserId: claims.actorUserId,
788
+ chatId: created.chat.id,
789
+ text: input.initialMessage.text,
790
+ audience: input.initialMessage.audience,
791
+ agentTurns,
792
+ clientMutationId,
793
+ });
794
+ initialMessage = sent.message;
795
+ hints.push(sent.hint);
796
+ if (agentTurns.length)
797
+ agents.startTurn(created.chat.id);
798
+ }
799
+ await this.publishHints(hints, [claims.actorUserId, ...memberUserIds]);
800
+ return {
801
+ chat: created.chat,
802
+ ...(initialMessage ? { initialMessage } : {}),
803
+ sync: hints,
804
+ };
805
+ }
806
+ async authorizeChat(runtimeToken, chatToken, permission) {
807
+ const { installationId } = await this.authorizeHost(runtimeToken, permission);
808
+ let claims;
809
+ try {
810
+ claims = await this.tokens.verifyPluginChatToken(chatToken);
811
+ }
812
+ catch {
813
+ throw new PluginError("forbidden", "Plugin chat token is invalid");
814
+ }
815
+ if (claims.installationId !== installationId)
816
+ throw new PluginError("forbidden", "Plugin chat token belongs to another installation");
817
+ return claims;
818
+ }
819
+ async authorizeUsers(installationId, capabilities) {
820
+ return Promise.all(capabilities.map(async (capability) => {
821
+ let claims;
822
+ try {
823
+ claims = await this.tokens.verifyPluginUserToken(capability.token);
824
+ }
825
+ catch {
826
+ throw new PluginError("forbidden", "Plugin user token is invalid");
827
+ }
828
+ if (claims.installationId !== installationId)
829
+ throw new PluginError("forbidden", "Plugin user token belongs to another installation");
830
+ if (claims.userId !== capability.id)
831
+ throw new PluginError("forbidden", "Plugin user token belongs to another user");
832
+ return claims.userId;
833
+ }));
834
+ }
835
+ async publishHints(hints, userIds) {
836
+ const publications = [];
837
+ for (const hint of hints) {
838
+ const event = { type: "sync", ...hint };
839
+ const topics = new Set([
840
+ realtimeTopics.server,
841
+ ...hint.chats.map(({ chatId }) => realtimeTopics.chat(chatId)),
842
+ ...userIds.map((userId) => realtimeTopics.user(userId)),
843
+ ]);
844
+ for (const topic of topics)
845
+ publications.push(this.pubsub.publish(topic, event));
846
+ }
847
+ await Promise.allSettled(publications).then((results) => {
848
+ for (const result of results)
849
+ if (result.status === "rejected")
850
+ this.onError(result.reason);
851
+ });
852
+ }
440
853
  async close() {
441
854
  this.closed = true;
442
855
  for (const { controller } of this.activations.values())
@@ -522,7 +935,14 @@ export class PluginService {
522
935
  .finally(() => this.activations.delete(installationId));
523
936
  this.activations.set(installationId, { controller, promise });
524
937
  }
525
- async withClient(installationId, signal, action) {
938
+ async stopActivation(installationId) {
939
+ const activation = this.activations.get(installationId);
940
+ activation?.controller.abort();
941
+ if (activation)
942
+ await activation.promise;
943
+ this.closeCommand(installationId);
944
+ }
945
+ async withClient(installationId, signal, agentCall, action) {
526
946
  signal?.throwIfAborted();
527
947
  const configuration = await pluginInstallationGetRuntimeConfiguration(this.executor, this.secrets, installationId);
528
948
  if (configuration.type === "skills_only")
@@ -530,7 +950,7 @@ export class PluginService {
530
950
  if (configuration.type === "local" && !configuration.mcp)
531
951
  return undefined;
532
952
  const localToken = configuration.type === "local"
533
- ? await this.pluginRuntimeToken(configuration)
953
+ ? await this.pluginRuntimeToken(configuration, agentCall)
534
954
  : undefined;
535
955
  const transport = configuration.type === "local"
536
956
  ? await this.runtime.openLocal({
@@ -640,10 +1060,10 @@ export class PluginService {
640
1060
  this.commandHandles.delete(installationId);
641
1061
  commandHandle.close();
642
1062
  }
643
- if (signal.aborted && this.closed)
644
- return;
645
1063
  if (preparedContainerName)
646
1064
  await this.runtime.removeLocal(preparedContainerName).catch(this.onError);
1065
+ if (signal.aborted)
1066
+ return;
647
1067
  const broken = error instanceof PluginError && error.code === "broken_configuration";
648
1068
  await this.status(installationId, broken ? "broken_configuration" : "failed", broken
649
1069
  ? "Plugin configuration must be corrected before it can start."
@@ -721,7 +1141,11 @@ export class PluginService {
721
1141
  await this.publish(hint).catch(this.onError);
722
1142
  }
723
1143
  publish(hint) {
724
- return this.pubsub.publish(realtimeTopics.server, { type: "sync", ...hint });
1144
+ const event = { type: "sync", ...hint };
1145
+ return Promise.all([
1146
+ this.pubsub.publish(realtimeTopics.server, event),
1147
+ ...hint.chats.map(({ chatId }) => this.pubsub.publish(realtimeTopics.chat(chatId), event)),
1148
+ ]).then(() => undefined);
725
1149
  }
726
1150
  closeCommand(installationId) {
727
1151
  const handle = this.commandHandles.get(installationId);
@@ -748,13 +1172,14 @@ export class PluginService {
748
1172
  HAPPY2_PLUGIN_API_TOKEN: token,
749
1173
  };
750
1174
  }
751
- pluginRuntimeToken(configuration) {
1175
+ pluginRuntimeToken(configuration, agentCall) {
752
1176
  if (!configuration.containerInstanceId)
753
1177
  throw new PluginError("not_ready", "Plugin container incarnation is unavailable");
754
1178
  return this.tokens.issuePluginRuntimeToken({
755
1179
  installationId: configuration.installationId,
756
1180
  containerInstanceId: configuration.containerInstanceId,
757
1181
  permissions: configuration.permissions,
1182
+ ...(agentCall ? { agentCall } : {}),
758
1183
  });
759
1184
  }
760
1185
  }
@@ -771,6 +1196,17 @@ function pluginFunctionName(installationId, toolName) {
771
1196
  const digest = createHash("sha256").update(toolName).digest("hex").slice(0, 16);
772
1197
  return `plugin_${installationId}_${normalized || "tool"}_${digest}`;
773
1198
  }
1199
+ function pluginChannelSlug(name) {
1200
+ const suffix = createId();
1201
+ const base = name
1202
+ .normalize("NFKD")
1203
+ .toLowerCase()
1204
+ .replace(/[^a-z0-9]+/g, "-")
1205
+ .replace(/^-+|-+$/g, "")
1206
+ .slice(0, 63 - suffix.length)
1207
+ .replace(/-+$/g, "");
1208
+ return `${base || "channel"}-${suffix}`;
1209
+ }
774
1210
  function pluginFunctionInstallationId(functionName) {
775
1211
  const match = /^plugin_([a-z0-9]+)_/u.exec(functionName);
776
1212
  return match?.[1];
@@ -899,6 +1335,7 @@ function preparedSummary(plugin, preparedToken, expiresAt) {
899
1335
  description: plugin.manifest.description,
900
1336
  skills: plugin.skills.map(({ name, description }) => ({ name, description })),
901
1337
  variables: plugin.manifest.variables,
1338
+ apiPermissions: pluginApiPermissionSections(effectiveContainer(plugin.manifest)?.permissions ?? []),
902
1339
  ...(mcp
903
1340
  ? {
904
1341
  mcp: {