openalerts 0.2.6

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.
Files changed (102) hide show
  1. package/README.md +253 -0
  2. package/dist/channels/console.d.ts +6 -0
  3. package/dist/channels/console.d.ts.map +1 -0
  4. package/dist/channels/console.js +10 -0
  5. package/dist/channels/console.js.map +1 -0
  6. package/dist/channels/telegram.d.ts +12 -0
  7. package/dist/channels/telegram.d.ts.map +1 -0
  8. package/dist/channels/telegram.js +28 -0
  9. package/dist/channels/telegram.js.map +1 -0
  10. package/dist/channels/webhook.d.ts +8 -0
  11. package/dist/channels/webhook.d.ts.map +1 -0
  12. package/dist/channels/webhook.js +15 -0
  13. package/dist/channels/webhook.js.map +1 -0
  14. package/dist/cli.d.ts +3 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +234 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/config.d.ts +51 -0
  19. package/dist/config.d.ts.map +1 -0
  20. package/dist/config.js +86 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/core/alert-channel.d.ts +16 -0
  23. package/dist/core/alert-channel.d.ts.map +1 -0
  24. package/dist/core/alert-channel.js +23 -0
  25. package/dist/core/alert-channel.js.map +1 -0
  26. package/dist/core/bounded-map.d.ts +52 -0
  27. package/dist/core/bounded-map.d.ts.map +1 -0
  28. package/dist/core/bounded-map.js +129 -0
  29. package/dist/core/bounded-map.js.map +1 -0
  30. package/dist/core/engine.d.ts +36 -0
  31. package/dist/core/engine.d.ts.map +1 -0
  32. package/dist/core/engine.js +162 -0
  33. package/dist/core/engine.js.map +1 -0
  34. package/dist/core/evaluator.d.ts +19 -0
  35. package/dist/core/evaluator.d.ts.map +1 -0
  36. package/dist/core/evaluator.js +168 -0
  37. package/dist/core/evaluator.js.map +1 -0
  38. package/dist/core/event-bus.d.ts +18 -0
  39. package/dist/core/event-bus.d.ts.map +1 -0
  40. package/dist/core/event-bus.js +32 -0
  41. package/dist/core/event-bus.js.map +1 -0
  42. package/dist/core/formatter.d.ts +15 -0
  43. package/dist/core/formatter.d.ts.map +1 -0
  44. package/dist/core/formatter.js +125 -0
  45. package/dist/core/formatter.js.map +1 -0
  46. package/dist/core/rules.d.ts +3 -0
  47. package/dist/core/rules.d.ts.map +1 -0
  48. package/dist/core/rules.js +410 -0
  49. package/dist/core/rules.js.map +1 -0
  50. package/dist/core/store.d.ts +9 -0
  51. package/dist/core/store.d.ts.map +1 -0
  52. package/dist/core/store.js +72 -0
  53. package/dist/core/store.js.map +1 -0
  54. package/dist/core/types.d.ts +158 -0
  55. package/dist/core/types.d.ts.map +1 -0
  56. package/dist/core/types.js +18 -0
  57. package/dist/core/types.js.map +1 -0
  58. package/dist/db/index.d.ts +6 -0
  59. package/dist/db/index.d.ts.map +1 -0
  60. package/dist/db/index.js +31 -0
  61. package/dist/db/index.js.map +1 -0
  62. package/dist/db/queries.d.ts +157 -0
  63. package/dist/db/queries.d.ts.map +1 -0
  64. package/dist/db/queries.js +221 -0
  65. package/dist/db/queries.js.map +1 -0
  66. package/dist/db/schema.d.ts +5 -0
  67. package/dist/db/schema.d.ts.map +1 -0
  68. package/dist/db/schema.js +177 -0
  69. package/dist/db/schema.js.map +1 -0
  70. package/dist/readers/openclaw.d.ts +11 -0
  71. package/dist/readers/openclaw.d.ts.map +1 -0
  72. package/dist/readers/openclaw.js +267 -0
  73. package/dist/readers/openclaw.js.map +1 -0
  74. package/dist/server/dashboard.d.ts +2 -0
  75. package/dist/server/dashboard.d.ts.map +1 -0
  76. package/dist/server/dashboard.js +765 -0
  77. package/dist/server/dashboard.js.map +1 -0
  78. package/dist/server/index.d.ts +10 -0
  79. package/dist/server/index.d.ts.map +1 -0
  80. package/dist/server/index.js +28 -0
  81. package/dist/server/index.js.map +1 -0
  82. package/dist/server/routes.d.ts +6 -0
  83. package/dist/server/routes.d.ts.map +1 -0
  84. package/dist/server/routes.js +146 -0
  85. package/dist/server/routes.js.map +1 -0
  86. package/dist/server/sse.d.ts +21 -0
  87. package/dist/server/sse.d.ts.map +1 -0
  88. package/dist/server/sse.js +53 -0
  89. package/dist/server/sse.js.map +1 -0
  90. package/dist/watchers/files.d.ts +19 -0
  91. package/dist/watchers/files.d.ts.map +1 -0
  92. package/dist/watchers/files.js +105 -0
  93. package/dist/watchers/files.js.map +1 -0
  94. package/dist/watchers/gateway-adapter.d.ts +18 -0
  95. package/dist/watchers/gateway-adapter.d.ts.map +1 -0
  96. package/dist/watchers/gateway-adapter.js +273 -0
  97. package/dist/watchers/gateway-adapter.js.map +1 -0
  98. package/dist/watchers/gateway.d.ts +27 -0
  99. package/dist/watchers/gateway.d.ts.map +1 -0
  100. package/dist/watchers/gateway.js +131 -0
  101. package/dist/watchers/gateway.js.map +1 -0
  102. package/package.json +48 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/server/dashboard.ts"],"names":[],"mappings":"AAAA,uGAAuG;AAEvG,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqJX,CAAC;AAEF,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqEZ,CAAC;AAEF,6FAA6F;AAC7F,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8gBd,CAAC;AAEF,MAAM,UAAU,gBAAgB;IAC/B,OAAO;;;;;;SAMC,GAAG;;;EAGV,IAAI;UACI,MAAM;;QAER,CAAC;AACT,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { DatabaseSync } from "node:sqlite";
2
+ import type { OpenAlertsEngine } from "../core/engine.js";
3
+ import type { ServerConfig } from "../config.js";
4
+ import { SseManager } from "./sse.js";
5
+ export interface HttpServer {
6
+ sse: SseManager;
7
+ close(): void;
8
+ }
9
+ export declare function startHttpServer(config: ServerConfig, db: DatabaseSync, engine: OpenAlertsEngine, getGatewayStatus?: () => boolean): HttpServer;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,CAAC,EAAE,MAAM,OAAO,GAC/B,UAAU,CA2BZ"}
@@ -0,0 +1,28 @@
1
+ import { createServer } from "node:http";
2
+ import { SseManager } from "./sse.js";
3
+ import { createRouter } from "./routes.js";
4
+ export function startHttpServer(config, db, engine, getGatewayStatus) {
5
+ const sse = new SseManager();
6
+ sse.start();
7
+ const router = createRouter(db, engine, sse, getGatewayStatus);
8
+ const server = createServer(router);
9
+ server.listen(config.port, config.host, () => {
10
+ console.log(`[server] Dashboard: http://${config.host}:${config.port}`);
11
+ console.log(`[server] API: http://${config.host}:${config.port}/api/state`);
12
+ });
13
+ server.on("error", (err) => {
14
+ if (err.code === "EADDRINUSE") {
15
+ console.error(`[server] Port ${config.port} already in use. Use --port to change.`);
16
+ process.exit(1);
17
+ }
18
+ console.error(`[server] Error: ${err.message}`);
19
+ });
20
+ return {
21
+ sse,
22
+ close() {
23
+ sse.stop();
24
+ server.close();
25
+ },
26
+ };
27
+ }
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAIzC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C,MAAM,UAAU,eAAe,CAC7B,MAAoB,EACpB,EAAgB,EAChB,MAAwB,EACxB,gBAAgC;IAEhC,MAAM,GAAG,GAAG,IAAI,UAAU,EAAE,CAAC;IAC7B,GAAG,CAAC,KAAK,EAAE,CAAC;IAEZ,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAEpC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QAC3C,OAAO,CAAC,GAAG,CAAC,8BAA8B,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,8BAA8B,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,YAAY,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;QAChD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,iBAAiB,MAAM,CAAC,IAAI,wCAAwC,CAAC,CAAC;YACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,GAAG;QACH,KAAK;YACH,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { DatabaseSync } from "node:sqlite";
3
+ import type { OpenAlertsEngine } from "../core/engine.js";
4
+ import type { SseManager } from "./sse.js";
5
+ export declare function createRouter(db: DatabaseSync, engine: OpenAlertsEngine, sse: SseManager, getGatewayStatus?: () => boolean): (req: IncomingMessage, res: ServerResponse) => void;
6
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAqB3C,wBAAgB,YAAY,CAC1B,EAAE,EAAE,YAAY,EAChB,MAAM,EAAE,gBAAgB,EACxB,GAAG,EAAE,UAAU,EACf,gBAAgB,CAAC,EAAE,MAAM,OAAO,IAEF,KAAK,eAAe,EAAE,KAAK,cAAc,KAAG,IAAI,CA4I/E"}
@@ -0,0 +1,146 @@
1
+ import { getDashboardState, getRecentAlerts, getRecentDiagnostics, getRecentHeartbeats, getRecentActions, getActivityLog, } from "../db/queries.js";
2
+ import { getDashboardHtml } from "./dashboard.js";
3
+ function json(res, data, status = 200) {
4
+ const body = JSON.stringify(data, null, 2);
5
+ res.writeHead(status, {
6
+ "Content-Type": "application/json",
7
+ "Access-Control-Allow-Origin": "*",
8
+ "Content-Length": Buffer.byteLength(body),
9
+ });
10
+ res.end(body);
11
+ }
12
+ function notFound(res) {
13
+ json(res, { error: "Not found" }, 404);
14
+ }
15
+ export function createRouter(db, engine, sse, getGatewayStatus) {
16
+ return function handleRequest(req, res) {
17
+ const url = new URL(req.url ?? "/", "http://localhost");
18
+ const pathname = url.pathname;
19
+ // CORS preflight
20
+ if (req.method === "OPTIONS") {
21
+ res.writeHead(204, {
22
+ "Access-Control-Allow-Origin": "*",
23
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
24
+ "Access-Control-Allow-Headers": "Content-Type",
25
+ });
26
+ res.end();
27
+ return;
28
+ }
29
+ // ── Dashboard UI ──────────────────────────────────────────────────────
30
+ if (pathname === "/" || pathname === "/dashboard") {
31
+ const html = getDashboardHtml();
32
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
33
+ res.end(html);
34
+ return;
35
+ }
36
+ // ── SSE stream ────────────────────────────────────────────────────────
37
+ if (pathname === "/events") {
38
+ sse.add(res);
39
+ // Send initial state snapshot
40
+ try {
41
+ const state = getDashboardState(db);
42
+ sse.emit("state", state);
43
+ }
44
+ catch { /* ignore */ }
45
+ return;
46
+ }
47
+ // ── Full state snapshot ───────────────────────────────────────────────
48
+ if (pathname === "/api/state") {
49
+ try {
50
+ json(res, getDashboardState(db));
51
+ }
52
+ catch (err) {
53
+ console.error("Error while fetching dashboard state:", err);
54
+ json(res, { error: "Internal server error" }, 500);
55
+ }
56
+ return;
57
+ }
58
+ // ── Recent alerts ─────────────────────────────────────────────────────
59
+ if (pathname === "/api/alerts") {
60
+ const limit = parseInt(url.searchParams.get("limit") ?? "50");
61
+ json(res, getRecentAlerts(db, Math.min(limit, 200)));
62
+ return;
63
+ }
64
+ // ── Recent diagnostics ────────────────────────────────────────────────
65
+ if (pathname === "/api/diagnostics") {
66
+ const limit = parseInt(url.searchParams.get("limit") ?? "100");
67
+ json(res, getRecentDiagnostics(db, Math.min(limit, 500)));
68
+ return;
69
+ }
70
+ // ── Heartbeat history ─────────────────────────────────────────────────
71
+ if (pathname === "/api/heartbeats") {
72
+ const limit = parseInt(url.searchParams.get("limit") ?? "50");
73
+ json(res, getRecentHeartbeats(db, Math.min(limit, 500)));
74
+ return;
75
+ }
76
+ // ── Action history ────────────────────────────────────────────────────
77
+ if (pathname === "/api/actions") {
78
+ const limit = parseInt(url.searchParams.get("limit") ?? "100");
79
+ const session = url.searchParams.get("session") ?? undefined;
80
+ json(res, getRecentActions(db, Math.min(limit, 500), session));
81
+ return;
82
+ }
83
+ // ── Unified activity log (actions + diagnostics merged) ───────────────
84
+ if (pathname === "/api/activity") {
85
+ const limit = parseInt(url.searchParams.get("limit") ?? "100");
86
+ const session = url.searchParams.get("session") ?? undefined;
87
+ json(res, getActivityLog(db, Math.min(limit, 500), session));
88
+ return;
89
+ }
90
+ // ── Structured logs (OpenClaw /logs style) ────────────────────────────
91
+ if (pathname === "/api/logs") {
92
+ const limit = parseInt(url.searchParams.get("limit") ?? "100");
93
+ const session = url.searchParams.get("session") ?? undefined;
94
+ const subsystem = url.searchParams.get("subsystem") ?? undefined;
95
+ let entries = getActivityLog(db, Math.min(limit * 2, 1000), session);
96
+ if (subsystem)
97
+ entries = entries.filter(e => e.subsystem === subsystem);
98
+ const logs = entries.slice(0, limit).map(e => ({
99
+ ts: new Date(e.ts).toISOString(),
100
+ tsMs: e.ts,
101
+ level: e.event_type.includes("error") || e.event_type.includes("fail") ? "ERROR"
102
+ : e.subsystem === "infra" ? "DEBUG" : "INFO",
103
+ subsystem: e.subsystem,
104
+ message: e.message,
105
+ ...(e.session_key ? { sessionKey: e.session_key } : {}),
106
+ ...(e.run_id ? { runId: e.run_id } : {}),
107
+ ...(e.tool_name ? { toolName: e.tool_name } : {}),
108
+ ...(e.duration_ms != null ? { durationMs: e.duration_ms } : {}),
109
+ ...(e.input_tokens != null ? { inputTokens: e.input_tokens } : {}),
110
+ ...(e.output_tokens != null ? { outputTokens: e.output_tokens } : {}),
111
+ }));
112
+ json(res, { entries: logs, total: logs.length });
113
+ return;
114
+ }
115
+ // ── Engine state (rules, stats, uptime) ───────────────────────────────
116
+ if (pathname === "/api/engine") {
117
+ json(res, {
118
+ running: engine.isRunning,
119
+ gatewayConnected: getGatewayStatus ? getGatewayStatus() : null,
120
+ startedAt: engine.state.startedAt,
121
+ stats: engine.state.stats,
122
+ hourlyAlerts: engine.state.hourlyAlerts,
123
+ lastHeartbeatTs: engine.state.lastHeartbeatTs,
124
+ });
125
+ return;
126
+ }
127
+ // ── Test alert ────────────────────────────────────────────────────────
128
+ if (pathname === "/api/test" && req.method === "POST") {
129
+ engine.sendTestAlert();
130
+ json(res, { ok: true, message: "Test alert fired" });
131
+ return;
132
+ }
133
+ // ── Health check ──────────────────────────────────────────────────────
134
+ if (pathname === "/health") {
135
+ json(res, {
136
+ ok: true,
137
+ ts: Date.now(),
138
+ sseClients: sse.size,
139
+ gatewayConnected: getGatewayStatus ? getGatewayStatus() : null,
140
+ });
141
+ return;
142
+ }
143
+ notFound(res);
144
+ };
145
+ }
146
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * SSE (Server-Sent Events) connection manager.
3
+ * Clients subscribe and receive real-time updates.
4
+ */
5
+ import type { ServerResponse } from "node:http";
6
+ export interface SseClient {
7
+ id: string;
8
+ res: ServerResponse;
9
+ }
10
+ export declare class SseManager {
11
+ private clients;
12
+ private heartbeatTimer;
13
+ private clientCounter;
14
+ start(): void;
15
+ stop(): void;
16
+ add(res: ServerResponse): string;
17
+ emit(eventName: string, data: unknown): void;
18
+ get size(): number;
19
+ private broadcast;
20
+ }
21
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/server/sse.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,cAAc,CAAC;CACrB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAAK;IAE1B,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAQZ,GAAG,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;IAehC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAK5C,IAAI,IAAI,IAAI,MAAM,CAA8B;IAEhD,OAAO,CAAC,SAAS;CASlB"}
@@ -0,0 +1,53 @@
1
+ export class SseManager {
2
+ clients = new Map();
3
+ heartbeatTimer = null;
4
+ clientCounter = 0;
5
+ start() {
6
+ this.heartbeatTimer = setInterval(() => {
7
+ this.broadcast(":heartbeat\n\n");
8
+ }, 15_000);
9
+ }
10
+ stop() {
11
+ if (this.heartbeatTimer) {
12
+ clearInterval(this.heartbeatTimer);
13
+ this.heartbeatTimer = null;
14
+ }
15
+ for (const client of this.clients.values()) {
16
+ try {
17
+ client.res.end();
18
+ }
19
+ catch { /* ignore */ }
20
+ }
21
+ this.clients.clear();
22
+ }
23
+ add(res) {
24
+ const id = `sse-${++this.clientCounter}`;
25
+ res.writeHead(200, {
26
+ "Content-Type": "text/event-stream",
27
+ "Cache-Control": "no-cache",
28
+ "Connection": "keep-alive",
29
+ "X-Accel-Buffering": "no",
30
+ "Access-Control-Allow-Origin": "*",
31
+ });
32
+ res.write(":ok\n\n");
33
+ this.clients.set(id, { id, res });
34
+ res.on("close", () => this.clients.delete(id));
35
+ return id;
36
+ }
37
+ emit(eventName, data) {
38
+ const payload = `event: ${eventName}\ndata: ${JSON.stringify(data)}\n\n`;
39
+ this.broadcast(payload);
40
+ }
41
+ get size() { return this.clients.size; }
42
+ broadcast(payload) {
43
+ for (const [id, client] of [...this.clients]) {
44
+ try {
45
+ client.res.write(payload);
46
+ }
47
+ catch {
48
+ this.clients.delete(id);
49
+ }
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/server/sse.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,UAAU;IACb,OAAO,GAA2B,IAAI,GAAG,EAAE,CAAC;IAC5C,cAAc,GAA0B,IAAI,CAAC;IAC7C,aAAa,GAAG,CAAC,CAAC;IAE1B,KAAK;QACH,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;YACrC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACnC,CAAC,EAAE,MAAM,CAAC,CAAC;IACb,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAAC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAAC,CAAC;QAC5F,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC;gBAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,GAAG,CAAC,GAAmB;QACrB,MAAM,EAAE,GAAG,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC;QACzC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,UAAU;YAC3B,YAAY,EAAE,YAAY;YAC1B,mBAAmB,EAAE,IAAI;YACzB,6BAA6B,EAAE,GAAG;SACnC,CAAC,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAClC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC,SAAiB,EAAE,IAAa;QACnC,MAAM,OAAO,GAAG,UAAU,SAAS,WAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QACzE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAExC,SAAS,CAAC,OAAe;QAC/B,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import type { DatabaseSync } from "node:sqlite";
2
+ import type { WatchConfig } from "../config.js";
3
+ type ChangeCallback = (changed: string) => void;
4
+ export declare class FileWatcher {
5
+ private watchers;
6
+ private debounceTimers;
7
+ private db;
8
+ private config;
9
+ private onChange;
10
+ constructor(db: DatabaseSync, config: WatchConfig, onChange: ChangeCallback);
11
+ start(): void;
12
+ stop(): void;
13
+ private watchDir;
14
+ private debounce;
15
+ private handleChange;
16
+ }
17
+ export declare function doFullLoad(db: DatabaseSync, config: WatchConfig): void;
18
+ export {};
19
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/watchers/files.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOhD,KAAK,cAAc,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAahD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAiB;gBAErB,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc;IAM3E,KAAK,IAAI,IAAI;IAqBb,IAAI,IAAI,IAAI;IAOZ,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,YAAY;CAmBrB;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAEtE"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * File-system watcher for the OpenClaw data directory.
3
+ * Uses node:fs watch (built-in). Debounces noisy filesystem events.
4
+ * Calls reload callbacks when relevant files change.
5
+ */
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { loadAll, readCronJobs, readCronRuns, readSessions, readActions, readDeliveryQueue, readWorkspaceDocs, readOcConfig, } from "../readers/openclaw.js";
9
+ // Files/dirs that trigger a specific partial reload
10
+ const RELOAD_MAP = [
11
+ [/cron[/\\]jobs\.json$/, (db, d) => readCronJobs(db, d)],
12
+ [/cron[/\\]runs[/\\]/, (db, d) => readCronRuns(db, d)],
13
+ [/collections[/\\]sessions\.json$/, (db, d) => readSessions(db, d)],
14
+ [/collections[/\\]actions\.jsonl$/, (db, d) => readActions(db, d)],
15
+ [/delivery-queue[/\\]/, (db, d) => readDeliveryQueue(db, d)],
16
+ [/openclaw\.json$/, (db, d) => readOcConfig(db, d)],
17
+ [/(SOUL|HEARTBEAT|MEMORY|IDENTITY|USER|AGENTS|TOOLS)\.md$/i, (db, d, ws) => readWorkspaceDocs(db, d, ws)],
18
+ ];
19
+ export class FileWatcher {
20
+ watchers = [];
21
+ debounceTimers = new Map();
22
+ db;
23
+ config;
24
+ onChange;
25
+ constructor(db, config, onChange) {
26
+ this.db = db;
27
+ this.config = config;
28
+ this.onChange = onChange;
29
+ }
30
+ start() {
31
+ const { openclawDir } = this.config;
32
+ if (!fs.existsSync(openclawDir)) {
33
+ console.warn(`[watcher] OpenClaw dir not found: ${openclawDir}`);
34
+ return;
35
+ }
36
+ // Watch top-level openclaw dir recursively
37
+ this.watchDir(openclawDir, true);
38
+ // Also watch each workspace dir directly (for MD files)
39
+ for (const ws of this.config.workspaces) {
40
+ const wsPath = path.isAbsolute(ws) ? ws : path.join(openclawDir, ws);
41
+ if (fs.existsSync(wsPath)) {
42
+ this.watchDir(wsPath, false);
43
+ }
44
+ }
45
+ console.log(`[watcher] Watching ${openclawDir}`);
46
+ }
47
+ stop() {
48
+ for (const w of this.watchers) {
49
+ try {
50
+ w.close();
51
+ }
52
+ catch { /* ignore */ }
53
+ }
54
+ this.watchers = [];
55
+ for (const t of this.debounceTimers.values())
56
+ clearTimeout(t);
57
+ this.debounceTimers.clear();
58
+ }
59
+ watchDir(dirPath, recursive) {
60
+ try {
61
+ const w = fs.watch(dirPath, { recursive }, (event, filename) => {
62
+ if (!filename)
63
+ return;
64
+ const fullPath = path.join(dirPath, filename);
65
+ this.debounce(fullPath);
66
+ });
67
+ w.on("error", err => console.warn(`[watcher] Watch error: ${err.message}`));
68
+ this.watchers.push(w);
69
+ }
70
+ catch (err) {
71
+ console.warn(`[watcher] Cannot watch ${dirPath}: ${err}`);
72
+ }
73
+ }
74
+ debounce(filePath) {
75
+ const existing = this.debounceTimers.get(filePath);
76
+ if (existing)
77
+ clearTimeout(existing);
78
+ this.debounceTimers.set(filePath, setTimeout(() => {
79
+ this.debounceTimers.delete(filePath);
80
+ this.handleChange(filePath);
81
+ }, 200));
82
+ }
83
+ handleChange(filePath) {
84
+ const normalized = filePath.replace(/\\/g, "/");
85
+ // Find matching reloader
86
+ for (const [pattern, reloader] of RELOAD_MAP) {
87
+ if (pattern.test(normalized)) {
88
+ try {
89
+ reloader(this.db, this.config.openclawDir, this.config.workspaces);
90
+ }
91
+ catch (err) {
92
+ console.warn(`[watcher] Reload failed for ${filePath}: ${err}`);
93
+ }
94
+ this.onChange(filePath);
95
+ return;
96
+ }
97
+ }
98
+ // For unmatched changes, just notify
99
+ this.onChange(filePath);
100
+ }
101
+ }
102
+ export function doFullLoad(db, config) {
103
+ loadAll(db, config);
104
+ }
105
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/watchers/files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Translates real OpenClaw gateway WS events into:
3
+ * 1. OpenAlertsEvents → engine for rule evaluation
4
+ * 2. DB writes → SQLite for dashboard state
5
+ * 3. SSE payloads → dashboard live feed
6
+ *
7
+ * Event shapes are derived from node/src/collections/event-parser.ts
8
+ */
9
+ import type { OpenAlertsEvent } from "../core/types.js";
10
+ import type { DatabaseSync } from "node:sqlite";
11
+ export interface GatewayTranslation {
12
+ event?: OpenAlertsEvent;
13
+ /** For pushing to SSE clients */
14
+ sseType?: string;
15
+ ssePayload?: unknown;
16
+ }
17
+ export declare function translateGatewayEvent(eventName: string, payload: unknown, db?: DatabaseSync | null): GatewayTranslation;
18
+ //# sourceMappingURL=gateway-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-adapter.d.ts","sourceRoot":"","sources":["../../src/watchers/gateway-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAoGhD,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,EAChB,EAAE,CAAC,EAAE,YAAY,GAAG,IAAI,GACvB,kBAAkB,CAgPpB"}