local-mcp 3.0.164 → 3.0.166
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/download.js +16 -2
- package/package.json +1 -1
- package/setup.js +15 -5
package/download.js
CHANGED
|
@@ -10,7 +10,7 @@ const http = require('http')
|
|
|
10
10
|
const fs = require('fs')
|
|
11
11
|
const path = require('path')
|
|
12
12
|
const os = require('os')
|
|
13
|
-
const { execFileSync } = require('child_process')
|
|
13
|
+
const { execFileSync, execSync } = require('child_process')
|
|
14
14
|
|
|
15
15
|
const BACKEND_URL = 'https://office-mcp-production.up.railway.app'
|
|
16
16
|
|
|
@@ -575,7 +575,21 @@ async function _ensureTrayWindows() {
|
|
|
575
575
|
const url = `https://download.local-mcp.com/lmcp-tray.exe?v=${version}`
|
|
576
576
|
process.stderr.write(`\nDescargando tray v${version}...\n`)
|
|
577
577
|
fs.mkdirSync(binDir, { recursive: true })
|
|
578
|
-
|
|
578
|
+
|
|
579
|
+
// Download to a temp file first — if the tray is running, the exe is locked
|
|
580
|
+
// and we can't write directly to it (EBUSY). Download first, then kill, then replace.
|
|
581
|
+
const tmpPath = trayPath + '.tmp'
|
|
582
|
+
try { if (fs.existsSync(tmpPath)) fs.unlinkSync(tmpPath) } catch {}
|
|
583
|
+
await downloadFile(url, tmpPath)
|
|
584
|
+
|
|
585
|
+
// Kill the running tray (if any) before replacing the binary
|
|
586
|
+
try { execSync('taskkill /F /IM lmcp-tray.exe /T', { stdio: 'ignore' }) } catch {}
|
|
587
|
+
// Give Windows a moment to release the file handle
|
|
588
|
+
await new Promise(r => setTimeout(r, 500))
|
|
589
|
+
|
|
590
|
+
// Replace the old binary with the downloaded one
|
|
591
|
+
try { if (fs.existsSync(trayPath)) fs.unlinkSync(trayPath) } catch {}
|
|
592
|
+
fs.renameSync(tmpPath, trayPath)
|
|
579
593
|
|
|
580
594
|
const stat = fs.statSync(trayPath)
|
|
581
595
|
if (stat.size < 100000) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "local-mcp",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.166",
|
|
4
4
|
"description": "LMCP — connect Claude Desktop, Cursor, Windsurf to Mail, Calendar, Contacts, Teams, OneDrive on macOS. Privacy-first: all data stays on your Mac.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
package/setup.js
CHANGED
|
@@ -509,8 +509,18 @@ async function runSetup(opts = {}) {
|
|
|
509
509
|
|
|
510
510
|
// Interactive email prompt — uses /dev/tty so it works even from `curl | bash`
|
|
511
511
|
// (stdin is the pipe in that context; /dev/tty is always the real terminal).
|
|
512
|
-
// Non-fatal: if /dev/tty is unavailable (CI, automated scripts) we
|
|
513
|
-
|
|
512
|
+
// Non-fatal: if /dev/tty is unavailable (CI, automated scripts) we skip.
|
|
513
|
+
// ENXIO fix (LMCA-401): pre-test /dev/tty open on macOS/Linux. ENXIO means
|
|
514
|
+
// no controlling terminal (launchd, SSH -T, background process). 11 machines
|
|
515
|
+
// were logging prompt failures — this avoids the noisy error path entirely.
|
|
516
|
+
let _hasTty = _IS_WIN ? true : false
|
|
517
|
+
if (!_IS_WIN) {
|
|
518
|
+
try { const fd = fs.openSync('/dev/tty', 'r'); fs.closeSync(fd); _hasTty = true }
|
|
519
|
+
catch { /* ENXIO or ENOENT — no terminal available */ }
|
|
520
|
+
}
|
|
521
|
+
if (!email && !_hasTty) {
|
|
522
|
+
_trackEmailPrompt('skipped_no_tty', '', '')
|
|
523
|
+
} else if (!email) {
|
|
514
524
|
let emailPromptResult = 'not_shown_no_tty'
|
|
515
525
|
let emailPromptError = ''
|
|
516
526
|
try {
|
|
@@ -652,15 +662,15 @@ async function runSetup(opts = {}) {
|
|
|
652
662
|
// succeeds and the server can retry at startup.
|
|
653
663
|
if (!email) {
|
|
654
664
|
try {
|
|
655
|
-
const cfg =
|
|
665
|
+
const cfg = (_safeReadConfig(cfgFile)).data || {}
|
|
656
666
|
const alreadyLinked = (cfg.license_email && cfg.license_email.length > 0)
|
|
657
667
|
const alreadyAnon = (cfg.cloud_token && typeof cfg.cloud_token === 'string' && cfg.cloud_token.startsWith('lmcp-'))
|
|
658
668
|
if (!alreadyLinked && !alreadyAnon) {
|
|
659
669
|
const tok = await _registerAnonToken()
|
|
660
670
|
if (tok) {
|
|
661
|
-
const cfg2 =
|
|
671
|
+
const cfg2 = (_safeReadConfig(cfgFile)).data || {}
|
|
662
672
|
cfg2.cloud_token = tok
|
|
663
|
-
|
|
673
|
+
_atomicWriteConfig(cfgFile, cfg2)
|
|
664
674
|
console.log(' ✓ Cloud relay activated (anonymous)')
|
|
665
675
|
}
|
|
666
676
|
}
|