diff --git a/src/daemon/index.ts b/src/daemon/index.ts index e919bec..8a0dce0 100644 --- a/src/daemon/index.ts +++ b/src/daemon/index.ts @@ -20,6 +20,7 @@ import { createWalletAdapter } from "./wallet"; import { createCocodClient } from "./wallet/cocod-client"; import { createModelService } from "./models"; import { createDaemonRequestHandler } from "./http"; +import { runIntegrationsForClients } from "../integrations"; import { RoutstrClient } from "@routstr/sdk"; async function main(): Promise { @@ -104,6 +105,17 @@ async function main(): Promise { try { await getRoutstr21Models(true); logger.log("Scheduled model refresh completed successfully."); + + // Refresh integrations for all registered clients + const state = store.getState(); + const clientIds = state.clientIds || []; + if (clientIds.length > 0) { + logger.log( + `Refreshing ${clientIds.length} client integration(s)...`, + ); + await runIntegrationsForClients(clientIds, updatedConfig, store); + logger.log("Client integrations refreshed."); + } } catch (error) { logger.error("Scheduled model refresh failed:", error); } @@ -203,8 +215,18 @@ async function main(): Promise { logger.log("Running initial model refresh..."); return getRoutstr21Models(true); }) - .then(() => { + .then(async () => { logger.log("Initial model refresh completed."); + // Refresh integrations for all registered clients after initial bootstrap + const state = store.getState(); + const clientIds = state.clientIds || []; + if (clientIds.length > 0) { + logger.log( + `Refreshing ${clientIds.length} client integration(s)...`, + ); + await runIntegrationsForClients(clientIds, updatedConfig, store); + logger.log("Client integrations refreshed."); + } }) .catch((error) => { logger.error("Initial model refresh failed:", error); diff --git a/src/integrations/index.ts b/src/integrations/index.ts index 22ebacf..852e6a6 100644 --- a/src/integrations/index.ts +++ b/src/integrations/index.ts @@ -4,6 +4,7 @@ import { installOpencodeIntegration } from "./opencode"; import { installOpenClawIntegration } from "./openclaw"; import { installPiIntegration } from "./pi"; import type { SdkStore } from "@routstr/sdk"; +export { CLIENT_INTEGRATIONS, runIntegrationsForClients } from "./registry"; function ask(question: string): Promise { process.stdout.write(question); diff --git a/src/integrations/registry.ts b/src/integrations/registry.ts new file mode 100644 index 0000000..e6e7727 --- /dev/null +++ b/src/integrations/registry.ts @@ -0,0 +1,33 @@ +import type { RoutstrdConfig } from "../utils/config"; +import type { SdkStore } from "@routstr/sdk"; +import { installOpencodeIntegration } from "./opencode"; +import { installPiIntegration } from "./pi"; +import { installOpenClawIntegration } from "./openclaw"; + +export type IntegrationFn = ( + config: RoutstrdConfig, + store: SdkStore, +) => Promise; + +export const CLIENT_INTEGRATIONS: Record = { + opencode: installOpencodeIntegration, + "pi-agent": installPiIntegration, + openclaw: installOpenClawIntegration, +}; + +export async function runIntegrationsForClients( + clientIds: Array<{ clientId: string }>, + config: RoutstrdConfig, + store: SdkStore, +): Promise { + for (const client of clientIds) { + const integrationFn = CLIENT_INTEGRATIONS[client.clientId]; + if (integrationFn) { + try { + await integrationFn(config, store); + } catch (error) { + console.error(`Integration failed for ${client.clientId}:`, error); + } + } + } +}