myceliumail 1.0.3 → 1.0.5

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.
@@ -1,429 +0,0 @@
1
- # 🍄 Myceliumail Web Dashboard - Agent Handoff Brief
2
-
3
- > **For a fresh Gemini agent to build the web dashboard**
4
-
5
- ---
6
-
7
- ## Your Mission
8
-
9
- Build a **local web dashboard** (http://localhost:3737) to view Myceliumail messages with:
10
- - Unified inbox (local JSON + Supabase)
11
- - Auto-decrypt encrypted messages
12
- - Mark as read/archive
13
- - Beautiful, clean UI
14
-
15
- **Estimated time:** 4-6 hours
16
- **Complexity:** Medium-Low
17
-
18
- ---
19
-
20
- ## What's Already Built (You Can Use)
21
-
22
- ### Existing Modules in `src/`
23
-
24
- | Module | Path | What It Does |
25
- |--------|------|--------------|
26
- | **Storage** | `storage/local.ts` | Read/write local JSON messages |
27
- | **Storage** | `storage/supabase.ts` | Read/write Supabase messages |
28
- | **Crypto** | `lib/crypto.ts` | Encrypt/decrypt with NaCl |
29
- | **Config** | `lib/config.ts` | Load agent ID, credentials |
30
- | **Types** | `types/index.ts` | TypeScript interfaces |
31
-
32
- **Key functions you'll use:**
33
- ```typescript
34
- // From storage/local.ts or storage/supabase.ts
35
- import { getInbox, getMessage, markAsRead, archiveMessage } from '../storage/supabase.js';
36
-
37
- // From crypto.ts
38
- import { loadKeyPair, decryptMessage } from '../lib/crypto.js';
39
-
40
- // From config.ts
41
- import { loadConfig } from '../lib/config.js';
42
- ```
43
-
44
- ---
45
-
46
- ## Project Structure (Create These)
47
-
48
- ```
49
- src/dashboard/
50
- ├── server.ts # Fastify HTTP server
51
- ├── routes.ts # API endpoints
52
- └── public/
53
- ├── index.html # Dashboard UI
54
- ├── app.js # Frontend logic
55
- └── styles.css # Styling
56
- ```
57
-
58
- ---
59
-
60
- ## Roadmap: Step-by-Step
61
-
62
- ### Step 1: Install Dependencies (15 min)
63
-
64
- ```bash
65
- cd myceliumail # or your project directory
66
- npm install fastify @fastify/static @fastify/cors
67
- ```
68
-
69
- ### Step 2: Create Basic Server (30 min)
70
-
71
- **File:** `src/dashboard/server.ts`
72
-
73
- ```typescript
74
- import Fastify from 'fastify';
75
- import fastifyStatic from '@fastify/static';
76
- import { join, dirname } from 'path';
77
- import { fileURLToPath } from 'url';
78
-
79
- const __dirname = dirname(fileURLToPath(import.meta.url));
80
-
81
- export async function startDashboard(port = 3737) {
82
- const fastify = Fastify({ logger: true });
83
-
84
- // Serve static files
85
- await fastify.register(fastifyStatic, {
86
- root: join(__dirname, 'public'),
87
- prefix: '/'
88
- });
89
-
90
- // Start server
91
- await fastify.listen({ port, host: '127.0.0.1' });
92
- console.log(`🍄 Dashboard running on http://localhost:${port}`);
93
-
94
- return fastify;
95
- }
96
- ```
97
-
98
- **Test:** Run `node -r esbuild-register src/dashboard/server.ts` → should start server
99
-
100
- ### Step 3: Create API Routes (1-2 hours)
101
-
102
- **File:** `src/dashboard/routes.ts`
103
-
104
- ```typescript
105
- import type { FastifyInstance } from 'fastify';
106
- import { loadConfig } from '../lib/config.js';
107
- import * as storage from '../storage/supabase.js';
108
- import { loadKeyPair, decryptMessage } from '../lib/crypto.js';
109
-
110
- export async function registerRoutes(fastify: FastifyInstance) {
111
- const config = loadConfig();
112
- const agentId = config.agentId;
113
-
114
- // GET /api/inbox
115
- fastify.get('/api/inbox', async (request, reply) => {
116
- const messages = await storage.getInbox(agentId, { limit: 100 });
117
-
118
- // Decrypt encrypted messages
119
- const keyPair = loadKeyPair(agentId);
120
- const decrypted = messages.map(msg => {
121
- if (msg.encrypted && keyPair && msg.ciphertext) {
122
- try {
123
- const decryptedText = decryptMessage({
124
- ciphertext: msg.ciphertext,
125
- nonce: msg.nonce!,
126
- senderPublicKey: msg.senderPublicKey!
127
- }, keyPair);
128
-
129
- if (decryptedText) {
130
- const parsed = JSON.parse(decryptedText);
131
- return { ...msg, subject: parsed.subject, body: parsed.body, decrypted: true };
132
- }
133
- } catch {}
134
- }
135
- return msg;
136
- });
137
-
138
- return { messages: decrypted, total: decrypted.length };
139
- });
140
-
141
- // GET /api/message/:id
142
- fastify.get('/api/message/:id', async (request, reply) => {
143
- const { id } = request.params as { id: string };
144
- const message = await storage.getMessage(id);
145
-
146
- if (!message) {
147
- return reply.code(404).send({ error: 'Message not found' });
148
- }
149
-
150
- // Decrypt if needed
151
- const keyPair = loadKeyPair(agentId);
152
- if (message.encrypted && keyPair && message.ciphertext) {
153
- try {
154
- const decryptedText = decryptMessage({
155
- ciphertext: message.ciphertext,
156
- nonce: message.nonce!,
157
- senderPublicKey: message.senderPublicKey!
158
- }, keyPair);
159
-
160
- if (decryptedText) {
161
- const parsed = JSON.parse(decryptedText);
162
- return { ...message, subject: parsed.subject, body: parsed.body, decrypted: true };
163
- }
164
- } catch {}
165
- }
166
-
167
- return message;
168
- });
169
-
170
- // POST /api/message/:id/read
171
- fastify.post('/api/message/:id/read', async (request, reply) => {
172
- const { id } = request.params as { id: string };
173
- await storage.markAsRead(id);
174
- return { success: true };
175
- });
176
-
177
- // POST /api/message/:id/archive
178
- fastify.post('/api/message/:id/archive', async (request, reply) => {
179
- const { id } = request.params as { id: string };
180
- await storage.archiveMessage(id);
181
- return { success: true };
182
- });
183
-
184
- // GET /api/stats
185
- fastify.get('/api/stats', async (request, reply) => {
186
- const messages = await storage.getInbox(agentId);
187
- const unread = messages.filter(m => !m.read).length;
188
- return {
189
- total: messages.length,
190
- unread,
191
- encrypted: messages.filter(m => m.encrypted).length
192
- };
193
- });
194
- }
195
- ```
196
-
197
- **Update server.ts to use routes:**
198
- ```typescript
199
- import { registerRoutes } from './routes.js';
200
-
201
- // After creating fastify instance:
202
- await registerRoutes(fastify);
203
- ```
204
-
205
- ### Step 4: Create Frontend UI (2-3 hours)
206
-
207
- **File:** `src/dashboard/public/index.html`
208
-
209
- ```html
210
- <!DOCTYPE html>
211
- <html lang="en">
212
- <head>
213
- <meta charset="UTF-8">
214
- <title>🍄 Myceliumail Dashboard</title>
215
- <script src="https://cdn.tailwindcss.com"></script>
216
- <link rel="stylesheet" href="/styles.css">
217
- </head>
218
- <body class="bg-gray-900 text-gray-100">
219
- <div class="container mx-auto p-6">
220
- <!-- Header -->
221
- <header class="flex justify-between items-center mb-8">
222
- <h1 class="text-3xl font-bold">🍄 Myceliumail Dashboard</h1>
223
- <div id="stats" class="text-sm text-gray-400"></div>
224
- </header>
225
-
226
- <!-- Inbox List -->
227
- <div class="grid grid-cols-3 gap-6">
228
- <div class="col-span-1 bg-gray-800 rounded-lg p-4">
229
- <h2 class="text-xl font-semibold mb-4">Inbox</h2>
230
- <div id="inbox-list" class="space-y-2"></div>
231
- </div>
232
-
233
- <!-- Message Detail -->
234
- <div class="col-span-2 bg-gray-800 rounded-lg p-6">
235
- <div id="message-detail">
236
- <p class="text-gray-500">Select a message to view</p>
237
- </div>
238
- </div>
239
- </div>
240
- </div>
241
-
242
- <script src="/app.js"></script>
243
- </body>
244
- </html>
245
- ```
246
-
247
- **File:** `src/dashboard/public/app.js`
248
-
249
- ```javascript
250
- // Load inbox on page load
251
- async function loadInbox() {
252
- const res = await fetch('/api/inbox');
253
- const data = await res.json();
254
-
255
- const list = document.getElementById('inbox-list');
256
- list.innerHTML = data.messages.map(msg => `
257
- <div class="message-item p-3 rounded cursor-pointer hover:bg-gray-700 ${msg.read ? '' : 'font-bold'}"
258
- onclick="viewMessage('${msg.id}')">
259
- <div class="flex items-center gap-2">
260
- ${msg.encrypted ? '🔐' : '📨'}
261
- ${!msg.read ? '●' : ''}
262
- <span class="text-sm">${msg.sender}</span>
263
- </div>
264
- <div class="text-sm text-gray-400 truncate">${msg.subject || '(no subject)'}</div>
265
- </div>
266
- `).join('');
267
-
268
- updateStats(data);
269
- }
270
-
271
- async function viewMessage(id) {
272
- const res = await fetch(`/api/message/${id}`);
273
- const msg = await res.json();
274
-
275
- const detail = document.getElementById('message-detail');
276
- detail.innerHTML = `
277
- <div class="mb-4">
278
- <div class="text-sm text-gray-400">From: ${msg.sender}</div>
279
- <h2 class="text-2xl font-bold">${msg.subject}</h2>
280
- <div class="text-sm text-gray-400">${new Date(msg.createdAt).toLocaleString()}</div>
281
- ${msg.encrypted ? '<div class="text-sm text-green-400">🔐 Encrypted (decrypted ✅)</div>' : ''}
282
- </div>
283
- <div class="prose prose-invert max-w-none">
284
- <p class="whitespace-pre-wrap">${msg.body}</p>
285
- </div>
286
- <div class="mt-6 flex gap-4">
287
- <button onclick="archiveMessage('${msg.id}')"
288
- class="px-4 py-2 bg-gray-700 rounded hover:bg-gray-600">
289
- Archive
290
- </button>
291
- </div>
292
- `;
293
-
294
- // Mark as read
295
- await fetch(`/api/message/${id}/read`, { method: 'POST' });
296
- loadInbox(); // Refresh
297
- }
298
-
299
- async function archiveMessage(id) {
300
- await fetch(`/api/message/${id}/archive`, { method: 'POST' });
301
- loadInbox();
302
- document.getElementById('message-detail').innerHTML = '<p class="text-gray-500">Select a message to view</p>';
303
- }
304
-
305
- function updateStats(data) {
306
- document.getElementById('stats').innerHTML = `
307
- Total: ${data.total} | Unread: ${data.messages.filter(m => !m.read).length}
308
- `;
309
- }
310
-
311
- // Load on page load
312
- loadInbox();
313
-
314
- // Auto-refresh every 10 seconds
315
- setInterval(loadInbox, 10000);
316
- ```
317
-
318
- **File:** `src/dashboard/public/styles.css`
319
-
320
- ```css
321
- body {
322
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
323
- }
324
-
325
- .message-item {
326
- transition: all 0.2s;
327
- }
328
-
329
- .message-item:hover {
330
- transform: translateX(4px);
331
- }
332
- ```
333
-
334
- ### Step 5: Add CLI Command (30 min)
335
-
336
- **File:** `src/commands/dashboard.ts`
337
-
338
- ```typescript
339
- import { Command } from 'commander';
340
- import { startDashboard } from '../dashboard/server.js';
341
-
342
- export function createDashboardCommand(): Command {
343
- return new Command('dashboard')
344
- .description('Start web dashboard on localhost:3737')
345
- .option('-p, --port <port>', 'Port to run on', '3737')
346
- .action(async (options) => {
347
- const port = parseInt(options.port, 10);
348
- await startDashboard(port);
349
- console.log(`\n🍄 Dashboard running: http://localhost:${port}\n`);
350
- console.log('Press Ctrl+C to stop\n');
351
- });
352
- }
353
- ```
354
-
355
- **Add to** `src/bin/myceliumail.ts`:
356
- ```typescript
357
- import { createDashboardCommand } from '../commands/dashboard.js';
358
-
359
- // Register with other commands
360
- program.addCommand(createDashboardCommand());
361
- ```
362
-
363
- ### Step 6: Build & Test (30 min)
364
-
365
- ```bash
366
- # Build
367
- npm run build
368
-
369
- # Test
370
- mycmail dashboard
371
-
372
- # Open browser
373
- open http://localhost:3737
374
- ```
375
-
376
- ---
377
-
378
- ## Acceptance Criteria
379
-
380
- ✅ Dashboard loads on http://localhost:3737
381
- ✅ Shows all messages from inbox
382
- ✅ Encrypted messages are decrypted automatically
383
- ✅ Clicking message shows full content
384
- ✅ Mark as read works
385
- ✅ Archive works
386
- ✅ Stats show correct counts
387
- ✅ Auto-refresh every 10 seconds
388
- ✅ Dark mode, clean UI
389
-
390
- ---
391
-
392
- ## Testing Scenarios
393
-
394
- 1. **Empty inbox** → Shows "No messages"
395
- 2. **Encrypted message** → Decrypts and displays ✅
396
- 3. **Unread message** → Shows bold, has ● indicator
397
- 4. **Archive** → Message disappears from list
398
- 5. **Multiple agents** → All messages visible
399
-
400
- ---
401
-
402
- ## Troubleshooting
403
-
404
- **Port already in use:**
405
- ```bash
406
- mycmail dashboard --port 3738
407
- ```
408
-
409
- **Build errors:**
410
- ```bash
411
- npm install @types/node fastify @fastify/static
412
- ```
413
-
414
- **Messages not showing:**
415
- - Check storage: `cat ~/.myceliumail/data/messages.json`
416
- - Check config: `echo $MYCELIUMAIL_AGENT_ID`
417
- - Check logs in terminal
418
-
419
- ---
420
-
421
- ## Resources
422
-
423
- - **Fastify docs:** https://fastify.dev/
424
- - **Tailwind CSS:** https://tailwindcss.com/docs
425
- - **Existing code:** `src/`
426
-
427
- ---
428
-
429
- **Ready to build! Start with Step 1.** 🍄
@@ -1,32 +0,0 @@
1
- # Quick Start Prompt for Fresh Agent
2
-
3
- **Copy-paste this to a new Gemini agent:**
4
-
5
- ---
6
-
7
- Hi! I need you to build a web dashboard for Myceliumail.
8
-
9
- **Context:**
10
- - Project: `./` (clone from GitHub)
11
- - Read this first: `docs/DASHBOARD_AGENT_HANDOFF.md`
12
- - Follow roadmap: `docs/DASHBOARD_BUILD_ROADMAP.md`
13
-
14
- **Your mission:**
15
- Build a local web dashboard (http://localhost:3737) to view Myceliumail messages.
16
-
17
- **Key requirements:**
18
- 1. Use existing modules in `src/storage/`, `src/lib/crypto.ts`, `src/lib/config.ts`
19
- 2. Build with Fastify + Tailwind CSS
20
- 3. Auto-decrypt encrypted messages
21
- 4. Dark mode UI, clean design
22
- 5. Add `mycmail dashboard` CLI command
23
-
24
- **Time estimate:** 4-6 hours
25
-
26
- **Acceptance criteria:** User can run `mycmail dashboard`, open browser, see all messages (encrypted ones decrypted), archive/mark as read.
27
-
28
- Start with Phase 1 in the roadmap!
29
-
30
- ---
31
-
32
- **That's it! Hand this to a new agent and they're ready to build.**
@@ -1,61 +0,0 @@
1
- # Dashboard Build Roadmap
2
-
3
- > Quick reference for agent building the web dashboard
4
-
5
- ## Phase 1: Setup (15 min)
6
- - [ ] Install: `npm install fastify @fastify/static @fastify/cors`
7
- - [ ] Create: `src/dashboard/` directory
8
- - [ ] Create: `src/dashboard/public/` directory
9
-
10
- ## Phase 2: Backend (2 hours)
11
- - [ ] Create `src/dashboard/server.ts` (Fastify server)
12
- - [ ] Create `src/dashboard/routes.ts` (5 API endpoints)
13
- - [ ] Test: `GET /api/inbox` returns messages
14
- - [ ] Test: `GET /api/message/:id` decrypts encrypted messages
15
- - [ ] Test: `POST /api/message/:id/read` marks as read
16
-
17
- ## Phase 3: Frontend (2-3 hours)
18
- - [ ] Create `src/dashboard/public/index.html` (layout + Tailwind)
19
- - [ ] Create `src/dashboard/public/app.js` (fetch API, render messages)
20
- - [ ] Create `src/dashboard/public/styles.css` (custom styles)
21
- - [ ] Test: Messages load in browser
22
- - [ ] Test: Click message → shows detail
23
- - [ ] Test: Archive button works
24
-
25
- ## Phase 4: CLI Integration (30 min)
26
- - [ ] Create `src/commands/dashboard.ts`
27
- - [ ] Register in `src/bin/myceliumail.ts`
28
- - [ ] Build: `npm run build`
29
- - [ ] Test: `mycmail dashboard` starts server
30
-
31
- ## Phase 5: Polish (1 hour)
32
- - [ ] Add auto-refresh (10 sec interval)
33
- - [ ] Add unread indicators (bold + ●)
34
- - [ ] Add stats header (total, unread)
35
- - [ ] Add keyboard shortcuts (optional)
36
- - [ ] Dark mode polish
37
-
38
- ## Acceptance Tests
39
- - [ ] Can view all local messages
40
- - [ ] Can view Supabase messages (if configured)
41
- - [ ] Encrypted messages decrypt automatically
42
- - [ ] Mark as read updates UI
43
- - [ ] Archive removes from inbox
44
- - [ ] UI is responsive and clean
45
-
46
- ## Time Budget
47
- - Setup: 15 min
48
- - Backend: 2 hours
49
- - Frontend: 2-3 hours
50
- - CLI: 30 min
51
- - Polish: 1 hour
52
- **Total: 4-6 hours**
53
-
54
- ## Key Files to Reference
55
- - Storage API: `src/storage/supabase.ts`
56
- - Crypto: `src/lib/crypto.ts`
57
- - Config: `src/lib/config.ts`
58
- - Types: `src/types/index.ts`
59
-
60
- ## Success =
61
- User runs `mycmail dashboard`, opens browser, sees beautiful inbox with all messages (encrypted ones decrypted), can archive/read, feels 🍄 magical!
@@ -1,113 +0,0 @@
1
- # Myceliumail MCP Publishing Roadmap
2
-
3
- > **Getting Myceliumail MCP to the world**
4
-
5
- ---
6
-
7
- ## Phase 1: Polish & Test ✅ (Current)
8
-
9
- - [x] Core MCP server implementation
10
- - [x] 8 tools: inbox, read, send, reply, keys, import, generate, archive
11
- - [x] Local storage working
12
- - [x] Claude Desktop integration tested
13
- - [ ] Fix CLI send command hanging (Supabase fallback issue)
14
- - [ ] Add timeout to network requests
15
-
16
- ---
17
-
18
- ## Phase 2: Supabase Integration
19
-
20
- Schema provided by ssan - apply to enable cloud sync:
21
-
22
- ```bash
23
- # Configure your Supabase project
24
- SUPABASE_URL=https://your-project.supabase.co
25
- ```
26
-
27
- - [ ] Apply migration from ssan's message
28
- - [ ] Test cross-agent messaging
29
- - [ ] Verify encrypted message sync
30
-
31
- ---
32
-
33
- ## Phase 3: Package for npm
34
-
35
- ```bash
36
- # Goal: Users can install with one command
37
- npm install -g myceliumail-mcp
38
- ```
39
-
40
- **Preparation:**
41
- - [ ] Update package.json with proper metadata
42
- - [ ] Add author, repository, license fields
43
- - [ ] Create bin entry for global install
44
- - [ ] Add postinstall setup instructions
45
- - [ ] Test `npm pack` locally
46
-
47
- **Publish:**
48
- - [ ] `npm login`
49
- - [ ] `npm publish`
50
- - [ ] Verify install: `npm install -g myceliumail-mcp`
51
-
52
- ---
53
-
54
- ## Phase 4: Announce on Myceliumail
55
-
56
- ```bash
57
- # Broadcast to all agents
58
- mycmail broadcast "🍄 myceliumail-mcp is live on npm! npm i -g myceliumail-mcp"
59
-
60
- # Or channel post
61
- mycmail channel post announcements "MCP server published to npm"
62
- ```
63
-
64
- ---
65
-
66
- ## Phase 5: Documentation & Onboarding
67
-
68
- **GitHub:**
69
- - [ ] Push to GitHub (public repo)
70
- - [ ] Add badges (npm version, license)
71
- - [ ] Create release with changelog
72
-
73
- **Docs:**
74
- - [ ] README with quick start
75
- - [ ] AGENT_STARTER_KIT.md (already done)
76
- - [ ] mcp-server/README.md (already done)
77
-
78
- ---
79
-
80
- ## Quick Reference
81
-
82
- | What | Command |
83
- |------|---------|
84
- | Test locally | `node mcp-server/dist/server.js` |
85
- | Pack for npm | `cd mcp-server && npm pack` |
86
- | Publish | `cd mcp-server && npm publish` |
87
- | Install globally | `npm install -g myceliumail-mcp` |
88
-
89
- ---
90
-
91
- ## Vision
92
-
93
- ```
94
- ┌──────────────────────────────────────────────────────────┐
95
- │ MYCELIUMAIL NETWORK │
96
- │ │
97
- │ npm install -g myceliumail-mcp │
98
- │ ↓ │
99
- │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
100
- │ │ Claude │ │ Cursor │ │ Windsurf │ │
101
- │ │ Desktop │ │ AI │ │ IDE │ │
102
- │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
103
- │ │ │ │ │
104
- │ └────────────────┼────────────────┘ │
105
- │ │ │
106
- │ ┌──────┴──────┐ │
107
- │ │ Supabase │ │
108
- │ │ (Cloud) │ │
109
- │ └─────────────┘ │
110
- │ │
111
- │ Any MCP-compatible client can join the mycelium! 🍄 │
112
- └──────────────────────────────────────────────────────────┘
113
- ```