myceliumail 1.0.1

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 (150) hide show
  1. package/.context7 +87 -0
  2. package/.env.example +12 -0
  3. package/.eslintrc.json +29 -0
  4. package/CLAUDE.md +35 -0
  5. package/COMPLETE.md +51 -0
  6. package/LICENSE +21 -0
  7. package/MYCELIUMAIL_STARTER_KIT.md +603 -0
  8. package/NEXT_STEPS.md +96 -0
  9. package/README.md +229 -0
  10. package/desktop/README.md +102 -0
  11. package/desktop/assets/icon.icns +0 -0
  12. package/desktop/assets/icon.iconset/icon_128x128.png +0 -0
  13. package/desktop/assets/icon.iconset/icon_128x128@2x.png +0 -0
  14. package/desktop/assets/icon.iconset/icon_16x16.png +0 -0
  15. package/desktop/assets/icon.iconset/icon_16x16@2x.png +0 -0
  16. package/desktop/assets/icon.iconset/icon_256x256.png +0 -0
  17. package/desktop/assets/icon.iconset/icon_256x256@2x.png +0 -0
  18. package/desktop/assets/icon.iconset/icon_32x32.png +0 -0
  19. package/desktop/assets/icon.iconset/icon_32x32@2x.png +0 -0
  20. package/desktop/assets/icon.iconset/icon_512x512.png +0 -0
  21. package/desktop/assets/icon.iconset/icon_512x512@2x.png +0 -0
  22. package/desktop/assets/icon.png +0 -0
  23. package/desktop/assets/tray-icon.png +0 -0
  24. package/desktop/main.js +257 -0
  25. package/desktop/package-lock.json +4198 -0
  26. package/desktop/package.json +48 -0
  27. package/desktop/preload.js +11 -0
  28. package/dist/bin/myceliumail.d.ts +8 -0
  29. package/dist/bin/myceliumail.d.ts.map +1 -0
  30. package/dist/bin/myceliumail.js +44 -0
  31. package/dist/bin/myceliumail.js.map +1 -0
  32. package/dist/commands/broadcast.d.ts +9 -0
  33. package/dist/commands/broadcast.d.ts.map +1 -0
  34. package/dist/commands/broadcast.js +59 -0
  35. package/dist/commands/broadcast.js.map +1 -0
  36. package/dist/commands/dashboard.d.ts +3 -0
  37. package/dist/commands/dashboard.d.ts.map +1 -0
  38. package/dist/commands/dashboard.js +18 -0
  39. package/dist/commands/dashboard.js.map +1 -0
  40. package/dist/commands/inbox.d.ts +6 -0
  41. package/dist/commands/inbox.d.ts.map +1 -0
  42. package/dist/commands/inbox.js +65 -0
  43. package/dist/commands/inbox.js.map +1 -0
  44. package/dist/commands/key-import.d.ts +6 -0
  45. package/dist/commands/key-import.d.ts.map +1 -0
  46. package/dist/commands/key-import.js +31 -0
  47. package/dist/commands/key-import.js.map +1 -0
  48. package/dist/commands/keygen.d.ts +6 -0
  49. package/dist/commands/keygen.d.ts.map +1 -0
  50. package/dist/commands/keygen.js +33 -0
  51. package/dist/commands/keygen.js.map +1 -0
  52. package/dist/commands/keys.d.ts +6 -0
  53. package/dist/commands/keys.d.ts.map +1 -0
  54. package/dist/commands/keys.js +47 -0
  55. package/dist/commands/keys.js.map +1 -0
  56. package/dist/commands/read.d.ts +6 -0
  57. package/dist/commands/read.d.ts.map +1 -0
  58. package/dist/commands/read.js +89 -0
  59. package/dist/commands/read.js.map +1 -0
  60. package/dist/commands/send.d.ts +8 -0
  61. package/dist/commands/send.d.ts.map +1 -0
  62. package/dist/commands/send.js +73 -0
  63. package/dist/commands/send.js.map +1 -0
  64. package/dist/commands/watch.d.ts +8 -0
  65. package/dist/commands/watch.d.ts.map +1 -0
  66. package/dist/commands/watch.js +88 -0
  67. package/dist/commands/watch.js.map +1 -0
  68. package/dist/dashboard/public/app.js +523 -0
  69. package/dist/dashboard/public/index.html +75 -0
  70. package/dist/dashboard/public/styles.css +68 -0
  71. package/dist/dashboard/routes.d.ts +3 -0
  72. package/dist/dashboard/routes.d.ts.map +1 -0
  73. package/dist/dashboard/routes.js +103 -0
  74. package/dist/dashboard/routes.js.map +1 -0
  75. package/dist/dashboard/server.d.ts +3 -0
  76. package/dist/dashboard/server.d.ts.map +1 -0
  77. package/dist/dashboard/server.js +29 -0
  78. package/dist/dashboard/server.js.map +1 -0
  79. package/dist/lib/config.d.ts +28 -0
  80. package/dist/lib/config.d.ts.map +1 -0
  81. package/dist/lib/config.js +90 -0
  82. package/dist/lib/config.js.map +1 -0
  83. package/dist/lib/crypto.d.ts +72 -0
  84. package/dist/lib/crypto.d.ts.map +1 -0
  85. package/dist/lib/crypto.js +169 -0
  86. package/dist/lib/crypto.js.map +1 -0
  87. package/dist/lib/realtime.d.ts +36 -0
  88. package/dist/lib/realtime.d.ts.map +1 -0
  89. package/dist/lib/realtime.js +73 -0
  90. package/dist/lib/realtime.js.map +1 -0
  91. package/dist/storage/local.d.ts +46 -0
  92. package/dist/storage/local.d.ts.map +1 -0
  93. package/dist/storage/local.js +160 -0
  94. package/dist/storage/local.js.map +1 -0
  95. package/dist/storage/supabase.d.ts +43 -0
  96. package/dist/storage/supabase.d.ts.map +1 -0
  97. package/dist/storage/supabase.js +256 -0
  98. package/dist/storage/supabase.js.map +1 -0
  99. package/dist/types/index.d.ts +48 -0
  100. package/dist/types/index.d.ts.map +1 -0
  101. package/dist/types/index.js +5 -0
  102. package/dist/types/index.js.map +1 -0
  103. package/docs/20251215_Treebird-Ecosystem_Knowledge-Base_v2.md +292 -0
  104. package/docs/20251215_Treebird-Ecosystem_Project-Instructions_v2.md +176 -0
  105. package/docs/AGENT_DELEGATION_WORKFLOW.md +453 -0
  106. package/docs/AGENT_STARTER_KIT.md +145 -0
  107. package/docs/ANNOUNCEMENT_DRAFTS.md +55 -0
  108. package/docs/DASHBOARD_AGENT_HANDOFF.md +429 -0
  109. package/docs/DASHBOARD_AGENT_PROMPT.md +32 -0
  110. package/docs/DASHBOARD_BUILD_ROADMAP.md +61 -0
  111. package/docs/DEPLOYMENT.md +59 -0
  112. package/docs/MCP_PUBLISHING_ROADMAP.md +113 -0
  113. package/docs/MCP_STARTER_KIT.md +117 -0
  114. package/docs/SSAN_MESSAGES_SUMMARY.md +92 -0
  115. package/docs/STORAGE_ARCHITECTURE.md +114 -0
  116. package/mcp-server/README.md +143 -0
  117. package/mcp-server/assets/icon.png +0 -0
  118. package/mcp-server/myceliumail-mcp-1.0.0.tgz +0 -0
  119. package/mcp-server/package-lock.json +1142 -0
  120. package/mcp-server/package.json +49 -0
  121. package/mcp-server/src/lib/config.ts +21 -0
  122. package/mcp-server/src/lib/crypto.ts +150 -0
  123. package/mcp-server/src/lib/storage.ts +257 -0
  124. package/mcp-server/src/server.ts +387 -0
  125. package/mcp-server/tsconfig.json +26 -0
  126. package/package.json +54 -0
  127. package/src/bin/myceliumail.ts +52 -0
  128. package/src/commands/broadcast.ts +70 -0
  129. package/src/commands/dashboard.ts +19 -0
  130. package/src/commands/inbox.ts +75 -0
  131. package/src/commands/key-import.ts +35 -0
  132. package/src/commands/keygen.ts +44 -0
  133. package/src/commands/keys.ts +55 -0
  134. package/src/commands/read.ts +97 -0
  135. package/src/commands/send.ts +89 -0
  136. package/src/commands/watch.ts +101 -0
  137. package/src/dashboard/public/app.js +523 -0
  138. package/src/dashboard/public/index.html +75 -0
  139. package/src/dashboard/public/styles.css +68 -0
  140. package/src/dashboard/routes.ts +128 -0
  141. package/src/dashboard/server.ts +33 -0
  142. package/src/lib/config.ts +104 -0
  143. package/src/lib/crypto.ts +210 -0
  144. package/src/lib/realtime.ts +109 -0
  145. package/src/storage/local.ts +209 -0
  146. package/src/storage/supabase.ts +336 -0
  147. package/src/types/index.ts +53 -0
  148. package/supabase/migrations/000_myceliumail_setup.sql +93 -0
  149. package/supabase/migrations/001_enable_realtime.sql +10 -0
  150. package/tsconfig.json +28 -0
@@ -0,0 +1,73 @@
1
+ /**
2
+ * send command - Send a message to another agent
3
+ *
4
+ * Messages are encrypted by default. Use --plaintext to send unencrypted.
5
+ */
6
+ import { Command } from 'commander';
7
+ import { loadConfig } from '../lib/config.js';
8
+ import { loadKeyPair, getKnownKey, encryptMessage, decodePublicKey } from '../lib/crypto.js';
9
+ import * as storage from '../storage/supabase.js';
10
+ export function createSendCommand() {
11
+ return new Command('send')
12
+ .description('Send a message to another agent (encrypted by default)')
13
+ .argument('<recipient>', 'Recipient agent ID')
14
+ .argument('<subject>', 'Message subject')
15
+ .option('-m, --message <body>', 'Message body (or provide via stdin)')
16
+ .option('-p, --plaintext', 'Send unencrypted (not recommended)')
17
+ .action(async (recipient, subject, options) => {
18
+ const config = loadConfig();
19
+ const sender = config.agentId;
20
+ if (sender === 'anonymous') {
21
+ console.error('❌ Agent ID not configured.');
22
+ console.error('Set MYCELIUMAIL_AGENT_ID or configure ~/.myceliumail/config.json');
23
+ process.exit(1);
24
+ }
25
+ const body = options.message || subject;
26
+ let messageOptions;
27
+ let encrypted = false;
28
+ // Encrypt by default unless --plaintext is specified
29
+ if (!options.plaintext) {
30
+ const senderKeyPair = loadKeyPair(sender);
31
+ const recipientPubKeyB64 = getKnownKey(recipient);
32
+ if (senderKeyPair && recipientPubKeyB64) {
33
+ try {
34
+ const recipientPubKey = decodePublicKey(recipientPubKeyB64);
35
+ const payload = JSON.stringify({ subject, body });
36
+ const encryptedData = encryptMessage(payload, recipientPubKey, senderKeyPair);
37
+ messageOptions = {
38
+ encrypted: true,
39
+ ciphertext: encryptedData.ciphertext,
40
+ nonce: encryptedData.nonce,
41
+ senderPublicKey: encryptedData.senderPublicKey,
42
+ };
43
+ encrypted = true;
44
+ }
45
+ catch (err) {
46
+ console.warn('⚠️ Encryption failed, sending plaintext:', err.message);
47
+ }
48
+ }
49
+ else {
50
+ // Warn user but don't block
51
+ if (!senderKeyPair) {
52
+ console.warn('⚠️ No keypair found. Run: mycmail keygen');
53
+ }
54
+ if (!recipientPubKeyB64) {
55
+ console.warn(`⚠️ No public key for ${recipient}. Run: mycmail key-import ${recipient} <key>`);
56
+ }
57
+ console.warn(' Sending as plaintext (use -p to suppress this warning)\n');
58
+ }
59
+ }
60
+ try {
61
+ const message = await storage.sendMessage(sender, recipient, subject, body, messageOptions);
62
+ console.log(`\n✅ Message sent to ${recipient}`);
63
+ console.log(` ID: ${message.id}`);
64
+ console.log(` Subject: ${subject}`);
65
+ console.log(` ${encrypted ? '🔐 Encrypted' : '📨 Plaintext'}`);
66
+ }
67
+ catch (error) {
68
+ console.error('❌ Failed to send message:', error);
69
+ process.exit(1);
70
+ }
71
+ });
72
+ }
73
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Watch Command
3
+ *
4
+ * Listen for new messages in real-time and show desktop notifications.
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare function createWatchCommand(): Command;
8
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,kBAAkB,IAAI,OAAO,CAyF5C"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Watch Command
3
+ *
4
+ * Listen for new messages in real-time and show desktop notifications.
5
+ */
6
+ import { Command } from 'commander';
7
+ import notifier from 'node-notifier';
8
+ import { loadConfig } from '../lib/config.js';
9
+ import { subscribeToMessages, closeConnection } from '../lib/realtime.js';
10
+ export function createWatchCommand() {
11
+ const command = new Command('watch')
12
+ .description('Watch for new messages in real-time')
13
+ .option('-a, --agent <id>', 'Agent ID to watch (default: current agent)')
14
+ .option('-q, --quiet', 'Suppress console output, only show notifications')
15
+ .action(async (options) => {
16
+ const config = loadConfig();
17
+ const agentId = options.agent || config.agentId;
18
+ if (!options.quiet) {
19
+ console.log(`\n🍄 Watching inbox for ${agentId}...`);
20
+ console.log('Press Ctrl+C to stop\n');
21
+ }
22
+ const channel = subscribeToMessages(agentId, (message) => {
23
+ // Show console output
24
+ if (!options.quiet) {
25
+ const time = new Date(message.created_at).toLocaleTimeString();
26
+ console.log(`📬 [${time}] New message from ${message.from_agent}`);
27
+ console.log(` Subject: ${message.subject}`);
28
+ if (!message.encrypted) {
29
+ const preview = message.message.length > 80
30
+ ? message.message.substring(0, 80) + '...'
31
+ : message.message;
32
+ console.log(` Preview: ${preview}`);
33
+ }
34
+ else {
35
+ console.log(` 🔒 [Encrypted]`);
36
+ }
37
+ console.log();
38
+ }
39
+ // Show desktop notification
40
+ const preview = message.encrypted
41
+ ? '🔒 Encrypted message'
42
+ : message.message.length > 100
43
+ ? message.message.substring(0, 100) + '...'
44
+ : message.message;
45
+ notifier.notify({
46
+ title: `📬 ${message.from_agent}: ${message.subject}`,
47
+ message: preview,
48
+ sound: true,
49
+ wait: false,
50
+ });
51
+ }, (status, error) => {
52
+ if (!options.quiet) {
53
+ switch (status) {
54
+ case 'SUBSCRIBED':
55
+ console.log('✅ Connected to Supabase Realtime\n');
56
+ break;
57
+ case 'CLOSED':
58
+ console.log('🔌 Connection closed');
59
+ break;
60
+ case 'CHANNEL_ERROR':
61
+ console.error('❌ Channel error:', error?.message);
62
+ break;
63
+ case 'TIMED_OUT':
64
+ console.error('⏱️ Connection timed out');
65
+ break;
66
+ }
67
+ }
68
+ });
69
+ if (!channel) {
70
+ console.error('❌ Failed to start watching. Check your Supabase configuration.');
71
+ process.exit(1);
72
+ }
73
+ // Handle graceful shutdown
74
+ const cleanup = async () => {
75
+ if (!options.quiet) {
76
+ console.log('\n👋 Stopping watch...');
77
+ }
78
+ await closeConnection();
79
+ process.exit(0);
80
+ };
81
+ process.on('SIGINT', cleanup);
82
+ process.on('SIGTERM', cleanup);
83
+ // Keep the process running
84
+ await new Promise(() => { });
85
+ });
86
+ return command;
87
+ }
88
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}