happy2 0.0.9 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/package.json +7 -3
- package/packages/happy2-server/PLUGINS.md +402 -0
- package/packages/happy2-server/README.md +39 -0
- package/packages/happy2-server/dist/daemon.d.ts +39 -0
- package/packages/happy2-server/dist/daemon.d.ts.map +1 -0
- package/packages/happy2-server/dist/daemon.js +302 -0
- package/packages/happy2-server/dist/daemon.js.map +1 -0
- package/packages/happy2-server/dist/daemon.test.d.ts +2 -0
- package/packages/happy2-server/dist/daemon.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/daemon.test.js +245 -0
- package/packages/happy2-server/dist/daemon.test.js.map +1 -0
- package/packages/happy2-server/dist/index.d.ts +7 -1
- package/packages/happy2-server/dist/index.d.ts.map +1 -1
- package/packages/happy2-server/dist/index.js +5 -1
- package/packages/happy2-server/dist/index.js.map +1 -1
- package/packages/happy2-server/dist/modules/agents/daemon.d.ts +10 -13
- package/packages/happy2-server/dist/modules/agents/daemon.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agents/daemon.js +19 -5
- package/packages/happy2-server/dist/modules/agents/daemon.js.map +1 -1
- package/packages/happy2-server/dist/modules/agents/service.d.ts +9 -1
- package/packages/happy2-server/dist/modules/agents/service.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/agents/service.js +59 -2
- package/packages/happy2-server/dist/modules/agents/service.js.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.d.ts +7 -0
- package/packages/happy2-server/dist/modules/auth/tokens.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.js +33 -0
- package/packages/happy2-server/dist/modules/auth/tokens.js.map +1 -1
- package/packages/happy2-server/dist/modules/auth/tokens.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/auth/tokens.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/auth/tokens.test.js +28 -0
- package/packages/happy2-server/dist/modules/auth/tokens.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/chat/types.d.ts +1 -1
- package/packages/happy2-server/dist/modules/chat/types.d.ts.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 +5 -0
- package/packages/happy2-server/dist/modules/config/defaults.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 +9 -0
- package/packages/happy2-server/dist/modules/config/loader.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/loader.test.js +15 -0
- package/packages/happy2-server/dist/modules/config/loader.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/paths.d.ts +1 -0
- package/packages/happy2-server/dist/modules/config/paths.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/config/paths.js +1 -0
- package/packages/happy2-server/dist/modules/config/paths.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/paths.test.js +1 -0
- package/packages/happy2-server/dist/modules/config/paths.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/config/type.d.ts +5 -0
- package/packages/happy2-server/dist/modules/config/type.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/integrations/transport.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/integrations/transport.js +8 -1
- package/packages/happy2-server/dist/modules/integrations/transport.js.map +1 -1
- package/packages/happy2-server/dist/modules/integrations/types.d.ts +2 -0
- package/packages/happy2-server/dist/modules/integrations/types.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/integrations/types.js.map +1 -1
- package/packages/happy2-server/dist/modules/plugin/catalog.d.ts +13 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.js +400 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.test.js +172 -0
- package/packages/happy2-server/dist/modules/plugin/catalog.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/functions.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/functions.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/functions.test.js +123 -0
- package/packages/happy2-server/dist/modules/plugin/functions.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/httpBridge.d.ts +19 -0
- package/packages/happy2-server/dist/modules/plugin/httpBridge.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/httpBridge.js +206 -0
- package/packages/happy2-server/dist/modules/plugin/httpBridge.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.d.ts +3 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.js +47 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asInstallation.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.d.ts +3 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.js +82 -0
- package/packages/happy2-server/dist/modules/plugin/impl/asPlugin.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/effectiveContainer.d.ts +3 -0
- package/packages/happy2-server/dist/modules/plugin/impl/effectiveContainer.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/effectiveContainer.js +12 -0
- package/packages/happy2-server/dist/modules/plugin/impl/effectiveContainer.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.d.ts +288 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.js +19 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installationSelection.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.d.ts +3 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.js +63 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.js +17 -0
- package/packages/happy2-server/dist/modules/plugin/impl/installedManifest.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginFunctionResult.d.ts +3 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginFunctionResult.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginFunctionResult.js +16 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginFunctionResult.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginSelection.d.ts +339 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginSelection.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginSelection.js +22 -0
- package/packages/happy2-server/dist/modules/plugin/impl/pluginSelection.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/index.d.ts +3 -0
- package/packages/happy2-server/dist/modules/plugin/index.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/index.js +3 -0
- package/packages/happy2-server/dist/modules/plugin/index.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts +15 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.js +90 -0
- package/packages/happy2-server/dist/modules/plugin/packageStore.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.d.ts +7 -0
- package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.js +9 -0
- package/packages/happy2-server/dist/modules/plugin/pluginAuthorizeManagement.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.d.ts +9 -0
- package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.js +64 -0
- package/packages/happy2-server/dist/modules/plugin/pluginCatalogList.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceAuthorize.d.ts +10 -0
- package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceAuthorize.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceAuthorize.js +20 -0
- package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceAuthorize.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceInvalidate.d.ts +12 -0
- package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceInvalidate.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceInvalidate.js +44 -0
- package/packages/happy2-server/dist/modules/plugin/pluginContainerInstanceInvalidate.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.d.ts +9 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.js +15 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFindBySource.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultAcquire.d.ts +23 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultAcquire.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultAcquire.js +54 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultAcquire.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultComplete.d.ts +13 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultComplete.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultComplete.js +37 -0
- package/packages/happy2-server/dist/modules/plugin/pluginFunctionResultComplete.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginGetImage.d.ts +17 -0
- package/packages/happy2-server/dist/modules/plugin/pluginGetImage.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginGetImage.js +29 -0
- package/packages/happy2-server/dist/modules/plugin/pluginGetImage.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstall.d.ts +27 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstall.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstall.js +180 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstall.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.d.ts +9 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.js +122 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetRuntimeConfiguration.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetStatus.d.ts +11 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetStatus.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetStatus.js +18 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationGetStatus.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.d.ts +8 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.js +19 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationList.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListForHost.d.ts +14 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListForHost.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListForHost.js +20 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListForHost.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListIds.d.ts +7 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListIds.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListIds.js +13 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListIds.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListReadyMcpIds.d.ts +7 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListReadyMcpIds.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListReadyMcpIds.js +16 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationListReadyMcpIds.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationUpdateStatus.d.ts +16 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationUpdateStatus.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationUpdateStatus.js +38 -0
- package/packages/happy2-server/dist/modules/plugin/pluginInstallationUpdateStatus.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginList.d.ts +8 -0
- package/packages/happy2-server/dist/modules/plugin/pluginList.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginList.js +17 -0
- package/packages/happy2-server/dist/modules/plugin/pluginList.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsList.d.ts +11 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsList.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsList.js +43 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsList.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsListReady.d.ts +15 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsListReady.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsListReady.js +37 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsListReady.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsReplace.d.ts +16 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsReplace.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsReplace.js +71 -0
- package/packages/happy2-server/dist/modules/plugin/pluginMcpToolsReplace.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginRemoveMissingBuiltins.d.ts +14 -0
- package/packages/happy2-server/dist/modules/plugin/pluginRemoveMissingBuiltins.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/pluginRemoveMissingBuiltins.js +51 -0
- package/packages/happy2-server/dist/modules/plugin/pluginRemoveMissingBuiltins.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/runtime.d.ts +56 -0
- package/packages/happy2-server/dist/modules/plugin/runtime.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/runtime.js +147 -0
- package/packages/happy2-server/dist/modules/plugin/runtime.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/secrets.d.ts +17 -0
- package/packages/happy2-server/dist/modules/plugin/secrets.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/secrets.js +56 -0
- package/packages/happy2-server/dist/modules/plugin/secrets.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/secrets.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/secrets.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/secrets.test.js +14 -0
- package/packages/happy2-server/dist/modules/plugin/secrets.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/service.d.ts +60 -0
- package/packages/happy2-server/dist/modules/plugin/service.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/service.js +584 -0
- package/packages/happy2-server/dist/modules/plugin/service.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/types.d.ts +194 -0
- package/packages/happy2-server/dist/modules/plugin/types.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/types.js +10 -0
- package/packages/happy2-server/dist/modules/plugin/types.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.d.ts +19 -0
- package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.js +97 -0
- package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.test.js +74 -0
- package/packages/happy2-server/dist/modules/plugin/utils/ndjsonStreamTransport.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.d.ts +29 -0
- package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.js +126 -0
- package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.js.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.test.d.ts +2 -0
- package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.test.js +75 -0
- package/packages/happy2-server/dist/modules/plugin/utils/remoteMcpTransport.test.js.map +1 -0
- package/packages/happy2-server/dist/modules/sandbox/index.d.ts +1 -1
- package/packages/happy2-server/dist/modules/sandbox/index.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.d.ts +9 -1
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.js +218 -4
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.js.map +1 -1
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.test.js +157 -2
- package/packages/happy2-server/dist/modules/sandbox/localOciSandboxProvider.test.js.map +1 -1
- package/packages/happy2-server/dist/modules/sandbox/types.d.ts +24 -0
- package/packages/happy2-server/dist/modules/sandbox/types.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/schema.d.ts +7781 -5489
- package/packages/happy2-server/dist/modules/schema.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/schema.js +87 -1
- package/packages/happy2-server/dist/modules/schema.js.map +1 -1
- package/packages/happy2-server/dist/modules/sync/syncGetDifference.d.ts.map +1 -1
- package/packages/happy2-server/dist/modules/sync/syncGetDifference.js +2 -0
- package/packages/happy2-server/dist/modules/sync/syncGetDifference.js.map +1 -1
- package/packages/happy2-server/dist/routes/pluginHost.d.ts +6 -0
- package/packages/happy2-server/dist/routes/pluginHost.d.ts.map +1 -0
- package/packages/happy2-server/dist/routes/pluginHost.js +37 -0
- package/packages/happy2-server/dist/routes/pluginHost.js.map +1 -0
- package/packages/happy2-server/dist/routes/plugins.d.ts +8 -0
- package/packages/happy2-server/dist/routes/plugins.d.ts.map +1 -0
- package/packages/happy2-server/dist/routes/plugins.js +198 -0
- package/packages/happy2-server/dist/routes/plugins.js.map +1 -0
- package/packages/happy2-server/dist/runner.js +64 -19
- package/packages/happy2-server/dist/runner.js.map +1 -1
- package/packages/happy2-server/dist/server.d.ts +8 -0
- package/packages/happy2-server/dist/server.d.ts.map +1 -1
- package/packages/happy2-server/dist/server.js +65 -3
- package/packages/happy2-server/dist/server.js.map +1 -1
- package/packages/happy2-server/dist/systemService.d.ts +48 -0
- package/packages/happy2-server/dist/systemService.d.ts.map +1 -0
- package/packages/happy2-server/dist/systemService.js +323 -0
- package/packages/happy2-server/dist/systemService.js.map +1 -0
- package/packages/happy2-server/dist/systemService.test.d.ts +2 -0
- package/packages/happy2-server/dist/systemService.test.d.ts.map +1 -0
- package/packages/happy2-server/dist/systemService.test.js +280 -0
- package/packages/happy2-server/dist/systemService.test.js.map +1 -0
- package/packages/happy2-server/dist/web/assets/index-9SGCQLg7.js +46 -0
- package/packages/happy2-server/dist/web/assets/{index-DZ1uRLgV.css → index-DWXBQDJB.css} +1 -1
- package/packages/happy2-server/dist/web/index.html +2 -2
- package/packages/happy2-server/drizzle/0020_plugins.sql +61 -0
- package/packages/happy2-server/drizzle/0021_plugin_function_results.sql +11 -0
- package/packages/happy2-server/drizzle/0022_plugin_container_runtime_tools.sql +16 -0
- package/packages/happy2-server/drizzle/meta/_journal.json +21 -0
- package/packages/happy2-server/happy2.example.toml +13 -0
- package/packages/happy2-server/plugins/README.md +7 -0
- package/packages/happy2-server/plugins/hello/container/Dockerfile +6 -0
- package/packages/happy2-server/plugins/hello/plugin.json +16 -0
- package/packages/happy2-server/plugins/hello/plugin.png +0 -0
- package/packages/happy2-server/plugins/hello/server.mjs +75 -0
- package/packages/happy2-server/plugins/hello/skills/hello/SKILL.md +11 -0
- package/packages/happy2-server/dist/web/assets/index-DH1SOwNV.js +0 -46
package/README.md
CHANGED
|
@@ -49,6 +49,35 @@ Open [http://127.0.0.1:3000](http://127.0.0.1:3000) in your browser. Happy (2)
|
|
|
49
49
|
stores its database, files, generated secrets, agent workspaces, and private Rig
|
|
50
50
|
runtime under `.happy2` in the directory where you start it.
|
|
51
51
|
|
|
52
|
+
Run it in the background without installing an operating-system service with:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npx happy2 daemon start
|
|
56
|
+
npx happy2 daemon stop
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The daemon stores `happy2.pid` and `happy2.log` under `./.happy2`. Stopping it
|
|
60
|
+
terminates the daemon process tree and removes the PID file.
|
|
61
|
+
|
|
62
|
+
Keep Happy (2) running across reboots with:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
npx happy2 service start
|
|
66
|
+
npx happy2 service stop
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
On macOS this installs a per-user LaunchAgent without `sudo`; it starts when the
|
|
70
|
+
user logs in. On Linux it writes and prints `./happy2.service`, then shows the
|
|
71
|
+
exact `sudo` commands you can run to install and start it as a system-wide
|
|
72
|
+
systemd unit. `service stop` prints the corresponding systemd removal commands;
|
|
73
|
+
it never invokes `sudo` itself. The generated file remains in the current
|
|
74
|
+
directory so you can inspect or reinstall it. Add
|
|
75
|
+
`--config /absolute/or/relative/happy2.toml` to `service start` to preserve an
|
|
76
|
+
explicit configuration file; otherwise the service keeps the current directory
|
|
77
|
+
as its working directory and uses its `.happy2` state. When started through
|
|
78
|
+
`npx`, the generated service runs `npx --yes happy2` instead of depending on an
|
|
79
|
+
evictable `_npx` cache path.
|
|
80
|
+
|
|
52
81
|
## Why Happy (2)?
|
|
53
82
|
|
|
54
83
|
- **People and agents share the same workspace.** Conversations, threads,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "happy2",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Happy (2) desktop web app and server bundle",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
"packages/happy2-server/bin/happy2.js",
|
|
14
14
|
"packages/happy2-server/dist",
|
|
15
15
|
"packages/happy2-server/drizzle",
|
|
16
|
+
"packages/happy2-server/plugins",
|
|
16
17
|
"packages/happy2-server/happy2.example.toml",
|
|
17
18
|
"packages/happy2-server/README.md",
|
|
19
|
+
"packages/happy2-server/PLUGINS.md",
|
|
18
20
|
"packages/happy2-server/Dockerfile"
|
|
19
21
|
],
|
|
20
22
|
"type": "module",
|
|
@@ -67,15 +69,17 @@
|
|
|
67
69
|
"@fastify/multipart": "^10.1.0",
|
|
68
70
|
"@fastify/static": "^10.1.0",
|
|
69
71
|
"@libsql/client": "^0.17.4",
|
|
72
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
70
73
|
"@paralleldrive/cuid2": "^3.3.0",
|
|
71
|
-
"@slopus/rig": "^0.0.
|
|
74
|
+
"@slopus/rig": "^0.0.24",
|
|
72
75
|
"drizzle-orm": "^0.45.2",
|
|
73
76
|
"fastify": "^5.8.2",
|
|
74
77
|
"jose": "^6.1.3",
|
|
75
78
|
"nodemailer": "^7.0.13",
|
|
76
79
|
"sharp": "^0.35.3",
|
|
77
80
|
"smol-toml": "^1.4.2",
|
|
78
|
-
"thumbhash": "^0.1.1"
|
|
81
|
+
"thumbhash": "^0.1.1",
|
|
82
|
+
"yaml": "^2.9.0"
|
|
79
83
|
},
|
|
80
84
|
"devDependencies": {
|
|
81
85
|
"@eslint/css": "^1.4.0",
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
# Server plugins
|
|
2
|
+
|
|
3
|
+
Happy (2) plugins package Agent Skills, a persistent container command, an MCP
|
|
4
|
+
server, or any useful combination of those pieces. This first
|
|
5
|
+
server-side implementation installs only packages bundled with the server. It
|
|
6
|
+
already keeps catalog discovery, durable system plugins, immutable package/image
|
|
7
|
+
snapshots, and independent runtime installations separate so a later remote
|
|
8
|
+
catalog/download step can reuse the same boundaries.
|
|
9
|
+
|
|
10
|
+
Plugin management is system-wide and administrator-only. The first installation
|
|
11
|
+
of a catalog package creates one durable system-plugin record and one immutable
|
|
12
|
+
package snapshot; later installations reuse that plugin identity and snapshot.
|
|
13
|
+
Every installation has its own CUID2, variables, selected image, lifecycle, and
|
|
14
|
+
dedicated container when it has a local runtime. Remote MCP configuration is
|
|
15
|
+
persisted and health-checked independently per installation. Ready MCP
|
|
16
|
+
installations expose their durably cached tools to Rig as external functions on
|
|
17
|
+
every agent submission. Happy executes each durable call against the originating
|
|
18
|
+
installation and resolves the result back into the paused Rig run. This feature
|
|
19
|
+
does not yet inject installed skills, and it does not yet implement upgrade,
|
|
20
|
+
uninstall, marketplace download, or OAuth flows.
|
|
21
|
+
|
|
22
|
+
MCP tools are discovered during each runtime activation and atomically replace
|
|
23
|
+
that installation's SQLite cache before it becomes ready. Local discovery runs
|
|
24
|
+
after every container creation, and remote discovery runs on every server
|
|
25
|
+
restart. Rig function discovery reads only this cache rather than opening every
|
|
26
|
+
MCP server again per submission. Each discovery page is bounded to 15
|
|
27
|
+
seconds, and one MCP tool execution is bounded to 30 seconds so a stalled plugin
|
|
28
|
+
cannot indefinitely block turn submission or Rig's global event consumer. Before
|
|
29
|
+
execution, Happy claims a 45-second database lease keyed by Rig session and call
|
|
30
|
+
ID. Other server instances wait for that lease or replay its completed result
|
|
31
|
+
instead of concurrently invoking the same tool. The first terminal outcome,
|
|
32
|
+
including an MCP error or timeout, is persisted and reused for every later event
|
|
33
|
+
delivery; Happy does not automatically retry an ambiguous failure because the
|
|
34
|
+
first request may already have produced an external side effect. A process crash
|
|
35
|
+
after the MCP side effect but before the outcome is committed can still cause one
|
|
36
|
+
lease-expiry replay, so plugin tools with external side effects should themselves
|
|
37
|
+
be idempotent.
|
|
38
|
+
|
|
39
|
+
Rig sessions use Full access so durable external functions are executable without
|
|
40
|
+
an unresolved permission prompt. Agent code still runs inside Happy's dedicated,
|
|
41
|
+
restricted OCI sandbox; plugin processes remain isolated in their own containers,
|
|
42
|
+
and only Happy crosses the boundary after matching the durable function identity
|
|
43
|
+
to a ready installation.
|
|
44
|
+
|
|
45
|
+
## Package anatomy
|
|
46
|
+
|
|
47
|
+
Each built-in package is a directory below `packages/happy2-server/plugins`:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
example-plugin/
|
|
51
|
+
├── plugin.json
|
|
52
|
+
├── plugin.png
|
|
53
|
+
├── container/ # optional; used by bundled stdio runtimes
|
|
54
|
+
│ └── Dockerfile
|
|
55
|
+
└── skills/ # optional
|
|
56
|
+
└── example-skill/
|
|
57
|
+
├── SKILL.md
|
|
58
|
+
├── scripts/ # optional Agent Skills resources
|
|
59
|
+
├── references/
|
|
60
|
+
└── assets/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`plugin.png` is required and must be a square PNG no larger than 4096×4096. A
|
|
64
|
+
1024×1024 source is preferred; smaller square icons remain valid. Catalog
|
|
65
|
+
validation calculates its byte size, dimensions, SHA-256 checksum, and
|
|
66
|
+
thumbhash. When the plugin first enters the system, those fields are persisted
|
|
67
|
+
on the plugin record and the exact PNG remains in the private package snapshot
|
|
68
|
+
on the filesystem.
|
|
69
|
+
|
|
70
|
+
Every direct child of `skills/` must follow the
|
|
71
|
+
[Agent Skills specification](https://agentskills.io/specification). In
|
|
72
|
+
particular, it needs `SKILL.md` with YAML frontmatter containing `name` and
|
|
73
|
+
`description`; `name` must match the skill directory. Package loading rejects
|
|
74
|
+
symlinks, unsafe relative paths, duplicate names, oversized packages, malformed
|
|
75
|
+
frontmatter, and unexpected manifest fields before the catalog becomes
|
|
76
|
+
available.
|
|
77
|
+
|
|
78
|
+
`plugin.json` uses schema version 1:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"schemaVersion": 1,
|
|
83
|
+
"version": "1.2.3",
|
|
84
|
+
"displayName": "Project Search",
|
|
85
|
+
"shortName": "project-search",
|
|
86
|
+
"description": "Searches source code and project documentation.",
|
|
87
|
+
"variables": [
|
|
88
|
+
{
|
|
89
|
+
"key": "PROJECT_API_TOKEN",
|
|
90
|
+
"displayName": "API token",
|
|
91
|
+
"description": "Token used by the MCP server.",
|
|
92
|
+
"kind": "secret"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"key": "PROJECT_REGION",
|
|
96
|
+
"displayName": "Region",
|
|
97
|
+
"description": "Region used for project queries.",
|
|
98
|
+
"kind": "text"
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"container": {
|
|
102
|
+
"dockerfile": "container/Dockerfile",
|
|
103
|
+
"command": "/plugin/bin/indexer",
|
|
104
|
+
"args": ["--watch"],
|
|
105
|
+
"permissions": ["plugins:list"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`version` uses `x.y.z` SemVer syntax. `shortName` is the stable catalog/package
|
|
111
|
+
link and must match the package directory; it is not an installation identity.
|
|
112
|
+
The durable system plugin and every installation receive separate CUID2 IDs.
|
|
113
|
+
Variable keys are environment variable names. Every declared variable is
|
|
114
|
+
required for each installation. Secret values are encrypted with AES-256-GCM
|
|
115
|
+
and are never returned by catalog or installation reads; text values are stored
|
|
116
|
+
as ordinary configuration. Both kinds are supplied to configured local
|
|
117
|
+
processes as environment variables.
|
|
118
|
+
|
|
119
|
+
A package must contain at least one skill, `container`, or `mcp` definition.
|
|
120
|
+
`container.command` is optional when the same container exposes a stdio MCP;
|
|
121
|
+
otherwise it is required. A command and stdio MCP run alongside each other in
|
|
122
|
+
the same dedicated installation container. Container variables are supplied to
|
|
123
|
+
each configured process, not persisted in the image or container definition.
|
|
124
|
+
|
|
125
|
+
`container.permissions` is an exact allowlist of host API capabilities. The
|
|
126
|
+
currently supported permission is `plugins:list`. Unknown and duplicate
|
|
127
|
+
permissions are rejected when the package is loaded.
|
|
128
|
+
|
|
129
|
+
The bundled `hello` package is the minimal skill-plus-MCP example. It declares no
|
|
130
|
+
variables or MCP authentication, so an administrator can install it with an
|
|
131
|
+
empty POST body; each call still creates a separate installation and bundled
|
|
132
|
+
container.
|
|
133
|
+
|
|
134
|
+
## Stdio MCP with a bundled container
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"mcp": {
|
|
139
|
+
"type": "stdio",
|
|
140
|
+
"command": "/plugin/bin/project-mcp",
|
|
141
|
+
"args": ["--stdio"]
|
|
142
|
+
},
|
|
143
|
+
"container": {
|
|
144
|
+
"dockerfile": "container/Dockerfile",
|
|
145
|
+
"args": [],
|
|
146
|
+
"permissions": []
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The Dockerfile path is package-relative. Creating the durable system plugin
|
|
152
|
+
copies the entire package once to `plugins.directory` before writing its
|
|
153
|
+
database record. Each installation lifecycle builds or resolves that exact
|
|
154
|
+
snapshot with the selected local Docker or Podman provider, using a
|
|
155
|
+
content-addressed `happy2-plugin:<sha256>` tag. It then creates a dedicated,
|
|
156
|
+
read-only container named from the installation CUID2, with `init`, all Linux capabilities
|
|
157
|
+
dropped, privilege escalation disabled, bounded shared memory, and ephemeral
|
|
158
|
+
`/tmp` and `/run` filesystems. Runtime resources are capped at 1 GiB of memory,
|
|
159
|
+
one CPU, and 256 processes per plugin container.
|
|
160
|
+
|
|
161
|
+
The resulting image must provide `/bin/sh`; Happy uses it only as the inert
|
|
162
|
+
container keepalive before starting the manifest command with OCI `exec`. A
|
|
163
|
+
bundled Dockerfile is responsible for copying or installing its MCP executable
|
|
164
|
+
and dependencies into the image. The MCP command itself must use newline-
|
|
165
|
+
delimited JSON-RPC on stdin/stdout and must not write non-protocol output to
|
|
166
|
+
stdout.
|
|
167
|
+
The fixed `HOME`, `TMPDIR`, and working directory are `/tmp`, so tools that
|
|
168
|
+
need a cache can still run without making the image root writable.
|
|
169
|
+
|
|
170
|
+
Each installation container stays alive as that installation's plugin runtime.
|
|
171
|
+
The optional persistent command is started detached once for each container
|
|
172
|
+
incarnation and monitored through a PID marker in the container's ephemeral
|
|
173
|
+
`/run`. Server restart recovery adopts and resumes monitoring that same command
|
|
174
|
+
without double-starting it. Each HTTP MCP session starts
|
|
175
|
+
the configured command with `docker exec`/`podman exec`; variables reach that
|
|
176
|
+
process through Docker/Podman's environment-copy option. Values are never placed
|
|
177
|
+
in command arguments, Happy's process environment, the long-lived container
|
|
178
|
+
definition, or the image build; they exist only in the short-lived OCI CLI child
|
|
179
|
+
and the target persistent-command or MCP process. Variables that could alter the OCI client itself, such as
|
|
180
|
+
`DOCKER_*`, proxy, loader, or executable-path settings, are rejected. Happy
|
|
181
|
+
transparently bridges newline-delimited stdio JSON-RPC to MCP Streamable HTTP, so
|
|
182
|
+
the plugin itself does not need an HTTP server.
|
|
183
|
+
|
|
184
|
+
## Stdio MCP using a selected container image
|
|
185
|
+
|
|
186
|
+
Omit `container.dockerfile` when the plugin does not bundle its own Dockerfile:
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"container": {
|
|
191
|
+
"args": [],
|
|
192
|
+
"permissions": []
|
|
193
|
+
},
|
|
194
|
+
"mcp": {
|
|
195
|
+
"type": "stdio",
|
|
196
|
+
"command": "npx",
|
|
197
|
+
"args": ["-y", "@example/project-mcp"]
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The install request must then include `containerImageId`. It must identify an
|
|
203
|
+
agent image whose build status is already `ready`. The selected image belongs
|
|
204
|
+
only to that installation and creates that installation's dedicated container;
|
|
205
|
+
it does not share an agent container or another plugin installation's container.
|
|
206
|
+
|
|
207
|
+
## Remote MCP
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"mcp": {
|
|
212
|
+
"type": "remote",
|
|
213
|
+
"url": "https://mcp.example.com/mcp",
|
|
214
|
+
"headers": {
|
|
215
|
+
"Authorization": "Bearer ${PROJECT_API_TOKEN}",
|
|
216
|
+
"X-Project-Region": "${PROJECT_REGION}"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Remote URLs must be public HTTPS URLs without embedded credentials or fragments.
|
|
223
|
+
Header templates may reference only declared variables. The health worker
|
|
224
|
+
resolves templates in memory, rejects newline-bearing resolved values, applies
|
|
225
|
+
the same public-address/DNS-rebinding policy used by outgoing webhooks, pins the
|
|
226
|
+
approved destination address, and sends an MCP `initialize` request. The remote
|
|
227
|
+
URL and templates are persisted; resolved secret headers are not.
|
|
228
|
+
|
|
229
|
+
Remote MCP remains remote: Happy does not create a container or proxy its normal
|
|
230
|
+
traffic. OAuth is intentionally unsupported. Authentication is limited to the
|
|
231
|
+
custom static headers described above. Production remote requests are capped at
|
|
232
|
+
1,000,000 bytes and responses at 256,000 bytes, matching the bounded webhook
|
|
233
|
+
transport used for SSRF-safe address pinning.
|
|
234
|
+
|
|
235
|
+
## Installation and lifecycle
|
|
236
|
+
|
|
237
|
+
`POST /v0/admin/plugins/:shortName/installPlugin` accepts:
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"variables": {
|
|
242
|
+
"PROJECT_API_TOKEN": "secret value",
|
|
243
|
+
"PROJECT_REGION": "us-west"
|
|
244
|
+
},
|
|
245
|
+
"containerImageId": "optional-ready-image-id"
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The request body may be omitted when the manifest declares no variables and
|
|
250
|
+
does not require a selected container image.
|
|
251
|
+
|
|
252
|
+
`containerImageId` is required for every local container manifest without a
|
|
253
|
+
bundled Dockerfile, and it is rejected in every other case. Unknown, missing, empty, or
|
|
254
|
+
oversized variable values are rejected. The endpoint returns HTTP 202 after the
|
|
255
|
+
durable system plugin (created once), immutable package/image snapshot, new
|
|
256
|
+
installation, variables, audit entry, initial state, and sync event are durable.
|
|
257
|
+
Calling it again for the same `shortName` creates another installation with a
|
|
258
|
+
new CUID2 and its own parameters and runtime. Container preparation continues
|
|
259
|
+
asynchronously.
|
|
260
|
+
|
|
261
|
+
If the catalog later advertises an update, additional installations remain
|
|
262
|
+
pinned to the existing system plugin's immutable manifest and package until an
|
|
263
|
+
explicit upgrade action exists. Catalog reads therefore project the stored
|
|
264
|
+
variable and MCP requirements for the install form while retaining the newer
|
|
265
|
+
catalog version and `updateAvailable` indicator.
|
|
266
|
+
|
|
267
|
+
An installation has one of these durable health states:
|
|
268
|
+
|
|
269
|
+
- `preparing`: copying/reconciling package and image/container state.
|
|
270
|
+
- `starting`: the container exists or remote endpoint is selected and MCP
|
|
271
|
+
initialization/health checking is in progress.
|
|
272
|
+
- `ready`: a container-only command survived its startup probe; or a local or
|
|
273
|
+
remote MCP server completed initialization, ping, and durable tool discovery.
|
|
274
|
+
A skills-only plugin becomes ready immediately
|
|
275
|
+
after its durable install.
|
|
276
|
+
- `broken_configuration`: stored variables, selected image state, manifest
|
|
277
|
+
material, or resolved headers cannot form a valid runtime configuration.
|
|
278
|
+
- `failed`: package integrity, image build, container creation, process startup,
|
|
279
|
+
protocol health, DNS, or network execution failed. `lastError` contains bounded
|
|
280
|
+
diagnostic text.
|
|
281
|
+
|
|
282
|
+
Every transition updates `plugin_installations`, appends a `plugin.*` sync
|
|
283
|
+
event, and publishes the normal server SSE hint with the `plugins` area. Clients
|
|
284
|
+
must reconcile the durable catalog after a hint; the event itself is not state.
|
|
285
|
+
On server restart, every installation is reconciled again. Its package path and
|
|
286
|
+
SHA-256 digest are revalidated first; a running local container with matching
|
|
287
|
+
installation and incarnation labels is adopted, otherwise it is recreated from
|
|
288
|
+
the installed snapshot. Adopted persistent commands resume liveness monitoring.
|
|
289
|
+
Remote endpoints are rechecked.
|
|
290
|
+
|
|
291
|
+
## Read and MCP endpoints
|
|
292
|
+
|
|
293
|
+
- `GET /v0/admin/plugins` lists the validated built-in catalog, requirements,
|
|
294
|
+
skill summaries, and MCP/container mode. When a catalog package exists in the
|
|
295
|
+
system, `systemPlugin` contains its CUID2, persisted image metadata and URL,
|
|
296
|
+
`updateAvailable`, and every independent installation with current health. It
|
|
297
|
+
requires an active server administrator and never returns configured values.
|
|
298
|
+
- `GET /v0/admin/plugins/:shortName/icon` returns the package PNG to an active
|
|
299
|
+
server administrator using the catalog link.
|
|
300
|
+
- `GET /v0/admin/systemPlugins` lists persisted system plugins independently of
|
|
301
|
+
the catalog, including image metadata and every linked installation.
|
|
302
|
+
- `GET /v0/admin/systemPlugins/:pluginId/image` returns the persisted system
|
|
303
|
+
plugin PNG from its private filesystem snapshot after validating the package
|
|
304
|
+
digest, storage key, byte size, and image checksum.
|
|
305
|
+
- `POST /v0/admin/plugins/:shortName/installPlugin` performs the durable install
|
|
306
|
+
and queues lifecycle work. It may be called any number of times; each call
|
|
307
|
+
creates a distinct installation linked to the same system plugin.
|
|
308
|
+
- `GET|POST /v0/pluginInstallations/:installationId/mcp` is the authenticated
|
|
309
|
+
Streamable HTTP bridge for one ready local stdio installation. It follows MCP
|
|
310
|
+
session semantics via `Mcp-Session-Id`. Happy’s existing bearer session is
|
|
311
|
+
required; there is no plugin-specific OAuth exchange.
|
|
312
|
+
- `GET /v0/admin/pluginInstallations/:installationId/mcpTools` returns the last
|
|
313
|
+
successfully synchronized MCP tool schemas from SQLite. It never contacts the
|
|
314
|
+
MCP server. Tool discovery is replaced atomically on every runtime activation,
|
|
315
|
+
including each server restart.
|
|
316
|
+
- `GET /plugins` on the dedicated plugin host listener is the first
|
|
317
|
+
capability-scoped host API. It is deliberately absent from the product API
|
|
318
|
+
listener. A
|
|
319
|
+
container may call it only when its manifest grants `plugins:list` and it
|
|
320
|
+
presents the incarnation token supplied as `HAPPY2_PLUGIN_API_TOKEN`.
|
|
321
|
+
|
|
322
|
+
Container processes receive `HAPPY2_PLUGIN_API_URL` and
|
|
323
|
+
`HAPPY2_PLUGIN_API_TOKEN`. The URL is always
|
|
324
|
+
`http://happy2.host.internal:<plugins.host_api_port>`; the hardened container
|
|
325
|
+
adds `happy2.host.internal:host-gateway`, while the capability-only listener
|
|
326
|
+
binds `plugins.host_api_host` on that fixed port. HTTP/TCP and the OCI
|
|
327
|
+
`host-gateway` mapping work across Docker and Podman on macOS and Linux.
|
|
328
|
+
The cross-platform default bind is `0.0.0.0` because a loopback bind is not
|
|
329
|
+
reachable through Docker Desktop's or Podman's host gateway. Operators who
|
|
330
|
+
expose the host to an untrusted LAN should firewall
|
|
331
|
+
`plugins.host_api_port`; it is a container capability endpoint, not a public
|
|
332
|
+
service.
|
|
333
|
+
|
|
334
|
+
The token is an RS256 capability containing the installation ID, a random CUID2
|
|
335
|
+
container-incarnation ID, and the exact manifest permissions. Token bytes are
|
|
336
|
+
never stored. The incarnation ID is stored in `plugin_installations` and also
|
|
337
|
+
attached to the OCI container as `dev.happy2.plugin-instance`. On each request,
|
|
338
|
+
Happy verifies the signature, matches the incarnation against the ready database
|
|
339
|
+
row, and confirms that the correspondingly labelled container is running. A
|
|
340
|
+
stopped, missing, or replaced container therefore receives 403. A surviving
|
|
341
|
+
container and its token remain valid after a server restart; startup adopts the
|
|
342
|
+
matching container and refreshes its MCP tool cache instead of recreating it.
|
|
343
|
+
The token intentionally has no time expiration: its lifetime is exactly the
|
|
344
|
+
database-and-OCI incarnation lifetime, allowing a command to survive arbitrarily
|
|
345
|
+
many server restarts without persisting or rotating token bytes. Killing,
|
|
346
|
+
replacing, failing, or removing that incarnation immediately makes the token
|
|
347
|
+
unauthorized.
|
|
348
|
+
The capability is not a user session and the dedicated listener exposes no
|
|
349
|
+
ordinary `/v0` APIs.
|
|
350
|
+
|
|
351
|
+
The bridge allows at most 128 simultaneous sessions server-wide and 16 per
|
|
352
|
+
authenticated user. Idle sessions close after 15 minutes; inbound requests and
|
|
353
|
+
outbound server messages both renew that lifetime. A session is bound to the
|
|
354
|
+
authenticated user who initialized it and cannot be reused by another user.
|
|
355
|
+
|
|
356
|
+
Only GET and POST are exposed. MCP session DELETE is optional in the protocol
|
|
357
|
+
and is not enabled by this API; server shutdown and transport closure clean up
|
|
358
|
+
processes and sessions.
|
|
359
|
+
|
|
360
|
+
## Persistence and future upgrades
|
|
361
|
+
|
|
362
|
+
`plugins` records the durable CUID2, catalog short name, display metadata, source
|
|
363
|
+
kind/reference and installed version, package SHA-256 digest, exact manifest,
|
|
364
|
+
persistent snapshot directory, installer, and timestamps. Its image columns
|
|
365
|
+
persist the filesystem storage key, content type, byte size, width, height,
|
|
366
|
+
thumbhash, and SHA-256 checksum.
|
|
367
|
+
|
|
368
|
+
`plugin_installations` records a separate CUID2 and foreign key to `plugins`,
|
|
369
|
+
plus that instance's container/image choice, lifecycle state, error detail,
|
|
370
|
+
installer, tool-sync timestamp, and timestamps. `plugin_mcp_tools` contains the
|
|
371
|
+
last complete MCP discovery keyed by installation and tool name.
|
|
372
|
+
`plugin_installation_variables` records each declared
|
|
373
|
+
value for one installation; secret rows contain authenticated ciphertext rather
|
|
374
|
+
than plaintext. No installation uses `shortName` as identity.
|
|
375
|
+
|
|
376
|
+
The built-in catalog and durable system plugin are deliberately independent.
|
|
377
|
+
Persisted rows use `source_kind = 'builtin'` as their built-in marker. During
|
|
378
|
+
startup, the server compares those rows with the current built-in catalog. If a
|
|
379
|
+
bundle was removed from the server, its installations, encrypted variables,
|
|
380
|
+
system-plugin row, private package/image snapshot, and any named local containers
|
|
381
|
+
are removed before the remaining runtimes start. Remotely sourced plugins will
|
|
382
|
+
not participate in this catalog-pruning rule.
|
|
383
|
+
|
|
384
|
+
When the catalog contains a different digest for a persisted plugin's
|
|
385
|
+
`shortName`, reads set `updateAvailable: true`; they do not mutate or restart its
|
|
386
|
+
installations. A future upgrade action can download/validate a remote package
|
|
387
|
+
into the same package abstraction, stage a new immutable package/image snapshot,
|
|
388
|
+
and atomically replace the system plugin version before reconciling all linked
|
|
389
|
+
installations. Until that action exists, upgrades are advertised only and the
|
|
390
|
+
old snapshot continues to run.
|
|
391
|
+
|
|
392
|
+
Configured installed-package storage:
|
|
393
|
+
|
|
394
|
+
```toml
|
|
395
|
+
[plugins]
|
|
396
|
+
directory = "/var/lib/happy2/plugins"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
The directory must be persistent and private. Plugin variables share the
|
|
400
|
+
server’s generated recoverable-secret master key but use a plugin-specific
|
|
401
|
+
authenticated-encryption context bound to the installation ID and variable key,
|
|
402
|
+
so ciphertext cannot be replayed across integrations, installations, or fields.
|
|
@@ -14,6 +14,14 @@ npx happy2-server --config ./happy2.toml
|
|
|
14
14
|
# Published all-in-one web app and API on http://127.0.0.1:3000
|
|
15
15
|
npx happy2
|
|
16
16
|
|
|
17
|
+
# Install or remove automatic startup for the all-in-one app
|
|
18
|
+
npx happy2 service start --config ./happy2.toml
|
|
19
|
+
npx happy2 service stop
|
|
20
|
+
|
|
21
|
+
# Start or stop it as a background process in the current directory
|
|
22
|
+
npx happy2 daemon start --config ./happy2.toml
|
|
23
|
+
npx happy2 daemon stop
|
|
24
|
+
|
|
17
25
|
# Development, with reload and no configuration file:
|
|
18
26
|
pnpm dev:server
|
|
19
27
|
|
|
@@ -46,6 +54,34 @@ package never connects to the user's global Rig daemon. Provide
|
|
|
46
54
|
`--config /path/to/happy2.toml` or
|
|
47
55
|
`HAPPY2_CONFIG=/path/to/happy2.toml` to override the defaults.
|
|
48
56
|
|
|
57
|
+
`happy2 service start` keeps the all-in-one app running across restarts. On
|
|
58
|
+
macOS it installs `~/Library/LaunchAgents/com.slopus.happy2.plist` without
|
|
59
|
+
`sudo`, starts at login, and writes logs under `~/Library/Logs/Happy2`. On Linux
|
|
60
|
+
it writes `happy2.service` in the current directory, prints the complete unit,
|
|
61
|
+
and prints the exact `sudo install` and `systemctl` commands required to install
|
|
62
|
+
and enable it. The command never invokes `sudo`. The Linux unit is system-wide
|
|
63
|
+
but runs the process as the user who generated it; logs go to the systemd
|
|
64
|
+
journal. The generated file remains in the current directory for inspection or
|
|
65
|
+
reinstallation. `happy2 service stop` directly stops and removes the macOS LaunchAgent,
|
|
66
|
+
while on Linux it prints the `sudo` commands that stop, disable, and remove the
|
|
67
|
+
systemd unit.
|
|
68
|
+
|
|
69
|
+
`happy2 daemon start` starts the all-in-one app in a detached process group and
|
|
70
|
+
returns immediately. It writes `.happy2/happy2.pid` and appends output to
|
|
71
|
+
`.happy2/happy2.log` in the current directory. `happy2 daemon stop` sends the
|
|
72
|
+
whole process group a graceful termination signal, force-stops it if necessary,
|
|
73
|
+
and removes the PID file. Unlike `service start`, daemon mode does not arrange
|
|
74
|
+
automatic startup after a login or reboot.
|
|
75
|
+
|
|
76
|
+
The service preserves the installation-time working directory, `PATH`, and
|
|
77
|
+
optional `RIG_HOME`. When `--config` is supplied, its path is made
|
|
78
|
+
absolute before installation. Put service secrets and SMTP environment values
|
|
79
|
+
in the private `.env` beside the TOML configuration rather than expecting an
|
|
80
|
+
interactive shell environment to exist during boot. An npx invocation generates
|
|
81
|
+
a service that runs `npx --yes happy2`, avoiding a dependency on the disposable
|
|
82
|
+
`_npx` cache directory. A global installation resolves `happy2` from the saved
|
|
83
|
+
`PATH`; regenerate and reinstall the service after changing that path.
|
|
84
|
+
|
|
49
85
|
Clients can discover the selected authentication method at `GET /v0/auth/methods`.
|
|
50
86
|
The response includes the server role, the durable `registration` availability
|
|
51
87
|
(`bootstrap`, `open`, or `closed`), and one `method` value: `password`,
|
|
@@ -53,6 +89,9 @@ The response includes the server role, the durable `registration` availability
|
|
|
53
89
|
Password responses also report the derived `signupEnabled`; OIDC responses report
|
|
54
90
|
`oidcProvider`.
|
|
55
91
|
|
|
92
|
+
The built-in plugin package, installation, container lifecycle, health, and MCP
|
|
93
|
+
HTTP contracts are documented in [`PLUGINS.md`](./PLUGINS.md).
|
|
94
|
+
|
|
56
95
|
## Server and user onboarding
|
|
57
96
|
|
|
58
97
|
Every new database begins with durable server onboarding. `GET /v0/setup/status`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface DaemonHost {
|
|
2
|
+
cwd: string;
|
|
3
|
+
environment: NodeJS.ProcessEnv;
|
|
4
|
+
executablePath: string;
|
|
5
|
+
executableArguments: readonly string[];
|
|
6
|
+
scriptPath: string;
|
|
7
|
+
directoryCreate(path: string): Promise<void>;
|
|
8
|
+
fileCreate(path: string, contents: string): Promise<boolean>;
|
|
9
|
+
fileExists(path: string): Promise<boolean>;
|
|
10
|
+
fileRead(path: string): Promise<string>;
|
|
11
|
+
fileRemove(path: string): Promise<void>;
|
|
12
|
+
processStart(input: {
|
|
13
|
+
arguments_: readonly string[];
|
|
14
|
+
cwd: string;
|
|
15
|
+
environment: NodeJS.ProcessEnv;
|
|
16
|
+
executablePath: string;
|
|
17
|
+
logPath: string;
|
|
18
|
+
pidPath: string;
|
|
19
|
+
}): Promise<number>;
|
|
20
|
+
processAlive(pid: number): boolean;
|
|
21
|
+
processTreeAlive(pid: number): boolean;
|
|
22
|
+
processTreeSignal(pid: number, signal: NodeJS.Signals): void;
|
|
23
|
+
wait(milliseconds: number): Promise<void>;
|
|
24
|
+
log(message: string): void;
|
|
25
|
+
}
|
|
26
|
+
export type ParsedDaemonCommand = {
|
|
27
|
+
action: "help" | "invalid" | "stop";
|
|
28
|
+
} | {
|
|
29
|
+
action: "start";
|
|
30
|
+
configPath?: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function parseDaemonCommand(arguments_: readonly string[]): ParsedDaemonCommand;
|
|
33
|
+
export declare function daemonStart(options: {
|
|
34
|
+
configPath?: string;
|
|
35
|
+
}, host?: DaemonHost): Promise<void>;
|
|
36
|
+
export declare function daemonStop(host?: DaemonHost): Promise<void>;
|
|
37
|
+
export declare function daemonUsage(): string;
|
|
38
|
+
export declare function createDaemonHost(): DaemonHost;
|
|
39
|
+
//# sourceMappingURL=daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../sources/daemon.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,UAAU;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,YAAY,CAAC,KAAK,EAAE;QAChB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;QAC9B,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC;QAC/B,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC7D,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,MAAM,mBAAmB,GACzB;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,mBAAmB,CAgCrF;AAED,wBAAsB,WAAW,CAC7B,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAChC,IAAI,GAAE,UAA+B,GACtC,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,wBAAsB,UAAU,CAAC,IAAI,GAAE,UAA+B,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BrF;AAED,wBAAgB,WAAW,IAAI,MAAM,CAQpC;AA4DD,wBAAgB,gBAAgB,IAAI,UAAU,CAuG7C"}
|