myceliumail 1.0.8 → 1.0.9

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.
@@ -22,6 +22,7 @@ import { createWatchCommand } from '../commands/watch.js';
22
22
  import { createExportCommand } from '../commands/export.js';
23
23
  import { createStatusCommand } from '../commands/status.js';
24
24
  import { createActivateCommand, createLicenseStatusCommand } from '../commands/activate.js';
25
+ import { checkForUpdates } from '../lib/update-check.js';
25
26
  const program = new Command();
26
27
  program
27
28
  .name('mycmail')
@@ -49,6 +50,8 @@ program.addCommand(createStatusCommand());
49
50
  // License management
50
51
  program.addCommand(createActivateCommand());
51
52
  program.addCommand(createLicenseStatusCommand());
53
+ // Check for updates (non-blocking, runs in background)
54
+ checkForUpdates().catch(() => { });
52
55
  // Parse and run
53
56
  program.parse();
54
57
  //# sourceMappingURL=myceliumail.js.map
@@ -1 +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,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,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;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAE5F,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,wBAAwB,EAAE,CAAC,CAAC;AAC/C,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;AACzC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAE1C,qBAAqB;AACrB,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,0BAA0B,EAAE,CAAC,CAAC;AAEjD,gBAAgB;AAChB,OAAO,CAAC,KAAK,EAAE,CAAC"}
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,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,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;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,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,wBAAwB,EAAE,CAAC,CAAC;AAC/C,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;AACzC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAE1C,qBAAqB;AACrB,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,0BAA0B,EAAE,CAAC,CAAC;AAEjD,uDAAuD;AACvD,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAEnC,gBAAgB;AAChB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Update Check Module
3
+ *
4
+ * Checks npm registry for newer versions and displays update notification.
5
+ * Non-blocking, fails silently.
6
+ */
7
+ /**
8
+ * Check for updates (non-blocking)
9
+ */
10
+ export declare function checkForUpdates(): Promise<void>;
11
+ //# sourceMappingURL=update-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwEH;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAkCrD"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Update Check Module
3
+ *
4
+ * Checks npm registry for newer versions and displays update notification.
5
+ * Non-blocking, fails silently.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
8
+ import { join } from 'path';
9
+ import { homedir } from 'os';
10
+ const CONFIG_DIR = join(homedir(), '.myceliumail');
11
+ const UPDATE_CACHE = join(CONFIG_DIR, 'update-cache.json');
12
+ const PACKAGE_NAME = 'myceliumail';
13
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
14
+ /**
15
+ * Get current installed version from package.json
16
+ */
17
+ function getCurrentVersion() {
18
+ try {
19
+ // Read from the installed package
20
+ const packagePath = new URL('../package.json', import.meta.url);
21
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
22
+ return pkg.version;
23
+ }
24
+ catch {
25
+ return '0.0.0';
26
+ }
27
+ }
28
+ /**
29
+ * Load update cache
30
+ */
31
+ function loadCache() {
32
+ try {
33
+ if (existsSync(UPDATE_CACHE)) {
34
+ return JSON.parse(readFileSync(UPDATE_CACHE, 'utf-8'));
35
+ }
36
+ }
37
+ catch {
38
+ // Ignore
39
+ }
40
+ return { lastCheck: 0, latestVersion: null };
41
+ }
42
+ /**
43
+ * Save update cache
44
+ */
45
+ function saveCache(cache) {
46
+ try {
47
+ if (!existsSync(CONFIG_DIR)) {
48
+ mkdirSync(CONFIG_DIR, { recursive: true });
49
+ }
50
+ writeFileSync(UPDATE_CACHE, JSON.stringify(cache));
51
+ }
52
+ catch {
53
+ // Ignore
54
+ }
55
+ }
56
+ /**
57
+ * Compare semantic versions
58
+ */
59
+ function isNewerVersion(current, latest) {
60
+ const currentParts = current.split('.').map(Number);
61
+ const latestParts = latest.split('.').map(Number);
62
+ for (let i = 0; i < 3; i++) {
63
+ if ((latestParts[i] || 0) > (currentParts[i] || 0))
64
+ return true;
65
+ if ((latestParts[i] || 0) < (currentParts[i] || 0))
66
+ return false;
67
+ }
68
+ return false;
69
+ }
70
+ /**
71
+ * Check for updates (non-blocking)
72
+ */
73
+ export async function checkForUpdates() {
74
+ try {
75
+ const cache = loadCache();
76
+ const now = Date.now();
77
+ // Only check once per day
78
+ if (now - cache.lastCheck < CHECK_INTERVAL_MS && cache.latestVersion) {
79
+ showUpdateNotification(cache.latestVersion);
80
+ return;
81
+ }
82
+ // Fetch latest version from npm (with timeout)
83
+ const controller = new AbortController();
84
+ const timeout = setTimeout(() => controller.abort(), 3000);
85
+ const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, { signal: controller.signal });
86
+ clearTimeout(timeout);
87
+ if (!response.ok)
88
+ return;
89
+ const data = await response.json();
90
+ const latestVersion = data.version;
91
+ // Update cache
92
+ saveCache({ lastCheck: now, latestVersion });
93
+ // Show notification if newer
94
+ showUpdateNotification(latestVersion);
95
+ }
96
+ catch {
97
+ // Silent fail - don't interrupt user
98
+ }
99
+ }
100
+ /**
101
+ * Display update notification if newer version available
102
+ */
103
+ function showUpdateNotification(latestVersion) {
104
+ const currentVersion = getCurrentVersion();
105
+ if (isNewerVersion(currentVersion, latestVersion)) {
106
+ console.log('');
107
+ console.log('╭─────────────────────────────────────────────╮');
108
+ console.log(`│ 🍄 Update available: ${currentVersion} → ${latestVersion.padEnd(10)} │`);
109
+ console.log('│ Run: npm install -g myceliumail │');
110
+ console.log('╰─────────────────────────────────────────────╯');
111
+ console.log('');
112
+ }
113
+ }
114
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACnD,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;AAC3D,MAAM,YAAY,GAAG,aAAa,CAAC;AACnC,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW;AAO1D;;GAEG;AACH,SAAS,iBAAiB;IACtB,IAAI,CAAC;QACD,kCAAkC;QAClC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QAC3D,OAAO,GAAG,CAAC,OAAO,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,OAAO,CAAC;IACnB,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,SAAS;IACd,IAAI,CAAC;QACD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAC3D,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,SAAS;IACb,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,KAAkB;IACjC,IAAI,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACL,SAAS;IACb,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,OAAe,EAAE,MAAc;IACnD,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAChE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IACrE,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACjC,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,0BAA0B;QAC1B,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,iBAAiB,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACnE,sBAAsB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAC5C,OAAO;QACX,CAAC;QAED,+CAA+C;QAC/C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;QAE3D,MAAM,QAAQ,GAAG,MAAM,KAAK,CACxB,8BAA8B,YAAY,SAAS,EACnD,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAChC,CAAC;QACF,YAAY,CAAC,OAAO,CAAC,CAAC;QAEtB,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO;QAEzB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAyB,CAAC;QAC1D,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC;QAEnC,eAAe;QACf,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;QAE7C,6BAA6B;QAC7B,sBAAsB,CAAC,aAAa,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACL,qCAAqC;IACzC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,aAAqB;IACjD,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAE3C,IAAI,cAAc,CAAC,cAAc,EAAE,aAAa,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,2BAA2B,cAAc,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myceliumail",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "End-to-End Encrypted Messaging for AI Agents",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -26,6 +26,7 @@ import { createWatchCommand } from '../commands/watch.js';
26
26
  import { createExportCommand } from '../commands/export.js';
27
27
  import { createStatusCommand } from '../commands/status.js';
28
28
  import { createActivateCommand, createLicenseStatusCommand } from '../commands/activate.js';
29
+ import { checkForUpdates } from '../lib/update-check.js';
29
30
 
30
31
  const program = new Command();
31
32
 
@@ -59,6 +60,9 @@ program.addCommand(createStatusCommand());
59
60
  program.addCommand(createActivateCommand());
60
61
  program.addCommand(createLicenseStatusCommand());
61
62
 
63
+ // Check for updates (non-blocking, runs in background)
64
+ checkForUpdates().catch(() => { });
65
+
62
66
  // Parse and run
63
67
  program.parse();
64
68
 
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Update Check Module
3
+ *
4
+ * Checks npm registry for newer versions and displays update notification.
5
+ * Non-blocking, fails silently.
6
+ */
7
+
8
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { homedir } from 'os';
11
+
12
+ const CONFIG_DIR = join(homedir(), '.myceliumail');
13
+ const UPDATE_CACHE = join(CONFIG_DIR, 'update-cache.json');
14
+ const PACKAGE_NAME = 'myceliumail';
15
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
16
+
17
+ interface UpdateCache {
18
+ lastCheck: number;
19
+ latestVersion: string | null;
20
+ }
21
+
22
+ /**
23
+ * Get current installed version from package.json
24
+ */
25
+ function getCurrentVersion(): string {
26
+ try {
27
+ // Read from the installed package
28
+ const packagePath = new URL('../package.json', import.meta.url);
29
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
30
+ return pkg.version;
31
+ } catch {
32
+ return '0.0.0';
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Load update cache
38
+ */
39
+ function loadCache(): UpdateCache {
40
+ try {
41
+ if (existsSync(UPDATE_CACHE)) {
42
+ return JSON.parse(readFileSync(UPDATE_CACHE, 'utf-8'));
43
+ }
44
+ } catch {
45
+ // Ignore
46
+ }
47
+ return { lastCheck: 0, latestVersion: null };
48
+ }
49
+
50
+ /**
51
+ * Save update cache
52
+ */
53
+ function saveCache(cache: UpdateCache): void {
54
+ try {
55
+ if (!existsSync(CONFIG_DIR)) {
56
+ mkdirSync(CONFIG_DIR, { recursive: true });
57
+ }
58
+ writeFileSync(UPDATE_CACHE, JSON.stringify(cache));
59
+ } catch {
60
+ // Ignore
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Compare semantic versions
66
+ */
67
+ function isNewerVersion(current: string, latest: string): boolean {
68
+ const currentParts = current.split('.').map(Number);
69
+ const latestParts = latest.split('.').map(Number);
70
+
71
+ for (let i = 0; i < 3; i++) {
72
+ if ((latestParts[i] || 0) > (currentParts[i] || 0)) return true;
73
+ if ((latestParts[i] || 0) < (currentParts[i] || 0)) return false;
74
+ }
75
+ return false;
76
+ }
77
+
78
+ /**
79
+ * Check for updates (non-blocking)
80
+ */
81
+ export async function checkForUpdates(): Promise<void> {
82
+ try {
83
+ const cache = loadCache();
84
+ const now = Date.now();
85
+
86
+ // Only check once per day
87
+ if (now - cache.lastCheck < CHECK_INTERVAL_MS && cache.latestVersion) {
88
+ showUpdateNotification(cache.latestVersion);
89
+ return;
90
+ }
91
+
92
+ // Fetch latest version from npm (with timeout)
93
+ const controller = new AbortController();
94
+ const timeout = setTimeout(() => controller.abort(), 3000);
95
+
96
+ const response = await fetch(
97
+ `https://registry.npmjs.org/${PACKAGE_NAME}/latest`,
98
+ { signal: controller.signal }
99
+ );
100
+ clearTimeout(timeout);
101
+
102
+ if (!response.ok) return;
103
+
104
+ const data = await response.json() as { version: string };
105
+ const latestVersion = data.version;
106
+
107
+ // Update cache
108
+ saveCache({ lastCheck: now, latestVersion });
109
+
110
+ // Show notification if newer
111
+ showUpdateNotification(latestVersion);
112
+ } catch {
113
+ // Silent fail - don't interrupt user
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Display update notification if newer version available
119
+ */
120
+ function showUpdateNotification(latestVersion: string): void {
121
+ const currentVersion = getCurrentVersion();
122
+
123
+ if (isNewerVersion(currentVersion, latestVersion)) {
124
+ console.log('');
125
+ console.log('╭─────────────────────────────────────────────╮');
126
+ console.log(`│ 🍄 Update available: ${currentVersion} → ${latestVersion.padEnd(10)} │`);
127
+ console.log('│ Run: npm install -g myceliumail │');
128
+ console.log('╰─────────────────────────────────────────────╯');
129
+ console.log('');
130
+ }
131
+ }