twindex-openclaw-plugin 0.7.6 → 0.8.1

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.7.6",
5
+ "version": "0.8.1",
6
6
  "skills": ["./skills"],
7
7
  "configSchema": {
8
8
  "type": "object",
@@ -32,6 +32,10 @@
32
32
  "enum": ["telegram", "slack"],
33
33
  "default": "telegram",
34
34
  "description": "Delivery channel."
35
+ },
36
+ "city": {
37
+ "type": "string",
38
+ "description": "User's city. Tour notifications highlight shows near this city."
35
39
  }
36
40
  }
37
41
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "twindex-openclaw-plugin",
3
- "version": "0.7.6",
3
+ "version": "0.8.1",
4
4
  "description": "Music intelligence for AI agents. Tours, merch drops, releases, presales.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -2,16 +2,16 @@
2
2
  name: New Lore
3
3
  description: Music intelligence — tours, merch drops, releases, presales for your favorite artists.
4
4
  tools:
5
- - twindex_setup
6
- - twindex_subscribe
7
- - twindex_unsubscribe
8
- - twindex_check
9
- - twindex_subscriptions
10
- - twindex_artist
11
- - twindex_search
12
- - twindex_artists
13
- - twindex_upload_photo
14
- - twindex_try_on
5
+ - newlore_setup
6
+ - newlore_subscribe
7
+ - newlore_unsubscribe
8
+ - newlore_check
9
+ - newlore_subscriptions
10
+ - newlore_artist
11
+ - newlore_search
12
+ - newlore_artists
13
+ - newlore_upload_photo
14
+ - newlore_try_on
15
15
  ---
16
16
 
17
17
  # New Lore — Music Intelligence
@@ -24,7 +24,7 @@ YOU to set it up using your tools. Do NOT tell them to visit a website.
24
24
 
25
25
  When a user asks for artist updates (tours, merch, releases):
26
26
  1. Ask which artists and how often (realtime/periodic/daily)
27
- 2. Call `twindex_setup` with the artist slugs, frequency, and their chat ID
27
+ 2. Call `newlore_setup` with the artist slugs, frequency, and their chat ID
28
28
  3. That's it — notifications auto-deliver from then on
29
29
 
30
30
  You already know the user's chat ID from the conversation context.
@@ -32,36 +32,36 @@ Artist slugs are lowercase with hyphens: "linkin-park", "nick-cave-the-bad-seeds
32
32
 
33
33
  ## Adding more artists
34
34
 
35
- Use `twindex_subscribe`. The existing delivery schedule picks them up automatically.
35
+ Use `newlore_subscribe`. The existing delivery schedule picks them up automatically.
36
36
 
37
37
  ## Merch Try-On
38
38
 
39
39
  This is the killer feature. Users can see themselves wearing merch.
40
40
 
41
41
  **When a user sends a photo/selfie:**
42
- 1. Call `twindex_upload_photo` with NO parameters (it auto-finds the photo)
42
+ 1. Call `newlore_upload_photo` with NO parameters (it auto-finds the photo)
43
43
  2. Tell them they're all set for try-ons
44
44
 
45
45
  **When a user asks to try on a product:**
46
- 1. Call `twindex_try_on` with the artist slug and product name
46
+ 1. Call `newlore_try_on` with the artist slug and product name
47
47
  2. The server does FUZZY MATCHING — you don't need the exact name
48
48
  3. Partial names work: "the hat", "black hoodie", "tour tee" are all fine
49
49
  4. If the user references something you just showed them in a notification, use that product name
50
50
 
51
51
  **After a merch notification:**
52
52
  - If you showed a product and the user says "try that on" or "let me see it on me", you ALREADY KNOW the product name from the notification you just delivered. Use it directly.
53
- - If the user says "try that on" after a merch notification, just call `twindex_try_on` with only the artist slug — no product name needed. The server remembers which product was shown.
53
+ - If the user says "try that on" after a merch notification, just call `newlore_try_on` with only the artist slug — no product name needed. The server remembers which product was shown.
54
54
  - Do NOT browse the store or ask for clarification. Just call the tool.
55
55
 
56
56
  If try-on returns a 404 (no photo), ask the user to send a selfie first.
57
57
 
58
58
  ## Checking manually
59
59
 
60
- Use `twindex_check` to look for updates right now.
60
+ Use `newlore_check` to look for updates right now.
61
61
 
62
62
  ## Viewing artist details
63
63
 
64
- Use `twindex_artist` with a slug to get their full page.
64
+ Use `newlore_artist` with a slug to get their full page.
65
65
 
66
66
  ## Rules
67
67
 
package/src/index.ts CHANGED
@@ -26,9 +26,9 @@ export default function register(api: any) {
26
26
  if (!disk.plugins.entries.twindex) disk.plugins.entries.twindex = {};
27
27
  disk.plugins.entries.twindex.config = api.config.plugins.entries.twindex.config;
28
28
  writeFileSync(configPath, JSON.stringify(disk, null, 2) + "\n", "utf-8");
29
- api.logger?.info?.("Twindex: config persisted to disk");
29
+ api.logger?.info?.("NewLore: config persisted to disk");
30
30
  } catch (err: any) {
31
- api.logger?.warn?.(`Twindex: failed to persist config: ${err.message}`);
31
+ api.logger?.warn?.(`NewLore: failed to persist config: ${err.message}`);
32
32
  }
33
33
  }
34
34
 
@@ -78,10 +78,10 @@ export default function register(api: any) {
78
78
  for (const artist of config.artists) {
79
79
  try {
80
80
  await twindex.subscribe(apiKey, artist);
81
- api.logger?.info?.(`Twindex: auto-subscribed to ${artist}`);
81
+ api.logger?.info?.(`NewLore: auto-subscribed to ${artist}`);
82
82
  } catch (err: any) {
83
83
  api.logger?.warn?.(
84
- `Twindex: failed to subscribe to ${artist}: ${err.message}`,
84
+ `NewLore: failed to subscribe to ${artist}: ${err.message}`,
85
85
  );
86
86
  }
87
87
  }
@@ -92,17 +92,28 @@ export default function register(api: any) {
92
92
  if (chatTarget) {
93
93
  updates.chatTarget = chatTarget;
94
94
  updates.chatChannel = inferChatChannel();
95
- api.logger?.info?.(`Twindex: auto-detected chatTarget=${chatTarget}`);
95
+ api.logger?.info?.(`NewLore: auto-detected chatTarget=${chatTarget}`);
96
96
  }
97
97
 
98
98
  persistConfig(updates);
99
+
100
+ // Set city if configured
101
+ if (config.city) {
102
+ try {
103
+ await twindex.setCity(apiKey, config.city);
104
+ api.logger?.info?.(`NewLore: city set to ${config.city}`);
105
+ } catch (err: any) {
106
+ api.logger?.warn?.(`NewLore: failed to set city: ${err.message}`);
107
+ }
108
+ }
109
+
99
110
  pollService.start();
100
111
  api.logger?.info?.(
101
- "Twindex: auto-bootstrap complete. Delivery via polling.",
112
+ "NewLore: auto-bootstrap complete. Delivery via polling.",
102
113
  );
103
114
  }
104
115
  } catch (err: any) {
105
- api.logger?.warn?.(`Twindex: auto-bootstrap failed: ${err.message}`);
116
+ api.logger?.warn?.(`NewLore: auto-bootstrap failed: ${err.message}`);
106
117
  } finally {
107
118
  bootstrapping = false;
108
119
  }
@@ -111,7 +122,7 @@ export default function register(api: any) {
111
122
  // ── Tools ──────────────────────────────────────────────────────────
112
123
 
113
124
  api.registerTool({
114
- name: "twindex_setup",
125
+ name: "newlore_setup",
115
126
  description:
116
127
  "Set up New Lore music notifications for the user. YOU are the user's interface to New Lore — do NOT tell them to visit a website. Registers, subscribes to artists, and starts polling. Call this when the user asks for music updates, mentions newlore.ai, or wants to follow artists.",
117
128
  parameters: {
@@ -207,9 +218,9 @@ export default function register(api: any) {
207
218
  });
208
219
 
209
220
  api.registerTool({
210
- name: "twindex_subscribe",
221
+ name: "newlore_subscribe",
211
222
  description:
212
- "Subscribe to a new artist on Twindex. The existing delivery schedule will automatically pick up notifications for this artist.",
223
+ "Subscribe to a new artist on New Lore. The existing delivery schedule will automatically pick up notifications for this artist.",
213
224
  parameters: {
214
225
  type: "object",
215
226
  properties: {
@@ -225,7 +236,7 @@ export default function register(api: any) {
225
236
  if (!apiKey) {
226
237
  return {
227
238
  content: [
228
- { type: "text", text: "Not set up yet. Use twindex_setup first." },
239
+ { type: "text", text: "Not set up yet. Use newlore_setup first." },
229
240
  ],
230
241
  };
231
242
  }
@@ -254,8 +265,8 @@ export default function register(api: any) {
254
265
  });
255
266
 
256
267
  api.registerTool({
257
- name: "twindex_unsubscribe",
258
- description: "Unsubscribe from an artist on Twindex.",
268
+ name: "newlore_unsubscribe",
269
+ description: "Unsubscribe from an artist on New Lore.",
259
270
  parameters: {
260
271
  type: "object",
261
272
  properties: {
@@ -271,7 +282,7 @@ export default function register(api: any) {
271
282
  if (!apiKey) {
272
283
  return {
273
284
  content: [
274
- { type: "text", text: "Not set up yet. Use twindex_setup first." },
285
+ { type: "text", text: "Not set up yet. Use newlore_setup first." },
275
286
  ],
276
287
  };
277
288
  }
@@ -297,9 +308,9 @@ export default function register(api: any) {
297
308
  });
298
309
 
299
310
  api.registerTool({
300
- name: "twindex_check",
311
+ name: "newlore_check",
301
312
  description:
302
- "Check for unread Twindex notifications right now. Returns any pending artist updates.",
313
+ "Check for unread New Lore notifications right now. Returns any pending artist updates.",
303
314
  parameters: {
304
315
  type: "object",
305
316
  properties: {},
@@ -309,7 +320,7 @@ export default function register(api: any) {
309
320
  if (!apiKey) {
310
321
  return {
311
322
  content: [
312
- { type: "text", text: "Not set up yet. Use twindex_setup first." },
323
+ { type: "text", text: "Not set up yet. Use newlore_setup first." },
313
324
  ],
314
325
  };
315
326
  }
@@ -352,8 +363,8 @@ export default function register(api: any) {
352
363
  });
353
364
 
354
365
  api.registerTool({
355
- name: "twindex_subscriptions",
356
- description: "List your current Twindex subscriptions.",
366
+ name: "newlore_subscriptions",
367
+ description: "List your current New Lore subscriptions.",
357
368
  parameters: {
358
369
  type: "object",
359
370
  properties: {},
@@ -363,7 +374,7 @@ export default function register(api: any) {
363
374
  if (!apiKey) {
364
375
  return {
365
376
  content: [
366
- { type: "text", text: "Not set up yet. Use twindex_setup first." },
377
+ { type: "text", text: "Not set up yet. Use newlore_setup first." },
367
378
  ],
368
379
  };
369
380
  }
@@ -396,9 +407,9 @@ export default function register(api: any) {
396
407
  });
397
408
 
398
409
  api.registerTool({
399
- name: "twindex_artist",
410
+ name: "newlore_artist",
400
411
  description:
401
- "Get the full Twindex page for an artist. Returns detailed info including tours, merch, releases.",
412
+ "Get the full New Lore page for an artist. Returns detailed info including tours, merch, releases.",
402
413
  parameters: {
403
414
  type: "object",
404
415
  properties: {
@@ -429,9 +440,9 @@ export default function register(api: any) {
429
440
  });
430
441
 
431
442
  api.registerTool({
432
- name: "twindex_search",
443
+ name: "newlore_search",
433
444
  description:
434
- "Search the Twindex music index. Find artists by name, genre, or keyword.",
445
+ "Search the New Lore music index. Find artists by name, genre, or keyword.",
435
446
  parameters: {
436
447
  type: "object",
437
448
  properties: {
@@ -469,7 +480,7 @@ export default function register(api: any) {
469
480
  });
470
481
 
471
482
  api.registerTool({
472
- name: "twindex_upload_photo",
483
+ name: "newlore_upload_photo",
473
484
  description:
474
485
  "Upload the user's selfie for personalized merch try-on. When the user sends a photo in chat, call this tool with NO parameters — it automatically finds the most recent photo from the conversation. One photo per user — uploading replaces the previous one.",
475
486
  parameters: {
@@ -487,7 +498,7 @@ export default function register(api: any) {
487
498
  if (!apiKey) {
488
499
  return {
489
500
  content: [
490
- { type: "text", text: "Not set up yet. Use twindex_setup first." },
501
+ { type: "text", text: "Not set up yet. Use newlore_setup first." },
491
502
  ],
492
503
  };
493
504
  }
@@ -563,7 +574,7 @@ export default function register(api: any) {
563
574
  });
564
575
 
565
576
  api.registerTool({
566
- name: "twindex_try_on",
577
+ name: "newlore_try_on",
567
578
  description:
568
579
  "Generate an image of the user wearing a merch product. Requires a photo uploaded first. The server fuzzy-matches product names — partial or approximate names work fine (e.g. 'the hat', 'black hoodie', 'tour tee'). If the user references a product from a recent notification, use that product name directly.",
569
580
  parameters: {
@@ -588,7 +599,7 @@ export default function register(api: any) {
588
599
  if (!apiKey) {
589
600
  return {
590
601
  content: [
591
- { type: "text", text: "Not set up yet. Use twindex_setup first." },
602
+ { type: "text", text: "Not set up yet. Use newlore_setup first." },
592
603
  ],
593
604
  };
594
605
  }
@@ -634,8 +645,8 @@ export default function register(api: any) {
634
645
  });
635
646
 
636
647
  api.registerTool({
637
- name: "twindex_artists",
638
- description: "List all artists currently indexed on Twindex.",
648
+ name: "newlore_artists",
649
+ description: "List all artists currently indexed on New Lore.",
639
650
  parameters: {
640
651
  type: "object",
641
652
  properties: {},