slashvibe-mcp 0.2.2 → 0.2.4

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.
Files changed (162) hide show
  1. package/README.md +1 -0
  2. package/analytics.js +107 -0
  3. package/config.js +174 -3
  4. package/index.js +163 -34
  5. package/intelligence/index.js +45 -0
  6. package/intelligence/infer.js +316 -0
  7. package/intelligence/interests.js +369 -0
  8. package/intelligence/patterns.js +651 -0
  9. package/intelligence/proactive.js +358 -0
  10. package/intelligence/serendipity.js +306 -0
  11. package/notification-emitter.js +77 -0
  12. package/notify.js +141 -18
  13. package/package.json +14 -6
  14. package/presence.js +5 -1
  15. package/protocol/index.js +88 -1
  16. package/protocol/telegram-commands.js +199 -0
  17. package/store/api.js +469 -29
  18. package/store/index.js +7 -7
  19. package/store/local.js +67 -11
  20. package/store/profiles.js +435 -0
  21. package/store/reservations.js +321 -0
  22. package/store/skills.js +378 -0
  23. package/tools/_actions.js +491 -22
  24. package/tools/_connection-queue.js +257 -0
  25. package/tools/_discovery-enhanced.js +290 -0
  26. package/tools/_discovery.js +439 -0
  27. package/tools/_proactive-discovery.js +301 -0
  28. package/tools/_shared/index.js +64 -0
  29. package/tools/_work-context.js +338 -0
  30. package/tools/_work-context.manual-test.js +199 -0
  31. package/tools/_work-context.test.js +260 -0
  32. package/tools/admin-inbox.js +218 -0
  33. package/tools/agent-treasury.js +288 -0
  34. package/tools/agents.js +122 -0
  35. package/tools/analytics.js +191 -0
  36. package/tools/approve.js +197 -0
  37. package/tools/arcade.js +173 -0
  38. package/tools/artifact-create.js +247 -0
  39. package/tools/artifact-view.js +174 -0
  40. package/tools/artifacts-price.js +107 -0
  41. package/tools/ask-expert.js +160 -0
  42. package/tools/auto-suggest-connections.js +304 -0
  43. package/tools/away.js +68 -0
  44. package/tools/back.js +51 -0
  45. package/tools/become-expert.js +150 -0
  46. package/tools/bootstrap-skills.js +231 -0
  47. package/tools/bridge-dashboard.js +342 -0
  48. package/tools/bridge-health.js +400 -0
  49. package/tools/bridge-live.js +384 -0
  50. package/tools/bridges.js +383 -0
  51. package/tools/broadcast.js +286 -0
  52. package/tools/bye.js +4 -0
  53. package/tools/chat.js +202 -0
  54. package/tools/collaborative-drawing.js +286 -0
  55. package/tools/colorguess.js +281 -0
  56. package/tools/crossword.js +369 -0
  57. package/tools/discover-insights.js +379 -0
  58. package/tools/discover-momentum.js +256 -0
  59. package/tools/discover.js +675 -0
  60. package/tools/discovery-analytics.js +345 -0
  61. package/tools/discovery-auto-suggest.js +275 -0
  62. package/tools/discovery-bootstrap.js +267 -0
  63. package/tools/discovery-daily.js +375 -0
  64. package/tools/discovery-dashboard.js +385 -0
  65. package/tools/discovery-digest.js +314 -0
  66. package/tools/discovery-hub.js +357 -0
  67. package/tools/discovery-insights.js +384 -0
  68. package/tools/discovery-momentum.js +281 -0
  69. package/tools/discovery-monitor.js +319 -0
  70. package/tools/discovery-proactive.js +300 -0
  71. package/tools/dm.js +84 -14
  72. package/tools/draw.js +317 -0
  73. package/tools/drawing.js +310 -0
  74. package/tools/earnings.js +126 -0
  75. package/tools/echo.js +16 -0
  76. package/tools/farcaster.js +307 -0
  77. package/tools/feed.js +215 -0
  78. package/tools/follow.js +224 -0
  79. package/tools/friends.js +192 -0
  80. package/tools/game.js +218 -110
  81. package/tools/games-catalog.js +376 -0
  82. package/tools/games.js +313 -0
  83. package/tools/genesis.js +233 -0
  84. package/tools/gig-browse.js +206 -0
  85. package/tools/gig-complete.js +139 -0
  86. package/tools/guessnumber.js +194 -0
  87. package/tools/hangman.js +129 -0
  88. package/tools/help.js +269 -0
  89. package/tools/idea.js +217 -0
  90. package/tools/inbox.js +291 -25
  91. package/tools/init.js +657 -33
  92. package/tools/insights.js +123 -0
  93. package/tools/invite.js +142 -21
  94. package/tools/l2-bridge.js +272 -0
  95. package/tools/l2-status.js +217 -0
  96. package/tools/l2.js +206 -0
  97. package/tools/migrate.js +156 -0
  98. package/tools/mint.js +377 -0
  99. package/tools/multiplayer-game.js +275 -0
  100. package/tools/multiplayer-tictactoe.js +303 -0
  101. package/tools/mute.js +97 -0
  102. package/tools/notifications.js +415 -0
  103. package/tools/observe.js +200 -0
  104. package/tools/onboarding.js +147 -0
  105. package/tools/open.js +52 -3
  106. package/tools/party-game.js +314 -0
  107. package/tools/plan.js +225 -0
  108. package/tools/presence-agent.js +167 -0
  109. package/tools/profile.js +219 -0
  110. package/tools/proof-of-work.js +139 -0
  111. package/tools/pulse.js +218 -0
  112. package/tools/react.js +4 -0
  113. package/tools/release.js +83 -0
  114. package/tools/report.js +109 -0
  115. package/tools/reputation.js +175 -0
  116. package/tools/request.js +231 -0
  117. package/tools/reservations.js +116 -0
  118. package/tools/reserve.js +111 -0
  119. package/tools/riddle.js +240 -0
  120. package/tools/run-bootstrap.js +69 -0
  121. package/tools/schedule.js +367 -0
  122. package/tools/session.js +420 -0
  123. package/tools/session_price.js +128 -0
  124. package/tools/settings.js +200 -0
  125. package/tools/ship.js +188 -0
  126. package/tools/shipback.js +326 -0
  127. package/tools/skills-analytics.js +349 -0
  128. package/tools/skills-bootstrap.js +301 -0
  129. package/tools/skills-dashboard.js +268 -0
  130. package/tools/skills-exchange.js +342 -0
  131. package/tools/skills.js +380 -0
  132. package/tools/smart-intro.js +353 -0
  133. package/tools/social-inbox.js +326 -69
  134. package/tools/social-post.js +251 -66
  135. package/tools/social-processor.js +445 -0
  136. package/tools/solo-game.js +390 -0
  137. package/tools/start.js +296 -81
  138. package/tools/status.js +53 -6
  139. package/tools/storybuilder.js +331 -0
  140. package/tools/stuck.js +297 -0
  141. package/tools/subscribe.js +148 -0
  142. package/tools/subscriptions.js +134 -0
  143. package/tools/suggest-tags.js +184 -0
  144. package/tools/tag-suggestions.js +257 -0
  145. package/tools/telegram-bot.js +183 -0
  146. package/tools/telegram-setup.js +214 -0
  147. package/tools/tictactoe.js +155 -0
  148. package/tools/tip.js +120 -0
  149. package/tools/token.js +103 -0
  150. package/tools/twentyquestions.js +143 -0
  151. package/tools/update.js +1 -1
  152. package/tools/wallet.js +127 -0
  153. package/tools/watch.js +157 -0
  154. package/tools/webhook-test.js +388 -0
  155. package/tools/who.js +118 -25
  156. package/tools/withdraw.js +145 -0
  157. package/tools/wordassociation.js +247 -0
  158. package/tools/work-summary.js +96 -0
  159. package/tools/workshop-buddy.js +394 -0
  160. package/tools/workshop.js +327 -0
  161. package/version.json +12 -3
  162. package/tools/board.js +0 -130
@@ -0,0 +1,217 @@
1
+ /**
2
+ * vibe_l2_status - VIBE L2 Chain Health
3
+ *
4
+ * Check the status of VIBE L2 chain, contracts, and infrastructure.
5
+ * Shows: chain health, block height, gas prices, contract status.
6
+ *
7
+ * Examples:
8
+ * - "vibe l2 status"
9
+ * - "check chain health"
10
+ * - "is vibe l2 running"
11
+ */
12
+
13
+ const fetch = require('node-fetch');
14
+
15
+ // Chain configuration (matches lib/vibe-l2/config.js)
16
+ const CHAINS = {
17
+ 'vibe-l2': {
18
+ chainId: 84532000, // Mainnet
19
+ name: 'VIBE L2',
20
+ rpcUrl: process.env.VIBE_L2_RPC || 'https://rpc.vibe.network',
21
+ explorerUrl: 'https://explorer.vibe.network',
22
+ },
23
+ 'vibe-l2-testnet': {
24
+ chainId: 84532001, // Testnet
25
+ name: 'VIBE L2 Testnet',
26
+ rpcUrl: process.env.VIBE_L2_TESTNET_RPC || 'https://rpc-testnet.vibe.network',
27
+ explorerUrl: 'https://explorer-testnet.vibe.network',
28
+ },
29
+ };
30
+
31
+ const definition = {
32
+ name: 'vibe_l2_status',
33
+ description: 'Check VIBE L2 chain health: block height, gas prices, contract status, Shipback registry.',
34
+ inputSchema: {
35
+ type: 'object',
36
+ properties: {
37
+ network: {
38
+ type: 'string',
39
+ description: 'Network to check: vibe-l2, vibe-l2-testnet (default: testnet)'
40
+ },
41
+ verbose: {
42
+ type: 'boolean',
43
+ description: 'Show detailed contract status'
44
+ }
45
+ }
46
+ }
47
+ };
48
+
49
+ async function handler(args) {
50
+ const { network = 'vibe-l2-testnet', verbose = false } = args;
51
+ try {
52
+ const chain = CHAINS[network];
53
+ if (!chain) {
54
+ return {
55
+ success: false,
56
+ error: `Unknown network: ${network}`,
57
+ available: Object.keys(CHAINS)
58
+ };
59
+ }
60
+
61
+ // Check RPC health
62
+ const rpcStatus = await checkRpcHealth(chain.rpcUrl);
63
+
64
+ // Get contract addresses from environment
65
+ // Standardized format: VIBE_ARTIFACTS_TESTNET or VIBE_ARTIFACTS_MAINNET
66
+ const envSuffix = network === 'vibe-l2' ? 'MAINNET' : 'TESTNET';
67
+ const contracts = {
68
+ vibeArtifacts: process.env[`VIBE_ARTIFACTS_${envSuffix}`],
69
+ shipbackRegistry: process.env[`SHIPBACK_REGISTRY_${envSuffix}`],
70
+ vibeToken: process.env[`VIBE_TOKEN_${envSuffix}`],
71
+ };
72
+
73
+ // Check Shipback API health
74
+ const apiUrl = process.env.VIBE_API_URL || 'https://www.slashvibe.dev';
75
+ let apiHealth = { status: 'unknown' };
76
+ try {
77
+ const apiResp = await fetch(`${apiUrl}/api/health?full=true`, { timeout: 5000 });
78
+ apiHealth = await apiResp.json();
79
+ } catch (e) {
80
+ apiHealth = { status: 'error', error: e.message };
81
+ }
82
+
83
+ // Build status report
84
+ const status = {
85
+ network: chain.name,
86
+ chainId: chain.chainId,
87
+ rpc: {
88
+ url: chain.rpcUrl,
89
+ ...rpcStatus
90
+ },
91
+ contracts: {
92
+ vibeArtifacts: contracts.vibeArtifacts || 'not deployed',
93
+ shipbackRegistry: contracts.shipbackRegistry || 'not deployed',
94
+ vibeToken: contracts.vibeToken || 'not deployed (optional)',
95
+ },
96
+ api: apiHealth.status === 'healthy' ? 'healthy' : apiHealth.status,
97
+ explorer: chain.explorerUrl
98
+ };
99
+
100
+ // Format output
101
+ const rpcIcon = rpcStatus.healthy ? '🟢' : '🔴';
102
+ const apiIcon = apiHealth.status === 'healthy' ? '🟢' : '🟡';
103
+
104
+ let formatted = `
105
+ ┌─────────────────────────────────────────────────────┐
106
+ │ VIBE L2 STATUS │
107
+ ├─────────────────────────────────────────────────────┤
108
+ │ Network: ${chain.name.padEnd(39)} │
109
+ │ Chain ID: ${String(chain.chainId).padEnd(38)} │
110
+ ├─────────────────────────────────────────────────────┤
111
+ │ RPC ${rpcIcon} │
112
+ │ Block: ${String(rpcStatus.blockNumber || 'N/A').padEnd(39)} │
113
+ │ Gas: ${String(rpcStatus.gasPrice || 'N/A').padEnd(41)} │
114
+ ├─────────────────────────────────────────────────────┤
115
+ │ Contracts │
116
+ │ Artifacts: ${(contracts.vibeArtifacts || 'not deployed').substring(0, 35).padEnd(35)} │
117
+ │ Shipback: ${(contracts.shipbackRegistry || 'not deployed').substring(0, 35).padEnd(35)} │
118
+ │ Token: ${(contracts.vibeToken || 'optional').substring(0, 35).padEnd(35)} │
119
+ ├─────────────────────────────────────────────────────┤
120
+ │ API ${apiIcon} ${apiUrl.padEnd(43)} │
121
+ └─────────────────────────────────────────────────────┘
122
+ `.trim();
123
+
124
+ if (verbose && rpcStatus.healthy) {
125
+ formatted += `\n\nDetailed RPC Info:
126
+ Latest Block: ${rpcStatus.blockNumber}
127
+ Block Time: ${rpcStatus.blockTime || 'unknown'}
128
+ Gas Price: ${rpcStatus.gasPrice} gwei
129
+ Chain ID: ${rpcStatus.chainId}`;
130
+ }
131
+
132
+ // Shipback info
133
+ formatted += `\n\n💰 Shipback Distribution: 80% creator / 15% protocol / 5% foundation`;
134
+ formatted += `\n📖 Explorer: ${chain.explorerUrl}`;
135
+
136
+ return {
137
+ display: formatted,
138
+ data: status
139
+ };
140
+
141
+ } catch (error) {
142
+ return {
143
+ display: `❌ Failed to check L2 status: ${error.message}`
144
+ };
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Check RPC endpoint health
150
+ */
151
+ async function checkRpcHealth(rpcUrl) {
152
+ try {
153
+ // eth_blockNumber
154
+ const blockResp = await fetch(rpcUrl, {
155
+ method: 'POST',
156
+ headers: { 'Content-Type': 'application/json' },
157
+ body: JSON.stringify({
158
+ jsonrpc: '2.0',
159
+ method: 'eth_blockNumber',
160
+ params: [],
161
+ id: 1
162
+ }),
163
+ timeout: 5000
164
+ });
165
+
166
+ const blockData = await blockResp.json();
167
+ const blockNumber = parseInt(blockData.result, 16);
168
+
169
+ // eth_gasPrice
170
+ const gasResp = await fetch(rpcUrl, {
171
+ method: 'POST',
172
+ headers: { 'Content-Type': 'application/json' },
173
+ body: JSON.stringify({
174
+ jsonrpc: '2.0',
175
+ method: 'eth_gasPrice',
176
+ params: [],
177
+ id: 2
178
+ }),
179
+ timeout: 5000
180
+ });
181
+
182
+ const gasData = await gasResp.json();
183
+ const gasPrice = parseInt(gasData.result, 16) / 1e9; // Convert to gwei
184
+
185
+ // eth_chainId
186
+ const chainResp = await fetch(rpcUrl, {
187
+ method: 'POST',
188
+ headers: { 'Content-Type': 'application/json' },
189
+ body: JSON.stringify({
190
+ jsonrpc: '2.0',
191
+ method: 'eth_chainId',
192
+ params: [],
193
+ id: 3
194
+ }),
195
+ timeout: 5000
196
+ });
197
+
198
+ const chainData = await chainResp.json();
199
+ const chainId = parseInt(chainData.result, 16);
200
+
201
+ return {
202
+ healthy: true,
203
+ blockNumber,
204
+ gasPrice: gasPrice.toFixed(4),
205
+ chainId,
206
+ latency: 'ok'
207
+ };
208
+
209
+ } catch (error) {
210
+ return {
211
+ healthy: false,
212
+ error: error.message
213
+ };
214
+ }
215
+ }
216
+
217
+ module.exports = { definition, handler };
package/tools/l2.js ADDED
@@ -0,0 +1,206 @@
1
+ /**
2
+ * vibe_l2 - Unified VIBE L2 Command
3
+ *
4
+ * One command to rule them all.
5
+ *
6
+ * Examples:
7
+ * - "vibe l2" - Overview and status
8
+ * - "vibe l2 status" - Chain health
9
+ * - "vibe l2 shipback" - View earnings
10
+ * - "vibe l2 bridge" - Bridge info
11
+ * - "vibe l2 mint" - Mint artifact on L2
12
+ */
13
+
14
+ const config = require('../config');
15
+
16
+ const definition = {
17
+ name: 'vibe_l2',
18
+ description: 'VIBE L2 commands: status, shipback, bridge, mint. Run "vibe l2" for overview.',
19
+ inputSchema: {
20
+ type: 'object',
21
+ properties: {
22
+ command: {
23
+ type: 'string',
24
+ description: 'Command: status, shipback, bridge, mint, or omit for overview'
25
+ },
26
+ args: {
27
+ type: 'object',
28
+ description: 'Arguments for the command'
29
+ }
30
+ }
31
+ }
32
+ };
33
+
34
+ async function handler(args) {
35
+ const { command, args: cmdArgs = {} } = args;
36
+
37
+ if (!config.isInitialized()) {
38
+ return {
39
+ display: 'Run `vibe init` first to set your identity.'
40
+ };
41
+ }
42
+
43
+ const handle = config.getHandle();
44
+
45
+ // No command = show overview
46
+ if (!command) {
47
+ return showOverview(handle);
48
+ }
49
+
50
+ // Route to specific tool
51
+ switch (command.toLowerCase()) {
52
+ case 'status':
53
+ const statusTool = require('./l2-status');
54
+ return statusTool.handler(cmdArgs);
55
+
56
+ case 'shipback':
57
+ case 'earnings':
58
+ const shipbackTool = require('./shipback');
59
+ return shipbackTool.handler(cmdArgs);
60
+
61
+ case 'bridge':
62
+ const bridgeTool = require('./l2-bridge');
63
+ return bridgeTool.handler(cmdArgs);
64
+
65
+ case 'mint':
66
+ return showMintInfo(handle);
67
+
68
+ case 'help':
69
+ return showHelp();
70
+
71
+ default:
72
+ return {
73
+ display: `Unknown command: ${command}\n\nRun "vibe l2 help" for available commands.`
74
+ };
75
+ }
76
+ }
77
+
78
+ function showOverview(handle) {
79
+ return {
80
+ display: `
81
+ ╔═══════════════════════════════════════════════════════════════════╗
82
+ ║ VIBE L2 ║
83
+ ║ Creator-First Economics for the AI Coding Era ║
84
+ ╠═══════════════════════════════════════════════════════════════════╣
85
+ ║ ║
86
+ ║ "You shipped it, you earn from it" ║
87
+ ║ ║
88
+ ║ VIBE L2 is an OP Stack chain where creators earn 80% of ║
89
+ ║ gas fees from interactions with their deployed contracts. ║
90
+ ║ ║
91
+ ╠═══════════════════════════════════════════════════════════════════╣
92
+ ║ ║
93
+ ║ SHIPBACK ECONOMICS ║
94
+ ║ ┌──────────────────────────────────────────────────────────┐ ║
95
+ ║ │ User interacts with your artifact │ ║
96
+ ║ │ ↓ │ ║
97
+ ║ │ Gas fee collected → Distributed: │ ║
98
+ ║ │ │ ║
99
+ ║ │ ████████████████████░░░░░ 80% → You (Creator) │ ║
100
+ ║ │ ███░░░░░░░░░░░░░░░░░░░░░░ 15% → Protocol Treasury │ ║
101
+ ║ │ █░░░░░░░░░░░░░░░░░░░░░░░░ 5% → Foundation Grants │ ║
102
+ ║ └──────────────────────────────────────────────────────────┘ ║
103
+ ║ ║
104
+ ╠═══════════════════════════════════════════════════════════════════╣
105
+ ║ ║
106
+ ║ COMMANDS ║
107
+ ║ ──────────────────────────────────────────────────────────── ║
108
+ ║ vibe l2 status Check chain health & contracts ║
109
+ ║ vibe l2 shipback View/claim your earnings ║
110
+ ║ vibe l2 bridge Move ETH between Base ↔ VIBE L2 ║
111
+ ║ vibe l2 mint Mint an artifact on VIBE L2 ║
112
+ ║ ║
113
+ ╠═══════════════════════════════════════════════════════════════════╣
114
+ ║ ║
115
+ ║ QUICK START ║
116
+ ║ 1. Bridge ETH: vibe l2 bridge deposit 0.1 ║
117
+ ║ 2. Link wallet: vibe l2 shipback link ║
118
+ ║ 3. Create art: vibe create artifact ║
119
+ ║ 4. Mint on L2: vibe l2 mint ║
120
+ ║ 5. Earn forever: vibe l2 shipback ║
121
+ ║ ║
122
+ ╚═══════════════════════════════════════════════════════════════════╝
123
+
124
+ Logged in as: @${handle}
125
+ `.trim()
126
+ };
127
+ }
128
+
129
+ function showMintInfo(handle) {
130
+ return {
131
+ display: `
132
+ 🎨 MINT ON VIBE L2
133
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
134
+
135
+ Minting on VIBE L2 gives you:
136
+ • 80% of all gas fees from interactions (Shipback)
137
+ • Ultra-low minting costs (~0.0001 ETH)
138
+ • Session provenance on-chain
139
+ • Automatic royalties (10% default)
140
+
141
+ To mint an artifact:
142
+
143
+ 1. First, create the artifact content:
144
+ vibe create artifact
145
+
146
+ 2. Then mint it on VIBE L2:
147
+ vibe mint --chain vibe-l2
148
+
149
+ Or use the API directly:
150
+ POST /api/nft/mint
151
+ {
152
+ "artifact_id": "art_xxx",
153
+ "chain": "vibe-l2"
154
+ }
155
+
156
+ Prerequisites:
157
+ • ETH on VIBE L2 (use: vibe l2 bridge deposit 0.1)
158
+ • Linked wallet (use: vibe l2 shipback link)
159
+
160
+ Current handle: @${handle}
161
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
162
+ `.trim()
163
+ };
164
+ }
165
+
166
+ function showHelp() {
167
+ return {
168
+ display: `
169
+ VIBE L2 COMMANDS
170
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
171
+
172
+ vibe l2 Show this overview
173
+ vibe l2 status Chain health, contracts, gas prices
174
+ vibe l2 shipback View Shipback earnings
175
+ vibe l2 shipback link Link wallet to handle
176
+ vibe l2 shipback claim Claim accumulated earnings
177
+ vibe l2 shipback contracts List registered contracts
178
+ vibe l2 bridge Bridge overview
179
+ vibe l2 bridge deposit X Deposit X ETH to VIBE L2
180
+ vibe l2 bridge withdraw X Withdraw X ETH to Base
181
+ vibe l2 bridge estimate Gas cost estimates
182
+ vibe l2 mint Mint artifact info
183
+
184
+ ARCHITECTURE
185
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
186
+
187
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
188
+ │ Ethereum │────▶│ Base │────▶│ VIBE L2 │
189
+ │ (Security) │ │ (Bridge) │ │ (Apps) │
190
+ └─────────────┘ └─────────────┘ └─────────────┘
191
+
192
+ Stack: OP Stack via Conduit
193
+ DA: Celestia
194
+ Gas: ETH (not token)
195
+
196
+ LINKS
197
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
198
+
199
+ Explorer: https://explorer.vibe.network
200
+ Bridge: https://bridge.vibe.network
201
+ Docs: https://docs.slashvibe.dev/l2
202
+ `.trim()
203
+ };
204
+ }
205
+
206
+ module.exports = { definition, handler };
@@ -0,0 +1,156 @@
1
+ /**
2
+ * vibe migrate — Migrate existing handle to GitHub auth
3
+ *
4
+ * For users who have existing handles with local keypairs,
5
+ * this command helps them migrate to the new Privy/GitHub auth.
6
+ *
7
+ * Flow:
8
+ * 1. Check if user has existing handle and keys
9
+ * 2. Sign migration request with old key (proves ownership)
10
+ * 3. Get migration URL from server
11
+ * 4. User completes GitHub auth in browser
12
+ * 5. Token pasted via `vibe token`
13
+ */
14
+
15
+ const config = require('../config');
16
+ const crypto = require('../crypto');
17
+
18
+ const definition = {
19
+ name: 'vibe_migrate',
20
+ description: 'Migrate your existing handle to GitHub authentication. Use this if you have an existing handle with local keys.',
21
+ inputSchema: {
22
+ type: 'object',
23
+ properties: {}
24
+ }
25
+ };
26
+
27
+ async function handler(args) {
28
+ const handle = config.getHandle();
29
+
30
+ if (!handle) {
31
+ return {
32
+ display: `❌ **No handle found**
33
+
34
+ You need to have an existing handle to migrate.
35
+ If you're new, use \`vibe init @yourhandle "what you're building"\` instead.`
36
+ };
37
+ }
38
+
39
+ // Check if already using Privy auth
40
+ if (config.hasPrivyAuth()) {
41
+ return {
42
+ display: `✅ **Already using GitHub auth**
43
+
44
+ @${handle} is already authenticated via GitHub.
45
+ No migration needed!`
46
+ };
47
+ }
48
+
49
+ // Check if we have a keypair to sign with
50
+ const keypair = config.getKeypair();
51
+
52
+ // Build migration request
53
+ const https = require('https');
54
+ const apiUrl = config.getApiUrl();
55
+
56
+ try {
57
+ const timestamp = Date.now();
58
+ let signature = null;
59
+
60
+ // If we have a keypair, sign the migration request
61
+ if (keypair) {
62
+ const messageToSign = {
63
+ action: 'migrate',
64
+ handle: handle,
65
+ timestamp: timestamp
66
+ };
67
+ signature = crypto.sign(messageToSign, keypair.privateKey);
68
+ }
69
+
70
+ // Request migration token from server
71
+ const result = await new Promise((resolve, reject) => {
72
+ const url = new URL('/api/auth/migrate', apiUrl);
73
+ const data = JSON.stringify({
74
+ handle,
75
+ legacy_signature: signature,
76
+ timestamp
77
+ });
78
+
79
+ const req = https.request({
80
+ hostname: url.hostname,
81
+ port: 443,
82
+ path: url.pathname,
83
+ method: 'POST',
84
+ headers: {
85
+ 'Content-Type': 'application/json',
86
+ 'Content-Length': data.length
87
+ }
88
+ }, (res) => {
89
+ let body = '';
90
+ res.on('data', chunk => body += chunk);
91
+ res.on('end', () => {
92
+ try {
93
+ resolve(JSON.parse(body));
94
+ } catch (e) {
95
+ resolve({ success: false, error: body });
96
+ }
97
+ });
98
+ });
99
+
100
+ req.on('error', reject);
101
+ req.write(data);
102
+ req.end();
103
+ });
104
+
105
+ if (!result.success) {
106
+ return {
107
+ display: `❌ **Migration failed**
108
+
109
+ Error: ${result.error}
110
+ ${result.message || ''}
111
+
112
+ If you're having trouble, try:
113
+ 1. Make sure your handle is registered
114
+ 2. Check that your local keys match what's on the server
115
+ 3. Contact support if the issue persists`
116
+ };
117
+ }
118
+
119
+ // Success - show auth URL
120
+ return {
121
+ display: `## Migrate @${handle} to GitHub Auth
122
+
123
+ ${result.verified ? '✅ **Ownership verified** via signature' : '⚠️ **Unverified** — GitHub auth will claim this handle'}
124
+
125
+ 🔐 **Open this URL in your browser:**
126
+
127
+ ${result.authUrl}
128
+
129
+ After authenticating:
130
+ \`vibe token <paste-token-here>\`
131
+
132
+ ---
133
+
134
+ **Why migrate?**
135
+ • Your identity is verified via GitHub (no impersonation)
136
+ • Messages are signed server-side (more secure)
137
+ • No private keys stored locally
138
+
139
+ _Migration token expires in 1 hour._`,
140
+ authUrl: result.authUrl,
141
+ verified: result.verified,
142
+ migrationToken: result.migrationToken
143
+ };
144
+
145
+ } catch (e) {
146
+ return {
147
+ display: `❌ **Migration request failed**
148
+
149
+ Error: ${e.message}
150
+
151
+ Make sure you have internet connectivity and try again.`
152
+ };
153
+ }
154
+ }
155
+
156
+ module.exports = { definition, handler };