vibedate 0.1.0 → 0.2.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 +27 -5
- package/dist/{chunk-64ME4THO.js → chunk-5ZJIPMU6.js} +2 -65
- package/dist/chunk-6NWF2VD7.js +744 -0
- package/dist/cli.d.ts +5 -1
- package/dist/cli.js +723 -44
- package/dist/index.d.ts +184 -2
- package/dist/index.js +17 -1
- package/dist/mcp.js +2 -2
- package/package.json +5 -3
- package/dist/chunk-AU7FN2LY.js +0 -133
package/README.md
CHANGED
|
@@ -11,8 +11,9 @@ Part of the **Vibe Suite** — companion tools for agentic coding CLIs. Ships as
|
|
|
11
11
|
|
|
12
12
|
> **Local-first.** Raw token usage is read and stored on your own machine and
|
|
13
13
|
> **never leaves it.** Only the coarse league *bucket* is ever shared — never the
|
|
14
|
-
> raw number, never per-project breakdowns.
|
|
15
|
-
> pool is a local
|
|
14
|
+
> raw number, never per-project breakdowns. Live matching is peer-to-peer over a
|
|
15
|
+
> DHT (no central server) and **opt-in only**; without it the pool is a local
|
|
16
|
+
> seeded demo.
|
|
16
17
|
|
|
17
18
|
## Status
|
|
18
19
|
|
|
@@ -42,7 +43,10 @@ vibedating connect
|
|
|
42
43
|
# 2. See candidates in your league (same or adjacent tier)
|
|
43
44
|
vibedating matches
|
|
44
45
|
|
|
45
|
-
# 3.
|
|
46
|
+
# 3. (Opt-in) find live same-league peers over the DHT — no server
|
|
47
|
+
vibedating discover --live # shares ONLY handle + league + harness
|
|
48
|
+
|
|
49
|
+
# 4. Open the local web app in your browser (served from your machine)
|
|
46
50
|
vibedating open
|
|
47
51
|
```
|
|
48
52
|
|
|
@@ -56,13 +60,27 @@ VIBEDATING_TOKENS=23400000 vibedating connect # also accepts 12M / 1.2B / 500k
|
|
|
56
60
|
|
|
57
61
|
```
|
|
58
62
|
vibedating connect Read usage, compute + print your league
|
|
59
|
-
vibedating matches
|
|
63
|
+
vibedating matches [--live] List candidates in your league (live peers if any)
|
|
64
|
+
vibedating discover [--live] Find live same-league peers over the DHT (opt-in)
|
|
60
65
|
vibedating open [--port N] Serve the local web app (default: random free port)
|
|
61
66
|
vibedating mcp Run the stdio MCP server (tools: profile, matches)
|
|
62
67
|
vibedating --version
|
|
63
68
|
vibedating --help
|
|
64
69
|
```
|
|
65
70
|
|
|
71
|
+
### Live P2P discovery (opt-in)
|
|
72
|
+
|
|
73
|
+
`vibedating discover --live` joins the public [hyperswarm](https://github.com/holepunchto/hyperswarm)
|
|
74
|
+
DHT on your league topic — `sha256('vibedate:' + leagueBucket)` — so same-league
|
|
75
|
+
peers find each other with **no central server**. On each encrypted connection
|
|
76
|
+
the two sides exchange a one-line hello with exactly
|
|
77
|
+
`{ handle, league, harness }`; raw usage is never put on the wire. Discovered
|
|
78
|
+
peers are stored in `~/.vibedating/peers.json` and shown by `vibedating matches`.
|
|
79
|
+
|
|
80
|
+
Live discovery is **off by default**. The `--live` flag is the explicit opt-in
|
|
81
|
+
(persisted as the `share:live` consent scope); every live run prints what it
|
|
82
|
+
shares before joining. `Ctrl+C` leaves the swarm cleanly.
|
|
83
|
+
|
|
66
84
|
## Three faces, one local engine
|
|
67
85
|
|
|
68
86
|
The same local engine drives all three, so you can use it wherever you work:
|
|
@@ -89,9 +107,13 @@ const who = matches(lg.name, CANDIDATES); // same/adjacent-tier candidat
|
|
|
89
107
|
- **Raw usage stays local.** `totalTokens` is read into memory, stored at
|
|
90
108
|
`~/.vibedating/state.json`, and shown in the web app only behind an opt-in
|
|
91
109
|
toggle. It is never transmitted.
|
|
92
|
-
- **Only the league bucket is shared**
|
|
110
|
+
- **Only the league bucket is shared** — with the local demo pool, and (only if
|
|
111
|
+
you opt in with `--live`) as `{ handle, league, harness }` with same-league
|
|
112
|
+
peers over the hyperswarm DHT. The handshake parser whitelists those three
|
|
113
|
+
fields, so a peer can't even be *sent* anything else into your process.
|
|
93
114
|
- Consent for sharing the league is modeled with `@pooriaarab/vibe-core`'s consent
|
|
94
115
|
ledger (scope `share:league`), granted on `connect` and revocable on reset.
|
|
116
|
+
Live P2P discovery has its own scope (`share:live`), default **off**.
|
|
95
117
|
|
|
96
118
|
## Leagues & matching
|
|
97
119
|
|
|
@@ -1,73 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CANDIDATES,
|
|
3
|
-
|
|
3
|
+
loadProfile,
|
|
4
4
|
matches
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6NWF2VD7.js";
|
|
6
6
|
|
|
7
7
|
// src/mcp.ts
|
|
8
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
9
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10
|
-
|
|
11
|
-
// src/state.ts
|
|
12
|
-
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
13
|
-
import os from "os";
|
|
14
|
-
import path from "path";
|
|
15
|
-
import { createConsentLedger } from "@pooriaarab/vibe-core";
|
|
16
|
-
var CONSENT_SCOPE = "share:league";
|
|
17
|
-
function defaultStateDir() {
|
|
18
|
-
return path.join(os.homedir(), ".vibedating");
|
|
19
|
-
}
|
|
20
|
-
var FileConsentStore = class {
|
|
21
|
-
constructor(file) {
|
|
22
|
-
this.file = file;
|
|
23
|
-
}
|
|
24
|
-
file;
|
|
25
|
-
load() {
|
|
26
|
-
try {
|
|
27
|
-
const raw = readFileSync(this.file, "utf8");
|
|
28
|
-
const data = JSON.parse(raw);
|
|
29
|
-
return data.grants ?? [];
|
|
30
|
-
} catch {
|
|
31
|
-
return [];
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
save(grants) {
|
|
35
|
-
mkdirSync(path.dirname(this.file), { recursive: true });
|
|
36
|
-
writeFileSync(this.file, JSON.stringify({ grants }, null, 2) + "\n", "utf8");
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
function createLedger(dir = defaultStateDir()) {
|
|
40
|
-
return createConsentLedger(new FileConsentStore(path.join(dir, "consent.json")));
|
|
41
|
-
}
|
|
42
|
-
function profilePath(dir) {
|
|
43
|
-
return path.join(dir, "state.json");
|
|
44
|
-
}
|
|
45
|
-
function connectProfile(snapshot, handle, dir = defaultStateDir()) {
|
|
46
|
-
const lg = league(snapshot.totalTokens);
|
|
47
|
-
createLedger(dir).grant(CONSENT_SCOPE, "connect: league bucket only; raw usage stays local");
|
|
48
|
-
const state = {
|
|
49
|
-
handle,
|
|
50
|
-
harness: snapshot.harness,
|
|
51
|
-
league: lg.name,
|
|
52
|
-
leagueMin: lg.min,
|
|
53
|
-
totalTokens: snapshot.totalTokens,
|
|
54
|
-
verified: snapshot.verified,
|
|
55
|
-
connectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
56
|
-
};
|
|
57
|
-
mkdirSync(dir, { recursive: true });
|
|
58
|
-
writeFileSync(profilePath(dir), JSON.stringify(state, null, 2) + "\n", "utf8");
|
|
59
|
-
return state;
|
|
60
|
-
}
|
|
61
|
-
function loadProfile(dir = defaultStateDir()) {
|
|
62
|
-
try {
|
|
63
|
-
const raw = readFileSync(profilePath(dir), "utf8");
|
|
64
|
-
return JSON.parse(raw);
|
|
65
|
-
} catch {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// src/mcp.ts
|
|
71
10
|
function textBlock(text) {
|
|
72
11
|
return { type: "text", text };
|
|
73
12
|
}
|
|
@@ -120,7 +59,5 @@ async function runMcp() {
|
|
|
120
59
|
}
|
|
121
60
|
|
|
122
61
|
export {
|
|
123
|
-
connectProfile,
|
|
124
|
-
loadProfile,
|
|
125
62
|
runMcp
|
|
126
63
|
};
|