twindex-openclaw-plugin 0.8.3 → 0.8.4

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.
@@ -2,7 +2,7 @@
2
2
  "id": "twindex",
3
3
  "name": "New Lore",
4
4
  "description": "Music intelligence for AI agents. Get notified about tours, merch drops, releases, and presales for your favorite artists.",
5
- "version": "0.8.3",
5
+ "version": "0.8.4",
6
6
  "skills": ["./skills"],
7
7
  "configSchema": {
8
8
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twindex-openclaw-plugin",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "description": "Music intelligence for AI agents. Tours, merch drops, releases, presales.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -13,23 +13,36 @@ const FREQUENCY_MS: Record<string, number> = {
13
13
  daily: 24 * 60 * 60 * 1000, // 24 hours
14
14
  };
15
15
 
16
+ const INITIAL_POLL_DELAY_MS = 15 * 1000;
17
+
16
18
  function sendMessage(
17
19
  message: string,
18
20
  channel: string,
19
21
  target: string,
20
- ): Promise<boolean> {
22
+ ): Promise<{ ok: boolean; reason?: string }> {
21
23
  return new Promise((resolve) => {
22
24
  execFile(
23
25
  "openclaw",
24
26
  ["message", "send", "--channel", channel, "--target", target, "-m", message],
25
- { timeout: 30_000 },
26
- (err) => resolve(!err),
27
+ { timeout: 10_000 },
28
+ (err, stdout, stderr) => {
29
+ if (!err) {
30
+ resolve({ ok: true });
31
+ return;
32
+ }
33
+
34
+ const details = [err.message, stderr?.trim(), stdout?.trim()]
35
+ .filter(Boolean)
36
+ .join(" | ");
37
+ resolve({ ok: false, reason: details || "unknown delivery error" });
38
+ },
27
39
  );
28
40
  });
29
41
  }
30
42
 
31
43
  export function createNotificationService(api: any) {
32
44
  let timer: ReturnType<typeof setInterval> | null = null;
45
+ let startupPoll: ReturnType<typeof setTimeout> | null = null;
33
46
  let running = false;
34
47
  let polling = false; // guard against overlapping polls
35
48
 
@@ -143,15 +156,17 @@ export function createNotificationService(api: any) {
143
156
  message += `\n\nWant to see how it looks on you? Send me a selfie and I'll show you.`;
144
157
  }
145
158
 
146
- const delivered = await sendMessage(message, channel, target);
147
- if (delivered) {
159
+ const delivery = await sendMessage(message, channel, target);
160
+ if (delivery.ok) {
148
161
  try {
149
162
  await twindex.markRead(apiKey, [notif.id]);
150
163
  } catch {
151
164
  // Non-fatal — delivered but read status will catch up
152
165
  }
153
166
  } else {
154
- logger?.warn?.("Twindex: message delivery failed, will retry next poll");
167
+ logger?.warn?.(
168
+ `Twindex: message delivery failed, will retry next poll (${delivery.reason})`,
169
+ );
155
170
  break; // Don't pile up failed deliveries
156
171
  }
157
172
  }
@@ -171,6 +186,10 @@ export function createNotificationService(api: any) {
171
186
  clearInterval(timer);
172
187
  timer = null;
173
188
  }
189
+ if (startupPoll) {
190
+ clearTimeout(startupPoll);
191
+ startupPoll = null;
192
+ }
174
193
 
175
194
  const apiKey = getApiKey();
176
195
  if (!apiKey) {
@@ -182,11 +201,15 @@ export function createNotificationService(api: any) {
182
201
  const freq = getFrequency();
183
202
  const intervalMs = FREQUENCY_MS[freq] ?? FREQUENCY_MS.periodic;
184
203
 
185
- // Immediate first poll
186
- poll();
187
-
188
204
  timer = setInterval(poll, intervalMs);
189
- logger?.info?.(`Twindex: poll service started (${freq}, every ${intervalMs / 1000}s)`);
205
+ const initialDelay = Math.min(INITIAL_POLL_DELAY_MS, intervalMs);
206
+ startupPoll = setTimeout(() => {
207
+ startupPoll = null;
208
+ poll();
209
+ }, initialDelay);
210
+ logger?.info?.(
211
+ `Twindex: poll service started (${freq}, every ${intervalMs / 1000}s, initial delay ${initialDelay / 1000}s)`,
212
+ );
190
213
  },
191
214
 
192
215
  stop() {
@@ -195,6 +218,10 @@ export function createNotificationService(api: any) {
195
218
  clearInterval(timer);
196
219
  timer = null;
197
220
  }
221
+ if (startupPoll) {
222
+ clearTimeout(startupPoll);
223
+ startupPoll = null;
224
+ }
198
225
  logger?.info?.("Twindex: poll service stopped");
199
226
  },
200
227
  };