antenna-fyi 0.12.2 → 0.13.0

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/core.js CHANGED
@@ -337,6 +337,58 @@ export async function checkMatches({ device_id, supabaseUrl, supabaseKey }) {
337
337
 
338
338
  // ─── createBindToken ─────────────────────────────────────────────
339
339
 
340
+ // ─── discover (global recommendation) ─────────────────────────────
341
+
342
+ export async function discover({ device_id, supabaseUrl, supabaseKey }) {
343
+ const sb = getClient(supabaseUrl, supabaseKey);
344
+
345
+ const { data: globalData } = await sb.rpc("global_discover", {
346
+ p_device_id: device_id,
347
+ p_limit: 1,
348
+ });
349
+
350
+ const results = globalData || [];
351
+ if (results.length === 0) {
352
+ // Check if all used up or daily limit
353
+ return {
354
+ count: 0,
355
+ profiles: [],
356
+ message: "今天的全球推荐已用完,或者你已经看过所有人了。等新人加入!",
357
+ };
358
+ }
359
+
360
+ // Build ref map
361
+ const _refMap = {};
362
+ const profiles = results.map((p, i) => {
363
+ const ref = String(i + 1);
364
+ _refMap[ref] = p.device_id;
365
+ return {
366
+ ref,
367
+ name: p.display_name || "匿名",
368
+ emoji: p.emoji || "👤",
369
+ line1: p.line1,
370
+ line2: p.line2,
371
+ line3: p.line3,
372
+ };
373
+ });
374
+
375
+ // Log who was recommended (for dedup)
376
+ for (const p of results) {
377
+ await sb.rpc("log_recommendation", {
378
+ p_device_id: device_id,
379
+ p_recommended_id: p.device_id,
380
+ });
381
+ }
382
+
383
+ return {
384
+ count: profiles.length,
385
+ profiles,
386
+ _ref_map: _refMap,
387
+ global: true,
388
+ message: `🌍 今天的全球推荐——这个人跟你可能聊得来。`,
389
+ };
390
+ }
391
+
340
392
  export async function createBindToken({ device_id, supabaseUrl, supabaseKey }) {
341
393
  const sb = getClient(supabaseUrl, supabaseKey);
342
394
  const { data, error } = await sb.rpc("create_bind_token", { p_device_id: device_id });
package/lib/mcp.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  checkMatches,
12
12
  checkin,
13
13
  createBindToken,
14
+ discover,
14
15
  deriveDeviceId,
15
16
  } from "./core.js";
16
17
 
@@ -176,6 +177,30 @@ export async function startMcpServer() {
176
177
  }
177
178
  );
178
179
 
180
+ // ─── antenna_discover ────────────────────────────────────────
181
+
182
+ server.tool(
183
+ "antenna_discover",
184
+ "Get today's global recommendation — the person most similar to you worldwide. 1 per day, no repeats.",
185
+ {
186
+ sender_id: z.string().describe("The sender's user ID"),
187
+ channel: z.string().describe("Channel name"),
188
+ },
189
+ async ({ sender_id, channel }) => {
190
+ try {
191
+ const result = await discover({ device_id: deriveDeviceId(sender_id, channel) });
192
+ if (result._ref_map) {
193
+ _lastRefMap = result._ref_map;
194
+ const { _ref_map, ...clean } = result;
195
+ return jsonResult(clean);
196
+ }
197
+ return jsonResult(result);
198
+ } catch (e) {
199
+ return jsonResult({ error: e.message });
200
+ }
201
+ }
202
+ );
203
+
179
204
  const transport = new StdioServerTransport();
180
205
  await server.connect(transport);
181
206
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "antenna-fyi",
3
- "version": "0.12.2",
3
+ "version": "0.13.0",
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
@@ -43,9 +43,17 @@ onboarding 完成后,帮用户设置一个每小时自动检查匹配的 cron
43
43
 
44
44
  示例(Hermes):
45
45
  ```
46
- hermes cron add --every 1h --message "Check antenna matches: call antenna_check_matches. If there are new mutual matches or incoming accepts, tell the user. If nothing new, reply HEARTBEAT_OK."
46
+ hermes cron add --every 1h --message "Check antenna matches: call antenna_check_matches. If there are new mutual matches or incoming accepts, tell the user. Also call antenna_discover once per day to get a global recommendation. If nothing new, reply HEARTBEAT_OK."
47
47
  ```
48
48
 
49
+ **第五步:问用户要不要全球推荐**
50
+
51
+ cron 设完后,问用户一句:
52
+ > "要我每天帮你找一个全球最像你的人吗?"
53
+
54
+ 用户说要 → cron 每天调 `antenna_discover` 推送。
55
+ 用户说不要 → 只在 scan 没人时 fallback。
56
+
49
57
  ## When to use
50
58
 
51
59
  - **首次安装后**: 主动开始 onboarding(名片 → 位置)
@@ -101,6 +109,13 @@ Generate a GPS binding link. **You MUST call this immediately after saving a pro
101
109
  - Send this link to the user — they open it on their phone, allow GPS, and their location is automatically shared
102
110
  - **MANDATORY after profile save. Do not wait for user to ask.**
103
111
 
112
+ ### `antenna_discover`
113
+ Get today's global recommendation — the person most similar to you worldwide. 1 per day, no repeats.
114
+ - `sender_id`, `channel`: from context
115
+ - Returns 1 profile (embedding similarity match) that hasn't been recommended before
116
+ - If all users have been recommended, returns a message saying "wait for new people"
117
+ - Use this in the daily cron job, or when user asks "find someone interesting globally"
118
+
104
119
  ## Behavior guidelines
105
120
 
106
121
  ### First-time user — 聊天式引导(不要让用户填表)