From 499b8ad972222ef9540c8d038b529681b59fe658 Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Mon, 16 Mar 2026 00:29:31 +0000 Subject: [PATCH] Services: restore host lifecycle facade --- src/extension-host/.DS_Store | Bin 8196 -> 0 bytes .../contributions/service-lifecycle.test.ts | 11 +++- .../contributions/service-lifecycle.ts | 6 ++- src/plugins/services.ts | 47 +++--------------- 4 files changed, 20 insertions(+), 44 deletions(-) delete mode 100644 src/extension-host/.DS_Store diff --git a/src/extension-host/.DS_Store b/src/extension-host/.DS_Store deleted file mode 100644 index 96cd27f08b7c883df9cb46c6c2ebadce4d86b5c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMJ!=$E6uoZ^Vf~0$rV4}hLjJ)R*2+dmXJvNQkA>O1)ir|MbXN9OVjo0B8!e*I zLaqD@f<>%Si3&EJ``&YNZ+2!71X=Jtc<&5zKjz#s!_3~dMC8`C2CGENMAXG(JarsP z&0ssvnbApSR)7xiM7L>!ZqblDZO(Yx2~)rnFa=BjQ@|9M2LQam0VmRy>y94ut zRm2!hE{2m!S9YmGapCHS%Yr+(Jff|pfGIGm0Qc_4(6tw#Zx{XhU{aKQ?@JD;bttc` zt`~kZ4msVuOHFMpaeG|JRecGDtmP{nw z7B@xS{dn4*RF<-RVgGk2E%{|(e-@$2?7ZeOkK!I|U<+tSSLq5(P^2oa#;nSsvv=#0 z$Z}qs@Vn{psL3bGX!lg~=_1o#!~^811pR{U$orxUn)0wZ94N_t{BmP2kySY)&FydH zPMwb?_#_f!P2*Nup$Q6uCb;xH5EOPv@XY(?`_qdnpM&T8?N32a_-KNeegF9u*)Rp> zU4bK!;4=6B=bQKc=e-Q$X9}1Cf1!X|=&kqoXK?DRXHs#monc1#;`y3_! diff --git a/src/extension-host/contributions/service-lifecycle.test.ts b/src/extension-host/contributions/service-lifecycle.test.ts index 37b2da2f328..e4e1c4ff849 100644 --- a/src/extension-host/contributions/service-lifecycle.test.ts +++ b/src/extension-host/contributions/service-lifecycle.test.ts @@ -19,7 +19,12 @@ import { startExtensionHostServices } from "./service-lifecycle.js"; function createRegistry(services: OpenClawPluginService[]) { const registry = createEmptyPluginRegistry(); for (const service of services) { - registry.services.push({ pluginId: "plugin:test", service, source: "test" }); + registry.services.push({ + pluginId: "plugin:test", + service, + source: "test", + rootDir: "/plugins/test-plugin", + }); } return registry; } @@ -116,7 +121,9 @@ describe("startExtensionHostServices", () => { await handle.stop(); expect(mockedLogger.error).toHaveBeenCalledWith( - expect.stringContaining("plugin service failed (service-start-fail):"), + expect.stringContaining( + "plugin service failed (service-start-fail, plugin=plugin:test, root=/plugins/test-plugin):", + ), ); expect(mockedLogger.warn).toHaveBeenCalledWith( expect.stringContaining("plugin service stop failed (service-stop-fail):"), diff --git a/src/extension-host/contributions/service-lifecycle.ts b/src/extension-host/contributions/service-lifecycle.ts index 3c6d1ccf101..446f8167a9a 100644 --- a/src/extension-host/contributions/service-lifecycle.ts +++ b/src/extension-host/contributions/service-lifecycle.ts @@ -55,7 +55,11 @@ export async function startExtensionHostServices(params: { stop: service.stop ? () => service.stop?.(serviceContext) : undefined, }); } catch (err) { - log.error(`plugin service failed (${service.id}): ${String(err)}`); + const error = err as Error; + const stack = error?.stack?.trim(); + log.error( + `plugin service failed (${service.id}, plugin=${entry.pluginId}, root=${entry.rootDir ?? "unknown"}): ${error?.message ?? String(err)}${stack ? `\n${stack}` : ""}`, + ); } } diff --git a/src/plugins/services.ts b/src/plugins/services.ts index d0eeda11cb1..a653da9ad2d 100644 --- a/src/plugins/services.ts +++ b/src/plugins/services.ts @@ -1,6 +1,10 @@ import type { OpenClawConfig } from "../config/config.js"; -import type { ExtensionHostServicesHandle } from "../extension-host/contributions/service-lifecycle.js"; +import { + startExtensionHostServices, + type ExtensionHostServicesHandle, +} from "../extension-host/contributions/service-lifecycle.js"; import type { PluginRegistry } from "./registry.js"; + export type PluginServicesHandle = ExtensionHostServicesHandle; export async function startPluginServices(params: { @@ -8,44 +12,5 @@ export async function startPluginServices(params: { config: OpenClawConfig; workspaceDir?: string; }): Promise { - const running: Array<{ - id: string; - stop?: () => void | Promise; - }> = []; - const serviceContext = createServiceContext({ - config: params.config, - workspaceDir: params.workspaceDir, - }); - - for (const entry of params.registry.services) { - const service = entry.service; - try { - await service.start(serviceContext); - running.push({ - id: service.id, - stop: service.stop ? () => service.stop?.(serviceContext) : undefined, - }); - } catch (err) { - const error = err as Error; - const stack = error?.stack?.trim(); - log.error( - `plugin service failed (${service.id}, plugin=${entry.pluginId}, root=${entry.rootDir ?? "unknown"}): ${error?.message ?? String(err)}${stack ? `\n${stack}` : ""}`, - ); - } - } - - return { - stop: async () => { - for (const entry of running.toReversed()) { - if (!entry.stop) { - continue; - } - try { - await entry.stop(); - } catch (err) { - log.warn(`plugin service stop failed (${entry.id}): ${String(err)}`); - } - } - }, - }; + return startExtensionHostServices(params); }