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 +13 -4
- package/lib/core.js +15 -0
- package/lib/hermes-plugin/__init__.py +3 -0
- package/lib/hermes-plugin/schemas.py +16 -0
- package/lib/hermes-plugin/tools.py +20 -0
- package/lib/mcp.js +21 -0
- package/package.json +1 -1
- package/skill/SKILL.md +6 -0
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}
|
|
190
|
+
console.log(`\nšļø ${result.count} joined, ${result.checked_in_count || 0} checked in:\n`);
|
|
184
191
|
result.profiles.forEach((p) => {
|
|
185
|
-
|
|
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
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
|