myceliumail 1.0.9 → 1.0.13

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 (96) hide show
  1. package/.mappersan/outbox.json +15 -0
  2. package/.spidersan/registry.json +39 -0
  3. package/CHANGELOG.md +29 -0
  4. package/CLAUDE.md +29 -0
  5. package/README.md +23 -2
  6. package/dist/bin/myceliumail.js +17 -1
  7. package/dist/bin/myceliumail.js.map +1 -1
  8. package/dist/commands/close.d.ts +9 -0
  9. package/dist/commands/close.d.ts.map +1 -0
  10. package/dist/commands/close.js +153 -0
  11. package/dist/commands/close.js.map +1 -0
  12. package/dist/commands/collab.d.ts +8 -0
  13. package/dist/commands/collab.d.ts.map +1 -0
  14. package/dist/commands/collab.js +112 -0
  15. package/dist/commands/collab.js.map +1 -0
  16. package/dist/commands/inbox.d.ts.map +1 -1
  17. package/dist/commands/inbox.js +105 -26
  18. package/dist/commands/inbox.js.map +1 -1
  19. package/dist/commands/tags.d.ts +6 -0
  20. package/dist/commands/tags.d.ts.map +1 -0
  21. package/dist/commands/tags.js +90 -0
  22. package/dist/commands/tags.js.map +1 -0
  23. package/dist/commands/wake.d.ts +9 -0
  24. package/dist/commands/wake.d.ts.map +1 -0
  25. package/dist/commands/wake.js +198 -0
  26. package/dist/commands/wake.js.map +1 -0
  27. package/dist/dashboard/public/app.js +117 -0
  28. package/dist/dashboard/public/index.html +63 -5
  29. package/dist/dashboard/routes.d.ts.map +1 -1
  30. package/dist/dashboard/routes.js +31 -2
  31. package/dist/dashboard/routes.js.map +1 -1
  32. package/dist/lib/update-check.d.ts.map +1 -1
  33. package/dist/lib/update-check.js +6 -4
  34. package/dist/lib/update-check.js.map +1 -1
  35. package/dist/lib/watson-digest.d.ts +40 -0
  36. package/dist/lib/watson-digest.d.ts.map +1 -0
  37. package/dist/lib/watson-digest.js +164 -0
  38. package/dist/lib/watson-digest.js.map +1 -0
  39. package/dist/storage/supabase.d.ts +4 -0
  40. package/dist/storage/supabase.d.ts.map +1 -1
  41. package/dist/storage/supabase.js +57 -0
  42. package/dist/storage/supabase.js.map +1 -1
  43. package/docs/COLLAB_mappersan_mycmail_setup.md +115 -0
  44. package/docs/COLLAB_wake_close_commands.md +518 -0
  45. package/docs/CROSS_TOOL_INTEGRATION_PLAN.md +246 -0
  46. package/docs/JSON_SCHEMA_WAKE_CLOSE.md +246 -0
  47. package/docs/MYCMAIL_QUICKSTART.md +103 -0
  48. package/docs/WAKE_AGENTS_SHARED_DOC.md +1215 -0
  49. package/mcp-server/README.md +75 -69
  50. package/mcp-server/package-lock.json +2 -2
  51. package/mcp-server/package.json +5 -1
  52. package/mcp-server/postinstall.js +14 -0
  53. package/mcp-server/src/server.ts +39 -0
  54. package/mobile-app/README.md +36 -0
  55. package/mobile-app/app/compose/page.tsx +140 -0
  56. package/mobile-app/app/favicon.ico +0 -0
  57. package/mobile-app/app/globals.css +26 -0
  58. package/mobile-app/app/layout.tsx +42 -0
  59. package/mobile-app/app/message/[id]/page.tsx +126 -0
  60. package/mobile-app/app/page.tsx +131 -0
  61. package/mobile-app/components/MessageCard.tsx +60 -0
  62. package/mobile-app/eslint.config.mjs +18 -0
  63. package/mobile-app/lib/supabase.ts +87 -0
  64. package/mobile-app/next.config.ts +7 -0
  65. package/mobile-app/package-lock.json +6674 -0
  66. package/mobile-app/package.json +27 -0
  67. package/mobile-app/postcss.config.mjs +7 -0
  68. package/mobile-app/public/file.svg +1 -0
  69. package/mobile-app/public/globe.svg +1 -0
  70. package/mobile-app/public/next.svg +1 -0
  71. package/mobile-app/public/vercel.svg +1 -0
  72. package/mobile-app/public/window.svg +1 -0
  73. package/mobile-app/tsconfig.json +34 -0
  74. package/package.json +2 -1
  75. package/postinstall.js +14 -0
  76. package/src/bin/myceliumail.ts +19 -1
  77. package/src/commands/close.ts +172 -0
  78. package/src/commands/collab.ts +125 -0
  79. package/src/commands/inbox.ts +120 -29
  80. package/src/commands/tags.ts +102 -0
  81. package/src/commands/wake.ts +228 -0
  82. package/src/dashboard/public/app.js +117 -0
  83. package/src/dashboard/public/index.html +63 -5
  84. package/src/dashboard/routes.ts +31 -2
  85. package/src/lib/update-check.ts +7 -4
  86. package/src/lib/watson-digest.ts +217 -0
  87. package/src/storage/supabase.ts +71 -0
  88. package/vscode-extension/README.md +107 -0
  89. package/vscode-extension/package-lock.json +1941 -0
  90. package/vscode-extension/package.json +117 -0
  91. package/vscode-extension/src/chatParticipant.ts +179 -0
  92. package/vscode-extension/src/extension.ts +262 -0
  93. package/vscode-extension/src/handlers.ts +265 -0
  94. package/vscode-extension/src/realtime.ts +302 -0
  95. package/vscode-extension/src/types.ts +41 -0
  96. package/vscode-extension/tsconfig.json +26 -0
@@ -0,0 +1,117 @@
1
+ {
2
+ "name": "myceliumail-wake",
3
+ "displayName": "Myceliumail Wake Agent",
4
+ "description": "Real-time agent wake-up via Myceliumail messages - receive push notifications when messages arrive",
5
+ "version": "0.1.0",
6
+ "publisher": "treebird",
7
+ "engines": {
8
+ "vscode": "^1.85.0"
9
+ },
10
+ "categories": [
11
+ "AI",
12
+ "Other"
13
+ ],
14
+ "keywords": [
15
+ "ai",
16
+ "agent",
17
+ "messaging",
18
+ "myceliumail",
19
+ "realtime"
20
+ ],
21
+ "activationEvents": [
22
+ "onStartupFinished"
23
+ ],
24
+ "main": "./dist/extension.js",
25
+ "contributes": {
26
+ "configuration": {
27
+ "title": "Myceliumail Wake",
28
+ "properties": {
29
+ "myceliumail.agentId": {
30
+ "type": "string",
31
+ "default": "",
32
+ "description": "Your agent ID for receiving messages"
33
+ },
34
+ "myceliumail.supabaseUrl": {
35
+ "type": "string",
36
+ "default": "",
37
+ "description": "Supabase project URL"
38
+ },
39
+ "myceliumail.supabaseKey": {
40
+ "type": "string",
41
+ "default": "",
42
+ "description": "Supabase anon key"
43
+ },
44
+ "myceliumail.enableNotifications": {
45
+ "type": "boolean",
46
+ "default": true,
47
+ "description": "Show VS Code notifications for incoming messages"
48
+ },
49
+ "myceliumail.enableChatParticipant": {
50
+ "type": "boolean",
51
+ "default": true,
52
+ "description": "Enable @mycelium chat participant"
53
+ },
54
+ "myceliumail.autoConnect": {
55
+ "type": "boolean",
56
+ "default": true,
57
+ "description": "Automatically connect to Myceliumail on startup"
58
+ }
59
+ }
60
+ },
61
+ "commands": [
62
+ {
63
+ "command": "myceliumail.testWake",
64
+ "title": "Myceliumail: Test Wake Notification"
65
+ },
66
+ {
67
+ "command": "myceliumail.openInbox",
68
+ "title": "Myceliumail: Open Inbox"
69
+ },
70
+ {
71
+ "command": "myceliumail.reconnect",
72
+ "title": "Myceliumail: Reconnect"
73
+ },
74
+ {
75
+ "command": "myceliumail.disconnect",
76
+ "title": "Myceliumail: Disconnect"
77
+ },
78
+ {
79
+ "command": "myceliumail.showStatus",
80
+ "title": "Myceliumail: Show Connection Status"
81
+ }
82
+ ],
83
+ "chatParticipants": [
84
+ {
85
+ "id": "myceliumail.agent",
86
+ "name": "mycelium",
87
+ "fullName": "Myceliumail Agent",
88
+ "description": "Handle Myceliumail messages and agent communication",
89
+ "isSticky": false
90
+ }
91
+ ]
92
+ },
93
+ "scripts": {
94
+ "vscode:prepublish": "npm run compile",
95
+ "compile": "tsc -p ./",
96
+ "watch": "tsc -watch -p ./",
97
+ "pretest": "npm run compile",
98
+ "lint": "eslint src --ext ts",
99
+ "package": "npx vsce package"
100
+ },
101
+ "devDependencies": {
102
+ "@types/node": "^20.10.0",
103
+ "@types/vscode": "^1.85.0",
104
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
105
+ "@typescript-eslint/parser": "^6.13.0",
106
+ "eslint": "^8.55.0",
107
+ "typescript": "^5.3.0"
108
+ },
109
+ "dependencies": {
110
+ "@supabase/supabase-js": "^2.88.0"
111
+ },
112
+ "repository": {
113
+ "type": "git",
114
+ "url": "https://github.com/treebird7/myceliumail"
115
+ },
116
+ "license": "MIT"
117
+ }
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Chat Participant for Myceliumail
3
+ *
4
+ * Provides @mycelium chat participant that can:
5
+ * - Display recent messages
6
+ * - Help compose replies
7
+ * - Show message context
8
+ */
9
+
10
+ import * as vscode from 'vscode';
11
+ import { AgentMessage } from './types';
12
+
13
+ /**
14
+ * Create and register the chat participant
15
+ */
16
+ export function createChatParticipant(
17
+ context: vscode.ExtensionContext
18
+ ): vscode.ChatParticipant {
19
+ const participant = vscode.chat.createChatParticipant(
20
+ 'myceliumail.agent',
21
+ (request, chatContext, stream, token) =>
22
+ handleChatRequest(request, chatContext, stream, token, context)
23
+ );
24
+
25
+ participant.iconPath = vscode.Uri.joinPath(
26
+ context.extensionUri,
27
+ 'media',
28
+ 'mycelium-icon.png'
29
+ );
30
+
31
+ return participant;
32
+ }
33
+
34
+ /**
35
+ * Handle incoming chat requests
36
+ */
37
+ async function handleChatRequest(
38
+ request: vscode.ChatRequest,
39
+ chatContext: vscode.ChatContext,
40
+ stream: vscode.ChatResponseStream,
41
+ token: vscode.CancellationToken,
42
+ context: vscode.ExtensionContext
43
+ ): Promise<vscode.ChatResult> {
44
+ const prompt = request.prompt.toLowerCase();
45
+
46
+ // Handle different intents
47
+ if (prompt.includes('inbox') || prompt.includes('messages') || prompt.includes('list')) {
48
+ return await handleInboxRequest(stream, context);
49
+ }
50
+
51
+ if (prompt.includes('send') || prompt.includes('reply')) {
52
+ return await handleSendRequest(request.prompt, stream);
53
+ }
54
+
55
+ if (prompt.includes('status')) {
56
+ return await handleStatusRequest(stream, context);
57
+ }
58
+
59
+ // Default: show help and recent messages
60
+ return await handleDefaultRequest(request.prompt, stream, context);
61
+ }
62
+
63
+ /**
64
+ * Handle inbox/messages request
65
+ */
66
+ async function handleInboxRequest(
67
+ stream: vscode.ChatResponseStream,
68
+ context: vscode.ExtensionContext
69
+ ): Promise<vscode.ChatResult> {
70
+ const messages = context.globalState.get<AgentMessage[]>('recentMessages', []);
71
+
72
+ if (messages.length === 0) {
73
+ stream.markdown('📭 **No recent messages** in the wake inbox.\n\n');
74
+ stream.markdown('Messages will appear here when they arrive via Myceliumail.\n');
75
+ } else {
76
+ stream.markdown('## 📬 Recent Messages\n\n');
77
+
78
+ for (const msg of messages.slice(0, 10)) {
79
+ const date = new Date(msg.created_at).toLocaleString();
80
+ const preview = msg.message?.slice(0, 100) || '(no content)';
81
+
82
+ stream.markdown(`### ${getPriorityEmoji(msg.priority)} From: **${msg.from_agent}**\n`);
83
+ stream.markdown(`**Subject:** ${msg.subject || '(none)'}\n`);
84
+ stream.markdown(`**Date:** ${date}\n\n`);
85
+ stream.markdown(`> ${preview}${(msg.message?.length || 0) > 100 ? '...' : ''}\n\n`);
86
+ stream.markdown('---\n\n');
87
+ }
88
+
89
+ if (messages.length > 10) {
90
+ stream.markdown(`*...and ${messages.length - 10} more messages*\n`);
91
+ }
92
+ }
93
+
94
+ return { metadata: { command: 'inbox' } };
95
+ }
96
+
97
+ /**
98
+ * Handle send/reply request
99
+ */
100
+ async function handleSendRequest(
101
+ prompt: string,
102
+ stream: vscode.ChatResponseStream
103
+ ): Promise<vscode.ChatResult> {
104
+ stream.markdown('## ✉️ Send a Message\n\n');
105
+ stream.markdown('To send a message, use the `mycmail` CLI:\n\n');
106
+ stream.markdown('```bash\n');
107
+ stream.markdown('mycmail send <recipient> "<subject>" "<body>"\n');
108
+ stream.markdown('```\n\n');
109
+ stream.markdown('For example:\n');
110
+ stream.markdown('```bash\n');
111
+ stream.markdown('mycmail send wsan "Task Update" "Completed the migration"\n');
112
+ stream.markdown('```\n\n');
113
+ stream.markdown('Or in the terminal, run `mycmail send --help` for more options.\n');
114
+
115
+ return { metadata: { command: 'send' } };
116
+ }
117
+
118
+ /**
119
+ * Handle status request
120
+ */
121
+ async function handleStatusRequest(
122
+ stream: vscode.ChatResponseStream,
123
+ context: vscode.ExtensionContext
124
+ ): Promise<vscode.ChatResult> {
125
+ const config = vscode.workspace.getConfiguration('myceliumail');
126
+ const agentId = config.get<string>('agentId') || 'Not configured';
127
+ const messages = context.globalState.get<AgentMessage[]>('recentMessages', []);
128
+
129
+ stream.markdown('## 📊 Myceliumail Wake Status\n\n');
130
+ stream.markdown(`| Setting | Value |\n`);
131
+ stream.markdown(`|---------|-------|\n`);
132
+ stream.markdown(`| Agent ID | \`${agentId}\` |\n`);
133
+ stream.markdown(`| Notifications | ${config.get('enableNotifications') ? '✅' : '❌'} |\n`);
134
+ stream.markdown(`| Auto-connect | ${config.get('autoConnect') ? '✅' : '❌'} |\n`);
135
+ stream.markdown(`| Messages cached | ${messages.length} |\n\n`);
136
+
137
+ stream.markdown('### Commands\n');
138
+ stream.markdown('- **Myceliumail: Reconnect** - Reconnect to Supabase\n');
139
+ stream.markdown('- **Myceliumail: Open Inbox** - View cached messages\n');
140
+ stream.markdown('- **Myceliumail: Show Status** - Connection status\n');
141
+
142
+ return { metadata: { command: 'status' } };
143
+ }
144
+
145
+ /**
146
+ * Handle default/general request
147
+ */
148
+ async function handleDefaultRequest(
149
+ prompt: string,
150
+ stream: vscode.ChatResponseStream,
151
+ context: vscode.ExtensionContext
152
+ ): Promise<vscode.ChatResult> {
153
+ stream.markdown('## 🍄 Myceliumail Agent\n\n');
154
+ stream.markdown('I can help you with Myceliumail messages. Try:\n\n');
155
+ stream.markdown('- **"show inbox"** - List recent messages\n');
156
+ stream.markdown('- **"status"** - Show connection status\n');
157
+ stream.markdown('- **"how to send"** - Help with sending messages\n\n');
158
+
159
+ // If the prompt contains message content, show it
160
+ if (prompt.includes('from') || prompt.includes('message')) {
161
+ stream.markdown('---\n\n');
162
+ stream.markdown(`Received: *${prompt}*\n\n`);
163
+ stream.markdown('Would you like me to help you draft a reply?\n');
164
+ }
165
+
166
+ return { metadata: { command: 'help' } };
167
+ }
168
+
169
+ /**
170
+ * Get emoji for message priority
171
+ */
172
+ function getPriorityEmoji(priority: string): string {
173
+ switch (priority) {
174
+ case 'urgent': return '🚨';
175
+ case 'high': return '❗';
176
+ case 'low': return '📭';
177
+ default: return '📬';
178
+ }
179
+ }
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Myceliumail Wake Agent Extension
3
+ *
4
+ * Real-time agent wake-up via Myceliumail messages.
5
+ * Listens to Supabase Realtime for incoming messages and
6
+ * wakes the agent through notifications, sidebar, or chat.
7
+ */
8
+
9
+ import * as vscode from 'vscode';
10
+ import { RealtimeConnection } from './realtime';
11
+ import { handleIncomingMessage, openInbox, triggerChatAgent } from './handlers';
12
+ import { createChatParticipant } from './chatParticipant';
13
+ import { WakeConfig, ConnectionState, AgentMessage } from './types';
14
+
15
+ let connection: RealtimeConnection | null = null;
16
+ let statusBarItem: vscode.StatusBarItem | null = null;
17
+ let outputChannel: vscode.OutputChannel;
18
+
19
+ /**
20
+ * Extension activation
21
+ */
22
+ export async function activate(context: vscode.ExtensionContext): Promise<void> {
23
+ // Create output channel for logging
24
+ outputChannel = vscode.window.createOutputChannel('Myceliumail Wake');
25
+ context.subscriptions.push(outputChannel);
26
+
27
+ log('Myceliumail Wake Agent extension activated');
28
+
29
+ // Create status bar item
30
+ statusBarItem = vscode.window.createStatusBarItem(
31
+ vscode.StatusBarAlignment.Right,
32
+ 100
33
+ );
34
+ statusBarItem.command = 'myceliumail.showStatus';
35
+ context.subscriptions.push(statusBarItem);
36
+
37
+ // Register commands
38
+ registerCommands(context);
39
+
40
+ // Register chat participant if available
41
+ try {
42
+ if (typeof vscode.chat !== 'undefined' && typeof vscode.chat.createChatParticipant === 'function') {
43
+ const participant = createChatParticipant(context);
44
+ context.subscriptions.push(participant);
45
+ log('Chat participant @mycelium registered');
46
+ } else {
47
+ log('Chat participant API not available (requires VS Code 1.85+)');
48
+ }
49
+ } catch (error) {
50
+ log(`Could not register chat participant: ${error}`);
51
+ }
52
+
53
+ // Load configuration and connect
54
+ const config = loadConfiguration();
55
+
56
+ if (config.autoConnect && config.agentId && config.supabaseUrl && config.supabaseKey) {
57
+ await initializeConnection(context, config);
58
+ } else if (!config.agentId) {
59
+ updateStatusBar('disconnected', 'Not configured');
60
+ log('Agent ID not configured. Set myceliumail.agentId in settings.');
61
+ }
62
+
63
+ // Watch for configuration changes
64
+ context.subscriptions.push(
65
+ vscode.workspace.onDidChangeConfiguration(async (e) => {
66
+ if (e.affectsConfiguration('myceliumail')) {
67
+ log('Configuration changed');
68
+ const newConfig = loadConfiguration();
69
+
70
+ if (connection) {
71
+ connection.updateConfig(newConfig);
72
+ } else if (newConfig.autoConnect && newConfig.agentId) {
73
+ await initializeConnection(context, newConfig);
74
+ }
75
+ }
76
+ })
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Initialize the realtime connection
82
+ */
83
+ async function initializeConnection(
84
+ context: vscode.ExtensionContext,
85
+ config: WakeConfig
86
+ ): Promise<void> {
87
+ // Clean up existing connection
88
+ if (connection) {
89
+ connection.dispose();
90
+ }
91
+
92
+ // Create new connection
93
+ connection = new RealtimeConnection(config, outputChannel);
94
+ context.subscriptions.push(connection);
95
+
96
+ // Handle incoming messages
97
+ connection.onMessage((message) => {
98
+ handleIncomingMessage(message, config, context);
99
+ });
100
+
101
+ // Handle status changes
102
+ connection.onStatus((state) => {
103
+ updateStatusBar(state.status, state.error);
104
+ });
105
+
106
+ // Connect
107
+ await connection.connect();
108
+ }
109
+
110
+ /**
111
+ * Register extension commands
112
+ */
113
+ function registerCommands(context: vscode.ExtensionContext): void {
114
+ // Test wake notification
115
+ context.subscriptions.push(
116
+ vscode.commands.registerCommand('myceliumail.testWake', async () => {
117
+ const testMessage: AgentMessage = {
118
+ id: 'test-' + Date.now(),
119
+ from_agent: 'test-agent',
120
+ to_agent: loadConfiguration().agentId || 'you',
121
+ subject: 'Test Wake Notification',
122
+ message: 'This is a test message to verify the wake notification system is working correctly.',
123
+ encrypted: false,
124
+ read: false,
125
+ archived: false,
126
+ priority: 'normal',
127
+ message_type: 'direct',
128
+ created_at: new Date().toISOString(),
129
+ updated_at: new Date().toISOString()
130
+ };
131
+
132
+ await handleIncomingMessage(testMessage, loadConfiguration(), context);
133
+ })
134
+ );
135
+
136
+ // Open inbox
137
+ context.subscriptions.push(
138
+ vscode.commands.registerCommand('myceliumail.openInbox', () => {
139
+ openInbox(context);
140
+ })
141
+ );
142
+
143
+ // Reconnect
144
+ context.subscriptions.push(
145
+ vscode.commands.registerCommand('myceliumail.reconnect', async () => {
146
+ const config = loadConfiguration();
147
+ if (!config.agentId || !config.supabaseUrl || !config.supabaseKey) {
148
+ vscode.window.showErrorMessage(
149
+ 'Myceliumail not configured. Please set agentId, supabaseUrl, and supabaseKey in settings.'
150
+ );
151
+ return;
152
+ }
153
+
154
+ log('Manual reconnect requested');
155
+ await initializeConnection(context, config);
156
+ })
157
+ );
158
+
159
+ // Disconnect
160
+ context.subscriptions.push(
161
+ vscode.commands.registerCommand('myceliumail.disconnect', async () => {
162
+ if (connection) {
163
+ await connection.disconnect();
164
+ log('Manually disconnected');
165
+ }
166
+ })
167
+ );
168
+
169
+ // Show status
170
+ context.subscriptions.push(
171
+ vscode.commands.registerCommand('myceliumail.showStatus', () => {
172
+ const config = loadConfiguration();
173
+ const state = connection?.getState();
174
+
175
+ let statusMessage = '📊 Myceliumail Wake Status\n\n';
176
+ statusMessage += `Agent ID: ${config.agentId || '(not set)'}\n`;
177
+ statusMessage += `Connection: ${state?.status || 'not initialized'}\n`;
178
+
179
+ if (state?.lastConnected) {
180
+ statusMessage += `Last connected: ${state.lastConnected.toLocaleString()}\n`;
181
+ }
182
+ if (state?.error) {
183
+ statusMessage += `Error: ${state.error}\n`;
184
+ }
185
+
186
+ vscode.window.showInformationMessage(statusMessage, 'Open Output').then(action => {
187
+ if (action === 'Open Output') {
188
+ outputChannel.show();
189
+ }
190
+ });
191
+ })
192
+ );
193
+ }
194
+
195
+ /**
196
+ * Load configuration from VS Code settings
197
+ */
198
+ function loadConfiguration(): WakeConfig {
199
+ const config = vscode.workspace.getConfiguration('myceliumail');
200
+
201
+ return {
202
+ agentId: config.get<string>('agentId') || '',
203
+ supabaseUrl: config.get<string>('supabaseUrl') || '',
204
+ supabaseKey: config.get<string>('supabaseKey') || '',
205
+ enableNotifications: config.get<boolean>('enableNotifications', true),
206
+ enableChatParticipant: config.get<boolean>('enableChatParticipant', true),
207
+ autoConnect: config.get<boolean>('autoConnect', true)
208
+ };
209
+ }
210
+
211
+ /**
212
+ * Update status bar item
213
+ */
214
+ function updateStatusBar(status: string, error?: string | null): void {
215
+ if (!statusBarItem) return;
216
+
217
+ switch (status) {
218
+ case 'connected':
219
+ statusBarItem.text = '$(mail) Myceliumail';
220
+ statusBarItem.tooltip = 'Myceliumail: Connected and listening';
221
+ statusBarItem.backgroundColor = undefined;
222
+ break;
223
+ case 'connecting':
224
+ case 'reconnecting':
225
+ statusBarItem.text = '$(sync~spin) Myceliumail';
226
+ statusBarItem.tooltip = `Myceliumail: ${status}...`;
227
+ statusBarItem.backgroundColor = undefined;
228
+ break;
229
+ case 'disconnected':
230
+ statusBarItem.text = '$(mail) Myceliumail';
231
+ statusBarItem.tooltip = 'Myceliumail: Disconnected';
232
+ statusBarItem.backgroundColor = undefined;
233
+ break;
234
+ case 'error':
235
+ statusBarItem.text = '$(warning) Myceliumail';
236
+ statusBarItem.tooltip = `Myceliumail Error: ${error || 'Unknown error'}`;
237
+ statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
238
+ break;
239
+ default:
240
+ statusBarItem.text = '$(mail) Myceliumail';
241
+ statusBarItem.tooltip = 'Myceliumail Wake Agent';
242
+ }
243
+
244
+ statusBarItem.show();
245
+ }
246
+
247
+ /**
248
+ * Log to output channel
249
+ */
250
+ function log(message: string): void {
251
+ const timestamp = new Date().toISOString();
252
+ outputChannel.appendLine(`[${timestamp}] ${message}`);
253
+ }
254
+
255
+ /**
256
+ * Extension deactivation
257
+ */
258
+ export function deactivate(): void {
259
+ if (connection) {
260
+ connection.dispose();
261
+ }
262
+ }