happy2 0.0.12 → 0.0.14
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 +2 -2
- package/packages/happy2-server/PLUGINS.md +281 -39
- package/packages/happy2-server/README.md +8 -7
- package/packages/happy2-server/dist/index.d.ts +3 -1
- package/packages/happy2-server/dist/index.d.ts.map +1 -1
- package/packages/happy2-server/dist/index.js +2 -0
- package/packages/happy2-server/dist/index.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentChatBind.d.ts +1 -0
- package/packages/happy2-server/dist/modules/agent/agentChatBind.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentChatBind.js +4 -0
- package/packages/happy2-server/dist/modules/agent/agentChatBind.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 +3 -1
- package/packages/happy2-server/dist/modules/agent/agentChatGetContext.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 +1 -0
- package/packages/happy2-server/dist/modules/agent/agentCreate.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentEffortBindingList.d.ts +4 -2
- package/packages/happy2-server/dist/modules/agent/agentEffortBindingList.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentEffortBindingList.js +8 -8
- package/packages/happy2-server/dist/modules/agent/agentEffortBindingList.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentEffortGetContext.d.ts +3 -3
- package/packages/happy2-server/dist/modules/agent/agentEffortGetContext.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentEffortGetContext.js +4 -4
- package/packages/happy2-server/dist/modules/agent/agentEffortGetContext.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentEffortUpdate.d.ts +4 -4
- package/packages/happy2-server/dist/modules/agent/agentEffortUpdate.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentEffortUpdate.js +57 -41
- package/packages/happy2-server/dist/modules/agent/agentEffortUpdate.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageCommitChange.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageCommitChange.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentImageCommitChange.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageCreate.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageCreate.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentImageCreate.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGet.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGet.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentImageGet.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGetChangeContext.d.ts +2 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGetChangeContext.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageGetChangeContext.js +11 -4
- package/packages/happy2-server/dist/modules/agent/agentImageGetChangeContext.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageList.d.ts +2 -2
- package/packages/happy2-server/dist/modules/agent/agentImageList.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageList.js +8 -4
- package/packages/happy2-server/dist/modules/agent/agentImageList.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageRequestBuild.d.ts +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 +1 -1
- package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentImageSetDefault.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAssignmentDelete.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAssignmentDelete.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentSecretAssignmentDelete.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAssignmentList.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAssignmentList.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentSecretAssignmentList.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAttachToAgent.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAttachToAgent.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentSecretAttachToAgent.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAttachToChannel.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAttachToChannel.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentSecretAttachToChannel.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAuthorizeManagement.d.ts +4 -3
- package/packages/happy2-server/dist/modules/agent/agentSecretAuthorizeManagement.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretAuthorizeManagement.js +5 -5
- package/packages/happy2-server/dist/modules/agent/agentSecretAuthorizeManagement.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretDetachFromAgent.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretDetachFromAgent.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentSecretDetachFromAgent.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretDetachFromChannel.d.ts +2 -2
- package/packages/happy2-server/dist/modules/agent/agentSecretDetachFromChannel.js +4 -4
- package/packages/happy2-server/dist/modules/agent/agentSecretDetachFromChannel.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretRecordRegistration.d.ts +1 -1
- package/packages/happy2-server/dist/modules/agent/agentSecretRecordRegistration.js +3 -3
- package/packages/happy2-server/dist/modules/agent/agentSecretRecordRegistration.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/agent/agentTurnStreamReply.d.ts +4 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnStreamReply.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentTurnStreamReply.js +207 -9
- package/packages/happy2-server/dist/modules/agent/agentTurnStreamReply.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/agentTurnTraceGet.d.ts +8 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnTraceGet.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnTraceGet.js +86 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnTraceGet.js.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnTraceStart.d.ts +19 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnTraceStart.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnTraceStart.js +87 -0
- package/packages/happy2-server/dist/modules/agent/agentTurnTraceStart.js.map +1 -0
- package/packages/happy2-server/dist/modules/agent/impl/agentChatContext.d.ts +2 -1
- package/packages/happy2-server/dist/modules/agent/impl/agentChatContext.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/impl/agentEffortContext.d.ts +4 -1
- package/packages/happy2-server/dist/modules/agent/impl/agentEffortContext.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/impl/agentEffortContextDb.d.ts +3 -3
- package/packages/happy2-server/dist/modules/agent/impl/agentEffortContextDb.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/impl/agentEffortContextDb.js +26 -40
- package/packages/happy2-server/dist/modules/agent/impl/agentEffortContextDb.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/impl/finishAgentTurn.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agent/impl/finishAgentTurn.js +63 -2
- package/packages/happy2-server/dist/modules/agent/impl/finishAgentTurn.js.map +1 -1
- package/packages/happy2-server/dist/modules/agent/types.d.ts +53 -0
- package/packages/happy2-server/dist/modules/agent/types.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agents/daemon.d.ts +31 -2
- package/packages/happy2-server/dist/modules/agents/daemon.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agents/daemon.js +12 -2
- package/packages/happy2-server/dist/modules/agents/daemon.js.map +1 -1
- package/packages/happy2-server/dist/modules/agents/service.d.ts +11 -6
- package/packages/happy2-server/dist/modules/agents/service.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agents/service.js +498 -50
- package/packages/happy2-server/dist/modules/agents/service.js.map +1 -1
- package/packages/happy2-server/dist/modules/auth/developmentTokenCreate.d.ts +12 -0
- package/packages/happy2-server/dist/modules/auth/developmentTokenCreate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/auth/developmentTokenCreate.js +27 -0
- package/packages/happy2-server/dist/modules/auth/developmentTokenCreate.js.map +1 -0
- package/packages/happy2-server/dist/modules/auth/developmentTokenFindActive.d.ts +8 -0
- package/packages/happy2-server/dist/modules/auth/developmentTokenFindActive.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/auth/developmentTokenFindActive.js +22 -0
- package/packages/happy2-server/dist/modules/auth/developmentTokenFindActive.js.map +1 -0
- package/packages/happy2-server/dist/modules/auth/methods.d.ts +1 -0
- package/packages/happy2-server/dist/modules/auth/methods.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/auth/methods.js +10 -6
- package/packages/happy2-server/dist/modules/auth/methods.js.map +1 -1
- package/packages/happy2-server/dist/modules/auth/service.d.ts +2 -0
- package/packages/happy2-server/dist/modules/auth/service.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/auth/service.js +26 -0
- package/packages/happy2-server/dist/modules/auth/service.js.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.d.ts +21 -0
- package/packages/happy2-server/dist/modules/auth/tokens.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.js +97 -3
- package/packages/happy2-server/dist/modules/auth/tokens.js.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.test.js +77 -0
- package/packages/happy2-server/dist/modules/auth/tokens.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/chat/asAgentTurnTrace.d.ts +17 -0
- package/packages/happy2-server/dist/modules/chat/asAgentTurnTrace.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/chat/asAgentTurnTrace.js +98 -0
- package/packages/happy2-server/dist/modules/chat/asAgentTurnTrace.js.map +1 -0
- package/packages/happy2-server/dist/modules/chat/asServiceMessage.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/chat/asServiceMessage.js +13 -5
- package/packages/happy2-server/dist/modules/chat/asServiceMessage.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/chat/chatUpdateMetadata.d.ts +20 -0
- package/packages/happy2-server/dist/modules/chat/chatUpdateMetadata.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/chat/chatUpdateMetadata.js +38 -0
- package/packages/happy2-server/dist/modules/chat/chatUpdateMetadata.js.map +1 -0
- package/packages/happy2-server/dist/modules/chat/types.d.ts +6 -0
- package/packages/happy2-server/dist/modules/chat/types.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/chat/types.js.map +1 -1
- package/packages/happy2-server/dist/modules/chat/userRequireActiveHuman.d.ts +7 -0
- package/packages/happy2-server/dist/modules/chat/userRequireActiveHuman.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/chat/userRequireActiveHuman.js +19 -0
- package/packages/happy2-server/dist/modules/chat/userRequireActiveHuman.js.map +1 -0
- package/packages/happy2-server/dist/modules/chat/userRequireServerAdmin.d.ts +2 -2
- package/packages/happy2-server/dist/modules/chat/userRequireServerAdmin.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/chat/userRequireServerAdmin.js +8 -5
- package/packages/happy2-server/dist/modules/chat/userRequireServerAdmin.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/defaults.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/config/defaults.js +1 -0
- package/packages/happy2-server/dist/modules/config/defaults.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/defaults.test.js +1 -0
- package/packages/happy2-server/dist/modules/config/defaults.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/loader.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/config/loader.js +4 -0
- package/packages/happy2-server/dist/modules/config/loader.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/loader.test.js +12 -0
- package/packages/happy2-server/dist/modules/config/loader.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/type.d.ts +3 -0
- package/packages/happy2-server/dist/modules/config/type.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/message/messageGetProjection.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/message/messageGetProjection.js +28 -0
- package/packages/happy2-server/dist/modules/message/messageGetProjection.js.map +1 -1
- package/packages/happy2-server/dist/modules/permission/impl/permissionEffectiveDb.d.ts +4 -0
- package/packages/happy2-server/dist/modules/permission/impl/permissionEffectiveDb.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/impl/permissionEffectiveDb.js +39 -0
- package/packages/happy2-server/dist/modules/permission/impl/permissionEffectiveDb.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/impl/permissionMutationRecord.d.ts +10 -0
- package/packages/happy2-server/dist/modules/permission/impl/permissionMutationRecord.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/impl/permissionMutationRecord.js +31 -0
- package/packages/happy2-server/dist/modules/permission/impl/permissionMutationRecord.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/permissionGetEffective.d.ts +8 -0
- package/packages/happy2-server/dist/modules/permission/permissionGetEffective.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/permissionGetEffective.js +13 -0
- package/packages/happy2-server/dist/modules/permission/permissionGetEffective.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/roleCreate.d.ts +16 -0
- package/packages/happy2-server/dist/modules/permission/roleCreate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/roleCreate.js +70 -0
- package/packages/happy2-server/dist/modules/permission/roleCreate.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/roleDelete.d.ts +11 -0
- package/packages/happy2-server/dist/modules/permission/roleDelete.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/roleDelete.js +41 -0
- package/packages/happy2-server/dist/modules/permission/roleDelete.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/roleList.d.ts +8 -0
- package/packages/happy2-server/dist/modules/permission/roleList.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/roleList.js +36 -0
- package/packages/happy2-server/dist/modules/permission/roleList.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/roleUpdate.d.ts +14 -0
- package/packages/happy2-server/dist/modules/permission/roleUpdate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/roleUpdate.js +78 -0
- package/packages/happy2-server/dist/modules/permission/roleUpdate.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/types.d.ts +24 -0
- package/packages/happy2-server/dist/modules/permission/types.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/types.js +10 -0
- package/packages/happy2-server/dist/modules/permission/types.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userPermissionGet.d.ts +16 -0
- package/packages/happy2-server/dist/modules/permission/userPermissionGet.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userPermissionGet.js +33 -0
- package/packages/happy2-server/dist/modules/permission/userPermissionGet.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userPermissionUpdate.d.ts +12 -0
- package/packages/happy2-server/dist/modules/permission/userPermissionUpdate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userPermissionUpdate.js +44 -0
- package/packages/happy2-server/dist/modules/permission/userPermissionUpdate.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userRequireAnyPermission.d.ts +8 -0
- package/packages/happy2-server/dist/modules/permission/userRequireAnyPermission.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userRequireAnyPermission.js +12 -0
- package/packages/happy2-server/dist/modules/permission/userRequireAnyPermission.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userRequirePermission.d.ts +8 -0
- package/packages/happy2-server/dist/modules/permission/userRequirePermission.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userRequirePermission.js +12 -0
- package/packages/happy2-server/dist/modules/permission/userRequirePermission.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userRoleAssign.d.ts +12 -0
- package/packages/happy2-server/dist/modules/permission/userRoleAssign.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userRoleAssign.js +46 -0
- package/packages/happy2-server/dist/modules/permission/userRoleAssign.js.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userRoleUnassign.d.ts +12 -0
- package/packages/happy2-server/dist/modules/permission/userRoleUnassign.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/permission/userRoleUnassign.js +53 -0
- package/packages/happy2-server/dist/modules/permission/userRoleUnassign.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/archive.d.ts +7 -0
- package/packages/happy2-server/dist/modules/plugin/archive.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/archive.js +222 -0
- package/packages/happy2-server/dist/modules/plugin/archive.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.d.ts +5 -1
- package/packages/happy2-server/dist/modules/plugin/catalog.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/catalog.js +35 -16
- package/packages/happy2-server/dist/modules/plugin/catalog.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/catalog.test.js +6 -2
- package/packages/happy2-server/dist/modules/plugin/catalog.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/httpBridge.d.ts +1 -0
- package/packages/happy2-server/dist/modules/plugin/httpBridge.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/httpBridge.js +7 -0
- package/packages/happy2-server/dist/modules/plugin/httpBridge.js.map +1 -1
- 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 +106 -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 +12 -2
- 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 +12 -3
- 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/impl/pluginSkillSource.d.ts +11 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginSkillSource.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginSkillSource.js +2 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginSkillSource.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 +67 -0
- package/packages/happy2-server/dist/modules/plugin/packageLinkDownloader.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts +27 -1
- package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/packageStore.js +234 -15
- 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/pluginAuthorizeManagement.d.ts +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.js +3 -3
- package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.js.map +1 -1
- 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/pluginFindBySource.d.ts +3 -1
- package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.js +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginGetImage.d.ts +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginGetImage.js +3 -3
- package/packages/happy2-server/dist/modules/plugin/pluginGetImage.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginGetSource.d.ts +13 -0
- package/packages/happy2-server/dist/modules/plugin/pluginGetSource.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginGetSource.js +37 -0
- package/packages/happy2-server/dist/modules/plugin/pluginGetSource.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 +36 -5
- 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 +3 -1
- 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/pluginInstallationList.d.ts +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.js +3 -3
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.js.map +1 -1
- 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/pluginList.d.ts +1 -1
- package/packages/happy2-server/dist/modules/plugin/pluginList.js +3 -3
- package/packages/happy2-server/dist/modules/plugin/pluginList.js.map +1 -1
- 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/pluginSkillsListInstalled.d.ts +8 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillsListInstalled.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillsListInstalled.js +24 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillsListInstalled.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillsListReady.d.ts +8 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillsListReady.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillsListReady.js +25 -0
- package/packages/happy2-server/dist/modules/plugin/pluginSkillsListReady.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginUninstall.d.ts +13 -0
- package/packages/happy2-server/dist/modules/plugin/pluginUninstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginUninstall.js +63 -0
- package/packages/happy2-server/dist/modules/plugin/pluginUninstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/runtime.d.ts +1 -0
- package/packages/happy2-server/dist/modules/plugin/runtime.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/runtime.js +1 -0
- package/packages/happy2-server/dist/modules/plugin/runtime.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/service.d.ts +157 -5
- package/packages/happy2-server/dist/modules/plugin/service.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/service.js +789 -19
- package/packages/happy2-server/dist/modules/plugin/service.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/source.d.ts +35 -0
- package/packages/happy2-server/dist/modules/plugin/source.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/source.js +189 -0
- package/packages/happy2-server/dist/modules/plugin/source.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/types.d.ts +116 -11
- package/packages/happy2-server/dist/modules/plugin/types.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/types.js +9 -0
- package/packages/happy2-server/dist/modules/plugin/types.js.map +1 -1
- package/packages/happy2-server/dist/modules/realtime/events.d.ts +3 -0
- package/packages/happy2-server/dist/modules/realtime/events.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/realtime/events.js +37 -5
- package/packages/happy2-server/dist/modules/realtime/events.js.map +1 -1
- package/packages/happy2-server/dist/modules/realtime/local.test.js +2 -0
- package/packages/happy2-server/dist/modules/realtime/local.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.js +4 -2
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.js.map +1 -1
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.test.js +4 -1
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/sandbox/types.d.ts +1 -0
- package/packages/happy2-server/dist/modules/sandbox/types.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/schema.d.ts +8024 -5446
- package/packages/happy2-server/dist/modules/schema.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/schema.js +140 -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/modules/user/userAdministrationList.js +2 -2
- package/packages/happy2-server/dist/modules/user/userAdministrationList.js.map +1 -1
- package/packages/happy2-server/dist/modules/user/userAdministrationUpdate.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/user/userAdministrationUpdate.js +49 -6
- package/packages/happy2-server/dist/modules/user/userAdministrationUpdate.js.map +1 -1
- package/packages/happy2-server/dist/modules/user/userCreateProfile.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/user/userCreateProfile.js +17 -2
- package/packages/happy2-server/dist/modules/user/userCreateProfile.js.map +1 -1
- package/packages/happy2-server/dist/routes/agents.d.ts.map +1 -1
- package/packages/happy2-server/dist/routes/agents.js +4 -2
- package/packages/happy2-server/dist/routes/agents.js.map +1 -1
- package/packages/happy2-server/dist/routes/auth.d.ts.map +1 -1
- package/packages/happy2-server/dist/routes/auth.js +12 -0
- package/packages/happy2-server/dist/routes/auth.js.map +1 -1
- package/packages/happy2-server/dist/routes/collaboration.d.ts.map +1 -1
- package/packages/happy2-server/dist/routes/collaboration.js +7 -0
- package/packages/happy2-server/dist/routes/collaboration.js.map +1 -1
- package/packages/happy2-server/dist/routes/files.d.ts.map +1 -1
- package/packages/happy2-server/dist/routes/files.js +2 -0
- package/packages/happy2-server/dist/routes/files.js.map +1 -1
- package/packages/happy2-server/dist/routes/permissions.d.ts +6 -0
- package/packages/happy2-server/dist/routes/permissions.d.ts.map +1 -0
- package/packages/happy2-server/dist/routes/permissions.js +207 -0
- package/packages/happy2-server/dist/routes/permissions.js.map +1 -0
- package/packages/happy2-server/dist/routes/pluginHost.d.ts +2 -1
- package/packages/happy2-server/dist/routes/pluginHost.d.ts.map +1 -1
- package/packages/happy2-server/dist/routes/pluginHost.js +356 -5
- 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 +375 -7
- package/packages/happy2-server/dist/routes/plugins.js.map +1 -1
- package/packages/happy2-server/dist/server.d.ts +4 -0
- package/packages/happy2-server/dist/server.d.ts.map +1 -1
- package/packages/happy2-server/dist/server.js +12 -7
- package/packages/happy2-server/dist/server.js.map +1 -1
- package/packages/happy2-server/dist/web/assets/index-Dn5SZu3y.js +39 -0
- package/packages/happy2-server/dist/web/assets/index-Dys3sWv8.css +2 -0
- package/packages/happy2-server/dist/web/index.html +2 -2
- package/packages/happy2-server/drizzle/0023_roles_and_permissions.sql +82 -0
- package/packages/happy2-server/drizzle/0024_session_bound_dev_tokens.sql +11 -0
- package/packages/happy2-server/drizzle/0025_plugin_skills.sql +8 -0
- package/packages/happy2-server/drizzle/0026_agent_turn_traces.sql +35 -0
- package/packages/happy2-server/drizzle/0027_chat_agent_effort.sql +9 -0
- 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/meta/_journal.json +49 -0
- package/packages/happy2-server/happy2.example.toml +6 -0
- package/packages/happy2-server/plugins/README.md +7 -1
- package/packages/happy2-server/plugins/chat-management/container/Dockerfile +6 -0
- package/packages/happy2-server/plugins/chat-management/plugin.json +17 -0
- package/packages/happy2-server/plugins/chat-management/plugin.png +0 -0
- package/packages/happy2-server/plugins/chat-management/server.mjs +280 -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 +63 -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 +137 -0
- package/packages/happy2-server/dist/web/assets/index-9SGCQLg7.js +0 -46
- package/packages/happy2-server/dist/web/assets/index-DWXBQDJB.css +0 -2
|
@@ -1,58 +1,101 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
1
|
+
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
2
|
import { createId } from "@paralleldrive/cuid2";
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
6
6
|
import { realtimeTopics } from "../realtime/index.js";
|
|
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";
|
|
7
11
|
import { pluginInstall } from "./pluginInstall.js";
|
|
8
12
|
import { pluginFindBySource } from "./pluginFindBySource.js";
|
|
13
|
+
import { pluginGetSource } from "./pluginGetSource.js";
|
|
9
14
|
import { pluginGetImage } from "./pluginGetImage.js";
|
|
10
15
|
import { pluginAuthorizeManagement } from "./pluginAuthorizeManagement.js";
|
|
11
16
|
import { pluginInstallationGetRuntimeConfiguration } from "./pluginInstallationGetRuntimeConfiguration.js";
|
|
17
|
+
import { pluginInstallationGetRequestUninstallContext } from "./pluginInstallationGetRequestUninstallContext.js";
|
|
18
|
+
import { pluginInstallationUninstall } from "./pluginInstallationUninstall.js";
|
|
12
19
|
import { pluginInstallationListIds } from "./pluginInstallationListIds.js";
|
|
13
20
|
import { pluginInstallationListReadyMcpIds } from "./pluginInstallationListReadyMcpIds.js";
|
|
14
21
|
import { pluginInstallationUpdateStatus } from "./pluginInstallationUpdateStatus.js";
|
|
22
|
+
import { pluginInstallationPermissionsUpdate } from "./pluginInstallationPermissionsUpdate.js";
|
|
23
|
+
import { pluginInstallationGetContainerName } from "./pluginInstallationGetContainerName.js";
|
|
24
|
+
import { pluginAgentCallContextGet } from "./pluginAgentCallContextGet.js";
|
|
15
25
|
import { pluginRemoveMissingBuiltins } from "./pluginRemoveMissingBuiltins.js";
|
|
16
26
|
import { pluginMcpToolsReplace } from "./pluginMcpToolsReplace.js";
|
|
17
27
|
import { pluginMcpToolsListReady } from "./pluginMcpToolsListReady.js";
|
|
28
|
+
import { pluginSkillsListReady } from "./pluginSkillsListReady.js";
|
|
29
|
+
import { pluginSkillsListInstalled } from "./pluginSkillsListInstalled.js";
|
|
30
|
+
import { pluginApiPermissionSections } from "./impl/apiPermissions.js";
|
|
31
|
+
import { effectiveContainer } from "./impl/effectiveContainer.js";
|
|
18
32
|
import { pluginContainerInstanceAuthorize } from "./pluginContainerInstanceAuthorize.js";
|
|
19
33
|
import { pluginContainerInstanceInvalidate } from "./pluginContainerInstanceInvalidate.js";
|
|
34
|
+
import { pluginUninstall } from "./pluginUninstall.js";
|
|
35
|
+
import { pluginArchiveExtract } from "./archive.js";
|
|
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";
|
|
20
48
|
import { RemotePluginMcpTransport } from "./utils/remoteMcpTransport.js";
|
|
49
|
+
import { downloadedPluginSource, remotePluginSource, remotePluginSourceFromInstalled, uploadedPluginSource, } from "./source.js";
|
|
21
50
|
import { PluginError, MAX_PLUGIN_MCP_TOOLS, } from "./types.js";
|
|
22
51
|
const HEALTH_TIMEOUT_MS = 15_000;
|
|
23
52
|
const COMMAND_STARTUP_GRACE_MS = 250;
|
|
24
53
|
const FUNCTION_EXECUTION_TIMEOUT_MS = 30_000;
|
|
25
54
|
const MAX_RIG_PLUGIN_FUNCTIONS = 128;
|
|
55
|
+
const MAX_RIG_PLUGIN_SKILLS = 128;
|
|
56
|
+
const PREPARATION_TTL_MS = 15 * 60_000;
|
|
57
|
+
const PLUGIN_CHAT_META_KEY = "happy2/chat";
|
|
58
|
+
const PLUGIN_USERS_META_KEY = "happy2/users";
|
|
26
59
|
/** Coordinates durable plugin installs with asynchronous container preparation, MCP health probes, restart recovery, and local connection creation. */
|
|
27
60
|
export class PluginService {
|
|
28
61
|
executor;
|
|
29
62
|
pubsub;
|
|
30
63
|
catalog;
|
|
31
64
|
packages;
|
|
65
|
+
packageLinks;
|
|
32
66
|
secrets;
|
|
33
67
|
runtime;
|
|
34
68
|
tokens;
|
|
35
69
|
urlPolicy;
|
|
36
70
|
remoteTransport;
|
|
37
71
|
hostApiUrl;
|
|
72
|
+
archiveDownloader;
|
|
38
73
|
onError;
|
|
39
74
|
activations = new Map();
|
|
40
75
|
commandHandles = new Map();
|
|
76
|
+
preparations = new Map();
|
|
41
77
|
closed = false;
|
|
42
|
-
constructor(executor, pubsub, catalog, packages, secrets, runtime, tokens, urlPolicy, remoteTransport, hostApiUrl, onError) {
|
|
78
|
+
constructor(executor, pubsub, catalog, packages, packageLinks, secrets, runtime, tokens, urlPolicy, remoteTransport, hostApiUrl, archiveDownloader, onError) {
|
|
43
79
|
this.executor = executor;
|
|
44
80
|
this.pubsub = pubsub;
|
|
45
81
|
this.catalog = catalog;
|
|
46
82
|
this.packages = packages;
|
|
83
|
+
this.packageLinks = packageLinks;
|
|
47
84
|
this.secrets = secrets;
|
|
48
85
|
this.runtime = runtime;
|
|
49
86
|
this.tokens = tokens;
|
|
50
87
|
this.urlPolicy = urlPolicy;
|
|
51
88
|
this.remoteTransport = remoteTransport;
|
|
52
89
|
this.hostApiUrl = hostApiUrl;
|
|
90
|
+
this.archiveDownloader = archiveDownloader;
|
|
53
91
|
this.onError = onError;
|
|
54
92
|
}
|
|
55
93
|
async start() {
|
|
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);
|
|
56
99
|
const removed = await pluginRemoveMissingBuiltins(this.executor, this.catalog.list().map(({ source }) => source.reference));
|
|
57
100
|
await Promise.all([
|
|
58
101
|
...removed.plugins.map(({ pluginId }) => this.packages.remove(pluginId).catch(this.onError)),
|
|
@@ -64,24 +107,70 @@ export class PluginService {
|
|
|
64
107
|
this.activate(installationId);
|
|
65
108
|
}
|
|
66
109
|
async install(input) {
|
|
67
|
-
|
|
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");
|
|
68
114
|
const plugin = this.catalog.get(input.shortName);
|
|
69
115
|
if (!plugin)
|
|
70
116
|
throw new PluginError("not_found", "Built-in plugin was not found");
|
|
71
|
-
|
|
72
|
-
|
|
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);
|
|
73
157
|
const candidateId = existing ? undefined : createId();
|
|
74
158
|
const candidate = candidateId
|
|
75
|
-
? {
|
|
159
|
+
? {
|
|
160
|
+
pluginId: candidateId,
|
|
161
|
+
...(await this.packages.install(input.plugin, candidateId)),
|
|
162
|
+
}
|
|
76
163
|
: undefined;
|
|
77
164
|
let result;
|
|
78
165
|
try {
|
|
79
166
|
result = await pluginInstall(this.executor, this.secrets, {
|
|
80
167
|
actorUserId: input.actorUserId,
|
|
168
|
+
actorInstallationId: input.actorInstallationId,
|
|
81
169
|
installationId,
|
|
82
|
-
plugin,
|
|
170
|
+
plugin: input.plugin,
|
|
83
171
|
candidate,
|
|
84
172
|
variables: input.variables,
|
|
173
|
+
permissions: input.permissions,
|
|
85
174
|
containerImageId: input.containerImageId,
|
|
86
175
|
});
|
|
87
176
|
}
|
|
@@ -92,11 +181,194 @@ export class PluginService {
|
|
|
92
181
|
}
|
|
93
182
|
if (candidateId && !result.pluginCreated)
|
|
94
183
|
await this.packages.remove(candidateId);
|
|
184
|
+
await this.packages.workspaceDirectory(result.pluginId, installationId);
|
|
95
185
|
await this.publish(result.hint).catch(this.onError);
|
|
96
186
|
if (result.installation.status === "preparing")
|
|
97
187
|
this.activate(installationId);
|
|
98
188
|
return result.installation;
|
|
99
189
|
}
|
|
190
|
+
async prepareUpload(actorUserId, archive, onProgress) {
|
|
191
|
+
await pluginAuthorizeManagement(this.executor, actorUserId);
|
|
192
|
+
onProgress("verifying", "Inspecting uploaded ZIP package.");
|
|
193
|
+
const prepared = await this.prepareArchive(actorUserId, archive, "zip", undefined, onProgress);
|
|
194
|
+
return { selectionRequired: false, candidates: prepared };
|
|
195
|
+
}
|
|
196
|
+
async prepareRemote(actorUserId, input, onProgress, signal) {
|
|
197
|
+
await pluginAuthorizeManagement(this.executor, actorUserId);
|
|
198
|
+
const remote = remotePluginSource(input.kind, input.url);
|
|
199
|
+
onProgress("downloading", "Downloading plugin ZIP from its remote source.");
|
|
200
|
+
const downloaded = await this.archiveDownloader.download(remote.archiveUrl, {
|
|
201
|
+
signal,
|
|
202
|
+
onProgress: (bytes) => onProgress("downloading", "Downloading plugin ZIP.", bytes),
|
|
203
|
+
});
|
|
204
|
+
onProgress("verifying", "Verifying archive structure and plugin metadata.");
|
|
205
|
+
const candidates = await this.prepareArchive(actorUserId, downloaded.body, input.kind === "github" ? "github" : "zip", remote, onProgress);
|
|
206
|
+
return { selectionRequired: candidates.length > 1, candidates };
|
|
207
|
+
}
|
|
208
|
+
async installPrepared(input) {
|
|
209
|
+
await pluginAuthorizeManagement(this.executor, input.actorUserId);
|
|
210
|
+
const prepared = await this.preparationTake(input.actorUserId, input.preparedToken);
|
|
211
|
+
try {
|
|
212
|
+
const existing = await pluginFindBySource(this.executor, prepared.plugin.source.kind, prepared.plugin.source.reference);
|
|
213
|
+
if (existing && existing.packageDigest !== prepared.plugin.packageDigest)
|
|
214
|
+
throw new PluginError("conflict", "This remote plugin has changed since its installed snapshot; update it before adding another installation");
|
|
215
|
+
const installationId = createId();
|
|
216
|
+
const candidateId = existing ? undefined : createId();
|
|
217
|
+
const candidate = candidateId
|
|
218
|
+
? {
|
|
219
|
+
pluginId: candidateId,
|
|
220
|
+
...(await this.packages.install(prepared.plugin, candidateId)),
|
|
221
|
+
}
|
|
222
|
+
: undefined;
|
|
223
|
+
let result;
|
|
224
|
+
try {
|
|
225
|
+
result = await pluginInstall(this.executor, this.secrets, {
|
|
226
|
+
actorUserId: input.actorUserId,
|
|
227
|
+
installationId,
|
|
228
|
+
plugin: prepared.plugin,
|
|
229
|
+
candidate,
|
|
230
|
+
variables: input.variables,
|
|
231
|
+
permissions: input.permissions,
|
|
232
|
+
containerImageId: input.containerImageId,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
if (candidateId)
|
|
237
|
+
await this.packages.remove(candidateId);
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
if (candidateId && !result.pluginCreated)
|
|
241
|
+
await this.packages.remove(candidateId);
|
|
242
|
+
await this.packages.workspaceDirectory(result.pluginId, installationId);
|
|
243
|
+
await this.publish(result.hint).catch(this.onError);
|
|
244
|
+
if (result.installation.status === "preparing")
|
|
245
|
+
this.activate(installationId);
|
|
246
|
+
return result.installation;
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
await this.packages.removePreparation(prepared.id).catch(this.onError);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async uninstall(actorUserId, pluginId) {
|
|
253
|
+
const result = await pluginUninstall(this.executor, actorUserId, pluginId);
|
|
254
|
+
for (const installationId of result.installationIds) {
|
|
255
|
+
const activation = this.activations.get(installationId);
|
|
256
|
+
activation?.controller.abort();
|
|
257
|
+
this.closeCommand(installationId);
|
|
258
|
+
}
|
|
259
|
+
await Promise.allSettled(result.installationIds.flatMap((installationId) => {
|
|
260
|
+
const activation = this.activations.get(installationId);
|
|
261
|
+
return activation ? [activation.promise] : [];
|
|
262
|
+
}));
|
|
263
|
+
await this.publish(result.hint).catch(this.onError);
|
|
264
|
+
await Promise.allSettled([
|
|
265
|
+
...result.containerNames.map((containerName) => {
|
|
266
|
+
return this.runtime.removeLocal(containerName);
|
|
267
|
+
}),
|
|
268
|
+
this.packages.remove(pluginId),
|
|
269
|
+
]).then((settled) => {
|
|
270
|
+
for (const item of settled)
|
|
271
|
+
if (item.status === "rejected")
|
|
272
|
+
this.onError(item.reason);
|
|
273
|
+
});
|
|
274
|
+
return { installationIds: result.installationIds, pluginId };
|
|
275
|
+
}
|
|
276
|
+
async checkForUpdate(actorUserId, pluginId, onProgress, signal) {
|
|
277
|
+
const installed = await pluginGetSource(this.executor, actorUserId, pluginId);
|
|
278
|
+
let remotePackage;
|
|
279
|
+
if (installed.source.kind === "builtin") {
|
|
280
|
+
const catalogPackage = this.catalog.get(installed.source.reference);
|
|
281
|
+
if (!catalogPackage)
|
|
282
|
+
throw new PluginError("not_found", "Built-in plugin is no longer in the catalog");
|
|
283
|
+
remotePackage = catalogPackage;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
const remote = remotePluginSourceFromInstalled(installed.source);
|
|
287
|
+
onProgress("downloading", "Downloading the current remote plugin package.");
|
|
288
|
+
const downloaded = await this.archiveDownloader.download(remote.archiveUrl, {
|
|
289
|
+
signal,
|
|
290
|
+
onProgress: (bytes) => onProgress("downloading", "Downloading remote package.", bytes),
|
|
291
|
+
});
|
|
292
|
+
const directory = await this.packages.createDownloadDirectory();
|
|
293
|
+
try {
|
|
294
|
+
onProgress("verifying", "Verifying the current remote plugin package.");
|
|
295
|
+
const candidates = await pluginArchiveExtract(downloaded.body, directory, remote.kind === "github" ? "github" : "zip");
|
|
296
|
+
const candidate = remote.packagePath === undefined
|
|
297
|
+
? candidates[0]
|
|
298
|
+
: candidates.find(({ packagePath }) => packagePath === remote.packagePath);
|
|
299
|
+
if (!candidate)
|
|
300
|
+
throw new PluginError("invalid_package", "The installed plugin path no longer exists remotely");
|
|
301
|
+
remotePackage = await pluginPackageLoadSource(candidate.directory, installed.source);
|
|
302
|
+
}
|
|
303
|
+
finally {
|
|
304
|
+
await this.packages.removeDownloadDirectory(directory);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (remotePackage.manifest.shortName !== installed.shortName)
|
|
308
|
+
throw new PluginError("invalid_package", "Remote plugin shortName changed");
|
|
309
|
+
return {
|
|
310
|
+
pluginId,
|
|
311
|
+
checkedAt: new Date().toISOString(),
|
|
312
|
+
updateAvailable: remotePackage.packageDigest !== installed.packageDigest,
|
|
313
|
+
installed: { version: installed.sourceVersion, packageDigest: installed.packageDigest },
|
|
314
|
+
remote: {
|
|
315
|
+
version: remotePackage.manifest.version,
|
|
316
|
+
packageDigest: remotePackage.packageDigest,
|
|
317
|
+
},
|
|
318
|
+
};
|
|
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
|
+
}
|
|
100
372
|
async image(actorUserId, pluginId) {
|
|
101
373
|
const image = await pluginGetImage(this.executor, actorUserId, pluginId);
|
|
102
374
|
const body = await this.packages.readImage(image.pluginId, image.packageDirectory, image.storageKey, image.shortName, image.packageDigest);
|
|
@@ -109,6 +381,165 @@ export class PluginService {
|
|
|
109
381
|
checksumSha256: image.checksumSha256,
|
|
110
382
|
};
|
|
111
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
|
+
}
|
|
112
543
|
async openLocal(installationId) {
|
|
113
544
|
const configuration = await pluginInstallationGetRuntimeConfiguration(this.executor, this.secrets, installationId);
|
|
114
545
|
if (configuration.type !== "local" || !configuration.mcp)
|
|
@@ -133,9 +564,45 @@ export class PluginService {
|
|
|
133
564
|
parameters: tool.inputSchema,
|
|
134
565
|
}));
|
|
135
566
|
}
|
|
136
|
-
async
|
|
567
|
+
async listSkills(signal) {
|
|
568
|
+
const skills = this.skillSources(await pluginSkillsListReady(this.executor), signal);
|
|
569
|
+
if (skills.length > MAX_RIG_PLUGIN_SKILLS)
|
|
570
|
+
throw new PluginSkillCatalogError(`Installed plugins expose ${skills.length} skills, exceeding Rig's ${MAX_RIG_PLUGIN_SKILLS}-skill limit`);
|
|
571
|
+
return skills.map(({ name, description }) => ({
|
|
572
|
+
name,
|
|
573
|
+
description,
|
|
574
|
+
location: "durable",
|
|
575
|
+
}));
|
|
576
|
+
}
|
|
577
|
+
async readSkill(skill, signal) {
|
|
578
|
+
try {
|
|
579
|
+
return await withOperationTimeout(FUNCTION_EXECUTION_TIMEOUT_MS, "Plugin skill read", signal, async (operationSignal) => {
|
|
580
|
+
const sources = this.skillSources(await pluginSkillsListInstalled(this.executor), operationSignal);
|
|
581
|
+
const source = sources.find(({ name }) => name === skill.name);
|
|
582
|
+
if (!source || source.description !== skill.description)
|
|
583
|
+
throw new Error("The plugin no longer provides this durable skill");
|
|
584
|
+
const loaded = await this.packages.readSkill(source.pluginId, source.packageDirectory, source.shortName, source.packageDigest, source.name, source.directory, operationSignal);
|
|
585
|
+
if (loaded.description !== skill.description)
|
|
586
|
+
throw new Error("Installed plugin skill metadata no longer matches");
|
|
587
|
+
return { status: "completed", output: loaded.source };
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
catch (error) {
|
|
591
|
+
if (signal?.aborted)
|
|
592
|
+
throw error;
|
|
593
|
+
return {
|
|
594
|
+
status: "failed",
|
|
595
|
+
error: {
|
|
596
|
+
code: "plugin_skill_failed",
|
|
597
|
+
message: errorMessage(error),
|
|
598
|
+
},
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
async callFunction(functionName, args, context, signal) {
|
|
137
603
|
try {
|
|
138
|
-
|
|
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));
|
|
139
606
|
}
|
|
140
607
|
catch (error) {
|
|
141
608
|
if (signal?.aborted)
|
|
@@ -149,7 +616,7 @@ export class PluginService {
|
|
|
149
616
|
};
|
|
150
617
|
}
|
|
151
618
|
}
|
|
152
|
-
async callFunctionWithSignal(functionName, args, signal) {
|
|
619
|
+
async callFunctionWithSignal(functionName, args, context, agentCall, signal) {
|
|
153
620
|
const installationId = pluginFunctionInstallationId(functionName);
|
|
154
621
|
if (!installationId)
|
|
155
622
|
throw new Error(`Unknown plugin function ${JSON.stringify(functionName)}`);
|
|
@@ -164,10 +631,31 @@ export class PluginService {
|
|
|
164
631
|
pluginFunctionName(installationId, tool.name) === functionName);
|
|
165
632
|
if (!cached)
|
|
166
633
|
throw new Error("The plugin no longer exposes this cached function");
|
|
167
|
-
const
|
|
634
|
+
const chatToken = await this.tokens.issuePluginChatToken({
|
|
635
|
+
installationId,
|
|
636
|
+
chatId: context.chatId,
|
|
637
|
+
actorUserId: context.triggeredByUserId,
|
|
638
|
+
agentUserId: context.agentUserId,
|
|
639
|
+
});
|
|
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) => {
|
|
168
648
|
const result = await client.callTool({
|
|
169
649
|
name: cached.name,
|
|
170
650
|
arguments: jsonArguments(args),
|
|
651
|
+
_meta: {
|
|
652
|
+
[PLUGIN_CHAT_META_KEY]: {
|
|
653
|
+
id: context.chatId,
|
|
654
|
+
token: chatToken,
|
|
655
|
+
triggeredByUserId: context.triggeredByUserId,
|
|
656
|
+
},
|
|
657
|
+
[PLUGIN_USERS_META_KEY]: referencedUsers,
|
|
658
|
+
},
|
|
171
659
|
});
|
|
172
660
|
if (result.isError)
|
|
173
661
|
return {
|
|
@@ -184,6 +672,17 @@ export class PluginService {
|
|
|
184
672
|
throw new Error("The plugin does not expose MCP tools");
|
|
185
673
|
return result;
|
|
186
674
|
}
|
|
675
|
+
skillSources(records, signal) {
|
|
676
|
+
const names = new Map();
|
|
677
|
+
for (const record of records) {
|
|
678
|
+
signal?.throwIfAborted();
|
|
679
|
+
const existing = names.get(record.name);
|
|
680
|
+
if (existing)
|
|
681
|
+
throw new PluginSkillCatalogError(`Installed plugins ${existing} and ${record.shortName} both provide skill ${record.name}`);
|
|
682
|
+
names.set(record.name, record.shortName);
|
|
683
|
+
}
|
|
684
|
+
return [...records];
|
|
685
|
+
}
|
|
187
686
|
async authorizeHost(token, permission) {
|
|
188
687
|
let claims;
|
|
189
688
|
try {
|
|
@@ -192,6 +691,14 @@ export class PluginService {
|
|
|
192
691
|
catch {
|
|
193
692
|
throw new PluginError("forbidden", "Plugin runtime token is invalid");
|
|
194
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
|
+
}
|
|
195
702
|
if (!claims.permissions.includes(permission))
|
|
196
703
|
throw new PluginError("forbidden", `Plugin runtime lacks ${permission} permission`);
|
|
197
704
|
const authorized = await pluginContainerInstanceAuthorize(this.executor, claims.installationId, claims.containerInstanceId);
|
|
@@ -208,7 +715,140 @@ export class PluginService {
|
|
|
208
715
|
await this.publish(hint).catch(this.onError);
|
|
209
716
|
throw new PluginError("forbidden", "Plugin container incarnation is not running");
|
|
210
717
|
}
|
|
211
|
-
return claims
|
|
718
|
+
return claims;
|
|
719
|
+
}
|
|
720
|
+
async chatUpdate(runtimeToken, chatToken, input) {
|
|
721
|
+
const claims = await this.authorizeChat(runtimeToken, chatToken, "chats:update");
|
|
722
|
+
const result = await chatUpdateMetadata(this.executor, {
|
|
723
|
+
chatId: claims.chatId,
|
|
724
|
+
...input,
|
|
725
|
+
});
|
|
726
|
+
const event = { type: "sync", ...result.hint };
|
|
727
|
+
await Promise.allSettled([
|
|
728
|
+
this.pubsub.publish(realtimeTopics.chat(claims.chatId), event),
|
|
729
|
+
this.pubsub.publish(realtimeTopics.server, event),
|
|
730
|
+
]).then((publications) => {
|
|
731
|
+
for (const publication of publications)
|
|
732
|
+
if (publication.status === "rejected")
|
|
733
|
+
this.onError(publication.reason);
|
|
734
|
+
});
|
|
735
|
+
return { chat: result.chat, sync: result.hint };
|
|
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
|
+
});
|
|
212
852
|
}
|
|
213
853
|
async close() {
|
|
214
854
|
this.closed = true;
|
|
@@ -218,6 +858,73 @@ export class PluginService {
|
|
|
218
858
|
for (const handle of this.commandHandles.values())
|
|
219
859
|
handle.close();
|
|
220
860
|
this.commandHandles.clear();
|
|
861
|
+
await Promise.allSettled([...this.preparations.values()].map(({ id }) => this.packages.removePreparation(id)));
|
|
862
|
+
this.preparations.clear();
|
|
863
|
+
}
|
|
864
|
+
async prepareArchive(actorUserId, archive, kind, remote, onProgress) {
|
|
865
|
+
this.preparationsExpire();
|
|
866
|
+
const directory = await this.packages.createDownloadDirectory();
|
|
867
|
+
try {
|
|
868
|
+
const candidates = await pluginArchiveExtract(archive, directory, kind);
|
|
869
|
+
const prepared = [];
|
|
870
|
+
for (const candidate of candidates) {
|
|
871
|
+
const provisionalSource = remote
|
|
872
|
+
? downloadedPluginSource(remote, candidate.packagePath)
|
|
873
|
+
: { kind: "upload", reference: "upload:pending" };
|
|
874
|
+
let plugin = await pluginPackageLoadSource(candidate.directory, provisionalSource);
|
|
875
|
+
if (/^plugins\/[^/]+$/.test(candidate.packagePath)) {
|
|
876
|
+
const folder = candidate.packagePath.split("/").at(-1);
|
|
877
|
+
if (plugin.manifest.shortName !== folder)
|
|
878
|
+
throw new PluginError("invalid_package", `${candidate.packagePath}: shortName must match its plugin folder`);
|
|
879
|
+
}
|
|
880
|
+
if (!remote)
|
|
881
|
+
plugin = { ...plugin, source: uploadedPluginSource(plugin.packageDigest) };
|
|
882
|
+
const id = createId();
|
|
883
|
+
plugin = await this.packages.prepare(plugin, id);
|
|
884
|
+
const secret = randomBytes(32).toString("base64url");
|
|
885
|
+
const token = `${id}.${secret}`;
|
|
886
|
+
const expiresAt = Date.now() + PREPARATION_TTL_MS;
|
|
887
|
+
this.preparations.set(id, {
|
|
888
|
+
actorUserId,
|
|
889
|
+
expiresAt,
|
|
890
|
+
id,
|
|
891
|
+
plugin,
|
|
892
|
+
secretHash: createHash("sha256").update(secret).digest(),
|
|
893
|
+
});
|
|
894
|
+
prepared.push(preparedSummary(plugin, token, expiresAt));
|
|
895
|
+
}
|
|
896
|
+
onProgress("prepared", "Plugin package is verified and ready to install.");
|
|
897
|
+
return prepared;
|
|
898
|
+
}
|
|
899
|
+
catch (error) {
|
|
900
|
+
if (error instanceof PluginError)
|
|
901
|
+
throw error;
|
|
902
|
+
throw new PluginError("invalid_package", errorMessage(error));
|
|
903
|
+
}
|
|
904
|
+
finally {
|
|
905
|
+
await this.packages.removeDownloadDirectory(directory);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
async preparationTake(actorUserId, token) {
|
|
909
|
+
this.preparationsExpire();
|
|
910
|
+
const match = /^([a-z0-9]+)\.([A-Za-z0-9_-]{43})$/.exec(token);
|
|
911
|
+
const prepared = match ? this.preparations.get(match[1]) : undefined;
|
|
912
|
+
const suppliedHash = match ? createHash("sha256").update(match[2]).digest() : undefined;
|
|
913
|
+
if (!prepared ||
|
|
914
|
+
!suppliedHash ||
|
|
915
|
+
prepared.actorUserId !== actorUserId ||
|
|
916
|
+
!timingSafeEqual(prepared.secretHash, suppliedHash))
|
|
917
|
+
throw new PluginError("not_found", "Prepared plugin token was not found or expired");
|
|
918
|
+
this.preparations.delete(prepared.id);
|
|
919
|
+
return prepared;
|
|
920
|
+
}
|
|
921
|
+
preparationsExpire() {
|
|
922
|
+
const now = Date.now();
|
|
923
|
+
for (const [id, prepared] of this.preparations)
|
|
924
|
+
if (prepared.expiresAt <= now) {
|
|
925
|
+
this.preparations.delete(id);
|
|
926
|
+
void this.packages.removePreparation(id).catch(this.onError);
|
|
927
|
+
}
|
|
221
928
|
}
|
|
222
929
|
activate(installationId) {
|
|
223
930
|
if (this.closed || this.activations.has(installationId))
|
|
@@ -228,7 +935,14 @@ export class PluginService {
|
|
|
228
935
|
.finally(() => this.activations.delete(installationId));
|
|
229
936
|
this.activations.set(installationId, { controller, promise });
|
|
230
937
|
}
|
|
231
|
-
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) {
|
|
232
946
|
signal?.throwIfAborted();
|
|
233
947
|
const configuration = await pluginInstallationGetRuntimeConfiguration(this.executor, this.secrets, installationId);
|
|
234
948
|
if (configuration.type === "skills_only")
|
|
@@ -236,7 +950,7 @@ export class PluginService {
|
|
|
236
950
|
if (configuration.type === "local" && !configuration.mcp)
|
|
237
951
|
return undefined;
|
|
238
952
|
const localToken = configuration.type === "local"
|
|
239
|
-
? await this.pluginRuntimeToken(configuration)
|
|
953
|
+
? await this.pluginRuntimeToken(configuration, agentCall)
|
|
240
954
|
: undefined;
|
|
241
955
|
const transport = configuration.type === "local"
|
|
242
956
|
? await this.runtime.openLocal({
|
|
@@ -267,6 +981,7 @@ export class PluginService {
|
|
|
267
981
|
let preparedContainerName;
|
|
268
982
|
let preparedContainerInstanceId;
|
|
269
983
|
let commandHandle;
|
|
984
|
+
let buildContextDirectory;
|
|
270
985
|
this.closeCommand(installationId);
|
|
271
986
|
try {
|
|
272
987
|
signal.throwIfAborted();
|
|
@@ -288,16 +1003,19 @@ export class PluginService {
|
|
|
288
1003
|
const dockerfile = configuration.bundledDockerfile
|
|
289
1004
|
? await readFile(join(configuration.packageDirectory, configuration.bundledDockerfile), "utf8")
|
|
290
1005
|
: undefined;
|
|
1006
|
+
if (dockerfile)
|
|
1007
|
+
buildContextDirectory = await this.packages.createBuildContext(configuration.pluginId, configuration.packageDirectory, configuration.shortName, configuration.packageDigest);
|
|
291
1008
|
const prepared = await this.runtime.prepareLocal({
|
|
292
1009
|
installationId,
|
|
293
1010
|
containerName: configuration.containerName,
|
|
294
1011
|
containerInstanceId: createId(),
|
|
295
1012
|
existingContainerInstanceId: configuration.containerInstanceId,
|
|
296
1013
|
imageTag: configuration.imageTag,
|
|
1014
|
+
workspaceDirectory: await this.packages.workspaceDirectory(configuration.pluginId, installationId),
|
|
297
1015
|
...(dockerfile
|
|
298
1016
|
? {
|
|
299
1017
|
build: {
|
|
300
|
-
contextDirectory:
|
|
1018
|
+
contextDirectory: buildContextDirectory,
|
|
301
1019
|
dockerfile,
|
|
302
1020
|
tag: configuration.imageTag,
|
|
303
1021
|
},
|
|
@@ -342,15 +1060,19 @@ export class PluginService {
|
|
|
342
1060
|
this.commandHandles.delete(installationId);
|
|
343
1061
|
commandHandle.close();
|
|
344
1062
|
}
|
|
345
|
-
if (signal.aborted && this.closed)
|
|
346
|
-
return;
|
|
347
1063
|
if (preparedContainerName)
|
|
348
1064
|
await this.runtime.removeLocal(preparedContainerName).catch(this.onError);
|
|
1065
|
+
if (signal.aborted)
|
|
1066
|
+
return;
|
|
349
1067
|
const broken = error instanceof PluginError && error.code === "broken_configuration";
|
|
350
1068
|
await this.status(installationId, broken ? "broken_configuration" : "failed", broken
|
|
351
1069
|
? "Plugin configuration must be corrected before it can start."
|
|
352
1070
|
: "Plugin runtime failed to prepare or start.", errorMessage(error), undefined, preparedContainerInstanceId ? null : undefined).catch(this.onError);
|
|
353
1071
|
}
|
|
1072
|
+
finally {
|
|
1073
|
+
if (buildContextDirectory)
|
|
1074
|
+
await this.packages.removeBuildContext(buildContextDirectory).catch(this.onError);
|
|
1075
|
+
}
|
|
354
1076
|
}
|
|
355
1077
|
async probeLocal(configuration, environment, signal) {
|
|
356
1078
|
if (!configuration.mcp)
|
|
@@ -419,7 +1141,11 @@ export class PluginService {
|
|
|
419
1141
|
await this.publish(hint).catch(this.onError);
|
|
420
1142
|
}
|
|
421
1143
|
publish(hint) {
|
|
422
|
-
|
|
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);
|
|
423
1149
|
}
|
|
424
1150
|
closeCommand(installationId) {
|
|
425
1151
|
const handle = this.commandHandles.get(installationId);
|
|
@@ -446,18 +1172,21 @@ export class PluginService {
|
|
|
446
1172
|
HAPPY2_PLUGIN_API_TOKEN: token,
|
|
447
1173
|
};
|
|
448
1174
|
}
|
|
449
|
-
pluginRuntimeToken(configuration) {
|
|
1175
|
+
pluginRuntimeToken(configuration, agentCall) {
|
|
450
1176
|
if (!configuration.containerInstanceId)
|
|
451
1177
|
throw new PluginError("not_ready", "Plugin container incarnation is unavailable");
|
|
452
1178
|
return this.tokens.issuePluginRuntimeToken({
|
|
453
1179
|
installationId: configuration.installationId,
|
|
454
1180
|
containerInstanceId: configuration.containerInstanceId,
|
|
455
1181
|
permissions: configuration.permissions,
|
|
1182
|
+
...(agentCall ? { agentCall } : {}),
|
|
456
1183
|
});
|
|
457
1184
|
}
|
|
458
1185
|
}
|
|
459
1186
|
class PluginFunctionCatalogError extends Error {
|
|
460
1187
|
}
|
|
1188
|
+
class PluginSkillCatalogError extends Error {
|
|
1189
|
+
}
|
|
461
1190
|
function pluginFunctionName(installationId, toolName) {
|
|
462
1191
|
const normalized = toolName
|
|
463
1192
|
.normalize("NFKD")
|
|
@@ -467,6 +1196,17 @@ function pluginFunctionName(installationId, toolName) {
|
|
|
467
1196
|
const digest = createHash("sha256").update(toolName).digest("hex").slice(0, 16);
|
|
468
1197
|
return `plugin_${installationId}_${normalized || "tool"}_${digest}`;
|
|
469
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
|
+
}
|
|
470
1210
|
function pluginFunctionInstallationId(functionName) {
|
|
471
1211
|
const match = /^plugin_([a-z0-9]+)_/u.exec(functionName);
|
|
472
1212
|
return match?.[1];
|
|
@@ -581,4 +1321,34 @@ function errorMessage(error) {
|
|
|
581
1321
|
const message = error instanceof Error ? error.message : String(error);
|
|
582
1322
|
return message.slice(0, 4_000);
|
|
583
1323
|
}
|
|
1324
|
+
function preparedSummary(plugin, preparedToken, expiresAt) {
|
|
1325
|
+
const mcp = plugin.manifest.mcp;
|
|
1326
|
+
return {
|
|
1327
|
+
preparedToken,
|
|
1328
|
+
expiresAt: new Date(expiresAt).toISOString(),
|
|
1329
|
+
sourceKind: plugin.source.kind,
|
|
1330
|
+
sourceReference: plugin.source.reference,
|
|
1331
|
+
packageDigest: plugin.packageDigest,
|
|
1332
|
+
version: plugin.manifest.version,
|
|
1333
|
+
displayName: plugin.manifest.displayName,
|
|
1334
|
+
shortName: plugin.manifest.shortName,
|
|
1335
|
+
description: plugin.manifest.description,
|
|
1336
|
+
skills: plugin.skills.map(({ name, description }) => ({ name, description })),
|
|
1337
|
+
variables: plugin.manifest.variables,
|
|
1338
|
+
apiPermissions: pluginApiPermissionSections(effectiveContainer(plugin.manifest)?.permissions ?? []),
|
|
1339
|
+
...(mcp
|
|
1340
|
+
? {
|
|
1341
|
+
mcp: {
|
|
1342
|
+
type: mcp.type,
|
|
1343
|
+
container: mcp.type === "remote"
|
|
1344
|
+
? "none"
|
|
1345
|
+
: mcp.container
|
|
1346
|
+
? "bundled"
|
|
1347
|
+
: "selection_required",
|
|
1348
|
+
},
|
|
1349
|
+
}
|
|
1350
|
+
: {}),
|
|
1351
|
+
image: plugin.image,
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
584
1354
|
//# sourceMappingURL=service.js.map
|