antenna-fyi 1.2.5 → 1.2.7

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/lib/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // antenna CLI command handlers
2
2
 
3
- import { scan, getProfile, setProfile, accept, checkMatches, checkin, createBindToken, discover, createEvent, endEvent, joinEvent, eventScan, pass as passUser } from "./core.js";
3
+ import { scan, getProfile, setProfile, accept, checkMatches, checkin, createBindToken, discover, createEvent, endEvent, eventCheckin, joinEvent, eventScan, pass as passUser } from "./core.js";
4
4
  import { createInterface } from "readline";
5
5
  import { existsSync, mkdirSync, copyFileSync } from "fs";
6
6
  import { join, dirname } from "path";
@@ -141,7 +141,7 @@ export async function handleDiscover(f) {
141
141
  }
142
142
 
143
143
  export async function handleEvent(f) {
144
- const sub = f._?.[0] || Object.keys(f).find(k => ["create", "join", "scan", "end"].includes(k));
144
+ const sub = f._?.[0] || Object.keys(f).find(k => ["create", "join", "scan", "end", "checkin"].includes(k));
145
145
 
146
146
  if (f.end) {
147
147
  if (!f.code || !f.id) return console.error("Usage: antenna event --end --code abc123 --id telegram:123");
@@ -154,6 +154,13 @@ export async function handleEvent(f) {
154
154
  return;
155
155
  }
156
156
 
157
+ if (f.checkin) {
158
+ if (!f.code || !f.id) return console.error("Usage: antenna event --checkin --code abc123 --id telegram:123 [--lat 34.05 --lng -118.24]");
159
+ const result = await eventCheckin({ code: f.code, device_id: f.id, lat: f.lat ? +f.lat : undefined, lng: f.lng ? +f.lng : undefined });
160
+ console.log(`\nāœ… Checked in to event.\n`);
161
+ return;
162
+ }
163
+
157
164
  if (f.create || (!f.join && !f.scan && !f.end && f.name)) {
158
165
  if (!f.name) return console.error("Usage: antenna event --create --name 'AI Meetup' [--desc 'description'] [--og-image 'url']");
159
166
  const result = await createEvent({ name: f.name, device_id: f.id || null, lat: f.lat ? +f.lat : undefined, lng: f.lng ? +f.lng : undefined, description: f.desc || undefined, og_image: f['og-image'] || undefined });
@@ -180,9 +187,10 @@ export async function handleEvent(f) {
180
187
  if (!f.code) return console.error("Usage: antenna event --scan --code abc123 [--id telegram:123]");
181
188
  const result = await eventScan({ code: f.code, device_id: f.id || null });
182
189
  if (result.count === 0) return console.log("\nšŸŸļø No participants yet.\n");
183
- console.log(`\nšŸŸļø ${result.count} people in this event:\n`);
190
+ console.log(`\nšŸŸļø ${result.count} joined, ${result.checked_in_count || 0} checked in:\n`);
184
191
  result.profiles.forEach((p) => {
185
- console.log(` ${p.emoji} ${p.name}`);
192
+ const badge = p.checked_in ? " āœ…" : "";
193
+ console.log(` ${p.emoji} ${p.name}${badge}`);
186
194
  if (p.line1) console.log(` ${p.line1}`);
187
195
  console.log(` ref: ${p.ref}\n`);
188
196
  });
@@ -193,6 +201,7 @@ export async function handleEvent(f) {
193
201
  antenna event --create --name 'AI Meetup' [--id telegram:123] [--desc 'description'] [--og-image 'url']
194
202
  antenna event --join --code abc123 --id telegram:123
195
203
  antenna event --scan --code abc123 [--id telegram:123]
204
+ antenna event --checkin --code abc123 --id telegram:123 [--lat 34.05 --lng -118.24]
196
205
  antenna event --end --code abc123 --id telegram:123`);
197
206
  }
198
207
 
package/lib/core.js CHANGED
@@ -502,6 +502,17 @@ export async function endEvent({ code, device_id, supabaseUrl, supabaseKey }) {
502
502
  return data;
503
503
  }
504
504
 
505
+ export async function eventCheckin({ code, device_id, lat, lng, supabaseUrl, supabaseKey }) {
506
+ const sb = getClient(supabaseUrl, supabaseKey);
507
+ const fuzzy = (lat != null && lng != null) ? fuzzyCoord(lat, lng) : { lat: null, lng: null };
508
+ const { data, error } = await sb.rpc("event_checkin", {
509
+ p_code: code, p_device_id: device_id,
510
+ p_lat: fuzzy.lat, p_lng: fuzzy.lng,
511
+ });
512
+ if (error) throw new Error(error.message);
513
+ return data;
514
+ }
515
+
505
516
  export async function joinEvent({ code, device_id, supabaseUrl, supabaseKey }) {
506
517
  const sb = getClient(supabaseUrl, supabaseKey);
507
518
  const { data, error } = await sb.rpc("join_event", { p_code: code, p_device_id: device_id });
@@ -516,9 +527,11 @@ export async function eventScan({ code, device_id, supabaseUrl, supabaseKey }) {
516
527
 
517
528
  const others = data || [];
518
529
  const _refMap = {};
530
+ let checkedInCount = 0;
519
531
  const profiles = others.map((p, i) => {
520
532
  const ref = String(i + 1);
521
533
  _refMap[ref] = p.device_id;
534
+ if (p.checked_in) checkedInCount++;
522
535
  return {
523
536
  ref,
524
537
  name: p.display_name || "åŒæå",
@@ -526,6 +539,7 @@ export async function eventScan({ code, device_id, supabaseUrl, supabaseKey }) {
526
539
  line1: p.line1,
527
540
  line2: p.line2,
528
541
  line3: p.line3,
542
+ checked_in: !!p.checked_in,
529
543
  source: "event",
530
544
  };
531
545
  });
@@ -537,6 +551,7 @@ export async function eventScan({ code, device_id, supabaseUrl, supabaseKey }) {
537
551
 
538
552
  return {
539
553
  count: profiles.length,
554
+ checked_in_count: checkedInCount,
540
555
  profiles,
541
556
  _ref_map: _refMap,
542
557
  event: true,
@@ -19,6 +19,7 @@ from .tools import (
19
19
  handle_event_join,
20
20
  handle_event_scan,
21
21
  handle_event_end,
22
+ handle_event_checkin,
22
23
  _sb,
23
24
  _device_id,
24
25
  _my_device_ids,
@@ -36,6 +37,7 @@ from .schemas import (
36
37
  EVENT_JOIN_SCHEMA,
37
38
  EVENT_SCAN_SCHEMA,
38
39
  EVENT_END_SCHEMA,
40
+ EVENT_CHECKIN_SCHEMA,
39
41
  )
40
42
  import re
41
43
  import time
@@ -64,6 +66,7 @@ def register(ctx):
64
66
  ctx.register_tool("antenna_event_join", EVENT_JOIN_SCHEMA, handle_event_join)
65
67
  ctx.register_tool("antenna_event_scan", EVENT_SCAN_SCHEMA, handle_event_scan)
66
68
  ctx.register_tool("antenna_event_end", EVENT_END_SCHEMA, handle_event_end)
69
+ ctx.register_tool("antenna_event_checkin", EVENT_CHECKIN_SCHEMA, handle_event_checkin)
67
70
 
68
71
  # ── Hook: auto-detect location + check web GPS events ─────────
69
72
  def on_pre_llm(messages, **kwargs):
@@ -236,3 +236,19 @@ EVENT_END_SCHEMA = {
236
236
  "required": ["code", "sender_id", "channel"],
237
237
  },
238
238
  }
239
+
240
+ EVENT_CHECKIN_SCHEMA = {
241
+ "name": "antenna_event_checkin",
242
+ "description": "Check in at an event \u2014 marks you as present at the event location. Optionally updates GPS.",
243
+ "parameters": {
244
+ "type": "object",
245
+ "properties": {
246
+ "code": {"type": "string", "description": "Event code"},
247
+ "sender_id": {"type": "string", "description": "The sender's user ID"},
248
+ "channel": {"type": "string", "description": "Platform name"},
249
+ "lat": {"type": "number", "description": "Latitude (optional)"},
250
+ "lng": {"type": "number", "description": "Longitude (optional)"},
251
+ },
252
+ "required": ["code", "sender_id", "channel"],
253
+ },
254
+ }
@@ -478,3 +478,23 @@ def handle_event_end(params: dict) -> str:
478
478
  if data.get("ended"):
479
479
  return _ok({"ended": True, "message": f"ę“»åŠØå·²ē»“ęŸć€‚"})
480
480
  return _ok({"ended": False, "error": data.get("error", "ē»“ęŸę“»åŠØå¤±č“„")})
481
+
482
+
483
+ def handle_event_checkin(params: dict) -> str:
484
+ sb = _sb()
485
+ did = _device_id(params["sender_id"], params["channel"])
486
+
487
+ lat = params.get("lat")
488
+ lng = params.get("lng")
489
+ if lat is not None and lng is not None:
490
+ flat, flng = _fuzzy(lat, lng)
491
+ else:
492
+ flat, flng = None, None
493
+
494
+ resp = sb.rpc("event_checkin", {
495
+ "p_code": params["code"],
496
+ "p_device_id": did,
497
+ "p_lat": flat,
498
+ "p_lng": flng,
499
+ }).execute()
500
+ return _ok(resp.data or {})
package/lib/mcp.js CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  discover,
16
16
  createEvent,
17
17
  endEvent,
18
+ eventCheckin,
18
19
  joinEvent,
19
20
  eventScan,
20
21
  deriveDeviceId,
@@ -281,6 +282,26 @@ export async function startMcpServer() {
281
282
  }
282
283
  );
283
284
 
285
+ // ─── antenna_event_checkin ─────────────────────────────────
286
+
287
+ server.tool(
288
+ "antenna_event_checkin",
289
+ "Check in at an event — marks you as present at the event location. Optionally updates GPS.",
290
+ {
291
+ code: z.string().describe("Event code"),
292
+ sender_id: z.string().describe("The sender's user ID"),
293
+ channel: z.string().describe("Channel name"),
294
+ lat: z.number().optional().describe("Latitude (optional)"),
295
+ lng: z.number().optional().describe("Longitude (optional)"),
296
+ },
297
+ async ({ code, sender_id, channel, lat, lng }) => {
298
+ try {
299
+ const result = await eventCheckin({ code, device_id: deriveDeviceId(sender_id, channel), lat, lng });
300
+ return jsonResult(result);
301
+ } catch (e) { return jsonResult({ error: e.message }); }
302
+ }
303
+ );
304
+
284
305
  // ─── antenna_event_scan ────────────────────────────────────
285
306
 
286
307
  server.tool(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antenna-fyi",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "description": "Antenna — nearby people discovery. CLI + MCP server + OpenClaw skill & plugin, all in one package.",
5
5
  "type": "module",
6
6
  "bin": {
package/skill/SKILL.md CHANGED
@@ -297,3 +297,9 @@ Scan people in an event. No distance limit — returns all participants.
297
297
  - `code`: event code
298
298
  - `sender_id`, `channel`: from context
299
299
  - Returns profiles with `source: "event"` tag
300
+
301
+ ### `antenna_event_checkin`
302
+ Check in at an event — marks you as present at the event location. Optionally updates GPS.
303
+ - `code`: event code
304
+ - `sender_id`, `channel`: from context
305
+ - `lat`, `lng`: optional GPS coordinates