granttap-mcp 0.8.80 → 0.8.82

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 CHANGED
@@ -32,11 +32,11 @@ checkout. Received previews remain on the device for offline inspection.
32
32
  Messages sent to a chat open in Codex Desktop continue that same conversation,
33
33
  including while a turn is running. The runtime forwards them to the existing
34
34
  desktop owner and preserves the delivery ID across retries. **Pause** reaches
35
- that owner too. A confirmed receipt means Codex accepted the message; its answer
36
- then arrives through the existing chat history.
35
+ that owner too. A provider acceptance receipt means Codex accepted the message; its answer
36
+ then arrives through the existing chat history. Relay storage is a separate stage.
37
37
 
38
38
  The MCP runtime, plugins, and CLI use the GrantTap Commercial Source License.
39
- Product use requires authorized GrantTap account access; official TestFlight
39
+ Managed service use requires authorized GrantTap account access; official TestFlight
40
40
  access remains free. Earlier releases through 0.8.75 retain their Apache-2.0
41
41
  permissions. The Apple apps, Engine, relay, and website have their own terms.
42
42
 
@@ -44,6 +44,76 @@ permissions. The Apple apps, Engine, relay, and website have their own terms.
44
44
  [Security model](SECURITY.md) ·
45
45
  [Relay source](https://github.com/sergii-ziborov/granttap-relay)
46
46
 
47
+ ## Start here
48
+
49
+ - [Connect your computer and devices](#account-mesh-and-devices)
50
+ - [Choose a connection mode and plan](#plans-and-what-you-pay-for)
51
+ - [Provider support](#supported-providers)
52
+ - [Install provider integrations](#install)
53
+ - [Messages, queues and decisions](#messages-queues-and-decisions)
54
+ - [Project Mesh and task transfer](#project-mesh-and-task-handoff)
55
+ - [Approvals and questions](#decisions-and-claude-questions)
56
+ - [Security and relay boundary](#relay-boundary)
57
+ - [Troubleshooting and help](#troubleshooting-and-help)
58
+ - [License](#license)
59
+
60
+ ## Plans and what you pay for
61
+
62
+ Planned US prices for the first commercial release:
63
+
64
+ | Plan | Monthly price | Managed publishing computers |
65
+ | --- | ---: | ---: |
66
+ | Personal | $4.99 | 2 |
67
+ | Personal Plus | $7.99 | 5 |
68
+ | Fleet | $13.99 | 15 |
69
+
70
+ The same core GrantTap features are included in every monthly plan. A computer
71
+ running several supported agents still uses one publishing-computer seat.
72
+ iPhone, iPad, Apple Watch and Macs used only as controllers do not use additional
73
+ execution-computer seats. Fleet is a larger personal allowance, without an
74
+ enterprise SLA or a per-person license.
75
+
76
+ An eligible new Apple subscription starts with **7 days free**, then renews
77
+ monthly at the price shown by Apple. To avoid renewal, cancel at least 24 hours
78
+ before the trial ends in Apple's subscription settings.
79
+ A local cache is not deleted when managed access ends.
80
+
81
+ **Official TestFlight builds include all features without a purchase or
82
+ subscription.** A trial and TestFlight access are different forms of access.
83
+ Paid products are still being prepared for commercial launch; the App Store
84
+ purchase sheet determines availability, localized prices, eligibility and terms.
85
+ Models, AI tokens and coding-provider plans are purchased separately.
86
+
87
+ **Mac Local is a separate $39.99 one-time purchase** for local control and an
88
+ own relay. Hosted managed delivery is not included in that purchase. An active
89
+ Personal subscription already covers a managed Mac client; both purchases are
90
+ not required for the same managed mode. npm distributes the computer runtime;
91
+ it does not sell an independent subscription or unlock a hosted entitlement.
92
+
93
+ See [current pricing](https://granttap.com/pricing),
94
+ [terms](https://granttap.com/terms) and [Help / FAQ](https://granttap.com/support).
95
+
96
+ ## Messages, queues and decisions
97
+
98
+ 1. The controller encrypts the message or decision and submits it to the relay.
99
+ 2. A **relay storage receipt** confirms that the relay saved it durably. The
100
+ computer can be asleep or offline at this point.
101
+ 3. The computer receives the packet when connected, routes it to the intended
102
+ Task/execution and reports provider acceptance, failure or a required decision.
103
+ 4. The provider's answer returns through the existing conversation.
104
+
105
+ A saved message does not mean the agent has started. Queue and delivery stages
106
+ remain distinct; bounded storage, retention, access checks and service limits
107
+ can reject a submission with an explicit error. A controller does not need to
108
+ wait for the execution computer before showing a confirmed relay save.
109
+
110
+ Use **Queue** to inspect waiting deliveries, **Send now** for an eligible queued
111
+ entry, and the available cancel action to stop a pending delivery. Delivery IDs
112
+ survive retries so a transport retry is not a request to run the prompt twice.
113
+ An already accepted or completed provider operation cannot be undone by deleting
114
+ its local queue card. Provider-wide deny rules always take precedence over a
115
+ mobile approval, including workspace and native-tool restrictions.
116
+
47
117
  ## Account Mesh and devices
48
118
 
49
119
  The passkey Account Mesh is the person's relay space. It exists with zero
@@ -84,7 +154,7 @@ device pairing without a passkey account.
84
154
  ## Supported providers
85
155
 
86
156
  - Claude Code and Codex: primary local control and continuation paths.
87
- - Cursor: Task visibility and supported local controls, with narrower coverage.
157
+ - Cursor (Beta): Task visibility and supported local controls, with narrower coverage.
88
158
  - Grok Build: observable work where the installed runtime exposes it.
89
159
 
90
160
  GrantTap reports the depth each provider actually exposes. Visibility does not
@@ -542,8 +612,8 @@ is still plain `Shell`.
542
612
 
543
613
  The Mesh keys a computer by an identity written down once, on first use, in
544
614
  `computer.json` in the config directory — the hostname it had then — and
545
- keeps it. A Mac renamed by the network it joins ("Mac.lan" at home,
546
- "Serhiis-MacBook-Pro.local" elsewhere) used to become a second computer with
615
+ keeps it. A Mac renamed by the network it joins ("workstation.home" on one network,
616
+ "workstation.local" elsewhere) used to become a second computer with
547
617
  its own open executions and repository bindings; now every later hostname is
548
618
  remembered as a former name of the same machine, its leftover executions are
549
619
  closed and its bindings marked unavailable, and the current hostname stays
@@ -679,6 +749,38 @@ APNs carries a content-neutral wake only. It contains no prompt, task title,
679
749
  command, path, request ID, or ciphertext. See [SECURITY.md](SECURITY.md) for the
680
750
  complete boundary and reporting instructions.
681
751
 
752
+ ## Troubleshooting and help
753
+
754
+ - **Computer not visible:** run `granttap status`, check the helper is running,
755
+ then check Devices in the controller. The same passkey links the same account;
756
+ a display name or IP address is not a computer identity.
757
+ - **Mac asks for local access:** complete GrantTap's local consent flow for the
758
+ installed helper. A provider OAuth login and granting the Mac app local access
759
+ serve different purposes.
760
+ - **Message saved while the computer is offline:** keep the queued entry. A
761
+ relay receipt confirms storage, while the agent can continue only when its
762
+ execution computer and provider become available.
763
+ - **An approval cannot be completed:** open the exact Task and inspect its native
764
+ restriction or pending form. GrantTap cannot override a provider's global deny.
765
+ - **History or Agents missing:** check that the execution is routed to the right
766
+ computer and update both the helper and controller. Nested agents stay inside
767
+ their parent Task; they are not separate root Tasks.
768
+ - **Health has no current architecture:** check the reported checkout and Engine
769
+ on the publishing computer, then request a rebuild. An old or partial report
770
+ remains inspectable and must not be treated as verified current architecture.
771
+ - **No purchase shown:** the product may not be released in that storefront.
772
+ TestFlight does not require a purchase. Use Restore Purchases for an existing
773
+ Apple purchase and the same GrantTap passkey for account access.
774
+
775
+ Update the helper with `npm install -g granttap-mcp@latest`, then reopen the
776
+ coding-provider integration if it still runs an older process. Keep existing
777
+ pairings; resetting an account or removing local history is not an update step.
778
+
779
+ [Help and connection pictures](https://granttap.com/support) are also available
780
+ in the Apple apps. Use the support contact there for product issues. Report
781
+ security vulnerabilities through [SECURITY.md](SECURITY.md); do not put pairing
782
+ QR codes, credentials or private chat transcripts into public issues.
783
+
682
784
  ## Development
683
785
 
684
786
  ```bash
@@ -324,8 +324,8 @@ hasown 2.0.4 — MIT
324
324
  Source: https://www.npmjs.com/package/hasown/v/2.0.4
325
325
  Notices: bf9b0d665be2a689851eea667ca9f42066ea1d903b38349c51e6a44b2577680a
326
326
 
327
- hono 4.13.7 — MIT
328
- Source: https://www.npmjs.com/package/hono/v/4.13.7
327
+ hono 4.13.13 — MIT
328
+ Source: https://www.npmjs.com/package/hono/v/4.13.13
329
329
  Notices: a6ab98e5c77b9070c443eaff2ff81034a6f8cc05a7524d5098eb0f24defa0115
330
330
 
331
331
  http-errors 2.0.1 — MIT
@@ -0,0 +1,20 @@
1
+ # Repository graph delivery
2
+
3
+ [Runtime entry point](../engine-projects.ts) · [Wire fitting](fit.ts)
4
+
5
+ The encrypted Mesh snapshot carries bounded, observed repository metadata.
6
+ `fitRepositoryGraph` preserves file identities, measured LOC and source sections.
7
+ When directed file links dominate the wire budget, it reduces those links before
8
+ discarding source sections. The bounded sample keeps links reaching previously
9
+ unrepresented files and external services, then fills in original report order.
10
+ It never invents links, reverses their direction, or edits the engine report.
11
+
12
+ Remaining reductions retain the existing wire limit and mark partial evidence.
13
+ The persistent cache keeps a last successful bounded report through an MCP
14
+ restart while the normal observation refresh obtains current engine evidence.
15
+
16
+ Behavior tests live in `tests/`; runtime and cache integration scenarios remain
17
+ under the repository's `tests/engine` harness.
18
+
19
+ License: this module is distributed under the GrantTap Commercial Source License
20
+ in the repository-root `LICENSE` file.
@@ -16,7 +16,12 @@ export function fitRepositoryGraph(
16
16
  }
17
17
  while (bytes() > maxBytes) {
18
18
  const map = bounded.codeMap;
19
- if (map?.files.some((file) => file.symbols.length > 0)) {
19
+ // Dense import graphs must not consume the source-section budget. Keep
20
+ // observed directed links across the inventory before reducing symbols.
21
+ if (map && map.roads.length > 16
22
+ && Buffer.byteLength(JSON.stringify(map.roads), "utf8") > maxBytes / 3) {
23
+ bounded = { ...bounded, codeMap: trimRoads(map) };
24
+ } else if (map?.files.some((file) => file.symbols.length > 0)) {
20
25
  bounded = { ...bounded, codeMap: trimSymbols(map) };
21
26
  } else if (bounded.relations.length > 8) {
22
27
  bounded = { ...bounded, relations: strongestRelations(bounded.relations,
@@ -27,8 +32,7 @@ export function fitRepositoryGraph(
27
32
  bounded = { ...bounded, nodes, relations: bounded.relations.filter((edge) =>
28
33
  ids.has(edge.source) && ids.has(edge.target)), truncated: true };
29
34
  } else if (map && map.roads.length > 16) {
30
- bounded = { ...bounded, codeMap: { ...map, truncated: true,
31
- roads: map.roads.slice(0, Math.ceil(map.roads.length / 2)) } };
35
+ bounded = { ...bounded, codeMap: trimRoads(map) };
32
36
  } else if (map && map.files.length > 8) {
33
37
  bounded = { ...bounded, codeMap: trimFiles(map) };
34
38
  } else if (map) {
@@ -40,6 +44,20 @@ export function fitRepositoryGraph(
40
44
  return bounded;
41
45
  }
42
46
 
47
+ function trimRoads(map: CodeMap): CodeMap {
48
+ const limit = Math.max(16, Math.ceil(map.roads.length / 2));
49
+ const kept = new Set<number>(), endpoints = new Set<string>();
50
+ for (const [index, road] of map.roads.entries()) {
51
+ if (kept.size === limit) break;
52
+ if (endpoints.has(road.source) && endpoints.has(road.target)) continue;
53
+ kept.add(index);
54
+ endpoints.add(road.source);
55
+ endpoints.add(road.target);
56
+ }
57
+ for (let index = 0; kept.size < limit; index++) kept.add(index);
58
+ return { ...map, truncated: true, roads: map.roads.filter((_, index) => kept.has(index)) };
59
+ }
60
+
43
61
  function strongestRelations(relations: Relation[], limit: number): Relation[] {
44
62
  return relations.map((edge, index) => ({ edge, index }))
45
63
  .sort((left, right) => (right.edge.evidenceCount ?? 0) - (left.edge.evidenceCount ?? 0)
@@ -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.80
13
+ npm install -g granttap-mcp@0.8.82
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.80\";\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"
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.82\";\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.80";
10
+ const PACKAGE = "granttap-mcp@0.8.82";
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.80",
3
+ "version": "0.8.82",
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": {