vibedate 0.4.0 → 0.5.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/README.md CHANGED
@@ -9,6 +9,12 @@ Part of the **Vibe Suite** — companion tools for agentic coding CLIs. Ships as
9
9
  **CLI + npm package + MCP server**, plus a local web app. Built on
10
10
  [`@pooriaarab/vibe-core`](https://www.npmjs.com/package/@pooriaarab/vibe-core).
11
11
 
12
+ ## Demo
13
+
14
+ [▶ Watch the launch video](branding/launch-video.mp4) — she matched with the man of her dreams. He was coding in a basement.
15
+
16
+ https://github.com/pooriaarab/vibedating/raw/main/branding/launch-video.mp4
17
+
12
18
  > **Local-first.** Raw token usage is read and stored on your own machine and
13
19
  > **never leaves it.** Only the coarse league *bucket* is ever shared — never the
14
20
  > raw number, never per-project breakdowns. Live matching is peer-to-peer over a
@@ -62,8 +68,15 @@ VIBEDATING_TOKENS=23400000 vibedating connect # also accepts 12M / 1.2B / 500k
62
68
 
63
69
  ```
64
70
  vibedating connect Read usage, compute + print your league
65
- vibedating matches [--live] List candidates in your league (live peers if any)
71
+ (first run auto-assigns a memetic handle never @you)
72
+ vibedating matches [--live] List candidates in your league (live peers if any,
73
+ with last-message time)
66
74
  vibedating discover [--live] Find live same-league peers over the DHT (opt-in)
75
+ vibedating live [--keep-alive] Live text chat (--keep-alive / non-TTY survives stdin EOF)
76
+ vibedating handle [@name] Print or set your handle
77
+ vibedating daemon [start|stop|status|install|uninstall]
78
+ Notify-only background daemon — alerts on NEW matches,
79
+ never opens chat/video; install = run on login (launchd/systemd)
67
80
  vibedating open [--port N] Serve the local web app (default: random free port)
68
81
  vibedating mcp Run the stdio MCP server (tools: profile, matches)
69
82
  vibedating --version
@@ -2,7 +2,7 @@ import {
2
2
  CANDIDATES,
3
3
  loadProfile,
4
4
  matches
5
- } from "./chunk-43IYNWES.js";
5
+ } from "./chunk-KKWP4DLY.js";
6
6
 
7
7
  // src/mcp.ts
8
8
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -656,6 +656,14 @@ function createPeerLink(socket, hello, initialBuffer = "", linkOpts = {}) {
656
656
  };
657
657
  }
658
658
 
659
+ // src/untrusted.ts
660
+ var MAX_DISPLAY_TEXT_LEN = MAX_TEXT_LEN;
661
+ var UNSAFE_DISPLAY_CHARS = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u200E\u200F\u202A-\u202E\u2066-\u2069\uFEFF]/g;
662
+ function sanitizePeerText(text, maxLen = MAX_DISPLAY_TEXT_LEN) {
663
+ const cleaned = text.replace(UNSAFE_DISPLAY_CHARS, "");
664
+ return cleaned.length > maxLen ? cleaned.slice(0, maxLen) : cleaned;
665
+ }
666
+
659
667
  // src/p2p.ts
660
668
  var TOPIC_PREFIX = "vibedate:";
661
669
  function leagueTopic(leagueName) {
@@ -838,7 +846,9 @@ async function startDiscovery(opts) {
838
846
  try {
839
847
  notify(
840
848
  makeEvent("match", hello.harness, process.cwd(), {
841
- summary: `matched with ${peer.handle} - LIVE SAME LEAGUE`,
849
+ // AEGIS-lite: the handle is untrusted wire data — sanitized for
850
+ // display (the structured `handle` field below stays verbatim).
851
+ summary: `matched with ${sanitizePeerText(peer.handle)} - LIVE SAME LEAGUE`,
842
852
  handle: peer.handle,
843
853
  league: peer.league,
844
854
  harness: peer.harness
@@ -1036,12 +1046,16 @@ function matches(myLeague, candidates = CANDIDATES) {
1036
1046
 
1037
1047
  export {
1038
1048
  parseFrame,
1049
+ defaultStateDir,
1039
1050
  connectProfile,
1040
1051
  loadProfile,
1041
1052
  grantLiveConsent,
1042
1053
  canShareLive,
1054
+ DEFAULT_HANDLE,
1055
+ MAX_HANDLE_LEN,
1043
1056
  sameHandle,
1044
1057
  normalizeHandle,
1058
+ loadHandle,
1045
1059
  saveHandle,
1046
1060
  resolveHandle,
1047
1061
  loadBlocklist,
@@ -1053,6 +1067,7 @@ export {
1053
1067
  signHelloClaims,
1054
1068
  verifyHelloClaims,
1055
1069
  classifyHelloIdentity,
1070
+ sanitizePeerText,
1056
1071
  TOPIC_PREFIX,
1057
1072
  leagueTopic,
1058
1073
  LIVE_NOTICE,
package/dist/cli.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /** Recognized top-level commands, plus the synthetic help/version. */
3
- type Command = 'connect' | 'matches' | 'discover' | 'open' | 'live' | 'find' | 'handle' | 'block' | 'unblock' | 'blocklist' | 'mcp' | 'help' | 'version' | null;
3
+ type Command = 'connect' | 'matches' | 'discover' | 'open' | 'live' | 'find' | 'handle' | 'block' | 'unblock' | 'blocklist' | 'daemon' | 'mcp' | 'help' | 'version' | null;
4
4
  interface ParsedArgs {
5
5
  readonly command: Command;
6
6
  /** Port for `open --port`; undefined means "let the OS pick". */
@@ -9,17 +9,32 @@ 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. */
12
+ /** `discover --any` / `live --any` / `open --any`: match every league (not just ±1). Default false. */
13
13
  readonly any: boolean;
14
14
  /** Positional argument for `handle`/`find` (e.g. `@name`). */
15
15
  readonly arg: string | undefined;
16
16
  /** `live --to <@handle>`: targeted match — auto-open that specific peer. */
17
17
  readonly to: string | undefined;
18
+ /** `live --keep-alive`: stay in the swarm after stdin EOF. Default false. */
19
+ readonly keepAlive: boolean;
18
20
  }
19
21
  /**
20
22
  * Parse argv (the slice AFTER the program name) into a command + options.
21
23
  * Pure: no IO, no process access — trivially unit-testable.
22
24
  */
23
25
  declare function parseArgs(argv: readonly string[]): ParsedArgs;
26
+ /**
27
+ * Compact relative time for local lists: an ISO timestamp → "just now" /
28
+ * "5m ago" / "3h ago" / "2d ago". Unparseable input → "unknown". Pure.
29
+ */
30
+ declare function formatAgo(iso: string, now?: Date): string;
31
+ /**
32
+ * Whether `live` should stay in the swarm after stdin closes. An explicit
33
+ * `--keep-alive` always keeps it; otherwise AUTO-detect: a non-TTY stdin
34
+ * (piped, `</dev/null`, backgrounded) hits EOF immediately, and exiting there
35
+ * would kill an unattended session — so it stays up until SIGINT/SIGTERM.
36
+ * Interactive TTY behavior is unchanged: Ctrl+D / EOF still exits.
37
+ */
38
+ declare function shouldKeepAlive(flag: boolean, stdinIsTTY: boolean | undefined): boolean;
24
39
 
25
- export { type Command, type ParsedArgs, parseArgs };
40
+ export { type Command, type ParsedArgs, formatAgo, parseArgs, shouldKeepAlive };