slashvibe-mcp 0.8.22 → 0.8.23

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/index.js CHANGED
@@ -595,7 +595,11 @@ class VibeMCPServer {
595
595
  // vibe_init reads only {handle, one_liner, auth_method} and ignores any
596
596
  // extra keys, so this is safe for every command yet lets relevant
597
597
  // context (e.g. a handle the caller already supplied) carry into auth.
598
- const initResult = await initTool.handler(params.arguments || {});
598
+ // The gated tool's arguments describe ITS job, not the person signing in:
599
+ // vibe_dm's `handle` is the recipient. Forwarding it made a first message
600
+ // to @brightseth request a sign-in AS @brightseth (login?handle=brightseth,
601
+ // config.handle saved as the recipient). GitHub says who you are; pass nothing.
602
+ const initResult = await initTool.handler({});
599
603
  const initDisplay = initResult.display || JSON.stringify(initResult, null, 2);
600
604
 
601
605
  // After auth, emit tools/list_changed so Claude sees full toolset
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "slashvibe-mcp",
3
- "version": "0.8.22",
3
+ "version": "0.8.23",
4
4
  "mcpName": "io.github.vibecodinginc/vibe",
5
- "description": "Presence + messaging for terminal coding agents (Claude Code, Codex, Cursor) \u2014 the /vibe kernel",
5
+ "description": "Presence + messaging for terminal coding agents (Claude Code, Codex, Cursor) — the /vibe kernel",
6
6
  "main": "index.js",
7
7
  "bin": {
8
8
  "slashvibe-mcp": "cli.js",
package/setup.js CHANGED
@@ -315,6 +315,14 @@ async function getOnlineCount() {
315
315
  try {
316
316
  const response = await fetch(`${API_BASE}/api/presence`);
317
317
  const data = await response.json();
318
+ // Before sign-in the roster is private: the server answers with counts only
319
+ // (`{ anonymous: true, counts: { humansActive, active, ... }, active: [] }`).
320
+ // Counting names here printed "0 builders online" to every newcomer while
321
+ // eleven people were on. Read the count the server actually gives.
322
+ if (data.counts && typeof data.counts === 'object') {
323
+ const n = data.counts.humansActive ?? data.counts.active;
324
+ if (Number.isFinite(n)) return n;
325
+ }
318
326
  return (data.active?.length || 0) + (data.away?.length || 0);
319
327
  } catch (e) {
320
328
  return 0;
@@ -324,28 +332,30 @@ async function getOnlineCount() {
324
332
  /**
325
333
  * Get online users with details for display
326
334
  */
327
- async function getOnlineUsers() {
335
+ async function getOnlineUsers(token) {
328
336
  try {
329
- const response = await fetch(`${API_BASE}/api/presence`);
337
+ // Handles are only served to a signed-in caller; pass the fresh token so the
338
+ // "here now" list after sign-in is real, not an empty anonymous answer.
339
+ const headers = token ? { Authorization: `Bearer ${token}` } : {};
340
+ const response = await fetch(`${API_BASE}/api/presence`, { headers });
330
341
  const data = await response.json();
331
- const active = data.active || [];
332
- const away = data.away || [];
342
+ const people = (u) => !u.isAgent;
343
+ // "Here now" means active humans only. Away rows were once appended below,
344
+ // which let the headline count disagree with the rows under it (codex P2).
345
+ const active = (data.active || []).filter(people);
346
+ const workText = (u) => u.workingOn || u.working_on || u.one_liner || '';
333
347
 
334
348
  // Format: { users: [{handle, status, one_liner}], total: number }
335
- const users = [
336
- ...active.slice(0, 5).map(u => ({
337
- handle: u.username || u.handle,
338
- status: 'active',
339
- one_liner: u.one_liner || u.status || ''
340
- })),
341
- ...away.slice(0, 2).map(u => ({
342
- handle: u.username || u.handle,
343
- status: 'away',
344
- one_liner: u.one_liner || u.status || ''
345
- }))
346
- ].slice(0, 5);
347
-
348
- return { users, total: active.length + away.length };
349
+ const users = active.slice(0, 5).map(u => ({
350
+ handle: u.username || u.handle,
351
+ status: 'active',
352
+ one_liner: workText(u)
353
+ }));
354
+
355
+ const total = Number.isFinite(data.counts?.humansActive)
356
+ ? data.counts.humansActive
357
+ : active.length;
358
+ return { users, total };
349
359
  } catch (e) {
350
360
  return { users: [], total: 0 };
351
361
  }
@@ -477,7 +487,9 @@ async function setup() {
477
487
  }
478
488
 
479
489
  const onlineCount = await getOnlineCount();
480
- console.log(`${colors.dim} → Connected! ${onlineCount} builders online${colors.reset}`);
490
+ console.log(onlineCount > 0
491
+ ? `${colors.dim} → Connected — ${onlineCount} ${onlineCount === 1 ? 'person' : 'people'} here now${colors.reset}`
492
+ : `${colors.dim} → Connected${colors.reset}`);
481
493
  printStep(3, 'Testing connection...', 'done');
482
494
 
483
495
  // Step 4: Authenticate
@@ -504,7 +516,7 @@ async function setup() {
504
516
  console.log(`${colors.dim} → Authenticated as @${authResult.handle}${colors.reset}`);
505
517
 
506
518
  // Success! Show who's online immediately
507
- const presence = await getOnlineUsers();
519
+ const presence = await getOnlineUsers(authResult.token);
508
520
 
509
521
  console.log('');
510
522
  console.log(`${colors.green} ✓ Setup complete!${colors.reset}`);
@@ -512,7 +524,7 @@ async function setup() {
512
524
 
513
525
  // Show who's vibing right now
514
526
  if (presence.users.length > 0) {
515
- console.log(`${colors.bold} 🟢 ${presence.total} builders vibing now:${colors.reset}`);
527
+ console.log(`${colors.bold} 🟢 ${presence.total} people here now:${colors.reset}`);
516
528
  for (const user of presence.users) {
517
529
  const statusIcon = user.status === 'active' ? colors.green + '●' : colors.yellow + '○';
518
530
  const liner = user.one_liner ? ` — ${user.one_liner.slice(0, 40)}` : '';
@@ -526,7 +538,7 @@ async function setup() {
526
538
 
527
539
  console.log(`${colors.bold} Quick start:${colors.reset}`);
528
540
  console.log(`${colors.dim} 1. Restart your coding agent${detected.length > 1 ? `s (${detected.join(', ')})` : ''}${colors.reset}`);
529
- console.log(`${colors.dim} 2. Send a real message to someone you already know — "dm @their-handle ..."${colors.reset}`);
541
+ console.log(`${colors.dim} 2. Say: "message @their-handle — ..." to someone you already know${colors.reset}`);
530
542
  console.log(`${colors.dim} 3. Claude Code: run "npx slashvibe-mcp hook install" — waiting messages appear at the top of your next session${colors.reset}`);
531
543
  console.log('');
532
544
  console.log(`${colors.cyan} Welcome to /vibe, @${authResult.handle}.${colors.reset}`);
package/version.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
- "version": "0.8.22",
3
- "updated": "2026-08-31",
4
- "changelog": "The first screen. vibe start is now seven lines: who you are, what's waiting, how many others are here, and where to go next. No message bodies, no chosen person, no drafted DM, no rotating tips. And it only says what it actually read — if your inbox or the room can't be reached it says so, instead of showing you a confident zero.",
2
+ "version": "0.8.23",
3
+ "updated": "2026-09-01",
4
+ "changelog": "The install tells the truth about the room. Setup used to say “0 builders online” to every newcomer, because the roster is private before you sign in and it was counting names it was never given; now it reads the count the server actually serves, and after sign-in it lists real people and what they are working on. And a first message to someone before you have signed in no longer asks GitHub to sign you in as them.",
5
5
  "features": [
6
- "vibe start is seven lines and states the unread count exactly once",
7
- "A failed read is never rendered as an empty inbox or an empty room",
8
- "No message bodies on the first screen, and nobody is chosen for you",
9
- "A read that did not succeed can no longer authorize a write — six places where one corrupt line destroyed messages, profiles, presence or your credential",
10
- "vibe token no longer says “old local keys removed” unless they are gone"
6
+ "Setup says how many people are here now — never a zero it did not measure",
7
+ "After sign-in, setup lists the people actually here and what they are working on",
8
+ "Messaging @someone before sign-in starts your own sign-in, not one for them",
9
+ "Setup's quick start is a sentence you can say, not a command to learn"
11
10
  ],
12
11
  "deprecated": [],
13
12
  "breaking": false,