vibedate 0.2.0 → 0.3.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.
@@ -2,7 +2,7 @@ import {
2
2
  CANDIDATES,
3
3
  loadProfile,
4
4
  matches
5
- } from "./chunk-6NWF2VD7.js";
5
+ } from "./chunk-VBLFAOV3.js";
6
6
 
7
7
  // src/mcp.ts
8
8
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -511,7 +511,8 @@ function recordPeer(hello, dir = defaultStateDir(), now = /* @__PURE__ */ new Da
511
511
  }
512
512
  async function startDiscovery(opts) {
513
513
  const { hello, stateDir = defaultStateDir(), onPeer, onLink, notify = vibeCoreNotify } = opts;
514
- const topic = opts.topic ?? leagueTopic(hello.league);
514
+ const topics = opts.topics ? [...opts.topics] : opts.topic !== void 0 ? [opts.topic] : [leagueTopic(hello.league)];
515
+ const acceptLeague = opts.acceptLeague ?? ((l) => l === hello.league);
515
516
  const { default: Hyperswarm } = await import("hyperswarm");
516
517
  const swarm = new Hyperswarm(opts.bootstrap === void 0 ? {} : { bootstrap: opts.bootstrap });
517
518
  await swarm.dht.fullyBootstrapped();
@@ -539,7 +540,7 @@ async function startDiscovery(opts) {
539
540
  league: frame.league,
540
541
  harness: frame.harness
541
542
  };
542
- if (peer.league !== hello.league) continue;
543
+ if (!acceptLeague(peer.league)) continue;
543
544
  peers.set(remoteKey, peer);
544
545
  const { isNew } = recordPeer(peer, stateDir);
545
546
  if (isNew) {
@@ -570,17 +571,22 @@ async function startDiscovery(opts) {
570
571
  socket.on("error", () => {
571
572
  });
572
573
  });
573
- const discovery = swarm.join(topic, { server: true, client: true });
574
- const ready = discovery.flushed().catch(() => void 0);
574
+ const discoveries = topics.map((t) => swarm.join(t, { server: true, client: true }));
575
+ const ready = Promise.all(
576
+ discoveries.map((d) => d.flushed().catch(() => void 0))
577
+ );
575
578
  await ready;
576
579
  const refresher = setInterval(() => {
577
- void discovery.refresh({ server: true, client: true }).catch(() => {
580
+ for (const d of discoveries) void d.refresh({ server: true, client: true }).catch(() => {
578
581
  });
579
582
  }, REFRESH_INTERVAL_MS);
580
583
  refresher.unref();
581
584
  let closed = false;
582
585
  return {
583
- topic,
586
+ topic: topics[0],
587
+ // primary (first) — kept for back-compat / display
588
+ topics,
589
+ // every joined topic (primary first)
584
590
  hello,
585
591
  peers,
586
592
  ready,
@@ -588,9 +594,11 @@ async function startDiscovery(opts) {
588
594
  if (closed) return;
589
595
  closed = true;
590
596
  clearInterval(refresher);
591
- try {
592
- await swarm.leave(topic);
593
- } catch {
597
+ for (const t of topics) {
598
+ try {
599
+ await swarm.leave(t);
600
+ } catch {
601
+ }
594
602
  }
595
603
  await swarm.destroy();
596
604
  }
@@ -619,6 +627,22 @@ function leagueIndex(name) {
619
627
  if (name === BELOW_LEAGUE) return -1;
620
628
  return LEAGUES.findIndex((l) => l.name === name);
621
629
  }
630
+ function allLeagueNames() {
631
+ return [BELOW_LEAGUE, ...LEAGUES.map((l) => l.name)];
632
+ }
633
+ function leaguesWithin(name, width) {
634
+ const w = Math.max(0, Math.trunc(width));
635
+ if (name === BELOW_LEAGUE) {
636
+ return [BELOW_LEAGUE, ...LEAGUES.slice(0, w).map((l) => l.name)];
637
+ }
638
+ const center = leagueIndex(name);
639
+ if (center < 0) return [];
640
+ const lo = Math.max(0, center - w);
641
+ const hi = Math.min(LEAGUES.length - 1, center + w);
642
+ const out = [];
643
+ for (let i = lo; i <= hi; i++) out.push(LEAGUES[i].name);
644
+ return out;
645
+ }
622
646
  var TOKENS_ENV = "VIBEDATING_TOKENS";
623
647
  var DEMO_TOTAL_TOKENS = 234e5;
624
648
  var MS_PER_DAY = 864e5;
@@ -733,6 +757,8 @@ export {
733
757
  BELOW_LEAGUE,
734
758
  league,
735
759
  leagueIndex,
760
+ allLeagueNames,
761
+ leaguesWithin,
736
762
  TOKENS_ENV,
737
763
  DEMO_TOTAL_TOKENS,
738
764
  readUsage,
package/dist/cli.d.ts CHANGED
@@ -9,6 +9,8 @@ interface ParsedArgs {
9
9
  readonly live: boolean;
10
10
  /** `live --dating`: pick-a-handle mode vs omegle auto-pair. Default false. */
11
11
  readonly dating: boolean;
12
+ /** `discover --any` / `live --any`: match every league (not just ±1). Default false. */
13
+ readonly any: boolean;
12
14
  }
13
15
  /**
14
16
  * Parse argv (the slice AFTER the program name) into a command + options.
package/dist/cli.js CHANGED
@@ -1,23 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runMcp
4
- } from "./chunk-5ZJIPMU6.js";
4
+ } from "./chunk-DMA7MSN7.js";
5
5
  import {
6
6
  CANDIDATES,
7
7
  LIVE_NOTICE,
8
8
  TOPIC_PREFIX,
9
+ allLeagueNames,
9
10
  canShareLive,
10
11
  connectProfile,
11
12
  grantLiveConsent,
12
13
  league,
13
14
  leagueIndex,
15
+ leagueTopic,
16
+ leaguesWithin,
14
17
  loadPeers,
15
18
  loadProfile,
16
19
  matches,
17
20
  parseFrame,
18
21
  readUsage,
19
22
  startDiscovery
20
- } from "./chunk-6NWF2VD7.js";
23
+ } from "./chunk-VBLFAOV3.js";
21
24
 
22
25
  // src/cli.ts
23
26
  import readline from "readline";
@@ -1387,26 +1390,30 @@ async function handle(req, res, opts) {
1387
1390
  }
1388
1391
 
1389
1392
  // src/cli.ts
1390
- var VERSION = "0.2.0";
1393
+ var VERSION = "0.3.0";
1391
1394
  function parsePort(raw) {
1392
1395
  const n = Number(raw);
1393
1396
  if (!Number.isInteger(n) || n < 1 || n > 65535) return void 0;
1394
1397
  return n;
1395
1398
  }
1396
1399
  function parseArgs(argv) {
1397
- let out = { command: null, port: void 0, live: false, dating: false };
1400
+ let out = { command: null, port: void 0, live: false, dating: false, any: false };
1398
1401
  for (let i = 0; i < argv.length; i++) {
1399
1402
  const a = argv[i];
1400
1403
  if (a === "--version" || a === "-v") {
1401
- return { command: "version", port: void 0, live: false, dating: false };
1404
+ return { command: "version", port: void 0, live: false, dating: false, any: false };
1402
1405
  }
1403
1406
  if (a === "--help" || a === "-h") {
1404
- return { command: "help", port: void 0, live: false, dating: false };
1407
+ return { command: "help", port: void 0, live: false, dating: false, any: false };
1405
1408
  }
1406
1409
  if (a === "--live") {
1407
1410
  out = { ...out, live: true };
1408
1411
  continue;
1409
1412
  }
1413
+ if (a === "--any") {
1414
+ out = { ...out, any: true };
1415
+ continue;
1416
+ }
1410
1417
  if (a === "--dating") {
1411
1418
  out = { ...out, dating: true };
1412
1419
  continue;
@@ -1436,6 +1443,24 @@ function parseArgs(argv) {
1436
1443
  function leagueLabel(name) {
1437
1444
  return name === "below-1M" ? "below 1M (not yet in a league)" : `${name} League`;
1438
1445
  }
1446
+ function discoveryScope(myLeague, any) {
1447
+ const names = any ? allLeagueNames() : leaguesWithin(myLeague, 1);
1448
+ const ordered = [myLeague, ...names.filter((n) => n !== myLeague)];
1449
+ if (any) {
1450
+ return { topics: ordered.map(leagueTopic), acceptLeague: () => true };
1451
+ }
1452
+ const accepted = new Set(names);
1453
+ return {
1454
+ topics: ordered.map(leagueTopic),
1455
+ acceptLeague: (peerLeague) => accepted.has(peerLeague)
1456
+ };
1457
+ }
1458
+ function peerDirection(myLeague, peerLeague, sameBullet = "+") {
1459
+ const d = leagueIndex(peerLeague) - leagueIndex(myLeague);
1460
+ if (d > 0) return { bullet: "\u2191", qual: " \xB7 higher league" };
1461
+ if (d < 0) return { bullet: "\u2193", qual: " \xB7 lower league" };
1462
+ return { bullet: sameBullet, qual: "" };
1463
+ }
1439
1464
  async function cmdConnect() {
1440
1465
  const harness = process2.env["VIBEDATING_HARNESS"] ?? "claude-code";
1441
1466
  const handle2 = process2.env["VIBEDATING_HANDLE"] ?? "@you";
@@ -1508,7 +1533,7 @@ async function cmdMatches(live) {
1508
1533
  process2.stdout.write("\n");
1509
1534
  return 0;
1510
1535
  }
1511
- async function cmdDiscover(live) {
1536
+ async function cmdDiscover(live, any) {
1512
1537
  const profile = loadProfile();
1513
1538
  if (!profile) {
1514
1539
  process2.stderr.write("Not connected yet. Run `vibedating connect` first.\n");
@@ -1529,20 +1554,31 @@ async function cmdDiscover(live) {
1529
1554
  process2.stdout.write("\n");
1530
1555
  process2.stdout.write(` ${LIVE_NOTICE}
1531
1556
  `);
1557
+ const { topics, acceptLeague } = discoveryScope(profile.league, any);
1532
1558
  const session = await startDiscovery({
1533
1559
  hello,
1560
+ topics,
1561
+ acceptLeague,
1534
1562
  onPeer: (peer, isNew) => {
1563
+ const { bullet, qual } = peerDirection(profile.league, peer.league);
1535
1564
  process2.stdout.write(
1536
- ` + ${peer.handle} (${peer.league} \xB7 ${peer.harness})${isNew ? " \u2190 new match" : ""}
1565
+ ` ${bullet} ${peer.handle} (${peer.league}${qual} \xB7 ${peer.harness})${isNew ? " \u2190 new match" : ""}
1537
1566
  `
1538
1567
  );
1539
1568
  }
1540
1569
  });
1541
1570
  process2.stdout.write(
1542
- ` topic: ${TOPIC_PREFIX}${profile.league} \u2192 ${session.topic.toString("hex").slice(0, 12)}\u2026
1571
+ ` topic: ${TOPIC_PREFIX}${profile.league} \u2192 ${session.topic.toString("hex").slice(0, 12)}\u2026${topics.length > 1 ? ` (+${topics.length - 1} more)` : ""}
1543
1572
  `
1544
1573
  );
1545
- process2.stdout.write(" listening for same-league peers\u2026 (Ctrl+C to stop)\n\n");
1574
+ if (!any && session.peers.size === 0) {
1575
+ process2.stdout.write(
1576
+ " no one in your league yet \u2014 also listening to adjacent leagues (use --any to match anyone)\n"
1577
+ );
1578
+ }
1579
+ process2.stdout.write(
1580
+ any ? " listening for ANY league peers\u2026 (Ctrl+C to stop)\n\n" : " listening for same + adjacent-league peers\u2026 (Ctrl+C to stop)\n\n"
1581
+ );
1546
1582
  await new Promise((resolve) => {
1547
1583
  process2.once("SIGINT", () => resolve());
1548
1584
  process2.once("SIGTERM", () => resolve());
@@ -1563,17 +1599,22 @@ async function cmdOpen(port) {
1563
1599
  if (profile) {
1564
1600
  if (!canShareLive()) grantLiveConsent();
1565
1601
  live = createLiveBridge();
1602
+ }
1603
+ const started = await startServer({ port, live });
1604
+ if (profile && live) {
1605
+ process2.stdout.write(`
1606
+ ${LIVE_NOTICE}
1607
+ `);
1566
1608
  const hello = {
1567
1609
  handle: profile.handle,
1568
1610
  league: profile.league,
1569
1611
  harness: profile.harness
1570
1612
  };
1571
- process2.stdout.write(`
1572
- ${LIVE_NOTICE}
1573
- `);
1574
- session = await startDiscovery({ hello, onLink: (link) => live.addLink(link) });
1613
+ void startDiscovery({ hello, onLink: (link) => live.addLink(link) }).then((s) => {
1614
+ session = s;
1615
+ }).catch(() => {
1616
+ });
1575
1617
  }
1576
- const started = await startServer({ port, live });
1577
1618
  process2.stdout.write(`
1578
1619
  vibedating local web app \u2192 ${started.url}
1579
1620
  `);
@@ -1593,7 +1634,7 @@ async function cmdOpen(port) {
1593
1634
  await new Promise((resolve) => started.server.close(() => resolve()));
1594
1635
  return 0;
1595
1636
  }
1596
- async function cmdLive(dating) {
1637
+ async function cmdLive(dating, any) {
1597
1638
  const profile = loadProfile();
1598
1639
  if (!profile) {
1599
1640
  process2.stderr.write("Not connected yet. Run `vibedating connect` first.\n");
@@ -1621,8 +1662,9 @@ async function cmdLive(dating) {
1621
1662
  process2.stdout.write(" \xB7 idle \u2014 no peer right now\n");
1622
1663
  return;
1623
1664
  }
1665
+ const { qual } = peerDirection(profile.league, link.hello.league);
1624
1666
  process2.stdout.write(
1625
- ` \xB7 matched ${link.hello.handle} (${link.hello.league} \xB7 ${link.hello.harness})
1667
+ ` \xB7 matched ${link.hello.handle} (${link.hello.league}${qual} \xB7 ${link.hello.harness})
1626
1668
  `
1627
1669
  );
1628
1670
  link.onMessage((m) => {
@@ -1630,12 +1672,15 @@ async function cmdLive(dating) {
1630
1672
  `);
1631
1673
  });
1632
1674
  });
1675
+ const { topics, acceptLeague } = discoveryScope(profile.league, any);
1633
1676
  const session = await startDiscovery({
1634
1677
  hello,
1678
+ topics,
1679
+ acceptLeague,
1635
1680
  onLink: (link) => pairing.add(link)
1636
1681
  });
1637
1682
  process2.stdout.write(
1638
- ` topic: ${TOPIC_PREFIX}${profile.league} \u2192 ${session.topic.toString("hex").slice(0, 12)}\u2026
1683
+ ` topic: ${TOPIC_PREFIX}${profile.league} \u2192 ${session.topic.toString("hex").slice(0, 12)}\u2026${topics.length > 1 ? ` (+${topics.length - 1} more)` : ""}
1639
1684
  `
1640
1685
  );
1641
1686
  process2.stdout.write(" type to chat \xB7 /next \xB7 /open <handle> \xB7 /quit\n");
@@ -1683,8 +1728,8 @@ var HELP = `vibedating ${VERSION} \u2014 dating by tokens (local-first)
1683
1728
  Usage:
1684
1729
  vibedating connect Read your usage, compute + print your league
1685
1730
  vibedating matches [--live] List candidates in your league (live peers if any)
1686
- vibedating discover [--live] Find live same-league peers over the DHT (opt-in)
1687
- vibedating live [--dating] Live chat with same-league peers (omegle /next, or --dating pick)
1731
+ vibedating discover [--live] [--any] Find live peers over the DHT (your league + adjacent; --any = everyone)
1732
+ vibedating live [--dating] [--any] Live chat (your league + adjacent; --any = everyone; /next or --dating pick)
1688
1733
  vibedating open [--port N] Serve the local web app (default: random port)
1689
1734
  + live A/V video with connected same-league peers
1690
1735
  vibedating mcp Run the stdio MCP server (profile, matches)
@@ -1696,6 +1741,10 @@ Privacy:
1696
1741
  bucket is ever shared. Live discovery (off by default) shares ONLY your
1697
1742
  handle + league + harness with same-league peers \u2014 opt in with --live.
1698
1743
 
1744
+ Matching:
1745
+ discover/live match your league + adjacent (\xB11) tiers by default, so thin
1746
+ leagues and cross-league friends still connect. --any matches every league.
1747
+
1699
1748
  Env:
1700
1749
  VIBEDATING_TOKENS=<n> Self-report a token count (e.g. 23400000 or 12M)
1701
1750
  VIBEDATING_HARNESS=<h> Harness id (claude-code, codex, \u2026)
@@ -1717,11 +1766,11 @@ async function main(argv) {
1717
1766
  case "matches":
1718
1767
  return cmdMatches(parsed.live);
1719
1768
  case "discover":
1720
- return cmdDiscover(parsed.live);
1769
+ return cmdDiscover(parsed.live, parsed.any);
1721
1770
  case "open":
1722
1771
  return cmdOpen(parsed.port);
1723
1772
  case "live":
1724
- return cmdLive(parsed.dating);
1773
+ return cmdLive(parsed.dating, parsed.any);
1725
1774
  case "mcp":
1726
1775
  await runMcp();
1727
1776
  return 0;
package/dist/index.d.ts CHANGED
@@ -142,9 +142,24 @@ interface DiscoveryOptions {
142
142
  readonly hello: PeerHello;
143
143
  /**
144
144
  * Override the joined topic (tests pass a random one on an isolated DHT).
145
- * Defaults to {@link leagueTopic}`(hello.league)`.
145
+ * Defaults to {@link leagueTopic}`(hello.league)`. Ignored when {@link topics}
146
+ * is set.
146
147
  */
147
148
  readonly topic?: Buffer;
149
+ /**
150
+ * ALL topics to join on the one swarm (e.g. your league + adjacent leagues),
151
+ * so thin pools and cross-league friends still connect. Every topic is
152
+ * joined, refreshed, and left on close. Defaults to `[topic]` — i.e. a single
153
+ * own-league topic (the legacy behavior).
154
+ */
155
+ readonly topics?: readonly Buffer[];
156
+ /**
157
+ * Predicate over an incoming peer's advertised league. Defaults to EXACT
158
+ * match against `hello.league` — the same privacy invariant as before. Widen
159
+ * it (e.g. ±1 adjacency via {@link leaguesWithin}) to accept cross-league
160
+ * peers that arrive on a shared topic.
161
+ */
162
+ readonly acceptLeague?: (peerLeague: string) => boolean;
148
163
  /** DHT bootstrap nodes; omit for the public DHT. Tests pass a local testnet. */
149
164
  readonly bootstrap?: ReadonlyArray<{
150
165
  readonly host: string;
@@ -165,15 +180,17 @@ interface DiscoveryOptions {
165
180
  readonly notify?: NotifySink;
166
181
  }
167
182
  interface DiscoverySession {
168
- /** The 32-byte topic actually joined. */
183
+ /** The primary (first) joined topic. See {@link topics} for the full set. */
169
184
  readonly topic: Buffer;
185
+ /** Every topic this session joined (primary first). */
186
+ readonly topics: readonly Buffer[];
170
187
  /** What we broadcast on every connection. */
171
188
  readonly hello: PeerHello;
172
189
  /** Live peer set, keyed by the remote's public key (hex). */
173
190
  readonly peers: ReadonlyMap<string, PeerHello>;
174
- /** Resolves when the first DHT announce/lookup round for the topic completes. */
191
+ /** Resolves when the first DHT announce/lookup round for every topic completes. */
175
192
  readonly ready: Promise<unknown>;
176
- /** Leave the topic and destroy the node. Idempotent. */
193
+ /** Leave every topic and destroy the node. Idempotent. */
177
194
  close(): Promise<void>;
178
195
  }
179
196
  /**
@@ -222,6 +239,29 @@ declare function league(totalTokens: number): {
222
239
  };
223
240
  /** Index of a league name in {@link LEAGUES}; {@link BELOW_LEAGUE} → -1. */
224
241
  declare function leagueIndex(name: string): number;
242
+ /**
243
+ * Every league name on the ladder: {@link BELOW_LEAGUE} first (it sits just
244
+ * below the 1M tier), then each {@link LEAGUES} name in ascending order.
245
+ * Pure; returns a fresh array each call.
246
+ */
247
+ declare function allLeagueNames(): string[];
248
+ /**
249
+ * League names whose index is within ±`width` of `name`'s index on the ladder,
250
+ * clamped to the array bounds. Ascending (index order), de-duplicated.
251
+ *
252
+ * Edge-case decisions:
253
+ * - **{@link BELOW_LEAGUE}** is treated as "index -1" — it sits just below the
254
+ * 1M tier, so `width` extends ONLY upward into the ladder
255
+ * (`leaguesWithin('below-1M', 1) → ['below-1M', '1M']`). This mirrors the
256
+ * existing `matches()` rule that below-1M is adjacent only to 1M.
257
+ * - **Unknown league names** (not in {@link LEAGUES}, not {@link BELOW_LEAGUE})
258
+ * return `[]` — we can't place them on the ladder, so they have no
259
+ * neighborhood.
260
+ * - **Negative width** is clamped to 0 (self only); non-integer width is
261
+ * truncated.
262
+ * - **Width larger than the ladder** is clamped to the bounds (whole ladder).
263
+ */
264
+ declare function leaguesWithin(name: string, width: number): string[];
225
265
  /** Env var that holds a self-reported total token count (e.g. `23400000`). */
226
266
  declare const TOKENS_ENV = "VIBEDATING_TOKENS";
227
267
  /**
@@ -277,4 +317,4 @@ declare const CANDIDATES: readonly Candidate[];
277
317
  */
278
318
  declare function matches(myLeague: string, candidates?: readonly Candidate[]): Candidate[];
279
319
 
280
- export { BELOW_LEAGUE, CANDIDATES, type Candidate, DEMO_TOTAL_TOKENS, type DiscoveryOptions, type DiscoverySession, LEAGUES, LIVE_NOTICE, type League, type PeerHello, type StoredPeer, TOKENS_ENV, TOPIC_PREFIX, league, leagueIndex, leagueTopic, loadPeers, matches, parseHandshake, parseTokensEnv, readUsage, recordPeer, serializeHandshake, startDiscovery, tryReadVerifiedUsage };
320
+ export { BELOW_LEAGUE, CANDIDATES, type Candidate, DEMO_TOTAL_TOKENS, type DiscoveryOptions, type DiscoverySession, LEAGUES, LIVE_NOTICE, type League, type PeerHello, type StoredPeer, TOKENS_ENV, TOPIC_PREFIX, allLeagueNames, league, leagueIndex, leagueTopic, leaguesWithin, loadPeers, matches, parseHandshake, parseTokensEnv, readUsage, recordPeer, serializeHandshake, startDiscovery, tryReadVerifiedUsage };
package/dist/index.js CHANGED
@@ -6,10 +6,12 @@ import {
6
6
  LIVE_NOTICE,
7
7
  TOKENS_ENV,
8
8
  TOPIC_PREFIX,
9
+ allLeagueNames,
9
10
  createConsentLedger,
10
11
  league,
11
12
  leagueIndex,
12
13
  leagueTopic,
14
+ leaguesWithin,
13
15
  loadPeers,
14
16
  matches,
15
17
  parseHandshake,
@@ -19,7 +21,7 @@ import {
19
21
  serializeHandshake,
20
22
  startDiscovery,
21
23
  tryReadVerifiedUsage
22
- } from "./chunk-6NWF2VD7.js";
24
+ } from "./chunk-VBLFAOV3.js";
23
25
  export {
24
26
  BELOW_LEAGUE,
25
27
  CANDIDATES,
@@ -28,10 +30,12 @@ export {
28
30
  LIVE_NOTICE,
29
31
  TOKENS_ENV,
30
32
  TOPIC_PREFIX,
33
+ allLeagueNames,
31
34
  createConsentLedger,
32
35
  league,
33
36
  leagueIndex,
34
37
  leagueTopic,
38
+ leaguesWithin,
35
39
  loadPeers,
36
40
  matches,
37
41
  parseHandshake,
package/dist/mcp.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  runMcp
3
- } from "./chunk-5ZJIPMU6.js";
4
- import "./chunk-6NWF2VD7.js";
3
+ } from "./chunk-DMA7MSN7.js";
4
+ import "./chunk-VBLFAOV3.js";
5
5
  export {
6
6
  runMcp
7
7
  };
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "vibedate",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Dating by tokens — matched by usage league across agentic CLIs. Raw usage stays local; only your league is shared. CLI + local web app + MCP. Local-first.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "Pooria Arab",
8
8
  "bin": {
9
- "vibedating": "./dist/cli.js"
9
+ "vibedate": "./dist/cli.js",
10
+ "vibedating": "./dist/cli.js",
11
+ "vibedate-mcp": "./dist/mcp.js"
10
12
  },
11
13
  "main": "./dist/index.js",
12
14
  "types": "./dist/index.d.ts",