From 2583af7ead511cc45b4b78e706307d30aa26e77c Mon Sep 17 00:00:00 2001 From: Guy Ben Aharon Date: Mon, 23 Mar 2026 14:45:41 +0200 Subject: [PATCH] fix: ensure OneCLI agents exist for all groups on startup --- package-lock.json | 8 +++---- package.json | 2 +- src/container-runner.test.ts | 1 + src/index.ts | 44 +++++++++++++++++++++++------------- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index e325d6e..afca823 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "nanoclaw", "version": "1.2.21", "dependencies": { - "@onecli-sh/sdk": "^0.1.6", + "@onecli-sh/sdk": "^0.2.0", "better-sqlite3": "^11.8.1", "cron-parser": "^5.5.0", "pino": "^9.6.0", @@ -788,9 +788,9 @@ } }, "node_modules/@onecli-sh/sdk": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@onecli-sh/sdk/-/sdk-0.1.6.tgz", - "integrity": "sha512-kqVg8BOI6kapJaQjpTLBv91DhdKNykuSZIUsfb1pH5puyNlShWlXw5DWwxRVmxBihBMaIm+JyN9VRJMrVKZ5vQ==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@onecli-sh/sdk/-/sdk-0.2.0.tgz", + "integrity": "sha512-u7PqWROEvTV9f0ADVkjigTrd2AZn3klbPrv7GGpeRHIJpjAxJUdlWqxr5kiGt6qTDKL8t3nq76xr4X2pxTiyBg==", "license": "MIT", "engines": { "node": ">=20" diff --git a/package.json b/package.json index 990f001..54185a0 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "test:watch": "vitest" }, "dependencies": { - "@onecli-sh/sdk": "^0.1.6", + "@onecli-sh/sdk": "^0.2.0", "better-sqlite3": "^11.8.1", "cron-parser": "^5.5.0", "pino": "^9.6.0", diff --git a/src/container-runner.test.ts b/src/container-runner.test.ts index 58c7e0d..2de45c5 100644 --- a/src/container-runner.test.ts +++ b/src/container-runner.test.ts @@ -56,6 +56,7 @@ vi.mock('@onecli-sh/sdk', () => ({ OneCLI: class { applyContainerConfig = vi.fn().mockResolvedValue(true); createAgent = vi.fn().mockResolvedValue({ id: 'test' }); + ensureAgent = vi.fn().mockResolvedValue({ name: 'test', identifier: 'test', created: true }); }, })); diff --git a/src/index.ts b/src/index.ts index a7fa9e7..3f5e710 100644 --- a/src/index.ts +++ b/src/index.ts @@ -74,6 +74,25 @@ const queue = new GroupQueue(); const onecli = new OneCLI({ url: ONECLI_URL }); +function ensureOneCLIAgent(jid: string, group: RegisteredGroup): void { + if (group.isMain) return; + const identifier = group.folder.toLowerCase().replace(/_/g, '-'); + onecli.ensureAgent({ name: group.name, identifier }).then( + (res) => { + logger.info( + { jid, identifier, created: res.created }, + 'OneCLI agent ensured', + ); + }, + (err) => { + logger.debug( + { jid, identifier, err: String(err) }, + 'OneCLI agent ensure skipped', + ); + }, + ); +} + function loadState(): void { lastTimestamp = getRouterState('last_timestamp') || ''; const agentTs = getRouterState('last_agent_timestamp'); @@ -114,22 +133,8 @@ function registerGroup(jid: string, group: RegisteredGroup): void { // Create group folder fs.mkdirSync(path.join(groupDir, 'logs'), { recursive: true }); - // Create a corresponding OneCLI agent (best-effort, non-blocking) - const identifier = group.folder.toLowerCase().replace(/_/g, '-'); - onecli.createAgent({ name: group.name, identifier }).then( - (agent) => { - logger.info( - { jid, agentId: agent.id, identifier }, - 'OneCLI agent created', - ); - }, - (err) => { - logger.debug( - { jid, identifier, err: String(err) }, - 'OneCLI agent creation skipped', - ); - }, - ); + // Ensure a corresponding OneCLI agent exists (best-effort, non-blocking) + ensureOneCLIAgent(jid, group); logger.info( { jid, name: group.name, folder: group.folder }, @@ -493,6 +498,13 @@ async function main(): Promise { initDatabase(); logger.info('Database initialized'); loadState(); + + // Ensure OneCLI agents exist for all registered groups. + // Recovers from missed creates (e.g. OneCLI was down at registration time). + for (const [jid, group] of Object.entries(registeredGroups)) { + ensureOneCLIAgent(jid, group); + } + restoreRemoteControl(); // Graceful shutdown handlers