tokenizor-mcp 0.3.0 → 0.3.2
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/bin/tokenizor-mcp.js +16 -4
- package/package.json +1 -1
- package/scripts/install.js +50 -9
package/bin/tokenizor-mcp.js
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
|
-
const { execFileSync } = require("child_process");
|
|
5
4
|
const fs = require("fs");
|
|
6
5
|
const path = require("path");
|
|
7
6
|
|
|
8
7
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
9
8
|
const binPath = path.join(__dirname, "tokenizor-mcp" + ext);
|
|
9
|
+
const pendingPath = path.join(__dirname, "tokenizor-mcp.pending" + ext);
|
|
10
|
+
|
|
11
|
+
// Apply pending update if one was staged (binary was locked during npm update)
|
|
12
|
+
if (fs.existsSync(pendingPath)) {
|
|
13
|
+
try {
|
|
14
|
+
fs.renameSync(pendingPath, binPath);
|
|
15
|
+
console.error("tokenizor-mcp: applied pending update.");
|
|
16
|
+
} catch {
|
|
17
|
+
// Still locked — will try again next launch
|
|
18
|
+
}
|
|
19
|
+
}
|
|
10
20
|
|
|
11
21
|
if (!fs.existsSync(binPath)) {
|
|
12
22
|
console.error("tokenizor-mcp binary not found. Running install...");
|
|
13
23
|
try {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
24
|
+
require("child_process").execFileSync(
|
|
25
|
+
process.execPath,
|
|
26
|
+
[path.join(__dirname, "..", "scripts", "install.js")],
|
|
27
|
+
{ stdio: "inherit" }
|
|
28
|
+
);
|
|
17
29
|
} catch {
|
|
18
30
|
process.exit(1);
|
|
19
31
|
}
|
package/package.json
CHANGED
package/scripts/install.js
CHANGED
|
@@ -30,11 +30,15 @@ function getVersion() {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function getBinaryPath() {
|
|
33
|
-
const artifact = getPlatformArtifact();
|
|
34
33
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
35
34
|
return path.join(BIN_DIR, "tokenizor-mcp" + ext);
|
|
36
35
|
}
|
|
37
36
|
|
|
37
|
+
function getPendingPath() {
|
|
38
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
39
|
+
return path.join(BIN_DIR, "tokenizor-mcp.pending" + ext);
|
|
40
|
+
}
|
|
41
|
+
|
|
38
42
|
function download(url) {
|
|
39
43
|
return new Promise((resolve, reject) => {
|
|
40
44
|
const client = url.startsWith("https") ? https : http;
|
|
@@ -53,16 +57,38 @@ function download(url) {
|
|
|
53
57
|
});
|
|
54
58
|
}
|
|
55
59
|
|
|
60
|
+
function getInstalledVersion(binPath) {
|
|
61
|
+
try {
|
|
62
|
+
const output = execSync(`"${binPath}" --version`, {
|
|
63
|
+
encoding: "utf8",
|
|
64
|
+
timeout: 5000,
|
|
65
|
+
}).trim();
|
|
66
|
+
const match = output.match(/(\d+\.\d+\.\d+)/);
|
|
67
|
+
return match ? match[1] : null;
|
|
68
|
+
} catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
56
73
|
async function main() {
|
|
57
74
|
const binPath = getBinaryPath();
|
|
75
|
+
const pendingPath = getPendingPath();
|
|
76
|
+
const version = getVersion();
|
|
58
77
|
|
|
59
|
-
// Skip if binary
|
|
78
|
+
// Skip only if binary exists AND matches the expected version
|
|
60
79
|
if (fs.existsSync(binPath)) {
|
|
61
|
-
|
|
62
|
-
|
|
80
|
+
const installed = getInstalledVersion(binPath);
|
|
81
|
+
if (installed === version) {
|
|
82
|
+
// Clean up any stale pending file
|
|
83
|
+
try { fs.unlinkSync(pendingPath); } catch {}
|
|
84
|
+
console.log(`tokenizor-mcp v${version} already installed.`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
console.log(
|
|
88
|
+
`tokenizor-mcp binary exists (v${installed || "unknown"}) but package wants v${version}. Updating...`
|
|
89
|
+
);
|
|
63
90
|
}
|
|
64
91
|
|
|
65
|
-
const version = getVersion();
|
|
66
92
|
const artifact = getPlatformArtifact();
|
|
67
93
|
const url = `https://github.com/${REPO}/releases/download/v${version}/${artifact}`;
|
|
68
94
|
|
|
@@ -71,12 +97,27 @@ async function main() {
|
|
|
71
97
|
|
|
72
98
|
try {
|
|
73
99
|
const data = await download(url);
|
|
74
|
-
|
|
75
100
|
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
76
|
-
fs.writeFileSync(binPath, data);
|
|
77
|
-
fs.chmodSync(binPath, 0o755);
|
|
78
101
|
|
|
79
|
-
|
|
102
|
+
// Try writing directly to the target path
|
|
103
|
+
try {
|
|
104
|
+
fs.writeFileSync(binPath, data);
|
|
105
|
+
fs.chmodSync(binPath, 0o755);
|
|
106
|
+
// Clean up any stale pending file
|
|
107
|
+
try { fs.unlinkSync(pendingPath); } catch {}
|
|
108
|
+
console.log(`Installed: ${binPath}`);
|
|
109
|
+
} catch (writeErr) {
|
|
110
|
+
// On Windows the binary may be locked by a running MCP server.
|
|
111
|
+
// Write to a .pending file — the JS wrapper will swap it in on next launch.
|
|
112
|
+
if (writeErr.code === "EPERM" || writeErr.code === "EBUSY") {
|
|
113
|
+
fs.writeFileSync(pendingPath, data);
|
|
114
|
+
fs.chmodSync(pendingPath, 0o755);
|
|
115
|
+
console.log(`Binary is locked (MCP server running). Staged update at: ${pendingPath}`);
|
|
116
|
+
console.log(`The update will apply automatically on next launch.`);
|
|
117
|
+
} else {
|
|
118
|
+
throw writeErr;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
80
121
|
} catch (err) {
|
|
81
122
|
console.error(`Failed to download binary: ${err.message}`);
|
|
82
123
|
console.error("");
|