granttap-mcp 0.8.83 → 0.8.84
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/README.md +8 -0
- package/apps/bridge/src/config/README.md +5 -1
- package/apps/bridge/src/config/index.ts +1 -0
- package/apps/bridge/src/config/runtime/node-requirement.d.mts +2 -0
- package/apps/bridge/src/config/runtime/node-requirement.mjs +15 -0
- package/apps/bridge/src/install/monitor-helper.ts +2 -2
- package/apps/mcp/src/http-service/installer.ts +3 -4
- package/bin/granttap-mcp.mjs +7 -0
- package/cursor-plugin/README.md +1 -1
- package/cursor-plugin/mcp.json +1 -1
- package/cursor-plugin/stdio-bootstrap.cjs +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -791,6 +791,14 @@ in the Apple apps. Use the support contact there for product issues. Report
|
|
|
791
791
|
security vulnerabilities through [SECURITY.md](SECURITY.md); do not put pairing
|
|
792
792
|
QR codes, credentials or private chat transcripts into public issues.
|
|
793
793
|
|
|
794
|
+
## Node.js requirement
|
|
795
|
+
|
|
796
|
+
Install the latest patched Node.js LTS release. GrantTap requires Node.js
|
|
797
|
+
22.13.0 or newer; Node.js 18 and 20 are not supported. The CLI checks this
|
|
798
|
+
before loading dependencies or changing local configuration. The npm `engines`
|
|
799
|
+
field also reports this requirement, but npm may only warn unless engine checks
|
|
800
|
+
are enforced by the installer.
|
|
801
|
+
|
|
794
802
|
## Development
|
|
795
803
|
|
|
796
804
|
```bash
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
# Bridge Configuration
|
|
2
2
|
|
|
3
3
|
This module owns local runtime policy, exact-session capability controls, paths,
|
|
4
|
-
and device pairing serialization.
|
|
4
|
+
and device pairing serialization. `index.ts` is its public entry point.
|
|
5
5
|
|
|
6
6
|
Behavior is covered by `tests/config.test.ts`, `tests/capabilities.test.ts`, and
|
|
7
7
|
`tests/core.test.ts`.
|
|
8
8
|
|
|
9
9
|
License: this module is distributed under the GrantTap Commercial Source License
|
|
10
10
|
in the repository-root `LICENSE` file.
|
|
11
|
+
|
|
12
|
+
Runtime startup and persistent OAuth share `runtime/node-requirement.mjs`, which
|
|
13
|
+
reads the package Node minimum before loading TypeScript dependencies. Runtime
|
|
14
|
+
compatibility regressions live in `runtime/tests/node-requirement.test.ts`.
|
|
@@ -4,6 +4,7 @@ export * from "./access/pairing";
|
|
|
4
4
|
export { writePrivateFile } from "./access/write-private";
|
|
5
5
|
export * from "./runtime/paths";
|
|
6
6
|
export * from "./runtime";
|
|
7
|
+
export { isSupportedNode, minimumNodeVersion } from "./runtime/node-requirement.mjs";
|
|
7
8
|
export {
|
|
8
9
|
classifyAction,
|
|
9
10
|
isSafeReadonlyShell,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
const manifest = JSON.parse(readFileSync(new URL("../../../../../package.json", import.meta.url), "utf8"));
|
|
4
|
+
export const minimumNodeVersion = manifest.engines.node.replace(/^>=/, "");
|
|
5
|
+
|
|
6
|
+
/** Shared by the native launcher and persistent-service installer before loading tsx. */
|
|
7
|
+
export function isSupportedNode(version) {
|
|
8
|
+
if (!/^v?\d+\.\d+\.\d+$/.test(version)) return false;
|
|
9
|
+
const actual = version.replace(/^v/, "").split(".").map(Number);
|
|
10
|
+
const minimum = minimumNodeVersion.split(".").map(Number);
|
|
11
|
+
for (let index = 0; index < 3; index += 1) {
|
|
12
|
+
if (actual[index] !== minimum[index]) return actual[index] > minimum[index];
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
@@ -209,13 +209,13 @@ export function installMonitorHelper(): InstallResult {
|
|
|
209
209
|
const node = resolveMonitorNodeBin();
|
|
210
210
|
return node && !isCursorHelperNode(node)
|
|
211
211
|
? installLinuxService("monitor", node, join(repoRoot, "bin", "granttap-mcp.mjs"), { forceReload: true })
|
|
212
|
-
: { status: "manual", detail: "A stable Node.js
|
|
212
|
+
: { status: "manual", detail: "A stable Node.js 22.13.0+ installation is required for Linux background sync." };
|
|
213
213
|
}
|
|
214
214
|
if (process.platform === "win32") {
|
|
215
215
|
const node = resolveMonitorNodeBin();
|
|
216
216
|
return node && !isCursorHelperNode(node)
|
|
217
217
|
? installWindowsTask("monitor", node, join(repoRoot, "bin", "granttap-mcp.mjs"), true)
|
|
218
|
-
: { status: "manual", detail: "A stable Node.js
|
|
218
|
+
: { status: "manual", detail: "A stable Node.js 22.13.0+ installation is required for Windows background sync." };
|
|
219
219
|
}
|
|
220
220
|
if (process.platform !== "darwin") {
|
|
221
221
|
return { status: "manual", detail: "background task sync currently requires macOS" };
|
|
@@ -4,7 +4,7 @@ import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileS
|
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import { isCursorHelperNode, resolveMonitorNodeBin, type InstallResult } from "../../../bridge/src/install";
|
|
7
|
-
import { configDir, normalizeRelayUrl, loadRuntimeConfig, verifiableEngine } from "../../../bridge/src/config";
|
|
7
|
+
import { configDir, normalizeRelayUrl, loadRuntimeConfig, verifiableEngine, isSupportedNode, minimumNodeVersion } from "../../../bridge/src/config";
|
|
8
8
|
import { installWindowsTask } from "../../../bridge/src/install/windows-service";
|
|
9
9
|
import { installLinuxService } from "../../../bridge/src/install/linux-service";
|
|
10
10
|
import { configuredCursorHttpMcpUrl } from "../cursor-config";
|
|
@@ -65,9 +65,8 @@ function validateInstallation(nodeBin: string, executable: string): InstallResul
|
|
|
65
65
|
return { status: "manual", detail: "Authorization requires a stable granttap-mcp install; npm's temporary _npx cache is not durable." };
|
|
66
66
|
}
|
|
67
67
|
const version = spawnSync(nodeBin, ["--version"], { encoding: "utf8" });
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
? { status: "manual", detail: `Persistent OAuth requires Node 20+ (${nodeBin}).` }
|
|
68
|
+
return version.status !== 0 || !isSupportedNode(version.stdout.trim())
|
|
69
|
+
? { status: "manual", detail: `Persistent OAuth requires Node ${minimumNodeVersion}+ (${nodeBin}).` }
|
|
71
70
|
: undefined;
|
|
72
71
|
}
|
|
73
72
|
|
package/bin/granttap-mcp.mjs
CHANGED
|
@@ -5,6 +5,13 @@ import { createRequire } from "node:module";
|
|
|
5
5
|
import { delimiter, dirname, join } from "node:path";
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
7
|
|
|
8
|
+
import { isSupportedNode, minimumNodeVersion } from "../apps/bridge/src/config/runtime/node-requirement.mjs";
|
|
9
|
+
|
|
10
|
+
if (!isSupportedNode(process.versions.node)) {
|
|
11
|
+
process.stderr.write(`[granttap-mcp] requires Node.js ${minimumNodeVersion} or newer; found ${process.versions.node}. Install the latest supported Node.js LTS release.\n`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
9
16
|
const [command = "mcp", ...commandArgs] = process.argv.slice(2);
|
|
10
17
|
const argument = commandArgs[0];
|
package/cursor-plugin/README.md
CHANGED
|
@@ -10,7 +10,7 @@ keeps each phone response tied to the exact originating chat and prompt.
|
|
|
10
10
|
Install the supported CLI on this computer, then run:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npm install -g granttap-mcp@0.8.
|
|
13
|
+
npm install -g granttap-mcp@0.8.84
|
|
14
14
|
granttap setup
|
|
15
15
|
granttap status
|
|
16
16
|
```
|
package/cursor-plugin/mcp.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"command": "node",
|
|
5
5
|
"args": [
|
|
6
6
|
"-e",
|
|
7
|
-
"\"use strict\";\n\n// Cursor may start this MCP from any cwd. Execute JavaScript entry points with\n// Node itself: Windows batch shims require shell quoting that differs by host.\nconst { spawn } = require(\"node:child_process\");\nconst { existsSync } = require(\"node:fs\");\nconst { delimiter, dirname, join } = require(\"node:path\");\n\nconst PACKAGE = \"granttap-mcp@0.8.
|
|
7
|
+
"\"use strict\";\n\n// Cursor may start this MCP from any cwd. Execute JavaScript entry points with\n// Node itself: Windows batch shims require shell quoting that differs by host.\nconst { spawn } = require(\"node:child_process\");\nconst { existsSync } = require(\"node:fs\");\nconst { delimiter, dirname, join } = require(\"node:path\");\n\nconst PACKAGE = \"granttap-mcp@0.8.84\";\nconst dryRun = process.env.GRANTTAP_BOOTSTRAP_DRY_RUN === \"1\";\nconst platform = dryRun && process.env.GRANTTAP_BOOTSTRAP_PLATFORM\n ? process.env.GRANTTAP_BOOTSTRAP_PLATFORM : process.platform;\nconst nodeRoot = dryRun && process.env.GRANTTAP_BOOTSTRAP_NODE_ROOT\n ? process.env.GRANTTAP_BOOTSTRAP_NODE_ROOT : dirname(process.execPath);\nconst pathRoots = (process.env.PATH || \"\").split(delimiter).filter(Boolean);\nconst appData = process.env.APPDATA;\nconst roots = [nodeRoot, ...pathRoots, ...(appData ? [join(appData, \"npm\")] : [])];\nconst first = (paths) => paths.find((path) => existsSync(path));\n\nfunction launch() {\n if (platform !== \"win32\") {\n const installed = first(roots.map((root) => join(root, \"granttap-mcp\")));\n if (installed) return { command: installed, args: [] };\n const npx = first(roots.map((root) => join(root, \"npx\"))) || \"npx\";\n return { command: npx, args: [\"-y\", PACKAGE] };\n }\n const installed = first(roots.map((root) =>\n join(root, \"node_modules\", \"granttap-mcp\", \"bin\", \"granttap-mcp.mjs\")));\n if (installed) return { command: process.execPath, args: [installed] };\n const npx = first(roots.map((root) =>\n join(root, \"node_modules\", \"npm\", \"bin\", \"npx-cli.js\")));\n if (npx) return { command: process.execPath, args: [npx, \"-y\", PACKAGE] };\n throw new Error(\"Node.js/npm 22.13.0+ is required on this Windows device. Install npm and retry GrantTap.\");\n}\n\nlet target;\ntry { target = launch(); }\ncatch (error) {\n process.stderr.write(`[granttap] ${error.message}\\n`);\n process.exit(1);\n}\n\nif (dryRun) {\n process.stdout.write(JSON.stringify(target));\n process.exit(0);\n}\n\nconst child = spawn(target.command, target.args, { stdio: \"inherit\", windowsHide: true });\nchild.on(\"error\", (error) => {\n process.stderr.write(`[granttap] ${error.message}\\n`);\n process.exit(1);\n});\nchild.on(\"exit\", (code, signal) => {\n if (signal && platform !== \"win32\") {\n try { process.kill(process.pid, signal); } catch { process.exit(code ?? 1); }\n return;\n }\n process.exit(code ?? 1);\n});\n"
|
|
8
8
|
]
|
|
9
9
|
}
|
|
10
10
|
}
|
|
@@ -7,7 +7,7 @@ const { spawn } = require("node:child_process");
|
|
|
7
7
|
const { existsSync } = require("node:fs");
|
|
8
8
|
const { delimiter, dirname, join } = require("node:path");
|
|
9
9
|
|
|
10
|
-
const PACKAGE = "granttap-mcp@0.8.
|
|
10
|
+
const PACKAGE = "granttap-mcp@0.8.84";
|
|
11
11
|
const dryRun = process.env.GRANTTAP_BOOTSTRAP_DRY_RUN === "1";
|
|
12
12
|
const platform = dryRun && process.env.GRANTTAP_BOOTSTRAP_PLATFORM
|
|
13
13
|
? process.env.GRANTTAP_BOOTSTRAP_PLATFORM : process.platform;
|
|
@@ -31,7 +31,7 @@ function launch() {
|
|
|
31
31
|
const npx = first(roots.map((root) =>
|
|
32
32
|
join(root, "node_modules", "npm", "bin", "npx-cli.js")));
|
|
33
33
|
if (npx) return { command: process.execPath, args: [npx, "-y", PACKAGE] };
|
|
34
|
-
throw new Error("Node.js/npm
|
|
34
|
+
throw new Error("Node.js/npm 22.13.0+ is required on this Windows device. Install npm and retry GrantTap.");
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
let target;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "granttap-mcp",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.84",
|
|
4
4
|
"description": "Commercial computer runtime connecting local coding agents to GrantTap on Mac, iPhone, iPad and Apple Watch.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"typescript": "^5.7.2"
|
|
56
56
|
},
|
|
57
57
|
"engines": {
|
|
58
|
-
"node": ">=
|
|
58
|
+
"node": ">=22.13.0"
|
|
59
59
|
},
|
|
60
60
|
"repository": {
|
|
61
61
|
"type": "git",
|