@golproductions/check 3.1.2 → 3.1.4

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.
Files changed (3) hide show
  1. package/README.md +19 -6
  2. package/package.json +1 -1
  3. package/src/index.js +42 -8
package/README.md CHANGED
@@ -7,12 +7,10 @@ No AI inside. Deterministic. Sub-100ms.
7
7
  ## Install
8
8
 
9
9
  ```
10
- npx @golproductions/check --install YOUR_KEY
10
+ npx @golproductions/check --install
11
11
  ```
12
12
 
13
- One command. Auto-detects your environment and configures everything.
14
-
15
- 120 free checks on signup at [golproductions.com/check](https://www.golproductions.com/check.html)
13
+ One command. It auto-detects your AI tools, wires them up, and activates a free key on first run. No signup, no API key to paste, no browser.
16
14
 
17
15
  ## Supported environments
18
16
 
@@ -20,16 +18,31 @@ Claude Code, Cursor, Gemini CLI, Windsurf, Devin Desktop, Continue, Amazon Q, Ro
20
18
 
21
19
  ## Pricing
22
20
 
23
- $0.0068 AUD per check. No subscription. Credits never expire.
21
+ 120 free checks every day. After that, $0.0068 AUD per check. No subscription. Credits never expire.
24
22
 
25
23
  | Tier | Checks |
26
24
  |------|--------|
27
- | Free | 120 |
25
+ | Free | 120 / day |
28
26
  | $5 | ~735 |
29
27
  | $10 | ~1,470 |
30
28
  | $25 | ~3,676 |
31
29
  | $50 | ~7,352 |
32
30
 
31
+ ## Bring your own key (optional)
32
+
33
+ A key is minted for you automatically. If you already have a Client ID, or want the same one across machines, set it and Check uses that instead:
34
+
35
+ ```
36
+ export GOL_CLIENT_ID=your_key
37
+ ```
38
+
39
+ ## Manage
40
+
41
+ ```
42
+ npx @golproductions/check --status Show your client ID and where Check is installed
43
+ npx @golproductions/check --uninstall Remove Check from every tool
44
+ ```
45
+
33
46
  ## Links
34
47
 
35
48
  - [Product page](https://www.golproductions.com/check.html)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golproductions/check",
3
- "version": "3.1.2",
3
+ "version": "3.1.4",
4
4
  "description": "The universal anti-hallucination engine for AI coding agents. Catches what is not real before it reaches your project.",
5
5
  "bin": {
6
6
  "check": "src/index.js",
package/src/index.js CHANGED
@@ -5,7 +5,7 @@ import { homedir, platform, arch } from "node:os";
5
5
  import { pipeline } from "node:stream/promises";
6
6
  import { Readable } from "node:stream";
7
7
 
8
- const VERSION = "3.1.2";
8
+ const VERSION = "3.1.4";
9
9
  const BINARY_VERSION = "3.0.0";
10
10
  const API = "https://triage.golproductions.com/preflight";
11
11
  const CDN = "https://pub-e55366a7f5994be9be04f0e205179f4a.r2.dev/releases";
@@ -37,6 +37,35 @@ async function validateKey(key) {
37
37
  }
38
38
  }
39
39
 
40
+ // Stable anonymous device fingerprint: one-way hash of coarse machine facts.
41
+ // No personal data. Server uses it only to rate-limit free-key minting.
42
+ async function deviceFingerprint() {
43
+ const { createHash } = await import("node:crypto");
44
+ const { hostname, userInfo } = await import("node:os");
45
+ let user = "";
46
+ try { user = userInfo().username || ""; } catch {}
47
+ const seed = [hostname(), platform(), arch(), user].join("|");
48
+ return createHash("sha256").update(seed).digest("hex");
49
+ }
50
+
51
+ // Mint a free key with no email and no browser. Returns the client_id or null.
52
+ async function mintInstantKey() {
53
+ try {
54
+ const fp = await deviceFingerprint();
55
+ const res = await fetch(API.replace("/preflight", "/instant-key"), {
56
+ method: "POST",
57
+ headers: { "Content-Type": "application/json", "User-Agent": "c/" + VERSION },
58
+ body: JSON.stringify({ fingerprint: fp, channel: "npm" }),
59
+ signal: AbortSignal.timeout(10000),
60
+ });
61
+ if (!res.ok) return null;
62
+ const d = await res.json();
63
+ return d && d.client_id ? d.client_id : null;
64
+ } catch {
65
+ return null;
66
+ }
67
+ }
68
+
40
69
  async function downloadBinary(dest) {
41
70
  const os = platform() === "win32" ? "win" : platform() === "darwin" ? "macos" : "linux";
42
71
  const cpu = arch() === "arm64" ? "arm64" : "x64";
@@ -49,14 +78,19 @@ async function downloadBinary(dest) {
49
78
  }
50
79
 
51
80
  async function install() {
52
- const key = process.argv[3] || process.env.GOL_CLIENT_ID || "";
81
+ let key = process.argv[3] || process.env.GOL_CLIENT_ID || "";
53
82
 
83
+ // No key provided: mint one instantly. No email, no browser, no copy-paste.
54
84
  if (!key || key === "your_key") {
55
- console.log("\n Check requires a valid Client ID to install.\n");
56
- console.log(" Get your key (free): https://golproductions.com/check\n");
57
- console.log(" Then run:");
58
- console.log(" npx @golproductions/check --install YOUR_KEY\n");
59
- process.exit(1);
85
+ console.log("\n Activating Check (free, no signup)...\n");
86
+ key = await mintInstantKey();
87
+ if (!key) {
88
+ console.log(" Could not activate automatically (offline, or this network hit its daily limit).\n");
89
+ console.log(" Get a key the manual way: https://golproductions.com/check\n");
90
+ console.log(" Then run: npx @golproductions/check --install YOUR_KEY\n");
91
+ process.exit(1);
92
+ }
93
+ console.log(" Activated. 120 free checks per day.\n");
60
94
  }
61
95
 
62
96
  const result = await validateKey(key);
@@ -642,7 +676,7 @@ async function main() {
642
676
  const res = await fetch(API, {
643
677
  method: "POST",
644
678
  headers: { "Content-Type": "application/json", "X-GOL-CLIENT-ID": CLIENT_ID, "User-Agent": "c/" + VERSION },
645
- body: JSON.stringify({ command: c, cwd: p.cwd || process.cwd(), platform: f, tool_name: p.tool_name, transcript_path: p.transcript_path, v: VERSION }),
679
+ body: JSON.stringify({ command: c, cwd: p.cwd || process.cwd(), platform: f, channel: "npm", tool_name: p.tool_name, transcript_path: p.transcript_path, v: VERSION }),
646
680
  signal: controller.signal
647
681
  });
648
682
  clearTimeout(timer);