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.
- package/.context7 +87 -0
- package/.env.example +12 -0
- package/.eslintrc.json +29 -0
- package/CLAUDE.md +35 -0
- package/COMPLETE.md +51 -0
- package/LICENSE +21 -0
- package/MYCELIUMAIL_STARTER_KIT.md +603 -0
- package/NEXT_STEPS.md +96 -0
- package/README.md +229 -0
- package/desktop/README.md +102 -0
- package/desktop/assets/icon.icns +0 -0
- package/desktop/assets/icon.iconset/icon_128x128.png +0 -0
- package/desktop/assets/icon.iconset/icon_128x128@2x.png +0 -0
- package/desktop/assets/icon.iconset/icon_16x16.png +0 -0
- package/desktop/assets/icon.iconset/icon_16x16@2x.png +0 -0
- package/desktop/assets/icon.iconset/icon_256x256.png +0 -0
- package/desktop/assets/icon.iconset/icon_256x256@2x.png +0 -0
- package/desktop/assets/icon.iconset/icon_32x32.png +0 -0
- package/desktop/assets/icon.iconset/icon_32x32@2x.png +0 -0
- package/desktop/assets/icon.iconset/icon_512x512.png +0 -0
- package/desktop/assets/icon.iconset/icon_512x512@2x.png +0 -0
- package/desktop/assets/icon.png +0 -0
- package/desktop/assets/tray-icon.png +0 -0
- package/desktop/main.js +257 -0
- package/desktop/package-lock.json +4198 -0
- package/desktop/package.json +48 -0
- package/desktop/preload.js +11 -0
- package/dist/bin/myceliumail.d.ts +8 -0
- package/dist/bin/myceliumail.d.ts.map +1 -0
- package/dist/bin/myceliumail.js +44 -0
- package/dist/bin/myceliumail.js.map +1 -0
- package/dist/commands/broadcast.d.ts +9 -0
- package/dist/commands/broadcast.d.ts.map +1 -0
- package/dist/commands/broadcast.js +59 -0
- package/dist/commands/broadcast.js.map +1 -0
- package/dist/commands/dashboard.d.ts +3 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +18 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/inbox.d.ts +6 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +65 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/key-import.d.ts +6 -0
- package/dist/commands/key-import.d.ts.map +1 -0
- package/dist/commands/key-import.js +31 -0
- package/dist/commands/key-import.js.map +1 -0
- package/dist/commands/keygen.d.ts +6 -0
- package/dist/commands/keygen.d.ts.map +1 -0
- package/dist/commands/keygen.js +33 -0
- package/dist/commands/keygen.js.map +1 -0
- package/dist/commands/keys.d.ts +6 -0
- package/dist/commands/keys.d.ts.map +1 -0
- package/dist/commands/keys.js +47 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/read.d.ts +6 -0
- package/dist/commands/read.d.ts.map +1 -0
- package/dist/commands/read.js +89 -0
- package/dist/commands/read.js.map +1 -0
- package/dist/commands/send.d.ts +8 -0
- package/dist/commands/send.d.ts.map +1 -0
- package/dist/commands/send.js +73 -0
- package/dist/commands/send.js.map +1 -0
- package/dist/commands/watch.d.ts +8 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +88 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/dashboard/public/app.js +523 -0
- package/dist/dashboard/public/index.html +75 -0
- package/dist/dashboard/public/styles.css +68 -0
- package/dist/dashboard/routes.d.ts +3 -0
- package/dist/dashboard/routes.d.ts.map +1 -0
- package/dist/dashboard/routes.js +103 -0
- package/dist/dashboard/routes.js.map +1 -0
- package/dist/dashboard/server.d.ts +3 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +29 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/lib/config.d.ts +28 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +90 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/crypto.d.ts +72 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +169 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/realtime.d.ts +36 -0
- package/dist/lib/realtime.d.ts.map +1 -0
- package/dist/lib/realtime.js +73 -0
- package/dist/lib/realtime.js.map +1 -0
- package/dist/storage/local.d.ts +46 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +160 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/supabase.d.ts +43 -0
- package/dist/storage/supabase.d.ts.map +1 -0
- package/dist/storage/supabase.js +256 -0
- package/dist/storage/supabase.js.map +1 -0
- package/dist/types/index.d.ts +48 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/docs/20251215_Treebird-Ecosystem_Knowledge-Base_v2.md +292 -0
- package/docs/20251215_Treebird-Ecosystem_Project-Instructions_v2.md +176 -0
- package/docs/AGENT_DELEGATION_WORKFLOW.md +453 -0
- package/docs/AGENT_STARTER_KIT.md +145 -0
- package/docs/ANNOUNCEMENT_DRAFTS.md +55 -0
- package/docs/DASHBOARD_AGENT_HANDOFF.md +429 -0
- package/docs/DASHBOARD_AGENT_PROMPT.md +32 -0
- package/docs/DASHBOARD_BUILD_ROADMAP.md +61 -0
- package/docs/DEPLOYMENT.md +59 -0
- package/docs/MCP_PUBLISHING_ROADMAP.md +113 -0
- package/docs/MCP_STARTER_KIT.md +117 -0
- package/docs/SSAN_MESSAGES_SUMMARY.md +92 -0
- package/docs/STORAGE_ARCHITECTURE.md +114 -0
- package/mcp-server/README.md +143 -0
- package/mcp-server/assets/icon.png +0 -0
- package/mcp-server/myceliumail-mcp-1.0.0.tgz +0 -0
- package/mcp-server/package-lock.json +1142 -0
- package/mcp-server/package.json +49 -0
- package/mcp-server/src/lib/config.ts +21 -0
- package/mcp-server/src/lib/crypto.ts +150 -0
- package/mcp-server/src/lib/storage.ts +257 -0
- package/mcp-server/src/server.ts +387 -0
- package/mcp-server/tsconfig.json +26 -0
- package/package.json +54 -0
- package/src/bin/myceliumail.ts +52 -0
- package/src/commands/broadcast.ts +70 -0
- package/src/commands/dashboard.ts +19 -0
- package/src/commands/inbox.ts +75 -0
- package/src/commands/key-import.ts +35 -0
- package/src/commands/keygen.ts +44 -0
- package/src/commands/keys.ts +55 -0
- package/src/commands/read.ts +97 -0
- package/src/commands/send.ts +89 -0
- package/src/commands/watch.ts +101 -0
- package/src/dashboard/public/app.js +523 -0
- package/src/dashboard/public/index.html +75 -0
- package/src/dashboard/public/styles.css +68 -0
- package/src/dashboard/routes.ts +128 -0
- package/src/dashboard/server.ts +33 -0
- package/src/lib/config.ts +104 -0
- package/src/lib/crypto.ts +210 -0
- package/src/lib/realtime.ts +109 -0
- package/src/storage/local.ts +209 -0
- package/src/storage/supabase.ts +336 -0
- package/src/types/index.ts +53 -0
- package/supabase/migrations/000_myceliumail_setup.sql +93 -0
- package/supabase/migrations/001_enable_realtime.sql +10 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "myceliumail-desktop",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Myceliumail Desktop - Agent Messaging Client",
|
|
5
|
+
"main": "main.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "electron .",
|
|
8
|
+
"build": "electron-builder --mac",
|
|
9
|
+
"build:all": "electron-builder --mac --win --linux"
|
|
10
|
+
},
|
|
11
|
+
"author": "Treebird",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"electron": "^28.0.0",
|
|
15
|
+
"electron-builder": "^24.9.1"
|
|
16
|
+
},
|
|
17
|
+
"build": {
|
|
18
|
+
"appId": "com.treebird.myceliumail",
|
|
19
|
+
"productName": "Myceliumail",
|
|
20
|
+
"mac": {
|
|
21
|
+
"category": "public.app-category.productivity",
|
|
22
|
+
"icon": "assets/icon.icns"
|
|
23
|
+
},
|
|
24
|
+
"win": {
|
|
25
|
+
"icon": "assets/icon.ico"
|
|
26
|
+
},
|
|
27
|
+
"linux": {
|
|
28
|
+
"icon": "assets/icon.png"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"main.js",
|
|
32
|
+
"preload.js",
|
|
33
|
+
"assets/**/*"
|
|
34
|
+
],
|
|
35
|
+
"extraResources": [
|
|
36
|
+
{
|
|
37
|
+
"from": "../dist",
|
|
38
|
+
"to": "cli",
|
|
39
|
+
"filter": [
|
|
40
|
+
"**/*"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@supabase/supabase-js": "^2.88.0"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Preload script - runs before web page loads
|
|
2
|
+
// Can expose Node.js APIs safely to the renderer
|
|
3
|
+
|
|
4
|
+
const { contextBridge, ipcRenderer } = require('electron');
|
|
5
|
+
|
|
6
|
+
// Expose protected methods to the renderer process
|
|
7
|
+
contextBridge.exposeInMainWorld('myceliumail', {
|
|
8
|
+
// Can add IPC methods here if needed
|
|
9
|
+
platform: process.platform,
|
|
10
|
+
version: process.env.npm_package_version || '0.1.0'
|
|
11
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"myceliumail.d.ts","sourceRoot":"","sources":["../../src/bin/myceliumail.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AAGH,OAAO,eAAe,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Myceliumail CLI
|
|
4
|
+
*
|
|
5
|
+
* End-to-End Encrypted Messaging for AI Agents
|
|
6
|
+
*/
|
|
7
|
+
// Load environment variables from .env file
|
|
8
|
+
import 'dotenv/config';
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import { loadConfig } from '../lib/config.js';
|
|
11
|
+
// Import commands
|
|
12
|
+
import { createKeygenCommand } from '../commands/keygen.js';
|
|
13
|
+
import { createKeysCommand } from '../commands/keys.js';
|
|
14
|
+
import { createKeyImportCommand } from '../commands/key-import.js';
|
|
15
|
+
import { createSendCommand } from '../commands/send.js';
|
|
16
|
+
import { createInboxCommand } from '../commands/inbox.js';
|
|
17
|
+
import { createReadCommand } from '../commands/read.js';
|
|
18
|
+
import { createDashboardCommand } from '../commands/dashboard.js';
|
|
19
|
+
import { createBroadcastCommand } from '../commands/broadcast.js';
|
|
20
|
+
import { createWatchCommand } from '../commands/watch.js';
|
|
21
|
+
const program = new Command();
|
|
22
|
+
program
|
|
23
|
+
.name('mycmail')
|
|
24
|
+
.description('š Myceliumail - End-to-End Encrypted Messaging for AI Agents')
|
|
25
|
+
.version('1.0.0');
|
|
26
|
+
// Show current agent in help
|
|
27
|
+
const config = loadConfig();
|
|
28
|
+
program.addHelpText('after', `
|
|
29
|
+
Current agent: ${config.agentId}
|
|
30
|
+
Config: ~/.myceliumail/config.json
|
|
31
|
+
`);
|
|
32
|
+
// Register commands
|
|
33
|
+
program.addCommand(createKeygenCommand());
|
|
34
|
+
program.addCommand(createKeysCommand());
|
|
35
|
+
program.addCommand(createKeyImportCommand());
|
|
36
|
+
program.addCommand(createSendCommand());
|
|
37
|
+
program.addCommand(createInboxCommand());
|
|
38
|
+
program.addCommand(createReadCommand());
|
|
39
|
+
program.addCommand(createDashboardCommand());
|
|
40
|
+
program.addCommand(createBroadcastCommand());
|
|
41
|
+
program.addCommand(createWatchCommand());
|
|
42
|
+
// Parse and run
|
|
43
|
+
program.parse();
|
|
44
|
+
//# sourceMappingURL=myceliumail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"myceliumail.js","sourceRoot":"","sources":["../../src/bin/myceliumail.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AAEH,4CAA4C;AAC5C,OAAO,eAAe,CAAC;AAEvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,kBAAkB;AAClB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,+DAA+D,CAAC;KAC5E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,6BAA6B;AAC7B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAC5B,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE;iBACZ,MAAM,CAAC,OAAO;;CAE9B,CAAC,CAAC;AAEH,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC,CAAC;AAC7C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC,CAAC;AAC7C,OAAO,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC,CAAC;AAC7C,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAEzC,gBAAgB;AAChB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* broadcast command - Send a message to all known agents
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
declare const AGENT_ALIASES: Record<string, string>;
|
|
6
|
+
declare function resolveAlias(agent: string): string;
|
|
7
|
+
export declare function createBroadcastCommand(): Command;
|
|
8
|
+
export { resolveAlias, AGENT_ALIASES };
|
|
9
|
+
//# sourceMappingURL=broadcast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/commands/broadcast.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,QAAA,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGzC,CAAC;AAEF,iBAAS,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,sBAAsB,IAAI,OAAO,CA+ChD;AAGD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* broadcast command - Send a message to all known agents
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { loadConfig } from '../lib/config.js';
|
|
6
|
+
import { getKnownKeys } from '../lib/crypto.js';
|
|
7
|
+
import * as storage from '../storage/supabase.js';
|
|
8
|
+
// Known agent aliases
|
|
9
|
+
const AGENT_ALIASES = {
|
|
10
|
+
'mycs': 'mycsan',
|
|
11
|
+
'treeb': 'treebird',
|
|
12
|
+
};
|
|
13
|
+
function resolveAlias(agent) {
|
|
14
|
+
return AGENT_ALIASES[agent] || agent;
|
|
15
|
+
}
|
|
16
|
+
export function createBroadcastCommand() {
|
|
17
|
+
return new Command('broadcast')
|
|
18
|
+
.description('Send a message to all known agents')
|
|
19
|
+
.argument('<subject>', 'Message subject/body')
|
|
20
|
+
.option('-m, --message <body>', 'Message body (optional)')
|
|
21
|
+
.action(async (subject, options) => {
|
|
22
|
+
const config = loadConfig();
|
|
23
|
+
const sender = config.agentId;
|
|
24
|
+
if (sender === 'anonymous') {
|
|
25
|
+
console.error('ā Agent ID not configured.');
|
|
26
|
+
console.error('Set MYCELIUMAIL_AGENT_ID or configure ~/.myceliumail/config.json');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const body = options.message || subject;
|
|
30
|
+
// Get all known agents from keys
|
|
31
|
+
const knownKeys = getKnownKeys();
|
|
32
|
+
const recipients = Object.keys(knownKeys).filter(agent => agent !== sender);
|
|
33
|
+
if (recipients.length === 0) {
|
|
34
|
+
console.error('ā No known agents to broadcast to.');
|
|
35
|
+
console.error('Import agent keys first:');
|
|
36
|
+
console.error(' mycmail key-import <agent> <their-public-key>');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
console.log(`š¢ Broadcasting to ${recipients.length} agents...`);
|
|
40
|
+
console.log(` Recipients: ${recipients.join(', ')}\n`);
|
|
41
|
+
let sent = 0;
|
|
42
|
+
let failed = 0;
|
|
43
|
+
for (const recipient of recipients) {
|
|
44
|
+
try {
|
|
45
|
+
await storage.sendMessage(sender, recipient, subject, body);
|
|
46
|
+
console.log(` ā
${recipient}`);
|
|
47
|
+
sent++;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.log(` ā ${recipient}: ${error}`);
|
|
51
|
+
failed++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
console.log(`\nš¬ Broadcast complete: ${sent} sent, ${failed} failed`);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Export alias resolver for use in send command
|
|
58
|
+
export { resolveAlias, AGENT_ALIASES };
|
|
59
|
+
//# sourceMappingURL=broadcast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/commands/broadcast.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAElD,sBAAsB;AACtB,MAAM,aAAa,GAA2B;IAC1C,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,UAAU;CACtB,CAAC;AAEF,SAAS,YAAY,CAAC,KAAa;IAC/B,OAAO,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,sBAAsB;IAClC,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;SAC1B,WAAW,CAAC,oCAAoC,CAAC;SACjD,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;SAC7C,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,OAAO,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;QAE9B,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC5C,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;YAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC;QAExC,iCAAiC;QACjC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;QAE5E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACpD,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC1C,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,UAAU,CAAC,MAAM,YAAY,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,kBAAkB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEzD,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC;gBACD,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC5D,OAAO,CAAC,GAAG,CAAC,QAAQ,SAAS,EAAE,CAAC,CAAC;gBACjC,IAAI,EAAE,CAAC;YACX,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CAAC,QAAQ,SAAS,KAAK,KAAK,EAAE,CAAC,CAAC;gBAC3C,MAAM,EAAE,CAAC;YACb,CAAC;QACL,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,UAAU,MAAM,SAAS,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACX,CAAC;AAED,gDAAgD;AAChD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,sBAAsB,IAAI,OAAO,CAehD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { startDashboard } from '../dashboard/server.js';
|
|
3
|
+
export function createDashboardCommand() {
|
|
4
|
+
return new Command('dashboard')
|
|
5
|
+
.description('Start web dashboard on localhost:3737')
|
|
6
|
+
.option('-p, --port <port>', 'Port to run on', '3737')
|
|
7
|
+
.action(async (options) => {
|
|
8
|
+
const port = parseInt(options.port, 10);
|
|
9
|
+
console.log(`\nš Starting Myceliumail Dashboard...`);
|
|
10
|
+
await startDashboard(port);
|
|
11
|
+
// Help text
|
|
12
|
+
console.log(`\n ā http://localhost:${port}`);
|
|
13
|
+
console.log('\nPress Ctrl+C to stop');
|
|
14
|
+
// Keep process alive
|
|
15
|
+
await new Promise(() => { });
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,UAAU,sBAAsB;IAClC,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;SAC1B,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,CAAC;SACrD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QAC3B,YAAY;QACZ,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QAEtC,qBAAqB;QACrB,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/commands/inbox.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,kBAAkB,IAAI,OAAO,CAiE5C"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inbox command - List incoming messages
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { loadConfig } from '../lib/config.js';
|
|
6
|
+
import { loadKeyPair, decryptMessage } from '../lib/crypto.js';
|
|
7
|
+
import * as storage from '../storage/supabase.js';
|
|
8
|
+
export function createInboxCommand() {
|
|
9
|
+
return new Command('inbox')
|
|
10
|
+
.description('List incoming messages')
|
|
11
|
+
.option('-u, --unread', 'Show only unread messages')
|
|
12
|
+
.option('-l, --limit <n>', 'Limit number of messages', '10')
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
const config = loadConfig();
|
|
15
|
+
const agentId = config.agentId;
|
|
16
|
+
if (agentId === 'anonymous') {
|
|
17
|
+
console.error('ā Agent ID not configured.');
|
|
18
|
+
console.error('Set MYCELIUMAIL_AGENT_ID or configure ~/.myceliumail/config.json');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const messages = await storage.getInbox(agentId, {
|
|
23
|
+
unreadOnly: options.unread,
|
|
24
|
+
limit: parseInt(options.limit, 10),
|
|
25
|
+
});
|
|
26
|
+
if (messages.length === 0) {
|
|
27
|
+
console.log('š No messages');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
console.log(`š¬ Inbox for ${agentId} (${messages.length} messages)\n`);
|
|
31
|
+
const keyPair = loadKeyPair(agentId);
|
|
32
|
+
for (const msg of messages) {
|
|
33
|
+
const readMarker = msg.read ? ' ' : 'ā ';
|
|
34
|
+
const encryptedMarker = msg.encrypted ? 'š ' : '';
|
|
35
|
+
const date = msg.createdAt.toLocaleString();
|
|
36
|
+
let displaySubject = msg.subject;
|
|
37
|
+
// Try to decrypt if encrypted and we have keys
|
|
38
|
+
if (msg.encrypted && keyPair && msg.ciphertext && msg.nonce && msg.senderPublicKey) {
|
|
39
|
+
try {
|
|
40
|
+
const decrypted = decryptMessage({
|
|
41
|
+
ciphertext: msg.ciphertext,
|
|
42
|
+
nonce: msg.nonce,
|
|
43
|
+
senderPublicKey: msg.senderPublicKey,
|
|
44
|
+
}, keyPair);
|
|
45
|
+
if (decrypted) {
|
|
46
|
+
const parsed = JSON.parse(decrypted);
|
|
47
|
+
displaySubject = parsed.subject || '[Decrypted]';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
displaySubject = '[Encrypted]';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
console.log(`${readMarker}${encryptedMarker}${msg.id.slice(0, 8)} | From: ${msg.sender} | ${displaySubject}`);
|
|
55
|
+
console.log(` ${date}`);
|
|
56
|
+
}
|
|
57
|
+
console.log('\nš” Use: mycmail read <id> to read a message');
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('ā Failed to fetch inbox:', error);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=inbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/commands/inbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-import.d.ts","sourceRoot":"","sources":["../../src/commands/key-import.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,sBAAsB,IAAI,OAAO,CA2BhD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* key-import command - Import a peer's public key
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { saveKnownKey, getKnownKey } from '../lib/crypto.js';
|
|
6
|
+
export function createKeyImportCommand() {
|
|
7
|
+
return new Command('key-import')
|
|
8
|
+
.description('Import a peer agent\'s public key')
|
|
9
|
+
.argument('<agent>', 'Agent ID to import key for')
|
|
10
|
+
.argument('<key>', 'Base64 encoded public key')
|
|
11
|
+
.option('-f, --force', 'Overwrite existing key')
|
|
12
|
+
.action(async (agentId, publicKey, options) => {
|
|
13
|
+
// Validate key format (basic check)
|
|
14
|
+
if (publicKey.length < 40) {
|
|
15
|
+
console.error('ā Invalid key format. Expected base64 encoded NaCl public key.');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const existing = getKnownKey(agentId);
|
|
19
|
+
if (existing && !options.force) {
|
|
20
|
+
console.log(`ā ļø Key already exists for ${agentId}`);
|
|
21
|
+
console.log(`Existing key: ${existing.slice(0, 20)}...`);
|
|
22
|
+
console.log('\nUse --force to overwrite');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
saveKnownKey(agentId, publicKey);
|
|
26
|
+
console.log(`ā
Imported public key for ${agentId}`);
|
|
27
|
+
console.log(`Key: ${publicKey.slice(0, 20)}...`);
|
|
28
|
+
console.log('\nš You can now send encrypted messages to this agent');
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=key-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-import.js","sourceRoot":"","sources":["../../src/commands/key-import.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,UAAU,sBAAsB;IAClC,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC;SAC3B,WAAW,CAAC,mCAAmC,CAAC;SAChD,QAAQ,CAAC,SAAS,EAAE,4BAA4B,CAAC;SACjD,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;SAC9C,MAAM,CAAC,aAAa,EAAE,wBAAwB,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,SAAiB,EAAE,OAAO,EAAE,EAAE;QAC1D,oCAAoC;QACpC,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,OAAO;QACX,CAAC;QAED,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAEjC,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,QAAQ,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keygen.d.ts","sourceRoot":"","sources":["../../src/commands/keygen.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,mBAAmB,IAAI,OAAO,CA6B7C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* keygen command - Generate encryption keypair
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { loadConfig } from '../lib/config.js';
|
|
6
|
+
import { generateKeyPair, saveKeyPair, hasKeyPair, getPublicKeyBase64, loadKeyPair } from '../lib/crypto.js';
|
|
7
|
+
export function createKeygenCommand() {
|
|
8
|
+
return new Command('keygen')
|
|
9
|
+
.description('Generate a new encryption keypair')
|
|
10
|
+
.option('-f, --force', 'Overwrite existing keypair')
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
const agentId = config.agentId;
|
|
14
|
+
if (hasKeyPair(agentId) && !options.force) {
|
|
15
|
+
console.log(`ā ļø Keypair already exists for ${agentId}`);
|
|
16
|
+
const existingPair = loadKeyPair(agentId);
|
|
17
|
+
if (existingPair) {
|
|
18
|
+
console.log(`š§ Your public key: ${getPublicKeyBase64(existingPair)}`);
|
|
19
|
+
}
|
|
20
|
+
console.log('\nUse --force to regenerate (ā ļø this will invalidate existing encrypted messages)');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const keyPair = generateKeyPair();
|
|
24
|
+
saveKeyPair(agentId, keyPair);
|
|
25
|
+
const publicKey = getPublicKeyBase64(keyPair);
|
|
26
|
+
console.log('š Keypair generated successfully!\n');
|
|
27
|
+
console.log(`Agent ID: ${agentId}`);
|
|
28
|
+
console.log(`š§ Your public key (share with other agents):\n`);
|
|
29
|
+
console.log(publicKey);
|
|
30
|
+
console.log('\nā
Keys stored in ~/.myceliumail/keys/');
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=keygen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keygen.js","sourceRoot":"","sources":["../../src/commands/keygen.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACH,eAAe,EACf,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,WAAW,EACd,MAAM,kBAAkB,CAAC;AAE1B,MAAM,UAAU,mBAAmB;IAC/B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACvB,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,aAAa,EAAE,4BAA4B,CAAC;SACnD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAE/B,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;YACzD,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,YAAY,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,uBAAuB,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAC3E,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;YAClG,OAAO;QACX,CAAC;QAED,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;QAClC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE9B,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAE9C,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,iBAAiB,IAAI,OAAO,CAyC3C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* keys command - List known public keys
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { loadConfig } from '../lib/config.js';
|
|
6
|
+
import { loadKnownKeys, listOwnKeys, loadKeyPair, getPublicKeyBase64 } from '../lib/crypto.js';
|
|
7
|
+
export function createKeysCommand() {
|
|
8
|
+
return new Command('keys')
|
|
9
|
+
.description('List known public keys')
|
|
10
|
+
.option('-a, --all', 'Show full keys (not truncated)')
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
const ownKeys = listOwnKeys();
|
|
14
|
+
const knownKeys = loadKnownKeys();
|
|
15
|
+
console.log('š Encryption Keys\n');
|
|
16
|
+
// Own keys
|
|
17
|
+
console.log('āā Your Keys āā');
|
|
18
|
+
if (ownKeys.length === 0) {
|
|
19
|
+
console.log(' No keypairs generated. Run: mycmail keygen');
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
for (const agentId of ownKeys) {
|
|
23
|
+
const keyPair = loadKeyPair(agentId);
|
|
24
|
+
if (keyPair) {
|
|
25
|
+
const pubKey = getPublicKeyBase64(keyPair);
|
|
26
|
+
const display = options.all ? pubKey : `${pubKey.slice(0, 20)}...`;
|
|
27
|
+
const marker = agentId === config.agentId ? ' (active)' : '';
|
|
28
|
+
console.log(` ${agentId}${marker}: ${display}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Known peer keys
|
|
33
|
+
console.log('\nāā Peer Keys āā');
|
|
34
|
+
const peerEntries = Object.entries(knownKeys);
|
|
35
|
+
if (peerEntries.length === 0) {
|
|
36
|
+
console.log(' No peer keys imported. Use: mycmail key-import <agent> <key>');
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
for (const [agentId, pubKey] of peerEntries) {
|
|
40
|
+
const display = options.all ? pubKey : `${pubKey.slice(0, 20)}...`;
|
|
41
|
+
console.log(` ${agentId}: ${display}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
console.log('\nš” Tip: Use --all to show full keys');
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACH,aAAa,EACb,WAAW,EACX,WAAW,EACX,kBAAkB,EACrB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,UAAU,iBAAiB;IAC7B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACrB,WAAW,CAAC,wBAAwB,CAAC;SACrC,MAAM,CAAC,WAAW,EAAE,gCAAgC,CAAC;SACrD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAElC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QAEpC,WAAW;QACX,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACJ,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;gBACrC,IAAI,OAAO,EAAE,CAAC;oBACV,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;oBAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;oBACnE,MAAM,MAAM,GAAG,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;gBACrD,CAAC;YACL,CAAC;QACL,CAAC;QAED,kBAAkB;QAClB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YACJ,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;gBAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;gBACnE,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,KAAK,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC;QACL,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,iBAAiB,IAAI,OAAO,CA+B3C"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* read command - Read a specific message
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { loadConfig } from '../lib/config.js';
|
|
6
|
+
import { loadKeyPair, decryptMessage } from '../lib/crypto.js';
|
|
7
|
+
import * as storage from '../storage/supabase.js';
|
|
8
|
+
export function createReadCommand() {
|
|
9
|
+
return new Command('read')
|
|
10
|
+
.description('Read a specific message')
|
|
11
|
+
.argument('<id>', 'Message ID (can be partial)')
|
|
12
|
+
.action(async (messageId) => {
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
const agentId = config.agentId;
|
|
15
|
+
try {
|
|
16
|
+
// Get message - handle partial ID
|
|
17
|
+
const message = await storage.getMessage(messageId);
|
|
18
|
+
if (!message) {
|
|
19
|
+
// Try to find by partial ID
|
|
20
|
+
const inbox = await storage.getInbox(agentId, { limit: 100 });
|
|
21
|
+
const found = inbox.find(m => m.id.startsWith(messageId));
|
|
22
|
+
if (!found) {
|
|
23
|
+
console.error(`ā Message not found: ${messageId}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
return readAndDisplay(found, agentId);
|
|
27
|
+
}
|
|
28
|
+
await readAndDisplay(message, agentId);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('ā Failed to read message:', error);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async function readAndDisplay(message, agentId) {
|
|
37
|
+
if (!message)
|
|
38
|
+
return;
|
|
39
|
+
// Mark as read
|
|
40
|
+
await storage.markAsRead(message.id);
|
|
41
|
+
let subject = message.subject;
|
|
42
|
+
let body = message.body;
|
|
43
|
+
// Decrypt if encrypted
|
|
44
|
+
if (message.encrypted && message.ciphertext && message.nonce && message.senderPublicKey) {
|
|
45
|
+
const keyPair = loadKeyPair(agentId);
|
|
46
|
+
if (!keyPair) {
|
|
47
|
+
console.log('ā ļø Cannot decrypt: no keypair found');
|
|
48
|
+
console.log(' Generate keypair with: mycmail keygen');
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
try {
|
|
52
|
+
const decrypted = decryptMessage({
|
|
53
|
+
ciphertext: message.ciphertext,
|
|
54
|
+
nonce: message.nonce,
|
|
55
|
+
senderPublicKey: message.senderPublicKey,
|
|
56
|
+
}, keyPair);
|
|
57
|
+
if (decrypted) {
|
|
58
|
+
const parsed = JSON.parse(decrypted);
|
|
59
|
+
subject = parsed.subject || subject;
|
|
60
|
+
body = parsed.body || body;
|
|
61
|
+
console.log('š Message decrypted\n');
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log('ā ļø Decryption failed\n');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
console.log('ā ļø Failed to parse decrypted message\n');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Display message
|
|
73
|
+
console.log('ā'.repeat(60));
|
|
74
|
+
console.log(`From: ${message.sender}`);
|
|
75
|
+
console.log(`To: ${message.recipient}`);
|
|
76
|
+
console.log(`Date: ${message.createdAt.toLocaleString()}`);
|
|
77
|
+
console.log(`Subject: ${subject}`);
|
|
78
|
+
if (message.encrypted) {
|
|
79
|
+
console.log(`š Encrypted message`);
|
|
80
|
+
}
|
|
81
|
+
console.log('ā'.repeat(60));
|
|
82
|
+
console.log('');
|
|
83
|
+
console.log(body);
|
|
84
|
+
console.log('');
|
|
85
|
+
console.log('ā'.repeat(60));
|
|
86
|
+
console.log(`ID: ${message.id}`);
|
|
87
|
+
console.log('\nš” Reply with: mycmail reply <id> "<message>"');
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
+
export declare function createSendCommand(): Command;
|
|
8
|
+
//# sourceMappingURL=send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,iBAAiB,IAAI,OAAO,CAwE3C"}
|