tokenizor-mcp 0.3.1 → 0.3.3

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.

Potentially problematic release.


This version of tokenizor-mcp might be problematic. Click here for more details.

@@ -1,19 +1,33 @@
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");
6
+ const os = require("os");
7
7
 
8
8
  const ext = process.platform === "win32" ? ".exe" : "";
9
- const binPath = path.join(__dirname, "tokenizor-mcp" + ext);
9
+ const installDir = path.join(os.homedir(), ".tokenizor", "bin");
10
+ const binPath = path.join(installDir, "tokenizor-mcp" + ext);
11
+ const pendingPath = path.join(installDir, "tokenizor-mcp.pending" + ext);
12
+
13
+ // Apply pending update if one was staged (binary was locked during npm update)
14
+ if (fs.existsSync(pendingPath)) {
15
+ try {
16
+ fs.renameSync(pendingPath, binPath);
17
+ console.error("tokenizor-mcp: applied pending update.");
18
+ } catch {
19
+ // Still locked — will try again next launch
20
+ }
21
+ }
10
22
 
11
23
  if (!fs.existsSync(binPath)) {
12
24
  console.error("tokenizor-mcp binary not found. Running install...");
13
25
  try {
14
- execFileSync(process.execPath, [path.join(__dirname, "..", "scripts", "install.js")], {
15
- stdio: "inherit",
16
- });
26
+ require("child_process").execFileSync(
27
+ process.execPath,
28
+ [path.join(__dirname, "..", "scripts", "install.js")],
29
+ { stdio: "inherit" }
30
+ );
17
31
  } catch {
18
32
  process.exit(1);
19
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokenizor-mcp",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Tokenizor MCP — in-memory code intelligence with parasitic hook integration for Claude Code",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -4,11 +4,15 @@
4
4
  const { execSync } = require("child_process");
5
5
  const fs = require("fs");
6
6
  const path = require("path");
7
+ const os = require("os");
7
8
  const https = require("https");
8
9
  const http = require("http");
9
10
 
10
11
  const REPO = "special-place-administrator/tokenizor_agentic_mcp";
11
- const BIN_DIR = path.join(__dirname, "..", "bin");
12
+
13
+ // Binary lives outside node_modules so npm can update the JS wrapper
14
+ // even while the MCP server holds a lock on the running .exe (Windows).
15
+ const INSTALL_DIR = path.join(os.homedir(), ".tokenizor", "bin");
12
16
 
13
17
  function getPlatformArtifact() {
14
18
  const platform = process.platform;
@@ -30,9 +34,13 @@ function getVersion() {
30
34
  }
31
35
 
32
36
  function getBinaryPath() {
33
- const artifact = getPlatformArtifact();
34
37
  const ext = process.platform === "win32" ? ".exe" : "";
35
- return path.join(BIN_DIR, "tokenizor-mcp" + ext);
38
+ return path.join(INSTALL_DIR, "tokenizor-mcp" + ext);
39
+ }
40
+
41
+ function getPendingPath() {
42
+ const ext = process.platform === "win32" ? ".exe" : "";
43
+ return path.join(INSTALL_DIR, "tokenizor-mcp.pending" + ext);
36
44
  }
37
45
 
38
46
  function download(url) {
@@ -59,7 +67,6 @@ function getInstalledVersion(binPath) {
59
67
  encoding: "utf8",
60
68
  timeout: 5000,
61
69
  }).trim();
62
- // Output format: "tokenizor-mcp x.y.z" or just "x.y.z"
63
70
  const match = output.match(/(\d+\.\d+\.\d+)/);
64
71
  return match ? match[1] : null;
65
72
  } catch {
@@ -69,19 +76,22 @@ function getInstalledVersion(binPath) {
69
76
 
70
77
  async function main() {
71
78
  const binPath = getBinaryPath();
79
+ const pendingPath = getPendingPath();
72
80
  const version = getVersion();
73
81
 
74
82
  // Skip only if binary exists AND matches the expected version
75
83
  if (fs.existsSync(binPath)) {
76
84
  const installed = getInstalledVersion(binPath);
77
85
  if (installed === version) {
78
- console.log(`tokenizor-mcp v${version} already installed.`);
86
+ try { fs.unlinkSync(pendingPath); } catch {}
87
+ console.log(`tokenizor-mcp v${version} already installed at ${binPath}`);
79
88
  return;
80
89
  }
81
90
  console.log(
82
- `tokenizor-mcp binary exists (v${installed || "unknown"}) but package wants v${version}. Updating...`
91
+ `tokenizor-mcp v${installed || "unknown"} found, updating to v${version}...`
83
92
  );
84
93
  }
94
+
85
95
  const artifact = getPlatformArtifact();
86
96
  const url = `https://github.com/${REPO}/releases/download/v${version}/${artifact}`;
87
97
 
@@ -90,12 +100,24 @@ async function main() {
90
100
 
91
101
  try {
92
102
  const data = await download(url);
93
-
94
- fs.mkdirSync(BIN_DIR, { recursive: true });
95
- fs.writeFileSync(binPath, data);
96
- fs.chmodSync(binPath, 0o755);
97
-
98
- console.log(`Installed: ${binPath}`);
103
+ fs.mkdirSync(INSTALL_DIR, { recursive: true });
104
+
105
+ try {
106
+ fs.writeFileSync(binPath, data);
107
+ fs.chmodSync(binPath, 0o755);
108
+ try { fs.unlinkSync(pendingPath); } catch {}
109
+ console.log(`Installed: ${binPath}`);
110
+ } catch (writeErr) {
111
+ // Binary locked by running MCP server — stage for 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(`Update will apply automatically on next launch.`);
117
+ } else {
118
+ throw writeErr;
119
+ }
120
+ }
99
121
  } catch (err) {
100
122
  console.error(`Failed to download binary: ${err.message}`);
101
123
  console.error("");