@createsomething/ground-mcp 0.3.0 → 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.
package/README.md CHANGED
@@ -46,8 +46,41 @@ Both commands print JSON evidence. `ground diff` only returns files inside the
46
46
  requested directory and resolves Git paths from the repository root, so it is
47
47
  safe to run from a package inside a monorepo.
48
48
 
49
- The release package includes the native Apple Silicon binaries directly; other
50
- supported platforms download the matching verified release asset during install.
49
+ ### Diff coverage
50
+
51
+ Every batch, diff, and duplicate-function response has a
52
+ `verification_status`; `ground diff` also returns the same status per requested
53
+ check in `check_coverage.<check>.status`. The contract is explicit:
54
+
55
+ - `PASS`: the check completed for the relevant supported files and found no issue.
56
+ - `FAIL`: the check found an issue or could not complete because of a read/parse failure.
57
+ - `NOT_APPLICABLE`: no changed file needs that check.
58
+ - `UNSUPPORTED`: relevant source exists, but the requested check cannot analyze its language (including Svelte duplicate-function scans).
59
+ - `TIMEOUT`: duplicate analysis reached its deadline before a complete result was available.
60
+
61
+ `ground analyze` and `ground diff` accept `--timeout-ms` (120000 by default).
62
+ The MCP equivalents accept `timeout_ms`; a deadline returns `TIMEOUT`, never a
63
+ clean result. `ground diff` includes `.mjs` with JavaScript source analysis.
64
+ Its `changed_files` and `changed_file_list` fields remain the analyzable-file
65
+ view; read `discovered_changed_files`, `analyzable_changed_files`, and
66
+ `excluded_changed_files` for the full Git scope. Per-check coverage also names
67
+ `unsupported_changed_files` and `excluded_changed_files`, so a clean claim is
68
+ valid only with `PASS`.
69
+
70
+ Ground 0.3.3 keeps `ground diff`'s complete changed-file coverage and makes
71
+ source traversal deterministic and cycle-safe. Diff mode parses the complete
72
+ corpus but only compares pairs involving changed files. Standalone broad
73
+ duplicate scans retain their safety bound and report their non-pass status with
74
+ `scan_complete: false` when the bound is hit.
75
+
76
+ The release package ships thin command wrappers for every platform. Install
77
+ downloads the matching versioned release asset and verifies its SHA-256 against
78
+ that release's `SHA256SUMS` manifest before extracting it. Record the artifact
79
+ that produced a receipt with:
80
+
81
+ ```bash
82
+ ground build-info --json
83
+ ```
51
84
 
52
85
  ## The Problem
53
86
 
@@ -196,7 +229,7 @@ The npm package downloads a platform-specific binary on install. If that failed:
196
229
 
197
230
  ```bash
198
231
  # Check if the binary exists
199
- ls node_modules/@createsomething/ground-mcp/bin/
232
+ ls node_modules/@createsomething/ground-mcp/bin/native/
200
233
 
201
234
  # Re-install
202
235
  npm install @createsomething/ground-mcp
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('./run-native').runNative('ground-mcp');
package/bin/ground.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('./run-native').runNative('ground');
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,27 @@
1
+ const { spawnSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ function runNative(binaryName) {
6
+ const extension = process.platform === 'win32' ? '.exe' : '';
7
+ const binary = path.join(__dirname, 'native', `${binaryName}${extension}`);
8
+
9
+ if (!fs.existsSync(binary)) {
10
+ console.error(
11
+ `Ground MCP native binary is unavailable at ${binary}. Reinstall @createsomething/ground-mcp to complete the verified release-asset download.`
12
+ );
13
+ process.exitCode = 1;
14
+ return;
15
+ }
16
+
17
+ const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' });
18
+ if (result.error) {
19
+ console.error(`Ground MCP could not start ${binaryName}: ${result.error.message}`);
20
+ process.exitCode = 1;
21
+ return;
22
+ }
23
+
24
+ process.exitCode = result.status ?? 1;
25
+ }
26
+
27
+ module.exports = { runNative };
package/install.js CHANGED
@@ -7,10 +7,10 @@
7
7
  */
8
8
 
9
9
  const { execSync } = require('child_process');
10
+ const { createHash } = require('crypto');
10
11
  const fs = require('fs');
11
12
  const https = require('https');
12
13
  const path = require('path');
13
- const zlib = require('zlib');
14
14
 
15
15
  const REPO = 'createsomethingtoday/create-something-monorepo';
16
16
  const VERSION = require('./package.json').version;
@@ -51,20 +51,24 @@ function getDownloadUrl(binaryName, platform = process.platform) {
51
51
  return `https://github.com/${REPO}/releases/download/ground-v${VERSION}/ground-${binaryName}.${ext}`;
52
52
  }
53
53
 
54
- function hasBundledNativeBinaries() {
55
- // The npm artifact includes a release-built Apple Silicon bootstrap pair.
56
- // Other platforms continue through the release-asset downloader below.
57
- if (getPlatformKey() !== 'darwin-arm64') return false;
58
-
59
- const binDir = path.join(__dirname, 'bin');
60
- return ['ground', 'ground-mcp'].every((name) => {
61
- const binary = path.join(binDir, name);
62
- try {
63
- return fs.statSync(binary).isFile() && (fs.statSync(binary).mode & 0o111) !== 0;
64
- } catch {
65
- return false;
66
- }
67
- });
54
+ function getChecksumsUrl() {
55
+ return `https://github.com/${REPO}/releases/download/ground-v${VERSION}/SHA256SUMS`;
56
+ }
57
+
58
+ function verifyArchiveIntegrity(archive, assetName, checksums) {
59
+ const expected = checksums
60
+ .split(/\r?\n/)
61
+ .map((line) => line.trim().match(/^([a-f0-9]{64})\s+\*?(.+)$/i))
62
+ .find((match) => match?.[2] === assetName)?.[1];
63
+
64
+ if (!expected) {
65
+ throw new Error(`Release checksum manifest does not contain a checksum for ${assetName}`);
66
+ }
67
+
68
+ const actual = createHash('sha256').update(archive).digest('hex');
69
+ if (actual !== expected.toLowerCase()) {
70
+ throw new Error(`Release checksum mismatch for ${assetName}`);
71
+ }
68
72
  }
69
73
 
70
74
  async function download(url) {
@@ -119,16 +123,11 @@ async function install() {
119
123
  return;
120
124
  }
121
125
 
122
- if (hasBundledNativeBinaries()) {
123
- console.log('Ground MCP: Using bundled darwin-arm64 binaries');
124
- return;
125
- }
126
-
127
126
  console.log('Ground MCP: Installing binary...');
128
127
 
129
128
  const binaryName = getBinaryName();
130
129
  const url = getDownloadUrl(binaryName);
131
- const binDir = path.join(__dirname, 'bin');
130
+ const binDir = path.join(__dirname, 'bin', 'native');
132
131
 
133
132
  console.log(`Platform: ${getPlatformKey()}`);
134
133
  console.log(`Downloading: ${url}`);
@@ -141,6 +140,8 @@ async function install() {
141
140
 
142
141
  // Download archive
143
142
  const buffer = await download(url);
143
+ const checksums = await download(getChecksumsUrl());
144
+ verifyArchiveIntegrity(buffer, path.basename(url), checksums.toString('utf8'));
144
145
  console.log(`Downloaded ${(buffer.length / 1024 / 1024).toFixed(2)} MB`);
145
146
 
146
147
  // Extract based on platform
@@ -203,5 +204,8 @@ if (require.main === module) {
203
204
  }
204
205
 
205
206
  module.exports = {
207
+ download,
206
208
  getDownloadUrl,
209
+ getChecksumsUrl,
210
+ verifyArchiveIntegrity,
207
211
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@createsomething/ground-mcp",
3
- "version": "0.3.0",
3
+ "version": "0.3.3",
4
4
  "description": "Grounded claims for code. MCP server that prevents AI hallucination in code analysis.",
5
5
  "author": "CREATE SOMETHING <hello@createsomething.io>",
6
6
  "license": "MIT",
@@ -48,11 +48,12 @@
48
48
  "css-analysis"
49
49
  ],
50
50
  "bin": {
51
- "ground": "bin/ground",
52
- "ground-mcp": "bin/ground-mcp"
51
+ "ground": "bin/ground.js",
52
+ "ground-mcp": "bin/ground-mcp.js"
53
53
  },
54
54
  "scripts": {
55
55
  "postinstall": "node install.js",
56
+ "prepublishOnly": "node release-verify.js",
56
57
  "pilot:build": "cargo build --release --manifest-path ../Cargo.toml --bin ground --bin ground-mcp",
57
58
  "pilot:benchmark": "tsx pilot/benchmark.ts",
58
59
  "pilot:check": "tsc --noEmit -p pilot/tsconfig.json",
package/bin/.gitkeep DELETED
@@ -1,4 +0,0 @@
1
- # Binary files are downloaded during npm install
2
- # This directory will contain:
3
- # - ground-mcp (or ground-mcp.exe on Windows)
4
- # - ground (or ground.exe on Windows)
package/bin/ground DELETED
Binary file
package/bin/ground-mcp DELETED
Binary file