granttap-mcp 0.8.111 → 0.8.112

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.
@@ -1,5 +1,10 @@
1
1
  # Task delivery
2
2
 
3
+ An explicit Grok Build usage-balance refusal is returned as a usage error rather
4
+ than a startup timeout or a successful answer. Both stderr exits and streaming
5
+ error events use the same explanation. Earlier confirmed response activity stays
6
+ recorded if a turn later fails; an error alone never creates admission evidence.
7
+
3
8
  This module prepares phone attachments, routes selected MCP/skill intent, and runs local agent commands. The public `reply.ts` entry point owns session queueing and agent-specific command selection.
4
9
 
5
10
  `provider-headless.ts` owns the provider-neutral headless start used when a Mesh
@@ -1,5 +1,6 @@
1
1
  import type { ReplyResult } from '../payload/types';
2
2
  import type { ProviderAdmission } from '../process';
3
+ import { providerUsageFailure } from '../process/auth-failure';
3
4
 
4
5
  function events(stdout: string): Record<string, unknown>[] {
5
6
  return stdout.split('\n').flatMap(line => {
@@ -40,7 +41,7 @@ export function parseGrok(stdout: string, fallback: string): ReplyResult {
40
41
  if (typeof event.session_id === 'string') sessionId = event.session_id;
41
42
  const error = typeof event.message === 'string' ? event.message : event.error;
42
43
  if (event.type === 'error' && typeof error === 'string') {
43
- return { ok: false, error: error.slice(0, 500) };
44
+ return { ok: false, error: providerUsageFailure(error) ?? error.slice(0, 500) };
44
45
  }
45
46
  }
46
47
  return text.trim() ? { ok: true, text: text.trim().slice(0, 4_000), sessionId }
@@ -9,3 +9,14 @@ export function providerSignInFailure(command: string, stderr: string): string |
9
9
  : executable.includes('codex') ? 'Codex' : executable.includes('cursor') ? 'Cursor' : 'the coding agent';
10
10
  return `Sign-in required for ${provider}. Open Devices, choose this computer, then Sign in for ${provider}. This message has not been submitted to the agent.`;
11
11
  }
12
+
13
+ /** Match the provider's explicit diagnostic, not an arbitrary HTTP 402 from a tool. */
14
+ export function providerUsageFailure(stderr: string): string | undefined {
15
+ if (!/\bGrok Build usage balance exhausted\b/i.test(stderr)) return;
16
+ return 'Grok usage limit reached: Grok Build usage balance exhausted. Check your Grok usage before retrying.';
17
+ }
18
+
19
+ export function providerExitFailure(command: string, stderr: string, stdout: string, code: number | null): string {
20
+ return providerUsageFailure(stderr)
21
+ ?? `${command} exited with code ${code}: ${(stderr.trim() || stdout.trim()).slice(0, 300)}`;
22
+ }
@@ -1,7 +1,7 @@
1
1
  import { spawn, type ChildProcess } from "node:child_process";
2
2
  import { delimiter, dirname } from 'node:path';
3
3
  import { realpathSync } from 'node:fs';
4
- import { providerSignInFailure } from './auth-failure';
4
+ import { providerSignInFailure, providerExitFailure } from './auth-failure';
5
5
  import { computerId } from "../../mesh/identity/computer";
6
6
  import { inspectRepository } from "../../mesh/catalog";
7
7
  import { localMeshStore } from "../../mesh/local-remote/local";
@@ -172,7 +172,7 @@ export function runProcess(
172
172
  if (code !== 0) {
173
173
  finish({
174
174
  ok: false,
175
- error: `${command} exited with code ${code}: ${(stderr.trim() || stdout.trim()).slice(0, 300)}`,
175
+ error: providerExitFailure(command, stderr, stdout, code),
176
176
  });
177
177
  return;
178
178
  }
@@ -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.111
13
+ npm install -g granttap-mcp@0.8.112
14
14
  granttap setup
15
15
  granttap status
16
16
  ```
@@ -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.111\";\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"
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.112\";\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.111";
10
+ const PACKAGE = "granttap-mcp@0.8.112";
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "granttap-mcp",
3
- "version": "0.8.111",
3
+ "version": "0.8.112",
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": {