@omnixal/openclaw-nats-plugin 0.2.5 → 0.2.7
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/cli/docker-setup.ts +3 -3
- package/cli/setup.ts +0 -6
- package/dashboard/src/App.svelte +3 -0
- package/package.json +1 -1
- package/sidecar/src/consumer/consumer.controller.ts +5 -1
- package/sidecar/src/pending/pending.controller.ts +5 -1
- package/sidecar/src/scheduler/scheduler.controller.ts +1 -1
package/cli/docker-setup.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { mkdirSync, cpSync, writeFileSync, existsSync } from 'node:fs';
|
|
|
2
2
|
import { execFileSync } from 'node:child_process';
|
|
3
3
|
import { join, dirname } from 'node:path';
|
|
4
4
|
import { PLUGIN_DIR, DOCKER_DIR, DASHBOARD_DIR, STATE_FILE, type PluginState } from './paths';
|
|
5
|
-
import { generateApiKey, writeEnvVariables } from './env-writer';
|
|
5
|
+
import { generateApiKey, getExistingApiKey, writeEnvVariables } from './env-writer';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Try to copy dashboard dist into a running OpenClaw container's volume.
|
|
@@ -58,8 +58,8 @@ export async function dockerSetup(): Promise<void> {
|
|
|
58
58
|
cpSync(templateDir, DOCKER_DIR, { recursive: true });
|
|
59
59
|
cpSync(sidecarSrc, join(DOCKER_DIR, 'sidecar'), { recursive: true });
|
|
60
60
|
|
|
61
|
-
// 2.
|
|
62
|
-
const apiKey = generateApiKey();
|
|
61
|
+
// 2. Reuse existing API key or generate new one
|
|
62
|
+
const apiKey = getExistingApiKey() ?? generateApiKey();
|
|
63
63
|
writeFileSync(join(DOCKER_DIR, '.env'), `NATS_PLUGIN_API_KEY=${apiKey}\n`);
|
|
64
64
|
|
|
65
65
|
// 3. Build and start
|
package/cli/setup.ts
CHANGED
|
@@ -12,12 +12,6 @@ export function buildDashboard(): void {
|
|
|
12
12
|
const dashboardDir = join(PLUGIN_ROOT, 'dashboard');
|
|
13
13
|
const stableDist = DASHBOARD_DIR; // ~/.openclaw/nats-plugin/dashboard/
|
|
14
14
|
|
|
15
|
-
// Already installed to stable location
|
|
16
|
-
if (existsSync(join(stableDist, 'index.html'))) {
|
|
17
|
-
console.log('Dashboard already built, skipping.');
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
if (!existsSync(join(dashboardDir, 'package.json'))) {
|
|
22
16
|
console.warn('Warning: dashboard source not found, skipping build.');
|
|
23
17
|
return;
|
package/dashboard/src/App.svelte
CHANGED
|
@@ -88,6 +88,9 @@
|
|
|
88
88
|
onclick={() => activeTab = tab.id}
|
|
89
89
|
>
|
|
90
90
|
{tab.label}
|
|
91
|
+
{#if tab.id === 'pending' && pending.length > 0}
|
|
92
|
+
<span class="ml-1.5 inline-flex items-center justify-center rounded-full bg-destructive/15 text-destructive text-xs font-semibold min-w-5 h-5 px-1.5">{pending.length}</span>
|
|
93
|
+
{/if}
|
|
91
94
|
</button>
|
|
92
95
|
{/each}
|
|
93
96
|
</div>
|
package/package.json
CHANGED
|
@@ -26,16 +26,18 @@ export class ConsumerController extends BaseController {
|
|
|
26
26
|
this.logger.info(`Queue connected, consuming as ${consumerName}`);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
@Subscribe('agent.events
|
|
29
|
+
@Subscribe('agent.events.#', {
|
|
30
30
|
ackMode: 'manual',
|
|
31
31
|
group: 'openclaw-main',
|
|
32
32
|
})
|
|
33
33
|
async handleInbound(message: Message<unknown>): Promise<void> {
|
|
34
34
|
try {
|
|
35
35
|
const envelope = this.extractEnvelope(message);
|
|
36
|
+
this.logger.info(`Inbound event: ${envelope.subject} (id=${envelope.id})`);
|
|
36
37
|
|
|
37
38
|
const { result, ctx } = await this.pipeline.process(envelope);
|
|
38
39
|
if (result === 'drop') {
|
|
40
|
+
this.logger.debug(`Event dropped by pipeline: ${envelope.id}`);
|
|
39
41
|
await message.ack();
|
|
40
42
|
return;
|
|
41
43
|
}
|
|
@@ -43,10 +45,12 @@ export class ConsumerController extends BaseController {
|
|
|
43
45
|
// Check routing rules
|
|
44
46
|
const routes = await this.routerService.findMatchingRoutes(envelope.subject);
|
|
45
47
|
if (routes.length === 0) {
|
|
48
|
+
this.logger.debug(`No matching routes for ${envelope.subject}`);
|
|
46
49
|
// No route — just ack (event is in JetStream for audit)
|
|
47
50
|
await message.ack();
|
|
48
51
|
return;
|
|
49
52
|
}
|
|
53
|
+
this.logger.info(`Matched ${routes.length} route(s) for ${envelope.subject}`);
|
|
50
54
|
|
|
51
55
|
// Deliver to each matching target
|
|
52
56
|
if (this.gatewayClient.isAlive()) {
|
|
@@ -13,7 +13,11 @@ export class PendingController extends BaseController {
|
|
|
13
13
|
@Get('/:sessionKey')
|
|
14
14
|
async fetchPending(@Param('sessionKey') sessionKey: string): Promise<OneBunResponse> {
|
|
15
15
|
const events = await this.pendingService.fetchPending(sessionKey);
|
|
16
|
-
return this.success(events
|
|
16
|
+
return this.success(events.map(e => ({
|
|
17
|
+
...e,
|
|
18
|
+
createdAt: e.createdAt.getTime(),
|
|
19
|
+
deliveredAt: e.deliveredAt?.getTime() ?? null,
|
|
20
|
+
})));
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
@Post('/mark-delivered')
|
|
@@ -92,7 +92,7 @@ export class SchedulerController extends BaseController {
|
|
|
92
92
|
return this.success({ deleted: true });
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
@Subscribe('scheduler.fire.*')
|
|
95
|
+
@Subscribe('scheduler.fire.*', { group: 'scheduler-handler' })
|
|
96
96
|
async handleFire(message: Message<unknown>): Promise<void> {
|
|
97
97
|
const jobName = message.pattern?.split('.').pop();
|
|
98
98
|
if (jobName) {
|