granttap-mcp 0.8.56 → 0.8.57
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/apps/bridge/src/capabilities/README.md +4 -0
- package/apps/bridge/src/capabilities/descriptors.ts +4 -1
- package/cursor-plugin/README.md +1 -1
- package/cursor-plugin/mcp.json +1 -1
- package/cursor-plugin/stdio-bootstrap.cjs +1 -1
- package/package.json +1 -1
- package/packages/core/outbound-scheduler/README.md +4 -0
- package/packages/core/outbound-scheduler/index.ts +4 -0
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
This module discovers provider-configured MCP servers and available skills. Metadata probing is isolated because it may start an MCP transport; local descriptors and skill discovery remain read-only.
|
|
4
4
|
|
|
5
|
+
Codex descriptor results, including failed lookups, are shared for 30 seconds.
|
|
6
|
+
A failed native CLI query retains the last known descriptors and is retried
|
|
7
|
+
after that window; it never repeats its timeout for each chat in one catalog.
|
|
8
|
+
|
|
5
9
|
Skill digests cover the bounded bundle, including scripts and references.
|
|
6
10
|
Catalog observations and Project requests do not install a skill or native MCP
|
|
7
11
|
configuration on another host. Availability requires a separate native apply
|
|
@@ -79,7 +79,10 @@ function codexMcpRows(): CodexMcpRow[] {
|
|
|
79
79
|
codexCache = { at: Date.now(), rows };
|
|
80
80
|
return rows;
|
|
81
81
|
} catch {
|
|
82
|
-
|
|
82
|
+
const rows = codexCache?.rows ?? [];
|
|
83
|
+
// One failed CLI call must not block again for every row in this catalog.
|
|
84
|
+
codexCache = { at: Date.now(), rows };
|
|
85
|
+
return rows;
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
88
|
|
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.57
|
|
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.57\";\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 20+ 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.57";
|
|
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;
|
package/package.json
CHANGED
|
@@ -7,6 +7,10 @@ replaceable snapshots. TCP write completion, bounded queued bytes, cancellation
|
|
|
7
7
|
on disconnect, and a fresh queue on reconnect prevent stale bursts from crossing
|
|
8
8
|
connection generations. No message content or keys are logged.
|
|
9
9
|
|
|
10
|
+
Disconnect rejects the current write as well as queued frames. Catalog and
|
|
11
|
+
history publishers can retry on the next connection even if the previous
|
|
12
|
+
socket never calls its write-completion callback.
|
|
13
|
+
|
|
10
14
|
Tests live in `tests/`; they include an actual WebSocket server with the relay's
|
|
11
15
|
rate limit. A socket write is transport evidence, never an approval receipt.
|
|
12
16
|
|
|
@@ -13,6 +13,7 @@ export class OutboundFrameQueue {
|
|
|
13
13
|
private snapshots: Job[] = [];
|
|
14
14
|
private bytes = 0;
|
|
15
15
|
private running = false;
|
|
16
|
+
private inFlight?: Job;
|
|
16
17
|
private closed = false;
|
|
17
18
|
private timer?: NodeJS.Timeout;
|
|
18
19
|
private nextAt = 0;
|
|
@@ -36,6 +37,7 @@ export class OutboundFrameQueue {
|
|
|
36
37
|
this.closed = true;
|
|
37
38
|
clearTimeout(this.timer);
|
|
38
39
|
this.timer = undefined;
|
|
40
|
+
this.inFlight?.reject(CLOSED());
|
|
39
41
|
for (const job of [...this.controls, ...this.snapshots]) job.reject(CLOSED());
|
|
40
42
|
this.controls = [];
|
|
41
43
|
this.snapshots = [];
|
|
@@ -53,6 +55,7 @@ export class OutboundFrameQueue {
|
|
|
53
55
|
const job = this.controls.shift() ?? this.snapshots.shift();
|
|
54
56
|
if (!job) return;
|
|
55
57
|
this.running = true;
|
|
58
|
+
this.inFlight = job;
|
|
56
59
|
this.bytes -= job.bytes;
|
|
57
60
|
try {
|
|
58
61
|
await this.write(job.frame);
|
|
@@ -60,6 +63,7 @@ export class OutboundFrameQueue {
|
|
|
60
63
|
job.resolve();
|
|
61
64
|
} catch (error) { job.reject(error instanceof Error ? error : CLOSED()); }
|
|
62
65
|
finally {
|
|
66
|
+
if (this.inFlight === job) this.inFlight = undefined;
|
|
63
67
|
this.running = false;
|
|
64
68
|
this.nextAt = performance.now() + this.intervalMs;
|
|
65
69
|
this.schedule();
|