@golproductions/check 2.4.1

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/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ GOL Productions Proprietary License
2
+
3
+ Copyright (c) 2026 GOL Productions. All rights reserved.
4
+
5
+ This software is the proprietary product of GOL Productions
6
+ ("GOL"). It is licensed, not sold.
7
+
8
+ GRANT OF LICENSE. GOL grants you a limited, non-exclusive,
9
+ non-transferable, revocable licence to use this software
10
+ exclusively with GOL's Check API service.
11
+
12
+ RESTRICTIONS. You may not:
13
+ 1. Copy, modify, or create derivative works of this software.
14
+ 2. Redistribute, sublicense, sell, or otherwise transfer this
15
+ software to any third party.
16
+ 3. Use this software with any competing command-validation or
17
+ preflight service.
18
+ 4. Reverse-engineer, decompile, or disassemble this software.
19
+
20
+ TERMINATION. This licence terminates immediately if you breach
21
+ any of its terms or if GOL revokes it at its discretion.
22
+
23
+ DISCLAIMER. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY
24
+ OF ANY KIND. GOL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED.
25
+
26
+ GOVERNING LAW. This licence is governed by the laws of the
27
+ State of Victoria, Australia.
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Check — The Anti-Hallucination Layer for AI Agents
2
+
3
+ Your AI says "done" when it isn't. Check stops that.
4
+
5
+ ## Install
6
+
7
+ One command. Every IDE.
8
+
9
+ ```
10
+ npx @golproductions/check --install your_key
11
+ ```
12
+
13
+ Auto-detects Claude Code, Gemini CLI, Antigravity, and Cursor. Writes the hook config, sets your key, done. Restart your IDE to activate.
14
+
15
+ Get your free API key at [golproductions.com/check.html](https://www.golproductions.com/check.html)
16
+
17
+ ## What it does
18
+
19
+ Check sits between your AI and the shell. Every command is verified before execution. If something is wrong, the AI knows before it speaks. No more hallucinated success, no more blind retries.
20
+
21
+ ## Pricing
22
+
23
+ $0.0068 AUD per check. 120 free checks on signup. Credits never expire.
24
+
25
+ ## Links
26
+
27
+ - [Documentation](https://www.golproductions.com/docs-triage-gate.html)
28
+ - [Pricing](https://www.golproductions.com/pricing.html)
29
+ - [VS Code extension](https://open-vsx.org/extension/golproductions/gol-check)
30
+
31
+ Copyright (c) 2026 GOL Productions. All rights reserved.
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@golproductions/check",
3
+ "version": "2.4.1",
4
+ "description": "The anti-hallucination layer for AI agents. Your AI says done when it isn't. Check stops that. Supports Claude Code, Gemini CLI, Antigravity, and Cursor.",
5
+ "bin": {
6
+ "check": "src/index.js",
7
+ "check-mcp": "src/mcp.js"
8
+ },
9
+ "type": "module",
10
+ "engines": {
11
+ "node": ">=18"
12
+ },
13
+ "files": [
14
+ "src/",
15
+ "LICENSE",
16
+ "README.md"
17
+ ],
18
+ "keywords": [
19
+ "claude-code",
20
+ "gemini-cli",
21
+ "antigravity",
22
+ "cursor",
23
+ "hooks",
24
+ "pretooluse",
25
+ "beforetool",
26
+ "beforeshellexecution",
27
+ "command-validation",
28
+ "anti-hallucination",
29
+ "firewall",
30
+ "ai-agents",
31
+ "vscode",
32
+ "openvsx",
33
+ "windsurf",
34
+ "mcp",
35
+ "model-context-protocol"
36
+ ],
37
+ "dependencies": {
38
+ "@modelcontextprotocol/sdk": "^1.12.0",
39
+ "zod": "^3.24.0"
40
+ },
41
+ "license": "SEE LICENSE IN LICENSE",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/golproductions/check.git"
45
+ },
46
+ "homepage": "https://www.golproductions.com/check.html"
47
+ }
package/src/index.js ADDED
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { homedir } from "node:os";
5
+
6
+ const VERSION = "2.4.0";
7
+ const API = "https://triage.golproductions.com/preflight";
8
+ const CLIENT_ID = process.env.GOL_CLIENT_ID || "";
9
+
10
+ function install() {
11
+ const key = process.argv[3] || process.env.GOL_CLIENT_ID || "your_key";
12
+ const home = homedir();
13
+ let installed = 0;
14
+
15
+ const scriptSrc = readFileSync(new URL(import.meta.url), "utf8");
16
+ const hooksDir = join(home, ".check");
17
+ mkdirSync(hooksDir, { recursive: true });
18
+ const scriptPath = join(hooksDir, "check.mjs");
19
+ writeFileSync(scriptPath, scriptSrc, "utf8");
20
+
21
+ const targets = [
22
+ {
23
+ name: "Claude Code",
24
+ dir: join(home, ".claude"),
25
+ file: "settings.json",
26
+ config: (existing) => {
27
+ existing.hooks = existing.hooks || {};
28
+ existing.hooks.PreToolUse = [{
29
+ matcher: "Bash|PowerShell",
30
+ hooks: [{ type: "command", command: "node", args: [scriptPath] }]
31
+ }];
32
+ existing.env = existing.env || {};
33
+ existing.env.GOL_CLIENT_ID = key;
34
+ return existing;
35
+ }
36
+ },
37
+ {
38
+ name: "Antigravity IDE",
39
+ dir: join(home, ".gemini", "config"),
40
+ file: "hooks.json",
41
+ config: (existing) => {
42
+ existing["check-gate"] = {
43
+ enabled: true,
44
+ PreToolUse: [{
45
+ matcher: "run_command",
46
+ hooks: [{ type: "command", command: "node " + scriptPath }]
47
+ }]
48
+ };
49
+ return existing;
50
+ }
51
+ },
52
+ {
53
+ name: "Cursor",
54
+ dir: join(home, ".cursor"),
55
+ file: "hooks.json",
56
+ config: (existing) => {
57
+ existing.version = existing.version || 1;
58
+ existing.hooks = existing.hooks || {};
59
+ existing.hooks.beforeShellExecution = [{
60
+ command: "node " + scriptPath
61
+ }];
62
+ return existing;
63
+ }
64
+ }
65
+ ];
66
+
67
+ for (const t of targets) {
68
+ if (!existsSync(t.dir)) continue;
69
+ const filepath = join(t.dir, t.file);
70
+ let existing = {};
71
+ try { existing = JSON.parse(readFileSync(filepath, "utf8")); } catch {}
72
+ const updated = t.config(existing);
73
+ writeFileSync(filepath, JSON.stringify(updated, null, 2) + "\n", "utf8");
74
+ installed++;
75
+ }
76
+
77
+ if (installed === 0) {
78
+ mkdirSync(join(home, ".claude"), { recursive: true });
79
+ const filepath = join(home, ".claude", "settings.json");
80
+ let existing = {};
81
+ try { existing = JSON.parse(readFileSync(filepath, "utf8")); } catch {}
82
+ const updated = targets[0].config(existing);
83
+ writeFileSync(filepath, JSON.stringify(updated, null, 2) + "\n", "utf8");
84
+ }
85
+
86
+ const agentsMd = join(process.cwd(), "AGENTS.md");
87
+ const checkRule = "Never fabricate, hallucinate, or invent values. If you don't have it, say you don't have it. No fake keys, no fake IDs, no fake paths, no fake URLs. If unsure, ask. Never guess and present it as fact.";
88
+ try {
89
+ const existing = existsSync(agentsMd) ? readFileSync(agentsMd, "utf8") : "";
90
+ if (!existing.includes("Never fabricate")) {
91
+ const prefix = existing.length > 0 ? existing.trimEnd() + "\n\n" : "";
92
+ writeFileSync(agentsMd, prefix + checkRule + "\n", "utf8");
93
+ }
94
+ } catch {}
95
+
96
+ console.log(`\nSafe travels wanderer..\n`);
97
+ process.exit(0);
98
+ }
99
+
100
+ if (process.argv.includes("--install")) { install(); }
101
+ if (process.argv.includes("--mcp")) { await import("./mcp.js"); process.exit(0); }
102
+
103
+ function detect(p) {
104
+ if (typeof p.command === "string" && !p.tool_input) return "cursor";
105
+ if (p.hook_event_name === "BeforeTool") return "gemini";
106
+ if (p.toolCall?.argumentsJson) return "antigravity";
107
+ return "claude";
108
+ }
109
+
110
+ function cmd(p, f) {
111
+ if (f === "cursor") return p.command;
112
+ if (f === "antigravity") {
113
+ try {
114
+ const a = typeof p.toolCall.argumentsJson === "string" ? JSON.parse(p.toolCall.argumentsJson) : p.toolCall.argumentsJson;
115
+ return a.command || a.CommandLine || a.command_line;
116
+ } catch { return null; }
117
+ }
118
+ return p.tool_input?.command;
119
+ }
120
+
121
+ function out(f, ok, reason) {
122
+ if (ok) {
123
+ const r = { cursor: { permission: "allow" }, gemini: { decision: "allow" }, antigravity: { decision: "allow" }, claude: { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow" } } };
124
+ process.stdout.write(JSON.stringify(r[f]));
125
+ process.exit(0);
126
+ }
127
+ if (f === "gemini" || f === "antigravity") { process.stderr.write(reason + "\n"); process.exit(2); }
128
+ const r = { cursor: { permission: "deny", user_message: reason, agent_message: reason }, claude: { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason } } };
129
+ process.stdout.write(JSON.stringify(r[f]));
130
+ process.exit(0);
131
+ }
132
+
133
+ async function main() {
134
+ let f = "claude";
135
+ try {
136
+ let input = "";
137
+ for await (const chunk of process.stdin) input += chunk;
138
+ input = input.replace(/^/, "").trim();
139
+ let p;
140
+ try { p = JSON.parse(input); } catch { out("claude", true); return; }
141
+ if (p.hook_event_name === "PostToolUse") { process.exit(0); return; }
142
+ f = detect(p);
143
+ const c = cmd(p, f);
144
+ if (!c) { out(f, true); return; }
145
+ if (!CLIENT_ID) { process.stderr.write("check: GOL_CLIENT_ID not set. Get your key at https://www.golproductions.com/check.html\n"); out(f, true); return; }
146
+ const controller = new AbortController();
147
+ const timer = setTimeout(() => controller.abort(), 5000);
148
+ const res = await fetch(API, {
149
+ method: "POST",
150
+ headers: { "Content-Type": "application/json", "X-GOL-CLIENT-ID": CLIENT_ID, "User-Agent": "c/" + VERSION },
151
+ body: JSON.stringify({ command: c, cwd: p.cwd || process.cwd(), platform: f, tool_name: p.tool_name, transcript_path: p.transcript_path, v: VERSION }),
152
+ signal: controller.signal
153
+ });
154
+ clearTimeout(timer);
155
+ const d = await res.json();
156
+ if (d.verdict === "runnable") { out(f, true); }
157
+ else { out(f, false, d.reason || "denied — address the issue before continuing"); }
158
+ } catch { out(f, true); }
159
+ }
160
+
161
+ main();
package/src/mcp.js ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import { execFile } from "node:child_process";
6
+ import { promisify } from "node:util";
7
+
8
+ const execFileAsync = promisify(execFile);
9
+ const VERSION = "2.4.0";
10
+ const API = "https://triage.golproductions.com/preflight";
11
+ const CLIENT_ID = process.env.GOL_CLIENT_ID;
12
+ const IS_WIN = process.platform === "win32";
13
+
14
+ if (!CLIENT_ID) {
15
+ process.stderr.write("check: GOL_CLIENT_ID environment variable is required.\nGet your key at https://www.golproductions.com/check.html\n");
16
+ process.exit(1);
17
+ }
18
+
19
+ async function validate(command) {
20
+ const res = await fetch(API, {
21
+ method: "POST",
22
+ headers: { "Content-Type": "application/json", "X-GOL-CLIENT-ID": CLIENT_ID, "User-Agent": "c/" + VERSION },
23
+ body: JSON.stringify({ command, v: VERSION })
24
+ });
25
+ return res.json();
26
+ }
27
+
28
+ const server = new McpServer({ name: "check", version: VERSION });
29
+
30
+ server.tool(
31
+ "Check",
32
+ "Know if a command will work before running it. Returns 'runnable' or 'invalid'. $0.0068 AUD per Check.",
33
+ { command: z.string().max(10000).describe("The shell command to validate before execution") },
34
+ async ({ command }) => {
35
+ try {
36
+ const d = await validate(command);
37
+ if (!d.verdict) return { content: [{ type: "text", text: `Error: ${d.error || "unknown"}` }], isError: true };
38
+ return { content: [{ type: "text", text: `Verdict: ${d.verdict === "runnable" ? "RUNNABLE" : "INVALID"}` }] };
39
+ } catch (err) {
40
+ return { content: [{ type: "text", text: `Check API error: ${err.message}` }], isError: true };
41
+ }
42
+ }
43
+ );
44
+
45
+ server.tool(
46
+ "CheckAndExecute",
47
+ "Validate a command with Check, then execute it if runnable. Returns the command output if valid, or blocks it.",
48
+ { command: z.string().max(10000).describe("The shell command to validate and execute") },
49
+ async ({ command }) => {
50
+ try {
51
+ const d = await validate(command);
52
+ if (d.verdict !== "runnable") return { content: [{ type: "text", text: "BLOCKED: " + (d.reason || "command is invalid") }] };
53
+ const { stdout, stderr } = await execFileAsync(IS_WIN ? "cmd" : "bash", IS_WIN ? ["/c", command] : ["-c", command], { timeout: 30000 });
54
+ return { content: [{ type: "text", text: (stdout || "") + (stderr ? "\nSTDERR: " + stderr : "") || "(no output)" }] };
55
+ } catch (err) {
56
+ if (err.stdout || err.stderr) return { content: [{ type: "text", text: `Exit ${err.code || 1}:\n${(err.stdout || "") + (err.stderr ? "\nSTDERR: " + err.stderr : "")}` }] };
57
+ return { content: [{ type: "text", text: `Error: ${err.message}` }], isError: true };
58
+ }
59
+ }
60
+ );
61
+
62
+ const transport = new StdioServerTransport();
63
+ await server.connect(transport);