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.
- package/package.json +1 -1
- package/packages/happy2-server/PLUGINS.md +202 -42
- package/packages/happy2-server/dist/index.d.ts +1 -0
- package/packages/happy2-server/dist/index.d.ts.map +1 -1
- package/packages/happy2-server/dist/index.js +1 -0
- package/packages/happy2-server/dist/index.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentChatGetContext.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentChatGetContext.js +1 -1
- package/packages/happy2-server/dist/modules/agent/agentChatGetContext.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentConversationCreate.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentConversationCreate.js +1 -1
- package/packages/happy2-server/dist/modules/agent/agentConversationCreate.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentCreate.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentCreate.js +2 -2
- package/packages/happy2-server/dist/modules/agent/agentCreate.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentDefaultCreate.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentDefaultCreate.js +1 -1
- package/packages/happy2-server/dist/modules/agent/agentDefaultCreate.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageCommitChange.js +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageCommitChange.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageCreate.d.ts +4 -3
- package/packages/happy2-server/dist/modules/agent/agentImageCreate.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageCreate.js +73 -23
- package/packages/happy2-server/dist/modules/agent/agentImageCreate.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageDeactivate.d.ts +15 -0
- package/packages/happy2-server/dist/modules/agent/agentImageDeactivate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentImageDeactivate.js +92 -0
- package/packages/happy2-server/dist/modules/agent/agentImageDeactivate.js.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentImageDockerfileGetForHost.d.ts +12 -0
- package/packages/happy2-server/dist/modules/agent/agentImageDockerfileGetForHost.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentImageDockerfileGetForHost.js +28 -0
- package/packages/happy2-server/dist/modules/agent/agentImageDockerfileGetForHost.js.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentImageFindDefinition.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageFindDefinition.js +2 -2
- package/packages/happy2-server/dist/modules/agent/agentImageFindDefinition.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGet.js +2 -2
- package/packages/happy2-server/dist/modules/agent/agentImageGet.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGetChangeContext.js +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGetChangeContext.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGetReadyDefault.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGetReadyDefault.js +2 -2
- package/packages/happy2-server/dist/modules/agent/agentImageGetReadyDefault.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageList.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageList.js +2 -1
- package/packages/happy2-server/dist/modules/agent/agentImageList.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageListForHost.d.ts +17 -0
- package/packages/happy2-server/dist/modules/agent/agentImageListForHost.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentImageListForHost.js +38 -0
- package/packages/happy2-server/dist/modules/agent/agentImageListForHost.js.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentImageListRequestedBuildIds.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageListRequestedBuildIds.js +2 -2
- package/packages/happy2-server/dist/modules/agent/agentImageListRequestedBuildIds.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageRequestBuild.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentImageRequestBuild.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.d.ts +4 -3
- package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.js +10 -6
- package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageTakeBuild.js +2 -2
- package/packages/happy2-server/dist/modules/agent/agentImageTakeBuild.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.d.ts +4 -0
- package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.js +15 -0
- package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.js.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.test.js +17 -0
- package/packages/happy2-server/dist/modules/agent/agentSkillHomeGet.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnGetPluginContext.d.ts +23 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnGetPluginContext.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnGetPluginContext.js +70 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnGetPluginContext.js.map +1 -0
- package/packages/happy2-server/dist/modules/agents/service.d.ts +23 -6
- package/packages/happy2-server/dist/modules/agents/service.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agents/service.js +21 -7
- package/packages/happy2-server/dist/modules/agents/service.js.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.d.ts +15 -0
- package/packages/happy2-server/dist/modules/auth/tokens.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.js +74 -6
- package/packages/happy2-server/dist/modules/auth/tokens.js.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.test.js +57 -0
- package/packages/happy2-server/dist/modules/auth/tokens.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/chat/channelCreateWithMembers.d.ts +19 -0
- package/packages/happy2-server/dist/modules/chat/channelCreateWithMembers.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/chat/channelCreateWithMembers.js +87 -0
- package/packages/happy2-server/dist/modules/chat/channelCreateWithMembers.js.map +1 -0
- package/packages/happy2-server/dist/modules/chat/channelMembersUpdate.d.ts +15 -0
- package/packages/happy2-server/dist/modules/chat/channelMembersUpdate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/chat/channelMembersUpdate.js +38 -0
- package/packages/happy2-server/dist/modules/chat/channelMembersUpdate.js.map +1 -0
- package/packages/happy2-server/dist/modules/chat/chatAppendAudit.d.ts +1 -1
- package/packages/happy2-server/dist/modules/chat/chatAppendAudit.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/draft/draftList.d.ts +8 -0
- package/packages/happy2-server/dist/modules/draft/draftList.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/draft/draftList.js +27 -0
- package/packages/happy2-server/dist/modules/draft/draftList.js.map +1 -0
- package/packages/happy2-server/dist/modules/draft/draftUpdate.d.ts +16 -0
- package/packages/happy2-server/dist/modules/draft/draftUpdate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/draft/draftUpdate.js +64 -0
- package/packages/happy2-server/dist/modules/draft/draftUpdate.js.map +1 -0
- package/packages/happy2-server/dist/modules/draft/types.d.ts +7 -0
- package/packages/happy2-server/dist/modules/draft/types.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/draft/types.js +2 -0
- package/packages/happy2-server/dist/modules/draft/types.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/catalog.js +3 -3
- package/packages/happy2-server/dist/modules/plugin/catalog.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/catalog.test.js +2 -2
- package/packages/happy2-server/dist/modules/plugin/catalog.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/environmentManagementServer.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/environmentManagementServer.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/environmentManagementServer.test.js +183 -0
- package/packages/happy2-server/dist/modules/plugin/environmentManagementServer.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/apiPermissions.d.ts +5 -0
- package/packages/happy2-server/dist/modules/plugin/impl/apiPermissions.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/apiPermissions.js +128 -0
- package/packages/happy2-server/dist/modules/plugin/impl/apiPermissions.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.js +10 -1
- package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/asManagementRequest.d.ts +3 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asManagementRequest.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asManagementRequest.js +68 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asManagementRequest.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.js +10 -2
- package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.d.ts +19 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.js +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.js +4 -2
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.js +14 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/impl/managementRequestSelection.d.ts +345 -0
- package/packages/happy2-server/dist/modules/plugin/impl/managementRequestSelection.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/managementRequestSelection.js +22 -0
- package/packages/happy2-server/dist/modules/plugin/impl/managementRequestSelection.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.d.ts +16 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.js +73 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.test.js +37 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts +14 -1
- package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/packageStore.js +112 -1
- package/packages/happy2-server/dist/modules/plugin/packageStore.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/packageStore.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.test.js +50 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginAgentCallContextGet.d.ts +5 -0
- package/packages/happy2-server/dist/modules/plugin/pluginAgentCallContextGet.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginAgentCallContextGet.js +26 -0
- package/packages/happy2-server/dist/modules/plugin/pluginAgentCallContextGet.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.js +7 -3
- package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginDeveloperServer.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/pluginDeveloperServer.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginDeveloperServer.test.js +44 -0
- package/packages/happy2-server/dist/modules/plugin/pluginDeveloperServer.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstall.d.ts +4 -2
- package/packages/happy2-server/dist/modules/plugin/pluginInstall.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginInstall.js +21 -4
- package/packages/happy2-server/dist/modules/plugin/pluginInstall.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetContainerName.d.ts +7 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetContainerName.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetContainerName.js +18 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetContainerName.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRequestUninstallContext.d.ts +13 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRequestUninstallContext.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRequestUninstallContext.js +35 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRequestUninstallContext.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.js +8 -2
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetUninstallContext.d.ts +6 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetUninstallContext.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetUninstallContext.js +17 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetUninstallContext.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationPermissionsUpdate.d.ts +18 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationPermissionsUpdate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationPermissionsUpdate.js +92 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationPermissionsUpdate.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationUninstall.d.ts +16 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationUninstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationUninstall.js +71 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationUninstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginInstall.d.ts +21 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginInstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginInstall.js +71 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginInstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginUninstall.d.ts +12 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginUninstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginUninstall.js +56 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestBeginUninstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteInstall.d.ts +11 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteInstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteInstall.js +44 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteInstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteUninstall.d.ts +10 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteUninstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteUninstall.js +41 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCompleteUninstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateInstall.d.ts +26 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateInstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateInstall.js +78 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateInstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateUninstall.d.ts +25 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateUninstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateUninstall.js +76 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestCreateUninstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestDeny.d.ts +11 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestDeny.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestDeny.js +48 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestDeny.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestGetPackage.d.ts +12 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestGetPackage.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestGetPackage.js +42 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestGetPackage.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestList.d.ts +5 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestList.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestList.js +18 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestList.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestListTerminalIds.d.ts +4 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestListTerminalIds.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestListTerminalIds.js +11 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestListTerminalIds.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestRecoverProcessing.d.ts +5 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestRecoverProcessing.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestRecoverProcessing.js +75 -0
- package/packages/happy2-server/dist/modules/plugin/pluginManagementRequestRecoverProcessing.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillPackageListReady.d.ts +12 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillPackageListReady.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillPackageListReady.js +33 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillPackageListReady.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/service.d.ts +108 -7
- package/packages/happy2-server/dist/modules/plugin/service.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/service.js +463 -26
- package/packages/happy2-server/dist/modules/plugin/service.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/types.d.ts +75 -9
- package/packages/happy2-server/dist/modules/plugin/types.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/types.js +12 -0
- package/packages/happy2-server/dist/modules/plugin/types.js.map +1 -1
- package/packages/happy2-server/dist/modules/schema.d.ts +4526 -3290
- package/packages/happy2-server/dist/modules/schema.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/schema.js +49 -0
- package/packages/happy2-server/dist/modules/schema.js.map +1 -1
- package/packages/happy2-server/dist/modules/sync/syncGetDifference.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/sync/syncGetDifference.js +2 -0
- package/packages/happy2-server/dist/modules/sync/syncGetDifference.js.map +1 -1
- package/packages/happy2-server/dist/routes/collaboration.d.ts.map +1 -1
- package/packages/happy2-server/dist/routes/collaboration.js +38 -1
- package/packages/happy2-server/dist/routes/collaboration.js.map +1 -1
- package/packages/happy2-server/dist/routes/pluginHost.d.ts +4 -1
- package/packages/happy2-server/dist/routes/pluginHost.d.ts.map +1 -1
- package/packages/happy2-server/dist/routes/pluginHost.js +401 -6
- package/packages/happy2-server/dist/routes/pluginHost.js.map +1 -1
- package/packages/happy2-server/dist/routes/plugins.d.ts.map +1 -1
- package/packages/happy2-server/dist/routes/plugins.js +229 -3
- package/packages/happy2-server/dist/routes/plugins.js.map +1 -1
- package/packages/happy2-server/dist/server.d.ts +2 -0
- package/packages/happy2-server/dist/server.d.ts.map +1 -1
- package/packages/happy2-server/dist/server.js +9 -7
- package/packages/happy2-server/dist/server.js.map +1 -1
- package/packages/happy2-server/dist/web/assets/index-BT_VezYx.js +39 -0
- package/packages/happy2-server/dist/web/assets/{index-BaPUPGPe.css → index-Dys3sWv8.css} +1 -1
- package/packages/happy2-server/dist/web/index.html +2 -2
- package/packages/happy2-server/drizzle/0028_plugin_api_permissions.sql +1 -0
- package/packages/happy2-server/drizzle/0029_plugin_management_requests.sql +35 -0
- package/packages/happy2-server/drizzle/0030_personal_synced_drafts.sql +11 -0
- package/packages/happy2-server/drizzle/0031_agent_image_deactivation.sql +1 -0
- package/packages/happy2-server/drizzle/meta/_journal.json +28 -0
- package/packages/happy2-server/plugins/README.md +9 -3
- package/packages/happy2-server/plugins/chat-management/plugin.json +3 -3
- package/packages/happy2-server/plugins/chat-management/server.mjs +184 -17
- package/packages/happy2-server/plugins/environment-management/container/Dockerfile +6 -0
- package/packages/happy2-server/plugins/environment-management/plugin.json +17 -0
- package/packages/happy2-server/plugins/environment-management/plugin.png +0 -0
- package/packages/happy2-server/plugins/environment-management/server.mjs +234 -0
- package/packages/happy2-server/plugins/environment-management/skills/happy2-environment-management/SKILL.md +41 -0
- package/packages/happy2-server/plugins/plugin-developer/container/Dockerfile +6 -0
- package/packages/happy2-server/plugins/plugin-developer/plugin.json +17 -0
- package/packages/happy2-server/plugins/plugin-developer/plugin.png +0 -0
- package/packages/happy2-server/plugins/plugin-developer/server.mjs +155 -0
- package/packages/happy2-server/plugins/plugin-developer/skills/happy2-plugin-development/SKILL.md +59 -0
- package/packages/happy2-server/plugins/plugin-developer/skills/happy2-plugin-development/references/host-api.md +88 -0
- package/packages/happy2-server/plugins/plugin-developer/skills/happy2-plugin-development/references/installing.md +86 -0
- package/packages/happy2-server/plugins/plugin-developer/skills/happy2-plugin-development/references/package-format.md +140 -0
- package/packages/happy2-server/dist/modules/agent/agentChatGetIdBySession.d.ts +0 -7
- package/packages/happy2-server/dist/modules/agent/agentChatGetIdBySession.d.ts.map +0 -1
- package/packages/happy2-server/dist/modules/agent/agentChatGetIdBySession.js +0 -15
- package/packages/happy2-server/dist/modules/agent/agentChatGetIdBySession.js.map +0 -1
- 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
|
-
|
|
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
|
-
|
|
87
|
-
|
|
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
|
-
? {
|
|
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
|
-
|
|
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
|
|
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
|
|
718
|
+
return claims;
|
|
413
719
|
}
|
|
414
720
|
async chatUpdate(runtimeToken, chatToken, input) {
|
|
415
|
-
const
|
|
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
|
|
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
|
-
|
|
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: {
|