@steadwing/openalerts 0.2.5 → 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 (134) hide show
  1. package/README.md +198 -141
  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 +3 -10
  23. package/dist/core/alert-channel.d.ts.map +1 -0
  24. package/dist/core/alert-channel.js +9 -30
  25. package/dist/core/alert-channel.js.map +1 -0
  26. package/dist/core/bounded-map.d.ts +1 -0
  27. package/dist/core/bounded-map.d.ts.map +1 -0
  28. package/dist/core/bounded-map.js +1 -0
  29. package/dist/core/bounded-map.js.map +1 -0
  30. package/dist/core/engine.d.ts +6 -18
  31. package/dist/core/engine.d.ts.map +1 -0
  32. package/dist/core/engine.js +48 -98
  33. package/dist/core/engine.js.map +1 -0
  34. package/dist/core/evaluator.d.ts +1 -0
  35. package/dist/core/evaluator.d.ts.map +1 -0
  36. package/dist/core/evaluator.js +1 -0
  37. package/dist/core/evaluator.js.map +1 -0
  38. package/dist/core/event-bus.d.ts +1 -0
  39. package/dist/core/event-bus.d.ts.map +1 -0
  40. package/dist/core/event-bus.js +1 -0
  41. package/dist/core/event-bus.js.map +1 -0
  42. package/dist/core/formatter.d.ts +1 -0
  43. package/dist/core/formatter.d.ts.map +1 -0
  44. package/dist/core/formatter.js +1 -0
  45. package/dist/core/formatter.js.map +1 -0
  46. package/dist/core/rules.d.ts +1 -0
  47. package/dist/core/rules.d.ts.map +1 -0
  48. package/dist/core/rules.js +1 -0
  49. package/dist/core/rules.js.map +1 -0
  50. package/dist/core/store.d.ts +6 -9
  51. package/dist/core/store.d.ts.map +1 -0
  52. package/dist/core/store.js +43 -96
  53. package/dist/core/store.js.map +1 -0
  54. package/dist/core/types.d.ts +1 -0
  55. package/dist/core/types.d.ts.map +1 -0
  56. package/dist/core/types.js +1 -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 +29 -43
  103. package/LICENSE +0 -201
  104. package/dist/collections/collection-manager.d.ts +0 -50
  105. package/dist/collections/collection-manager.js +0 -583
  106. package/dist/collections/event-parser.d.ts +0 -27
  107. package/dist/collections/event-parser.js +0 -321
  108. package/dist/collections/index.d.ts +0 -6
  109. package/dist/collections/index.js +0 -6
  110. package/dist/collections/persistence.d.ts +0 -25
  111. package/dist/collections/persistence.js +0 -213
  112. package/dist/collections/types.d.ts +0 -177
  113. package/dist/collections/types.js +0 -15
  114. package/dist/core/index.d.ts +0 -13
  115. package/dist/core/index.js +0 -23
  116. package/dist/core/llm-enrichment.d.ts +0 -21
  117. package/dist/core/llm-enrichment.js +0 -180
  118. package/dist/core/platform.d.ts +0 -17
  119. package/dist/core/platform.js +0 -93
  120. package/dist/index.d.ts +0 -8
  121. package/dist/index.js +0 -600
  122. package/dist/plugin/adapter.d.ts +0 -150
  123. package/dist/plugin/adapter.js +0 -530
  124. package/dist/plugin/commands.d.ts +0 -18
  125. package/dist/plugin/commands.js +0 -103
  126. package/dist/plugin/dashboard-html.d.ts +0 -7
  127. package/dist/plugin/dashboard-html.js +0 -968
  128. package/dist/plugin/dashboard-routes.d.ts +0 -12
  129. package/dist/plugin/dashboard-routes.js +0 -444
  130. package/dist/plugin/gateway-client.d.ts +0 -39
  131. package/dist/plugin/gateway-client.js +0 -200
  132. package/dist/plugin/log-bridge.d.ts +0 -22
  133. package/dist/plugin/log-bridge.js +0 -363
  134. package/openclaw.plugin.json +0 -87
@@ -1,177 +0,0 @@
1
- export interface MonitorSession {
2
- key: string;
3
- agentId: string;
4
- platform: string;
5
- recipient: string;
6
- isGroup: boolean;
7
- lastActivityAt: number;
8
- status: "idle" | "active" | "thinking";
9
- spawnedBy?: string;
10
- messageCount?: number;
11
- totalCostUsd?: number;
12
- totalInputTokens?: number;
13
- totalOutputTokens?: number;
14
- }
15
- export type MonitorActionType = "start" | "streaming" | "complete" | "aborted" | "error" | "tool_call" | "tool_result";
16
- export type MonitorActionEventType = "chat" | "agent" | "system";
17
- export interface MonitorAction {
18
- id: string;
19
- runId: string;
20
- sessionKey: string;
21
- seq: number;
22
- type: MonitorActionType;
23
- eventType: MonitorActionEventType;
24
- timestamp: number;
25
- content?: string;
26
- toolName?: string;
27
- toolArgs?: unknown;
28
- startedAt?: number;
29
- endedAt?: number;
30
- duration?: number;
31
- inputTokens?: number;
32
- outputTokens?: number;
33
- stopReason?: string;
34
- costUsd?: number;
35
- model?: string;
36
- provider?: string;
37
- }
38
- export type MonitorExecEventType = "started" | "output" | "completed";
39
- export type MonitorExecProcessStatus = "running" | "completed" | "failed";
40
- export interface MonitorExecOutputChunk {
41
- id: string;
42
- stream: "stdout" | "stderr" | string;
43
- text: string;
44
- timestamp: number;
45
- }
46
- export interface MonitorExecEvent {
47
- id: string;
48
- execId: string;
49
- runId: string;
50
- pid: number;
51
- sessionId?: string;
52
- sessionKey?: string;
53
- eventType: MonitorExecEventType;
54
- command?: string;
55
- stream?: "stdout" | "stderr" | string;
56
- output?: string;
57
- startedAt?: number;
58
- durationMs?: number;
59
- exitCode?: number;
60
- status?: string;
61
- timestamp: number;
62
- }
63
- export interface MonitorExecProcess {
64
- id: string;
65
- runId: string;
66
- pid: number;
67
- command: string;
68
- sessionId?: string;
69
- sessionKey?: string;
70
- status: MonitorExecProcessStatus;
71
- startedAt: number;
72
- completedAt?: number;
73
- durationMs?: number;
74
- exitCode?: number;
75
- outputs: MonitorExecOutputChunk[];
76
- outputTruncated?: boolean;
77
- timestamp: number;
78
- lastActivityAt: number;
79
- }
80
- export interface ChatEvent {
81
- runId: string;
82
- sessionKey: string;
83
- seq: number;
84
- state: "delta" | "final" | "aborted" | "error";
85
- message?: unknown;
86
- errorMessage?: string;
87
- usage?: {
88
- inputTokens?: number;
89
- outputTokens?: number;
90
- };
91
- stopReason?: string;
92
- }
93
- export interface AgentEvent {
94
- runId: string;
95
- seq: number;
96
- stream: string;
97
- ts: number;
98
- data: Record<string, unknown>;
99
- sessionKey?: string;
100
- }
101
- export interface ExecStartedEvent {
102
- pid: number;
103
- command: string;
104
- sessionId: string;
105
- runId: string;
106
- startedAt: number;
107
- }
108
- export interface ExecOutputEvent {
109
- pid: number;
110
- runId: string;
111
- sessionId?: string;
112
- stream: "stdout" | "stderr" | string;
113
- output: string;
114
- }
115
- export interface ExecCompletedEvent {
116
- pid: number;
117
- runId: string;
118
- sessionId?: string;
119
- exitCode: number;
120
- durationMs: number;
121
- status: string;
122
- }
123
- export declare function parseSessionKey(key: string): {
124
- agentId: string;
125
- platform: string;
126
- recipient: string;
127
- isGroup: boolean;
128
- };
129
- export interface CollectionStats {
130
- sessions: number;
131
- actions: number;
132
- execs: number;
133
- runSessionMapSize: number;
134
- totalCostUsd?: number;
135
- }
136
- export interface DiagnosticUsageEvent {
137
- type: "model.usage";
138
- ts: number;
139
- seq: number;
140
- sessionKey?: string;
141
- sessionId?: string;
142
- channel?: string;
143
- provider?: string;
144
- model?: string;
145
- usage: {
146
- input?: number;
147
- output?: number;
148
- cacheRead?: number;
149
- cacheWrite?: number;
150
- promptTokens?: number;
151
- total?: number;
152
- };
153
- context?: {
154
- limit?: number;
155
- used?: number;
156
- };
157
- costUsd?: number;
158
- durationMs?: number;
159
- }
160
- export interface CostUsageTotals {
161
- input: number;
162
- output: number;
163
- cacheRead: number;
164
- cacheWrite: number;
165
- totalTokens: number;
166
- totalCost: number;
167
- inputCost: number;
168
- outputCost: number;
169
- cacheReadCost: number;
170
- cacheWriteCost: number;
171
- missingCostEntries: number;
172
- }
173
- export interface CostUsageSummary {
174
- totals: CostUsageTotals;
175
- byModel?: Record<string, CostUsageTotals>;
176
- bySession?: Record<string, CostUsageTotals>;
177
- }
@@ -1,15 +0,0 @@
1
- // ─── Session Types ───────────────────────────────────────────────────────────
2
- // ─── Utility Functions ───────────────────────────────────────────────────────
3
- export function parseSessionKey(key) {
4
- // Format: "agent:main:discord:channel:1234567890"
5
- // Or: "agent:main:telegram:group:12345"
6
- // Or: "agent:main:whatsapp:+1234567890"
7
- const parts = key.split(":");
8
- const agentId = parts[1] || "unknown";
9
- const platform = parts[2] || "unknown";
10
- // Check if 4th part indicates a type (channel, group, dm, etc)
11
- const hasType = ["channel", "group", "dm", "thread"].includes(parts[3] || "");
12
- const isGroup = parts[3] === "group" || parts[3] === "channel";
13
- const recipient = hasType ? parts.slice(3).join(":") : parts.slice(3).join(":");
14
- return { agentId, platform, recipient, isGroup };
15
- }
@@ -1,13 +0,0 @@
1
- export type { AlertChannel, AlertEnricher, AlertEvent, AlertRuleDefinition, AlertSeverity, AlertTarget, DiagnosticSnapshot, EvaluatorState, HeartbeatSnapshot, MonitorConfig, RuleContext, RuleOverride, OpenAlertsEvent, OpenAlertsEventType, OpenAlertsInitOptions, OpenAlertsLogger, StoredEvent, WindowEntry, } from "./types.js";
2
- export { DEFAULTS, LOG_FILENAME, STORE_DIR_NAME } from "./types.js";
3
- export { OpenAlertsEngine } from "./engine.js";
4
- export { OpenAlertsEventBus } from "./event-bus.js";
5
- export { AlertDispatcher } from "./alert-channel.js";
6
- export { createEvaluatorState, processEvent, processWatchdogTick, warmFromHistory, } from "./evaluator.js";
7
- export { ALL_RULES } from "./rules.js";
8
- export { appendEvent, pruneLog, readAllEvents, readRecentEvents, } from "./store.js";
9
- export { createLlmEnricher, type LlmEnricherOptions } from "./llm-enrichment.js";
10
- export { formatAlertMessage, formatAlertsOutput, formatHealthOutput, } from "./formatter.js";
11
- export { createPlatformSync, type PlatformSync } from "./platform.js";
12
- export { BoundedMap, type BoundedMapOptions, type BoundedMapStats, } from "./bounded-map.js";
13
- export type { MonitorSession, MonitorActionType, MonitorActionEventType, MonitorAction, MonitorExecEventType, MonitorExecProcessStatus, MonitorExecOutputChunk, MonitorExecEvent, MonitorExecProcess, CollectionStats, DiagnosticUsageEvent, CostUsageTotals, CostUsageSummary, } from "../collections/types.js";
@@ -1,23 +0,0 @@
1
- // OpenAlerts core — engine, rules, evaluator, store
2
- // Constants
3
- export { DEFAULTS, LOG_FILENAME, STORE_DIR_NAME } from "./types.js";
4
- // Engine
5
- export { OpenAlertsEngine } from "./engine.js";
6
- // Event Bus
7
- export { OpenAlertsEventBus } from "./event-bus.js";
8
- // Alert Dispatcher
9
- export { AlertDispatcher } from "./alert-channel.js";
10
- // Evaluator
11
- export { createEvaluatorState, processEvent, processWatchdogTick, warmFromHistory, } from "./evaluator.js";
12
- // Rules
13
- export { ALL_RULES } from "./rules.js";
14
- // Store
15
- export { appendEvent, pruneLog, readAllEvents, readRecentEvents, } from "./store.js";
16
- // LLM Enrichment
17
- export { createLlmEnricher } from "./llm-enrichment.js";
18
- // Formatter
19
- export { formatAlertMessage, formatAlertsOutput, formatHealthOutput, } from "./formatter.js";
20
- // Platform
21
- export { createPlatformSync } from "./platform.js";
22
- // Bounded Map
23
- export { BoundedMap, } from "./bounded-map.js";
@@ -1,21 +0,0 @@
1
- import type { AlertEnricher, OpenAlertsLogger } from "./types.js";
2
- export type LlmEnricherOptions = {
3
- /** Model string from config, e.g. "openai/gpt-5-nano" */
4
- modelString: string;
5
- /** Pre-resolved API key (caller reads from env to avoid env+fetch in same file) */
6
- apiKey: string;
7
- /** Logger for debug/warn messages */
8
- logger?: OpenAlertsLogger;
9
- /** Timeout in ms (default: 10000) */
10
- timeoutMs?: number;
11
- };
12
- /**
13
- * Resolve the environment variable name for a given model string's provider.
14
- * Returns null if the model string is invalid or the provider is unknown.
15
- */
16
- export declare function resolveApiKeyEnvVar(modelString: string): string | null;
17
- /**
18
- * Create an AlertEnricher that calls an LLM to add a summary + action to alerts.
19
- * Returns null if provider can't be resolved.
20
- */
21
- export declare function createLlmEnricher(opts: LlmEnricherOptions): AlertEnricher | null;
@@ -1,180 +0,0 @@
1
- const PROVIDER_MAP = {
2
- openai: {
3
- type: "openai-compatible",
4
- baseUrl: "https://api.openai.com/v1",
5
- apiKeyEnvVar: "OPENAI_API_KEY",
6
- },
7
- groq: {
8
- type: "openai-compatible",
9
- baseUrl: "https://api.groq.com/openai/v1",
10
- apiKeyEnvVar: "GROQ_API_KEY",
11
- },
12
- together: {
13
- type: "openai-compatible",
14
- baseUrl: "https://api.together.xyz/v1",
15
- apiKeyEnvVar: "TOGETHER_API_KEY",
16
- },
17
- deepseek: {
18
- type: "openai-compatible",
19
- baseUrl: "https://api.deepseek.com/v1",
20
- apiKeyEnvVar: "DEEPSEEK_API_KEY",
21
- },
22
- anthropic: {
23
- type: "anthropic",
24
- baseUrl: "https://api.anthropic.com/v1",
25
- apiKeyEnvVar: "ANTHROPIC_API_KEY",
26
- },
27
- };
28
- // ─── Prompt ─────────────────────────────────────────────────────────────────
29
- function buildPrompt(alert) {
30
- return `You are a concise DevOps alert analyst. Given this monitoring alert, provide:
31
- 1. A brief human-friendly summary (1 sentence, plain language)
32
- 2. One actionable suggestion to resolve it
33
-
34
- Alert:
35
- - Rule: ${alert.ruleId}
36
- - Severity: ${alert.severity}
37
- - Title: ${alert.title}
38
- - Detail: ${alert.detail}
39
-
40
- Reply in exactly this format (2 lines only):
41
- Summary: <your summary>
42
- Action: <your suggestion>`;
43
- }
44
- // ─── Response Parsing ───────────────────────────────────────────────────────
45
- function parseEnrichment(text) {
46
- const lines = text.trim().split("\n");
47
- let summary = "";
48
- let action = "";
49
- for (const line of lines) {
50
- const trimmed = line.trim();
51
- if (trimmed.toLowerCase().startsWith("summary:")) {
52
- summary = trimmed.slice("summary:".length).trim();
53
- }
54
- else if (trimmed.toLowerCase().startsWith("action:")) {
55
- action = trimmed.slice("action:".length).trim();
56
- }
57
- }
58
- if (!summary && !action)
59
- return null;
60
- return { summary, action };
61
- }
62
- // ─── HTTP Calls ─────────────────────────────────────────────────────────────
63
- async function callOpenAICompatible(baseUrl, apiKey, model, prompt, timeoutMs) {
64
- const controller = new AbortController();
65
- const timer = setTimeout(() => controller.abort(), timeoutMs);
66
- try {
67
- const res = await fetch(`${baseUrl}/chat/completions`, {
68
- method: "POST",
69
- headers: {
70
- "Content-Type": "application/json",
71
- Authorization: `Bearer ${apiKey}`,
72
- },
73
- body: JSON.stringify({
74
- model,
75
- messages: [{ role: "user", content: prompt }],
76
- max_tokens: 200,
77
- temperature: 0.3,
78
- }),
79
- signal: controller.signal,
80
- });
81
- if (!res.ok)
82
- return null;
83
- const data = (await res.json());
84
- return data.choices?.[0]?.message?.content ?? null;
85
- }
86
- catch {
87
- return null;
88
- }
89
- finally {
90
- clearTimeout(timer);
91
- }
92
- }
93
- async function callAnthropic(baseUrl, apiKey, model, prompt, timeoutMs) {
94
- const controller = new AbortController();
95
- const timer = setTimeout(() => controller.abort(), timeoutMs);
96
- try {
97
- const res = await fetch(`${baseUrl}/messages`, {
98
- method: "POST",
99
- headers: {
100
- "Content-Type": "application/json",
101
- "x-api-key": apiKey,
102
- "anthropic-version": "2023-06-01",
103
- },
104
- body: JSON.stringify({
105
- model,
106
- max_tokens: 200,
107
- messages: [{ role: "user", content: prompt }],
108
- }),
109
- signal: controller.signal,
110
- });
111
- if (!res.ok)
112
- return null;
113
- const data = (await res.json());
114
- const textBlock = data.content?.find((b) => b.type === "text");
115
- return textBlock?.text ?? null;
116
- }
117
- catch {
118
- return null;
119
- }
120
- finally {
121
- clearTimeout(timer);
122
- }
123
- }
124
- // ─── Factory ────────────────────────────────────────────────────────────────
125
- /**
126
- * Resolve the environment variable name for a given model string's provider.
127
- * Returns null if the model string is invalid or the provider is unknown.
128
- */
129
- export function resolveApiKeyEnvVar(modelString) {
130
- const slashIdx = modelString.indexOf("/");
131
- if (slashIdx < 1)
132
- return null;
133
- const providerKey = modelString.slice(0, slashIdx).toLowerCase();
134
- return PROVIDER_MAP[providerKey]?.apiKeyEnvVar ?? null;
135
- }
136
- /**
137
- * Create an AlertEnricher that calls an LLM to add a summary + action to alerts.
138
- * Returns null if provider can't be resolved.
139
- */
140
- export function createLlmEnricher(opts) {
141
- const { modelString, apiKey, logger, timeoutMs = 10_000 } = opts;
142
- // Parse "provider/model-name" format
143
- const slashIdx = modelString.indexOf("/");
144
- if (slashIdx < 1) {
145
- logger?.warn(`openalerts: llm-enrichment skipped — invalid model string "${modelString}"`);
146
- return null;
147
- }
148
- const providerKey = modelString.slice(0, slashIdx).toLowerCase();
149
- const model = modelString.slice(slashIdx + 1);
150
- const providerConfig = PROVIDER_MAP[providerKey];
151
- if (!providerConfig) {
152
- logger?.warn(`openalerts: llm-enrichment skipped — unknown provider "${providerKey}"`);
153
- return null;
154
- }
155
- logger?.info(`openalerts: llm-enrichment enabled (${providerKey}/${model})`);
156
- return async (alert) => {
157
- const prompt = buildPrompt(alert);
158
- let responseText = null;
159
- if (providerConfig.type === "anthropic") {
160
- responseText = await callAnthropic(providerConfig.baseUrl, apiKey, model, prompt, timeoutMs);
161
- }
162
- else {
163
- responseText = await callOpenAICompatible(providerConfig.baseUrl, apiKey, model, prompt, timeoutMs);
164
- }
165
- if (!responseText)
166
- return null;
167
- const parsed = parseEnrichment(responseText);
168
- if (!parsed)
169
- return null;
170
- // Append enrichment to the original detail
171
- let enrichedDetail = alert.detail;
172
- if (parsed.summary) {
173
- enrichedDetail += `\n\nSummary: ${parsed.summary}`;
174
- }
175
- if (parsed.action) {
176
- enrichedDetail += `\nAction: ${parsed.action}`;
177
- }
178
- return { ...alert, detail: enrichedDetail };
179
- };
180
- }
@@ -1,17 +0,0 @@
1
- import { type OpenAlertsLogger, type StoredEvent } from "./types.js";
2
- export type PlatformSync = {
3
- enqueue: (event: StoredEvent) => void;
4
- flush: () => Promise<void>;
5
- stop: () => void;
6
- isConnected: () => boolean;
7
- };
8
- /**
9
- * Create a platform sync instance that batches events and pushes them
10
- * to the OpenAlerts backend API. Only active when apiKey is provided.
11
- */
12
- export declare function createPlatformSync(opts: {
13
- apiKey: string;
14
- baseUrl?: string;
15
- logger: OpenAlertsLogger;
16
- logPrefix?: string;
17
- }): PlatformSync;
@@ -1,93 +0,0 @@
1
- import { DEFAULTS } from "./types.js";
2
- /**
3
- * Create a platform sync instance that batches events and pushes them
4
- * to the OpenAlerts backend API. Only active when apiKey is provided.
5
- */
6
- export function createPlatformSync(opts) {
7
- const { apiKey, logger } = opts;
8
- const baseUrl = opts.baseUrl?.replace(/\/+$/, "") ?? "https://api.openalerts.dev";
9
- const prefix = opts.logPrefix ?? "openalerts";
10
- let batch = [];
11
- let flushTimer = null;
12
- let disabled = false;
13
- let connected = true;
14
- // Start periodic flush
15
- flushTimer = setInterval(() => {
16
- void doFlush().catch(() => { });
17
- }, DEFAULTS.platformFlushIntervalMs);
18
- async function doFlush() {
19
- if (disabled || batch.length === 0)
20
- return;
21
- const events = batch.splice(0, DEFAULTS.platformBatchSize);
22
- const body = JSON.stringify({
23
- events,
24
- plugin_version: "0.1.0",
25
- ts: Date.now(),
26
- });
27
- let lastErr;
28
- for (let attempt = 0; attempt < 2; attempt++) {
29
- try {
30
- const res = await fetch(`${baseUrl}/api/monitor/ingest`, {
31
- method: "POST",
32
- headers: {
33
- "Content-Type": "application/json",
34
- Authorization: `Bearer ${apiKey}`,
35
- },
36
- body,
37
- signal: AbortSignal.timeout(15_000),
38
- });
39
- if (res.ok) {
40
- connected = true;
41
- return; // Success
42
- }
43
- if (res.status === 401 || res.status === 403) {
44
- logger.warn(`${prefix}: invalid API key (${res.status}). Platform sync disabled. Check your key at app.openalerts.dev.`);
45
- disabled = true;
46
- connected = false;
47
- return;
48
- }
49
- lastErr = `HTTP ${res.status}`;
50
- }
51
- catch (err) {
52
- lastErr = err;
53
- }
54
- // Wait before retry
55
- if (attempt < 1) {
56
- await new Promise((r) => setTimeout(r, 5000));
57
- }
58
- }
59
- // Failed after retries — put events back and log
60
- batch.unshift(...events);
61
- // Cap batch to prevent unbounded growth
62
- if (batch.length > DEFAULTS.platformBatchSize * 2) {
63
- batch = batch.slice(-DEFAULTS.platformBatchSize);
64
- }
65
- connected = false;
66
- logger.warn(`${prefix}: platform sync failed: ${String(lastErr)}`);
67
- }
68
- return {
69
- enqueue(event) {
70
- if (disabled)
71
- return;
72
- batch.push(event);
73
- // Auto-flush if batch full
74
- if (batch.length >= DEFAULTS.platformBatchSize) {
75
- void doFlush().catch(() => { });
76
- }
77
- },
78
- async flush() {
79
- await doFlush();
80
- },
81
- stop() {
82
- if (flushTimer) {
83
- clearInterval(flushTimer);
84
- flushTimer = null;
85
- }
86
- // Final flush attempt (best-effort, don't await in stop)
87
- void doFlush().catch(() => { });
88
- },
89
- isConnected() {
90
- return connected && !disabled;
91
- },
92
- };
93
- }
package/dist/index.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
- declare const plugin: {
3
- id: string;
4
- name: string;
5
- description: string;
6
- register(api: OpenClawPluginApi): void;
7
- };
8
- export default plugin;