antenna-openclaw-plugin 1.1.0 โ†’ 1.2.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.
package/index.ts CHANGED
@@ -288,7 +288,7 @@ export default function register(api: any) {
288
288
  return { ref, emoji: p.emoji || "๐Ÿ‘ค", name: p.display_name || "ๅŒฟๅ", line1: p.line1, line2: p.line2, line3: p.line3 };
289
289
  });
290
290
  (api as any)._antennaRefMap = gRefMap;
291
- try { await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: JSON.stringify(gRefMap) }); } catch {}
291
+ try { await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: gRefMap }); } catch {}
292
292
  for (const p of globalOthers) {
293
293
  try { await supabase.rpc("log_recommendation", { p_device_id: deviceId, p_recommended_id: p.device_id }); } catch {}
294
294
  }
@@ -318,7 +318,7 @@ export default function register(api: any) {
318
318
  // Store ref map for accept โ€” memory + DB
319
319
  (api as any)._antennaRefMap = _refMap;
320
320
  try {
321
- await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: JSON.stringify(_refMap) });
321
+ await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: _refMap });
322
322
  } catch { /* best effort */ }
323
323
 
324
324
  return ok({
@@ -614,7 +614,7 @@ export default function register(api: any) {
614
614
  // Persist refs + log recommendation
615
615
  (api as any)._antennaRefMap = { ...(api as any)._antennaRefMap, ..._refMap };
616
616
  try {
617
- await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: JSON.stringify(_refMap) });
617
+ await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: _refMap });
618
618
  } catch { /* best effort */ }
619
619
  for (const p of results) {
620
620
  await supabase.rpc("log_recommendation", { p_device_id: deviceId, p_recommended_id: p.device_id });
@@ -627,6 +627,105 @@ export default function register(api: any) {
627
627
  },
628
628
  });
629
629
 
630
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
631
+ // Tool: antenna_event_create
632
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
633
+ api.registerTool({
634
+ name: "antenna_event_create",
635
+ description: "Create an event. Returns a shareable link (antenna.fyi/e/CODE) for participants to join.",
636
+ parameters: {
637
+ type: "object",
638
+ properties: {
639
+ name: { type: "string", description: "Event name" },
640
+ sender_id: { type: "string" },
641
+ channel: { type: "string" },
642
+ lat: { type: "number", description: "Event latitude" },
643
+ lng: { type: "number", description: "Event longitude" },
644
+ starts_at: { type: "string", description: "Start time ISO" },
645
+ ends_at: { type: "string", description: "End time ISO" },
646
+ },
647
+ required: ["name", "sender_id", "channel"],
648
+ },
649
+ async execute(_id: string, params: any) {
650
+ const cfg = getConfig(api);
651
+ const supabase = getSupabase(cfg);
652
+ const deviceId = deriveDeviceId(params.sender_id, params.channel);
653
+ const { data, error } = await supabase.rpc("create_event", {
654
+ p_name: params.name,
655
+ p_lat: params.lat || null,
656
+ p_lng: params.lng || null,
657
+ p_created_by: deviceId,
658
+ p_starts_at: params.starts_at || new Date().toISOString(),
659
+ p_ends_at: params.ends_at || new Date(Date.now() + 12*60*60*1000).toISOString(),
660
+ });
661
+ if (error) return ok({ error: error.message });
662
+ return ok(data);
663
+ },
664
+ });
665
+
666
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
667
+ // Tool: antenna_event_join
668
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
669
+ api.registerTool({
670
+ name: "antenna_event_join",
671
+ description: "Join an event by its code from the event URL.",
672
+ parameters: {
673
+ type: "object",
674
+ properties: {
675
+ code: { type: "string", description: "Event code" },
676
+ sender_id: { type: "string" },
677
+ channel: { type: "string" },
678
+ },
679
+ required: ["code", "sender_id", "channel"],
680
+ },
681
+ async execute(_id: string, params: any) {
682
+ const cfg = getConfig(api);
683
+ const supabase = getSupabase(cfg);
684
+ const deviceId = deriveDeviceId(params.sender_id, params.channel);
685
+ const { data, error } = await supabase.rpc("join_event", { p_code: params.code, p_device_id: deviceId });
686
+ if (error) return ok({ error: error.message });
687
+ return ok(data);
688
+ },
689
+ });
690
+
691
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
692
+ // Tool: antenna_event_scan
693
+ // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
694
+ api.registerTool({
695
+ name: "antenna_event_scan",
696
+ description: "Scan people in an event. No distance limit.",
697
+ parameters: {
698
+ type: "object",
699
+ properties: {
700
+ code: { type: "string", description: "Event code" },
701
+ sender_id: { type: "string" },
702
+ channel: { type: "string" },
703
+ },
704
+ required: ["code", "sender_id", "channel"],
705
+ },
706
+ async execute(_id: string, params: any) {
707
+ const cfg = getConfig(api);
708
+ const supabase = getSupabase(cfg);
709
+ const deviceId = deriveDeviceId(params.sender_id, params.channel);
710
+
711
+ const { data, error } = await supabase.rpc("event_participants_list", { p_code: params.code, p_device_id: deviceId });
712
+ if (error) return ok({ error: error.message });
713
+
714
+ const others = (data || []) as any[];
715
+ const _refMap: Record<string, string> = {};
716
+ const profiles = others.map((p, i) => {
717
+ const ref = String(i + 1);
718
+ _refMap[ref] = p.device_id;
719
+ return { ref, emoji: p.emoji || "๐Ÿ‘ค", name: p.display_name || "ๅŒฟๅ", line1: p.line1, line2: p.line2, line3: p.line3, source: "event" };
720
+ });
721
+
722
+ (api as any)._antennaRefMap = { ...(api as any)._antennaRefMap, ..._refMap };
723
+ try { await supabase.rpc("save_scan_refs", { p_owner: deviceId, p_refs: _refMap }); } catch {}
724
+
725
+ return ok({ count: profiles.length, profiles, event: true });
726
+ },
727
+ });
728
+
630
729
  // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
631
730
  // Tool: antenna_pass
632
731
  // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antenna-openclaw-plugin",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Antenna โ€” agent-mediated nearby people discovery for OpenClaw",
5
5
  "openclaw": {
6
6
  "extensions": ["./index.ts"]
@@ -83,7 +83,7 @@ After receiving the nearby profiles, **you decide** who to recommend:
83
83
  View or update the user's name card.
84
84
  - `action`: "get" or "set"
85
85
  - `sender_id`, `channel`: from context
86
- - For "set": `display_name`, `emoji`, `line1`, `line2`, `line3`, `visible`
86
+ - For "set": `display_name`, `emoji`, `line1`, `line2`, `line3`, `visible`, `matching_context`
87
87
 
88
88
  The name card has:
89
89
  - **emoji**: a single emoji that represents them
@@ -91,6 +91,12 @@ The name card has:
91
91
  - **line1**: who they are / what they do
92
92
  - **line2**: what they're into
93
93
  - **line3**: what they're looking for right now
94
+ - **matching_context** (optional, not shown to others): A richer description generated by the agent based on what it knows about the user โ€” career background, tech stack, interests, projects, personality traits. ~200 words. Only used for embedding-based matching, never displayed to other users.
95
+
96
+ **After saving the profile, generate `matching_context` automatically** based on your knowledge of the user (memory, conversations, context). Don't ask the user to write it โ€” you write it. Example:
97
+ > "Product designer at a tech company in Beijing, focusing on AI search experience. Interested in music (Sakamoto), swimming, cooking, language learning. Recently exploring AI agent ecosystems and social discovery. Looking to connect with AI builders, indie hackers, and creative technologists."
98
+ - **line2**: what they're into
99
+ - **line3**: what they're looking for right now
94
100
 
95
101
  ### `antenna_accept`
96
102
  Accept a match after the user sees results. Can optionally include contact info to share.
@@ -251,3 +257,21 @@ Plugin ่‡ชๅธฆๅŽๅฐๆœๅŠก๏ผŒๆฏ 10 ๅˆ†้’Ÿ่ฝฎ่ฏขไธ€ๆฌก Supabase ๆŸฅๆ–ฐ็š„ mutual
251
257
  3. ๅฆ‚ๆžœๅฏนๆ–นๅˆ†ไบซไบ†่”็ณปๆ–นๅผ๏ผŒไธ€ๅนถๅฑ•็คบ
252
258
 
253
259
  ็”จๆˆทไธ้œ€่ฆไธปๅŠจ้—ฎ๏ผŒagent ไผš่‡ชๅŠจๆ”ถๅˆฐ้€š็Ÿฅใ€‚
260
+
261
+ ### `antenna_event_create`
262
+ Create an event. Returns a shareable link (antenna.fyi/e/CODE).
263
+ - `name`: event name
264
+ - `sender_id`, `channel`: from context
265
+ - `lat`, `lng`: optional event location
266
+ - `starts_at`, `ends_at`: optional time range (default: now to +12h)
267
+
268
+ ### `antenna_event_join`
269
+ Join an event by code.
270
+ - `code`: from the event URL (antenna.fyi/e/CODE)
271
+ - `sender_id`, `channel`: from context
272
+
273
+ ### `antenna_event_scan`
274
+ Scan people in an event. No distance limit โ€” returns all participants.
275
+ - `code`: event code
276
+ - `sender_id`, `channel`: from context
277
+ - Returns profiles with `source: "event"` tag