slashvibe-mcp 0.5.5 → 0.5.7
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/notify.js +7 -5
- package/package.json +1 -1
- package/tools/init.js +35 -2
- package/version.json +6 -6
package/notify.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* This is escalation, not baseline.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const {
|
|
13
|
+
const { execFile } = require('child_process');
|
|
14
14
|
const os = require('os');
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const path = require('path');
|
|
@@ -56,16 +56,18 @@ function showNotification(title, message, sound = false, bell = true) {
|
|
|
56
56
|
ringBell();
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
// Escape quotes
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
// Escape double quotes so title/message stay inside their AppleScript string
|
|
60
|
+
// literals. Everything is passed to osascript via execFile (no shell), so
|
|
61
|
+
// sender-controlled single quotes can no longer break out into a shell command.
|
|
62
|
+
const safeTitle = String(title).replace(/"/g, '\\"');
|
|
63
|
+
const safeMessage = String(message).replace(/"/g, '\\"');
|
|
62
64
|
|
|
63
65
|
let script = `display notification "${safeMessage}" with title "${safeTitle}"`;
|
|
64
66
|
if (sound) {
|
|
65
67
|
script += ` sound name "Ping"`;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
execFile('osascript', ['-e', script], (err) => {
|
|
69
71
|
if (err) {
|
|
70
72
|
// Silently fail - notifications are best-effort
|
|
71
73
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slashvibe-mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"mcpName": "io.github.vibecodinginc/vibe",
|
|
5
5
|
"description": "Social layer for Claude Code - DMs, presence, Matrix multiplayer rooms, and connection between AI-assisted developers",
|
|
6
6
|
"main": "index.js",
|
package/tools/init.js
CHANGED
|
@@ -641,12 +641,45 @@ async function handler(args) {
|
|
|
641
641
|
if (config.hasOAuth()) {
|
|
642
642
|
const existingHandle = config.getHandle();
|
|
643
643
|
if (existingHandle) {
|
|
644
|
+
// Enrich the returning-user surface — this fires on every `vibe` for an
|
|
645
|
+
// already-authed user, so it's our highest-frequency touchpoint. Surface
|
|
646
|
+
// unread (the reason to come back) and, if we have no email on file, nudge
|
|
647
|
+
// the return loop right at the teachable moment. Both are best-effort with
|
|
648
|
+
// tight timeouts — never hold up the response; degrade to the plain message.
|
|
649
|
+
let unreadCount = 0;
|
|
650
|
+
let hasEmail = null;
|
|
651
|
+
try {
|
|
652
|
+
[unreadCount, hasEmail] = await Promise.all([
|
|
653
|
+
Promise.race([
|
|
654
|
+
store.getUnreadCount(existingHandle),
|
|
655
|
+
new Promise(resolve => setTimeout(() => resolve(0), 1500))
|
|
656
|
+
]).catch(() => 0),
|
|
657
|
+
Promise.race([
|
|
658
|
+
fetchHasEmail(config.getAuthToken()),
|
|
659
|
+
new Promise(resolve => setTimeout(() => resolve(null), 1500))
|
|
660
|
+
]).catch(() => null)
|
|
661
|
+
]);
|
|
662
|
+
} catch (e) {}
|
|
663
|
+
|
|
664
|
+
const unreadLine = unreadCount > 0
|
|
665
|
+
? `\n\n📬 **${unreadCount} unread** — say \`vibe inbox\` to read ${unreadCount > 1 ? 'them' : 'it'}.`
|
|
666
|
+
: '';
|
|
667
|
+
|
|
668
|
+
// Only nudge when we genuinely can't reach them out-of-band. If they have
|
|
669
|
+
// unread right now, the value is concrete: "these landed while you were
|
|
670
|
+
// away — next time we'll email you." Otherwise it's a gentle one-liner.
|
|
671
|
+
const emailNudge = hasEmail === false
|
|
672
|
+
? (unreadCount > 0
|
|
673
|
+
? `\n\n📧 These landed while you were away. Add an email and /vibe pings you next time — say **"vibe email you@example.com"** _(offline only · one-click unsubscribe)_.`
|
|
674
|
+
: `\n\n📧 **Don't miss a DM** — add an email and /vibe pings you when someone messages you while you're away: **"vibe email you@example.com"** _(offline only · one-click unsubscribe)_.`)
|
|
675
|
+
: '';
|
|
676
|
+
|
|
644
677
|
return {
|
|
645
|
-
display: `## Already signed in as @${existingHandle}
|
|
678
|
+
display: `## Already signed in as @${existingHandle}${unreadLine}
|
|
646
679
|
|
|
647
680
|
To sign out and re-authenticate: \`vibe logout\`
|
|
648
681
|
To see who's online: \`vibe who\`
|
|
649
|
-
To check messages: \`vibe inbox
|
|
682
|
+
To check messages: \`vibe inbox\`${emailNudge}`
|
|
650
683
|
};
|
|
651
684
|
}
|
|
652
685
|
}
|
package/version.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.5.
|
|
3
|
-
"updated": "2026-06-
|
|
4
|
-
"changelog": "
|
|
2
|
+
"version": "0.5.6",
|
|
3
|
+
"updated": "2026-06-30",
|
|
4
|
+
"changelog": "Come back to what you missed. Returning to /vibe now shows your unread count right away, and if we don't have an email to reach you at, we offer to arm the return-loop ping at the moment it matters — when a DM just landed while you were away.",
|
|
5
5
|
"features": [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
6
|
+
"Returning 'already signed in' surface now shows your unread count instead of a static line",
|
|
7
|
+
"Contextual email nudge on return: if a DM landed while you were away and we can't reach you, we offer 'vibe email' right then",
|
|
8
|
+
"One-line, offline-only, one-click unsubscribe — the return loop only pings when you're actually gone"
|
|
9
9
|
],
|
|
10
10
|
"deprecated": [
|
|
11
11
|
"vibe_pair — use Matrix room invites",
|