slashvibe-mcp 0.3.21 → 0.3.22
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/LICENSE +21 -0
- package/README.md +280 -47
- package/config.js +36 -31
- package/crypto.js +1 -6
- package/discord.js +19 -19
- package/index.js +217 -207
- package/intelligence/index.js +2 -9
- package/intelligence/infer.js +10 -16
- package/intelligence/patterns.js +23 -18
- package/intelligence/proactive.js +16 -15
- package/intelligence/serendipity.js +57 -20
- package/memory.js +13 -8
- package/notify.js +39 -14
- package/package.json +27 -20
- package/presence.js +2 -2
- package/prompts.js +5 -9
- package/protocol/index.js +123 -87
- package/protocol/telegram-commands.js +36 -37
- package/store/api.js +358 -529
- package/store/local.js +9 -10
- package/store/profiles.js +48 -192
- package/store/reservations.js +2 -9
- package/store/skills.js +69 -71
- package/store/sqlite.js +355 -0
- package/tools/_actions.js +48 -387
- package/tools/_connection-queue.js +45 -56
- package/tools/_discovery-enhanced.js +52 -57
- package/tools/_discovery.js +87 -185
- package/tools/{l2-status.js → _experimental/l2-status.js} +68 -70
- package/tools/{shipback.js → _experimental/shipback.js} +4 -3
- package/tools/_proactive-discovery.js +60 -73
- package/tools/_shared/index.js +41 -64
- package/tools/admin-inbox.js +10 -15
- package/tools/agents.js +1 -1
- package/tools/artifact-create.js +13 -23
- package/tools/artifact-view.js +4 -4
- package/tools/{_deprecated/back.js → back.js} +1 -1
- package/tools/bye.js +3 -5
- package/tools/consent.js +2 -2
- package/tools/context.js +9 -10
- package/tools/crossword.js +3 -2
- package/tools/discover.js +94 -356
- package/tools/dm.js +27 -86
- package/tools/doctor.js +12 -41
- package/tools/drawing.js +34 -20
- package/tools/echo.js +11 -11
- package/tools/feed.js +30 -58
- package/tools/follow.js +64 -187
- package/tools/{_deprecated/forget.js → forget.js} +4 -7
- package/tools/game.js +144 -48
- package/tools/handoff.js +6 -8
- package/tools/help.js +3 -3
- package/tools/idea.js +15 -27
- package/tools/inbox.js +121 -293
- package/tools/init.js +54 -151
- package/tools/invite.js +8 -21
- package/tools/migrate.js +27 -24
- package/tools/multiplayer-game.js +50 -40
- package/tools/{_deprecated/mute.js → mute.js} +4 -3
- package/tools/notifications.js +58 -48
- package/tools/observe.js +12 -15
- package/tools/onboarding.js +8 -11
- package/tools/open.js +13 -144
- package/tools/party-game.js +23 -12
- package/tools/patterns.js +2 -1
- package/tools/ping.js +5 -7
- package/tools/react.js +28 -30
- package/tools/{_deprecated/recall.js → recall.js} +5 -10
- package/tools/release.js +4 -2
- package/tools/{_deprecated/remember.js → remember.js} +4 -6
- package/tools/report.js +2 -2
- package/tools/request.js +6 -26
- package/tools/reserve.js +1 -1
- package/tools/session-fork.js +97 -0
- package/tools/session-save.js +109 -0
- package/tools/settings.js +30 -99
- package/tools/ship.js +74 -56
- package/tools/{_deprecated/skills-exchange.js → skills-exchange.js} +38 -39
- package/tools/social-inbox.js +22 -28
- package/tools/social-post.js +24 -27
- package/tools/solo-game.js +54 -46
- package/tools/start.js +14 -148
- package/tools/status.js +21 -68
- package/tools/submit.js +4 -2
- package/tools/suggest-tags.js +36 -33
- package/tools/summarize.js +19 -16
- package/tools/tag-suggestions.js +72 -73
- package/tools/test.js +1 -1
- package/tools/{_deprecated/tictactoe.js → tictactoe.js} +26 -26
- package/tools/token.js +4 -4
- package/tools/update.js +1 -2
- package/tools/watch.js +132 -112
- package/tools/who.js +20 -40
- package/tools/{_deprecated/wordassociation.js → wordassociation.js} +23 -20
- package/tools/workshop-buddy.js +52 -53
- package/tools/x-mentions.js +0 -1
- package/tools/x-reply.js +0 -1
- package/twitter.js +14 -20
- package/version.json +8 -10
- package/analytics.js +0 -107
- package/auth-store.js +0 -148
- package/auto-update.js +0 -130
- package/bridges/bridge-monitor.js +0 -388
- package/bridges/discord-bot.js +0 -431
- package/bridges/farcaster.js +0 -299
- package/bridges/telegram.js +0 -261
- package/bridges/webhook-health.js +0 -420
- package/bridges/webhook-server.js +0 -437
- package/bridges/whatsapp.js +0 -441
- package/bridges/x-webhook.js +0 -423
- package/games/arcade.js +0 -406
- package/games/chess.js +0 -451
- package/games/colorguess.js +0 -343
- package/games/crossword-words.js +0 -171
- package/games/crossword.js +0 -461
- package/games/drawing.js +0 -347
- package/games/gameroulette.js +0 -300
- package/games/gamerouter.js +0 -336
- package/games/gamestatus.js +0 -337
- package/games/guessnumber.js +0 -209
- package/games/hangman.js +0 -279
- package/games/memory.js +0 -338
- package/games/multiplayer-tictactoe.js +0 -389
- package/games/pixelart.js +0 -399
- package/games/quickduel.js +0 -354
- package/games/riddle.js +0 -371
- package/games/rockpaperscissors.js +0 -291
- package/games/snake.js +0 -406
- package/games/storybuilder.js +0 -343
- package/games/tictactoe.js +0 -345
- package/games/twentyquestions.js +0 -286
- package/games/twotruths.js +0 -207
- package/games/werewolf.js +0 -508
- package/games/wordassociation.js +0 -247
- package/games/wordchain.js +0 -135
- package/intelligence/interests.js +0 -369
- package/notification-emitter.js +0 -77
- package/setup.js +0 -480
- package/smart-inbox.js +0 -276
- package/tools/_deprecated/auto-suggest-connections.js +0 -304
- package/tools/_deprecated/bootstrap-skills.js +0 -231
- package/tools/_deprecated/bridge-dashboard.js +0 -342
- package/tools/_deprecated/bridge-health.js +0 -400
- package/tools/_deprecated/bridge-live.js +0 -384
- package/tools/_deprecated/bridges.js +0 -383
- package/tools/_deprecated/colorguess.js +0 -281
- package/tools/_deprecated/discover-insights.js +0 -379
- package/tools/_deprecated/discover-momentum.js +0 -256
- package/tools/_deprecated/discovery-analytics.js +0 -345
- package/tools/_deprecated/discovery-auto-suggest.js +0 -275
- package/tools/_deprecated/discovery-bootstrap.js +0 -267
- package/tools/_deprecated/discovery-daily.js +0 -375
- package/tools/_deprecated/discovery-dashboard.js +0 -385
- package/tools/_deprecated/discovery-digest.js +0 -314
- package/tools/_deprecated/discovery-hub.js +0 -357
- package/tools/_deprecated/discovery-insights.js +0 -384
- package/tools/_deprecated/discovery-momentum.js +0 -281
- package/tools/_deprecated/discovery-monitor.js +0 -319
- package/tools/_deprecated/discovery-proactive.js +0 -300
- package/tools/_deprecated/draw.js +0 -317
- package/tools/_deprecated/farcaster.js +0 -307
- package/tools/_deprecated/games-catalog.js +0 -376
- package/tools/_deprecated/games.js +0 -313
- package/tools/_deprecated/guessnumber.js +0 -194
- package/tools/_deprecated/hangman.js +0 -129
- package/tools/_deprecated/multiplayer-tictactoe.js +0 -303
- package/tools/_deprecated/riddle.js +0 -240
- package/tools/_deprecated/run-bootstrap.js +0 -69
- package/tools/_deprecated/skills-analytics.js +0 -349
- package/tools/_deprecated/skills-bootstrap.js +0 -301
- package/tools/_deprecated/skills-dashboard.js +0 -268
- package/tools/_deprecated/skills.js +0 -380
- package/tools/_deprecated/smart-intro.js +0 -353
- package/tools/_deprecated/storybuilder.js +0 -331
- package/tools/_deprecated/telegram-bot.js +0 -183
- package/tools/_deprecated/telegram-setup.js +0 -214
- package/tools/_deprecated/twentyquestions.js +0 -143
- package/tools/_shared.js +0 -234
- package/tools/_work-context.js +0 -338
- package/tools/_work-context.manual-test.js +0 -199
- package/tools/_work-context.test.js +0 -260
- package/tools/activity.js +0 -220
- package/tools/agent-treasury.js +0 -288
- package/tools/analytics.js +0 -191
- package/tools/approve.js +0 -197
- package/tools/arcade.js +0 -173
- package/tools/artifacts-price.js +0 -107
- package/tools/ask-expert.js +0 -160
- package/tools/available.js +0 -120
- package/tools/become-expert.js +0 -150
- package/tools/broadcast.js +0 -325
- package/tools/chat.js +0 -202
- package/tools/collaborative-drawing.js +0 -286
- package/tools/connection-status.js +0 -178
- package/tools/earnings.js +0 -126
- package/tools/friends.js +0 -207
- package/tools/genesis.js +0 -233
- package/tools/gig-browse.js +0 -206
- package/tools/gig-complete.js +0 -144
- package/tools/health.js +0 -87
- package/tools/leaderboard.js +0 -117
- package/tools/lib/git-apply.js +0 -206
- package/tools/lib/git-bundle.js +0 -407
- package/tools/mint.js +0 -377
- package/tools/plan.js +0 -225
- package/tools/profile.js +0 -219
- package/tools/proof-of-work.js +0 -144
- package/tools/pulse.js +0 -218
- package/tools/reply.js +0 -166
- package/tools/reputation.js +0 -175
- package/tools/schedule.js +0 -367
- package/tools/search-messages.js +0 -123
- package/tools/session.js +0 -467
- package/tools/session_price.js +0 -128
- package/tools/smart-check.js +0 -201
- package/tools/social-processor.js +0 -445
- package/tools/streak.js +0 -147
- package/tools/stuck.js +0 -297
- package/tools/subscribe.js +0 -148
- package/tools/subscriptions.js +0 -134
- package/tools/tip.js +0 -193
- package/tools/wallet.js +0 -269
- package/tools/webhook-test.js +0 -388
- package/tools/withdraw.js +0 -145
- package/tools/work-summary.js +0 -96
- package/tools/workshop.js +0 -327
- /package/tools/{l2-bridge.js → _experimental/l2-bridge.js} +0 -0
- /package/tools/{l2.js → _experimental/l2.js} +0 -0
- /package/tools/{_deprecated/away.js → away.js} +0 -0
package/tools/arcade.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe arcade — Browse and discover all /vibe games
|
|
3
|
-
*
|
|
4
|
-
* Your gateway to 20+ games built by @games-agent!
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const config = require('../config');
|
|
8
|
-
const { requireInit } = require('./_shared');
|
|
9
|
-
|
|
10
|
-
// Import arcade system
|
|
11
|
-
const arcade = require('../games/arcade');
|
|
12
|
-
const gameRoulette = require('../games/gameroulette');
|
|
13
|
-
|
|
14
|
-
// Global arcade state (simple in-memory storage)
|
|
15
|
-
let arcadeState = null;
|
|
16
|
-
let rouletteState = null;
|
|
17
|
-
|
|
18
|
-
function getArcadeState() {
|
|
19
|
-
if (!arcadeState) {
|
|
20
|
-
arcadeState = arcade.createInitialArcadeState();
|
|
21
|
-
}
|
|
22
|
-
return arcadeState;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function getRouletteState() {
|
|
26
|
-
if (!rouletteState) {
|
|
27
|
-
rouletteState = gameRoulette.createInitialGameRouletteState();
|
|
28
|
-
}
|
|
29
|
-
return rouletteState;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const definition = {
|
|
33
|
-
name: 'vibe_arcade',
|
|
34
|
-
description: 'Browse and discover all /vibe games. Use "arcade" for main menu, "roulette" for random game',
|
|
35
|
-
inputSchema: {
|
|
36
|
-
type: 'object',
|
|
37
|
-
properties: {
|
|
38
|
-
command: {
|
|
39
|
-
type: 'string',
|
|
40
|
-
description: 'Arcade command: "main", category name, game name, "back", "roulette", "random", or mood',
|
|
41
|
-
default: 'main'
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
required: []
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
async function handler(args) {
|
|
49
|
-
const initCheck = requireInit();
|
|
50
|
-
if (initCheck) return initCheck;
|
|
51
|
-
|
|
52
|
-
const myHandle = config.getHandle();
|
|
53
|
-
const command = args.command || 'main';
|
|
54
|
-
const cmd = command.toLowerCase().trim();
|
|
55
|
-
|
|
56
|
-
// Handle roulette and random commands
|
|
57
|
-
if (cmd === 'roulette' || cmd === 'random' || cmd === 'surprise') {
|
|
58
|
-
const rState = getRouletteState();
|
|
59
|
-
const result = gameRoulette.getRandomGame(rState, myHandle);
|
|
60
|
-
|
|
61
|
-
if (result.error) {
|
|
62
|
-
return { display: `🎲 **Game Roulette Error:** ${result.error}` };
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
rouletteState = result.gameState;
|
|
66
|
-
const display = gameRoulette.formatRouletteDisplay(result.gameState, result.recommendation, myHandle);
|
|
67
|
-
|
|
68
|
-
return { display };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Handle mood-based recommendations
|
|
72
|
-
const moods = ['chill', 'competitive', 'social', 'quick', 'thoughtful', 'creative'];
|
|
73
|
-
if (moods.includes(cmd)) {
|
|
74
|
-
const rState = getRouletteState();
|
|
75
|
-
const result = gameRoulette.getSmartRecommendation(rState, myHandle, cmd);
|
|
76
|
-
|
|
77
|
-
if (result.success) {
|
|
78
|
-
rouletteState = result.gameState;
|
|
79
|
-
let display = `🎯 **${cmd.toUpperCase()} MOOD MATCH**\n\n`;
|
|
80
|
-
display += gameRoulette.formatRouletteDisplay(result.gameState, result.recommendation, myHandle);
|
|
81
|
-
return { display };
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Handle special arcade commands
|
|
86
|
-
if (cmd === 'stats') {
|
|
87
|
-
const totalGames = Object.keys(arcade.GAMES).length;
|
|
88
|
-
const categories = Object.keys(arcade.CATEGORIES).length;
|
|
89
|
-
|
|
90
|
-
let display = `🎮 **Workshop Arcade Stats**\n\n`;
|
|
91
|
-
display += `**Total Games:** ${totalGames}\n`;
|
|
92
|
-
display += `**Categories:** ${categories}\n\n`;
|
|
93
|
-
|
|
94
|
-
// Show category breakdown
|
|
95
|
-
Object.entries(arcade.CATEGORIES).forEach(([id, category]) => {
|
|
96
|
-
const gameCount = arcade.getGamesByCategory(id).length;
|
|
97
|
-
display += `${category.icon} ${category.name}: ${gameCount} games\n`;
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Show roulette stats if available
|
|
101
|
-
const rStats = gameRoulette.getRouletteStats(getRouletteState());
|
|
102
|
-
if (rStats) {
|
|
103
|
-
display += `\n**Your Session:**\n`;
|
|
104
|
-
display += `• Recommendations: ${rStats.totalRecommendations}\n`;
|
|
105
|
-
if (rStats.favoriteCategory) {
|
|
106
|
-
display += `• Favorite category: ${rStats.favoriteCategory}\n`;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return { display };
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (cmd === 'help') {
|
|
114
|
-
let display = `🎮 **Workshop Arcade Help**\n\n`;
|
|
115
|
-
display += `**Navigation:**\n`;
|
|
116
|
-
display += `• \`arcade\` or \`arcade main\` - Main menu\n`;
|
|
117
|
-
display += `• \`arcade classic\` - Browse category\n`;
|
|
118
|
-
display += `• \`arcade chess\` - Game info\n`;
|
|
119
|
-
display += `• \`arcade back\` - Go back\n\n`;
|
|
120
|
-
display += `**Discovery:**\n`;
|
|
121
|
-
display += `• \`arcade roulette\` - Random game\n`;
|
|
122
|
-
display += `• \`arcade competitive\` - Mood-based pick\n`;
|
|
123
|
-
display += `• \`arcade stats\` - View arcade stats\n\n`;
|
|
124
|
-
display += `**Moods:** chill, competitive, social, quick, thoughtful, creative\n`;
|
|
125
|
-
display += `**Categories:** classic, word, puzzle, action, creative, social`;
|
|
126
|
-
|
|
127
|
-
return { display };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Handle regular arcade navigation
|
|
131
|
-
const aState = getArcadeState();
|
|
132
|
-
|
|
133
|
-
if (cmd === 'main' || cmd === '' || cmd === 'arcade') {
|
|
134
|
-
// Reset to main menu
|
|
135
|
-
const result = arcade.navigateBack(aState);
|
|
136
|
-
if (result.success) {
|
|
137
|
-
arcadeState = result.gameState;
|
|
138
|
-
}
|
|
139
|
-
const display = arcade.formatArcadeDisplay(getArcadeState());
|
|
140
|
-
return { display };
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Handle arcade navigation command
|
|
144
|
-
const result = arcade.handleArcadeCommand(aState, command);
|
|
145
|
-
|
|
146
|
-
if (result.error) {
|
|
147
|
-
// Try partial matches or suggestions
|
|
148
|
-
let display = `❌ ${result.error}\n\n`;
|
|
149
|
-
|
|
150
|
-
// Show available options based on current view
|
|
151
|
-
if (aState.view === 'main') {
|
|
152
|
-
display += `Try: category names (classic, word, puzzle, action, creative, social) or game names\n`;
|
|
153
|
-
display += `Or use: \`arcade roulette\` for a random game recommendation!`;
|
|
154
|
-
} else if (aState.view === 'category') {
|
|
155
|
-
const games = arcade.getGamesByCategory(aState.selectedCategory);
|
|
156
|
-
const gameNames = games.slice(0, 4).map(g => g.name).join(', ');
|
|
157
|
-
display += `Try: ${gameNames}... or \`arcade back\``;
|
|
158
|
-
} else {
|
|
159
|
-
display += `Try: \`arcade back\` or \`arcade main\``;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return { display };
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (result.success) {
|
|
166
|
-
arcadeState = result.gameState;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const display = arcade.formatArcadeDisplay(getArcadeState());
|
|
170
|
-
return { display };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
module.exports = { definition, handler };
|
package/tools/artifacts-price.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe_artifacts_price - Set pricing for an artifact
|
|
3
|
-
*
|
|
4
|
-
* Enables artifact commerce by setting a price.
|
|
5
|
-
* Supports one-time purchase, pay-what-you-want, and tip jar models.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const config = require('../config');
|
|
9
|
-
const { requireInit, success, error, header } = require('./_shared');
|
|
10
|
-
|
|
11
|
-
const BASE_URL = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
12
|
-
|
|
13
|
-
const definition = {
|
|
14
|
-
name: 'vibe_artifacts_price',
|
|
15
|
-
description: 'Set pricing for an artifact you created. Enable commerce for your artifacts.',
|
|
16
|
-
inputSchema: {
|
|
17
|
-
type: 'object',
|
|
18
|
-
properties: {
|
|
19
|
-
artifact_id: {
|
|
20
|
-
type: 'string',
|
|
21
|
-
description: 'The artifact ID to price (e.g., art_abc123)'
|
|
22
|
-
},
|
|
23
|
-
price: {
|
|
24
|
-
type: 'number',
|
|
25
|
-
description: 'Price in dollars (e.g., 5.00). Set to 0 to make free.'
|
|
26
|
-
},
|
|
27
|
-
sale_type: {
|
|
28
|
-
type: 'string',
|
|
29
|
-
enum: ['one_time', 'pay_what_you_want', 'tip'],
|
|
30
|
-
description: 'Sale type: one_time (fixed price), pay_what_you_want (price is minimum), tip (free with optional tip)'
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
required: ['artifact_id', 'price', 'sale_type']
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
async function handler(args) {
|
|
38
|
-
const initCheck = requireInit();
|
|
39
|
-
if (initCheck) return initCheck;
|
|
40
|
-
|
|
41
|
-
const { artifact_id, price, sale_type } = args;
|
|
42
|
-
const handle = config.getHandle();
|
|
43
|
-
|
|
44
|
-
// Validate price
|
|
45
|
-
if (price < 0) {
|
|
46
|
-
return { display: error('Price cannot be negative') };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (price > 1000) {
|
|
50
|
-
return { display: error('Price cannot exceed $1000') };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
const response = await fetch(`${BASE_URL}/api/artifacts/price`, {
|
|
55
|
-
method: 'POST',
|
|
56
|
-
headers: { 'Content-Type': 'application/json' },
|
|
57
|
-
body: JSON.stringify({
|
|
58
|
-
artifact_id,
|
|
59
|
-
handle,
|
|
60
|
-
price_cents: Math.round(price * 100),
|
|
61
|
-
sale_type
|
|
62
|
-
})
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const data = await response.json();
|
|
66
|
-
|
|
67
|
-
if (!data.success) {
|
|
68
|
-
return { display: error(data.error || 'Failed to set pricing') };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Format display
|
|
72
|
-
let display = success('Artifact Pricing Updated') + '\n\n';
|
|
73
|
-
|
|
74
|
-
display += header('Pricing Details', 3) + '\n';
|
|
75
|
-
display += `**Artifact:** ${data.artifact?.title || artifact_id}\n`;
|
|
76
|
-
display += `**Price:** $${price.toFixed(2)}\n`;
|
|
77
|
-
display += `**Sale Type:** ${formatSaleType(sale_type)}\n`;
|
|
78
|
-
display += `**Status:** ${price > 0 ? 'For Sale' : 'Free'}\n\n`;
|
|
79
|
-
|
|
80
|
-
if (data.artifact?.url) {
|
|
81
|
-
display += `**Share Link:** ${data.artifact.url}\n`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (sale_type === 'pay_what_you_want') {
|
|
85
|
-
display += `\n_Buyers can pay $${price.toFixed(2)} or more_`;
|
|
86
|
-
} else if (sale_type === 'tip') {
|
|
87
|
-
display += `\n_Free to access, tips optional_`;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return { display };
|
|
91
|
-
|
|
92
|
-
} catch (e) {
|
|
93
|
-
console.error('[artifacts-price] Error:', e);
|
|
94
|
-
return { display: error(`Failed to set pricing: ${e.message}`) };
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function formatSaleType(type) {
|
|
99
|
-
const types = {
|
|
100
|
-
one_time: 'One-Time Purchase',
|
|
101
|
-
pay_what_you_want: 'Pay What You Want',
|
|
102
|
-
tip: 'Free with Tips'
|
|
103
|
-
};
|
|
104
|
-
return types[type] || type;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
module.exports = { definition, handler };
|
package/tools/ask-expert.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe_ask_expert - Ask a question to a human expert via ping.money
|
|
3
|
-
*
|
|
4
|
-
* Creates escrow, matches you with best expert, notifies them
|
|
5
|
-
*
|
|
6
|
-
* Examples:
|
|
7
|
-
* - "ask an expert: how do I implement WebSocket authentication with JWT?"
|
|
8
|
-
* - "vibe ask_expert about smart contract security"
|
|
9
|
-
* - "ping @alice about react performance"
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const fetch = require('node-fetch');
|
|
13
|
-
|
|
14
|
-
module.exports = {
|
|
15
|
-
name: 'vibe_ask_expert',
|
|
16
|
-
description: 'Ask a question to a human expert. Creates escrow, matches you with best expert based on skills/rating/availability. Min budget: $5',
|
|
17
|
-
|
|
18
|
-
inputSchema: {
|
|
19
|
-
type: 'object',
|
|
20
|
-
properties: {
|
|
21
|
-
question: {
|
|
22
|
-
type: 'string',
|
|
23
|
-
description: 'Your question for the expert (be specific)'
|
|
24
|
-
},
|
|
25
|
-
budget: {
|
|
26
|
-
type: 'number',
|
|
27
|
-
description: 'Budget in USD (min $5, typical $10-$50)'
|
|
28
|
-
},
|
|
29
|
-
preferred_expert: {
|
|
30
|
-
type: 'string',
|
|
31
|
-
description: 'Optional: Specific expert handle (e.g., @alice). If not provided, best match will be found.'
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
required: ['question', 'budget']
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
async execute({ question, budget, preferred_expert }, context) {
|
|
38
|
-
try {
|
|
39
|
-
const from = context.handle;
|
|
40
|
-
|
|
41
|
-
if (!from) {
|
|
42
|
-
return {
|
|
43
|
-
success: false,
|
|
44
|
-
error: 'Not authenticated. Use vibe init first.'
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Validate budget
|
|
49
|
-
if (budget < 5) {
|
|
50
|
-
return {
|
|
51
|
-
success: false,
|
|
52
|
-
error: 'Minimum budget is $5'
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const apiUrl = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
57
|
-
|
|
58
|
-
// If no preferred expert, first show matches
|
|
59
|
-
if (!preferred_expert) {
|
|
60
|
-
// Get expert matches
|
|
61
|
-
const matchResponse = await fetch(`${apiUrl}/api/ping/match`, {
|
|
62
|
-
method: 'POST',
|
|
63
|
-
headers: {
|
|
64
|
-
'Content-Type': 'application/json',
|
|
65
|
-
'Authorization': `Bearer ${context.token}`
|
|
66
|
-
},
|
|
67
|
-
body: JSON.stringify({
|
|
68
|
-
question,
|
|
69
|
-
budget,
|
|
70
|
-
asker_handle: from
|
|
71
|
-
})
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const matchResult = await matchResponse.json();
|
|
75
|
-
|
|
76
|
-
if (!matchResponse.ok || !matchResult.success) {
|
|
77
|
-
return {
|
|
78
|
-
success: false,
|
|
79
|
-
error: 'No experts available',
|
|
80
|
-
details: matchResult.error
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const topMatch = matchResult.matches?.[0];
|
|
85
|
-
|
|
86
|
-
if (!topMatch) {
|
|
87
|
-
return {
|
|
88
|
-
success: false,
|
|
89
|
-
error: 'No suitable experts found for this question'
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Use top match
|
|
94
|
-
preferred_expert = topMatch.expert_handle;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Create escrow and ask question
|
|
98
|
-
const askResponse = await fetch(`${apiUrl}/api/ping/ask`, {
|
|
99
|
-
method: 'POST',
|
|
100
|
-
headers: {
|
|
101
|
-
'Content-Type': 'application/json',
|
|
102
|
-
'Authorization': `Bearer ${context.token}`
|
|
103
|
-
},
|
|
104
|
-
body: JSON.stringify({
|
|
105
|
-
from,
|
|
106
|
-
question,
|
|
107
|
-
budget,
|
|
108
|
-
preferred_expert
|
|
109
|
-
})
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
const askResult = await askResponse.json();
|
|
113
|
-
|
|
114
|
-
if (!askResponse.ok) {
|
|
115
|
-
return {
|
|
116
|
-
success: false,
|
|
117
|
-
error: askResult.error || 'Failed to ask expert',
|
|
118
|
-
details: askResult.details
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return {
|
|
123
|
-
success: true,
|
|
124
|
-
message: `Question sent to ${askResult.expert_handle}`,
|
|
125
|
-
session: {
|
|
126
|
-
session_id: askResult.session_id,
|
|
127
|
-
expert: askResult.expert_handle,
|
|
128
|
-
expert_skills: askResult.expert_skills,
|
|
129
|
-
escrow_amount: `$${askResult.escrow_amount}`,
|
|
130
|
-
escrow_id: askResult.escrow_id,
|
|
131
|
-
tx_hash: askResult.tx_hash,
|
|
132
|
-
status: askResult.status,
|
|
133
|
-
timeout: '48 hours'
|
|
134
|
-
},
|
|
135
|
-
formatted: `
|
|
136
|
-
🎓 Question sent to ${askResult.expert_handle}!
|
|
137
|
-
|
|
138
|
-
Session: ${askResult.session_id}
|
|
139
|
-
Expert: ${askResult.expert_handle}
|
|
140
|
-
Skills: ${askResult.expert_skills?.join(', ') || 'N/A'}
|
|
141
|
-
|
|
142
|
-
Escrow: $${askResult.escrow_amount} (locked for 48 hours)
|
|
143
|
-
Status: ${askResult.status}
|
|
144
|
-
|
|
145
|
-
The expert has been notified and will respond soon.
|
|
146
|
-
You'll be notified when they answer.
|
|
147
|
-
|
|
148
|
-
To complete session: vibe ping complete ${askResult.session_id}
|
|
149
|
-
`.trim()
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
} catch (error) {
|
|
153
|
-
return {
|
|
154
|
-
success: false,
|
|
155
|
-
error: 'Failed to ask expert',
|
|
156
|
-
details: error.message
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
};
|
package/tools/available.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe available — Signal you're open to chat
|
|
3
|
-
*
|
|
4
|
-
* Lower the barrier to connection by explicitly signaling
|
|
5
|
-
* what topics you're happy to help with.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* - vibe available "React, auth, Postgres"
|
|
9
|
-
* - vibe available --clear
|
|
10
|
-
* - vibe available (show current)
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const config = require('../config');
|
|
14
|
-
const store = require('../store');
|
|
15
|
-
const { requireInit } = require('./_shared');
|
|
16
|
-
|
|
17
|
-
const definition = {
|
|
18
|
-
name: 'vibe_available',
|
|
19
|
-
description: 'Signal you\'re open to chat about specific topics. Others see you\'re available and what you can help with.',
|
|
20
|
-
inputSchema: {
|
|
21
|
-
type: 'object',
|
|
22
|
-
properties: {
|
|
23
|
-
topics: {
|
|
24
|
-
type: 'string',
|
|
25
|
-
description: 'Topics you\'re available to help with (e.g., "React, auth, Postgres")'
|
|
26
|
-
},
|
|
27
|
-
clear: {
|
|
28
|
-
type: 'boolean',
|
|
29
|
-
description: 'Clear your availability - stop signaling you\'re open'
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
async function handler(args) {
|
|
36
|
-
const initCheck = requireInit();
|
|
37
|
-
if (initCheck) return initCheck;
|
|
38
|
-
|
|
39
|
-
const myHandle = config.getHandle();
|
|
40
|
-
const { topics, clear } = args;
|
|
41
|
-
|
|
42
|
-
// Clear availability
|
|
43
|
-
if (clear) {
|
|
44
|
-
await store.heartbeat(myHandle, config.getOneLiner(), {
|
|
45
|
-
availableFor: null
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
return {
|
|
49
|
-
display: `## Availability Cleared
|
|
50
|
-
|
|
51
|
-
You're no longer signaling openness to chat.
|
|
52
|
-
|
|
53
|
-
Others won't see availability topics next to your name.
|
|
54
|
-
|
|
55
|
-
**To signal availability again:**
|
|
56
|
-
\`vibe available "React, auth, Postgres"\``
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Show current availability
|
|
61
|
-
if (!topics) {
|
|
62
|
-
return {
|
|
63
|
-
display: `## Signal Availability
|
|
64
|
-
|
|
65
|
-
Let others know you're open to chat about specific topics.
|
|
66
|
-
|
|
67
|
-
**Set your availability:**
|
|
68
|
-
\`vibe available "React, auth, Postgres"\`
|
|
69
|
-
|
|
70
|
-
**What happens:**
|
|
71
|
-
- Your presence shows: \`@${myHandle} — available for: React, auth, Postgres\`
|
|
72
|
-
- Others know they won't be bothering you
|
|
73
|
-
- Lower barrier to reaching out
|
|
74
|
-
|
|
75
|
-
**Clear availability:**
|
|
76
|
-
\`vibe available --clear\`
|
|
77
|
-
|
|
78
|
-
_Availability is ephemeral — clears when you go offline._`
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Parse topics (comma or space separated)
|
|
83
|
-
const topicList = topics
|
|
84
|
-
.split(/[,\s]+/)
|
|
85
|
-
.map(t => t.trim().toLowerCase())
|
|
86
|
-
.filter(t => t.length > 0 && t.length <= 30)
|
|
87
|
-
.slice(0, 5); // Max 5 topics
|
|
88
|
-
|
|
89
|
-
if (topicList.length === 0) {
|
|
90
|
-
return {
|
|
91
|
-
display: `Please provide at least one topic. Example:\n\`vibe available "React, auth, Postgres"\``
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Update presence with availability
|
|
96
|
-
await store.heartbeat(myHandle, config.getOneLiner(), {
|
|
97
|
-
availableFor: topicList
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const topicsFormatted = topicList.join(', ');
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
display: `## You're Available! 🤝
|
|
104
|
-
|
|
105
|
-
**Topics:** ${topicsFormatted}
|
|
106
|
-
|
|
107
|
-
Others now see:
|
|
108
|
-
\`@${myHandle} — available for: ${topicsFormatted}\`
|
|
109
|
-
|
|
110
|
-
This signals you're open to questions about these topics.
|
|
111
|
-
People are more likely to reach out when they know they won't be bothering you.
|
|
112
|
-
|
|
113
|
-
**Clear when busy:**
|
|
114
|
-
\`vibe available --clear\`
|
|
115
|
-
|
|
116
|
-
_Availability clears automatically when you go offline._`
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
module.exports = { definition, handler };
|
package/tools/become-expert.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vibe_become_expert - Register as an expert in ping.money
|
|
3
|
-
*
|
|
4
|
-
* List your skills, set your rates, start earning
|
|
5
|
-
*
|
|
6
|
-
* Examples:
|
|
7
|
-
* - "become an expert in blockchain"
|
|
8
|
-
* - "vibe become_expert skills: react, typescript, performance"
|
|
9
|
-
* - "register as expert: smart contracts, $100/hr"
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const fetch = require('node-fetch');
|
|
13
|
-
|
|
14
|
-
module.exports = {
|
|
15
|
-
name: 'vibe_become_expert',
|
|
16
|
-
description: 'Register as an expert in the ping.money marketplace. Set skills, rates, availability. Start earning from answering questions.',
|
|
17
|
-
|
|
18
|
-
inputSchema: {
|
|
19
|
-
type: 'object',
|
|
20
|
-
properties: {
|
|
21
|
-
skills: {
|
|
22
|
-
type: 'array',
|
|
23
|
-
items: { type: 'string' },
|
|
24
|
-
description: 'Your areas of expertise (e.g., ["blockchain", "smart contracts", "solidity"])'
|
|
25
|
-
},
|
|
26
|
-
bio: {
|
|
27
|
-
type: 'string',
|
|
28
|
-
description: 'Short bio describing your experience'
|
|
29
|
-
},
|
|
30
|
-
hourly_rate: {
|
|
31
|
-
type: 'number',
|
|
32
|
-
description: 'Optional hourly rate in USD (e.g., 100 for $100/hour)'
|
|
33
|
-
},
|
|
34
|
-
min_escrow: {
|
|
35
|
-
type: 'number',
|
|
36
|
-
description: 'Minimum escrow amount for sessions (default $5)',
|
|
37
|
-
default: 5
|
|
38
|
-
},
|
|
39
|
-
availability: {
|
|
40
|
-
type: 'string',
|
|
41
|
-
enum: ['available', 'busy', 'offline'],
|
|
42
|
-
description: 'Current availability status',
|
|
43
|
-
default: 'available'
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
required: ['skills']
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
async execute({ skills, bio, hourly_rate, min_escrow = 5, availability = 'available' }, context) {
|
|
50
|
-
try {
|
|
51
|
-
const handle = context.handle;
|
|
52
|
-
|
|
53
|
-
if (!handle) {
|
|
54
|
-
return {
|
|
55
|
-
success: false,
|
|
56
|
-
error: 'Not authenticated. Use vibe init first.'
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Validate skills
|
|
61
|
-
if (!skills || skills.length === 0) {
|
|
62
|
-
return {
|
|
63
|
-
success: false,
|
|
64
|
-
error: 'Must provide at least one skill'
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const apiUrl = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
|
|
69
|
-
|
|
70
|
-
const response = await fetch(`${apiUrl}/api/ping/expert/register`, {
|
|
71
|
-
method: 'POST',
|
|
72
|
-
headers: {
|
|
73
|
-
'Content-Type': 'application/json',
|
|
74
|
-
'Authorization': `Bearer ${context.token}`
|
|
75
|
-
},
|
|
76
|
-
body: JSON.stringify({
|
|
77
|
-
handle,
|
|
78
|
-
skills,
|
|
79
|
-
bio,
|
|
80
|
-
hourly_rate,
|
|
81
|
-
min_escrow,
|
|
82
|
-
availability
|
|
83
|
-
})
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
const result = await response.json();
|
|
87
|
-
|
|
88
|
-
if (!response.ok) {
|
|
89
|
-
return {
|
|
90
|
-
success: false,
|
|
91
|
-
error: result.error || 'Failed to register as expert',
|
|
92
|
-
details: result.details
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const isUpdate = result.action === 'updated';
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
success: true,
|
|
100
|
-
message: isUpdate ? 'Expert profile updated' : 'Registered as expert',
|
|
101
|
-
profile: {
|
|
102
|
-
handle: result.expert_handle,
|
|
103
|
-
skills: result.skills,
|
|
104
|
-
bio: result.bio,
|
|
105
|
-
hourly_rate: result.hourly_rate ? `$${result.hourly_rate}/hour` : 'Not set',
|
|
106
|
-
min_escrow: `$${result.min_escrow}`,
|
|
107
|
-
availability: result.availability,
|
|
108
|
-
tier: result.tier,
|
|
109
|
-
rating: result.rating || 0,
|
|
110
|
-
total_sessions: result.total_sessions || 0
|
|
111
|
-
},
|
|
112
|
-
formatted: `
|
|
113
|
-
🎓 ${isUpdate ? 'Expert Profile Updated' : 'Welcome to ping.money!'}
|
|
114
|
-
|
|
115
|
-
Expert: ${result.expert_handle}
|
|
116
|
-
Tier: ${result.tier}
|
|
117
|
-
|
|
118
|
-
Skills: ${result.skills.join(', ')}
|
|
119
|
-
${result.bio ? `Bio: ${result.bio}` : ''}
|
|
120
|
-
|
|
121
|
-
Pricing:
|
|
122
|
-
${result.hourly_rate ? `Hourly Rate: $${result.hourly_rate}` : 'Hourly Rate: Not set'}
|
|
123
|
-
Min Escrow: $${result.min_escrow}
|
|
124
|
-
|
|
125
|
-
Availability: ${result.availability}
|
|
126
|
-
${result.rating > 0 ? `Rating: ${result.rating}/5.0 (${result.total_sessions} sessions)` : ''}
|
|
127
|
-
|
|
128
|
-
You're now listed in the expert marketplace!
|
|
129
|
-
|
|
130
|
-
When users ask questions matching your skills:
|
|
131
|
-
• You'll be auto-matched and notified
|
|
132
|
-
• Escrow is created automatically
|
|
133
|
-
• Answer via DM and get paid
|
|
134
|
-
|
|
135
|
-
Commands:
|
|
136
|
-
• Check profile: vibe expert profile
|
|
137
|
-
• View sessions: vibe expert sessions
|
|
138
|
-
• Update status: vibe expert availability
|
|
139
|
-
`.trim()
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
} catch (error) {
|
|
143
|
-
return {
|
|
144
|
-
success: false,
|
|
145
|
-
error: 'Failed to register as expert',
|
|
146
|
-
details: error.message
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
};
|