@golproductions/check 3.0.4 → 3.0.6

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 +61 -24
  2. package/package.json +8 -2
  3. package/src/index.js +84 -22
package/README.md CHANGED
@@ -11,12 +11,12 @@ No AI inside. Deterministic. Same input, same output. Every time.
11
11
  One command. Every IDE.
12
12
 
13
13
  ```
14
- npx @golproductions/check --install your_key
14
+ npx @golproductions/check --install YOUR_KEY
15
15
  ```
16
16
 
17
- Auto-detects **Claude Code**, **Cursor**, and **Antigravity**. Writes the hook config, sets your key, done. Restart your IDE to activate.
17
+ Auto-detects and configures **Claude Code**, **Cursor**, **Gemini CLI / Antigravity**, and MCP servers for **Windsurf / Devin Desktop**, **Continue**, **Amazon Q**, and **Roo Code**.
18
18
 
19
- Get your free API key (120 free checks) at [golproductions.com](https://www.golproductions.com/check.html)
19
+ Get your free API key (120 free checks) at [golproductions.com/check](https://www.golproductions.com/check.html)
20
20
 
21
21
  ## What it catches
22
22
 
@@ -28,12 +28,64 @@ Get your free API key (120 free checks) at [golproductions.com](https://www.golp
28
28
  | **Broken syntax** | AI writes a file with mismatched brackets. **Flagged.** |
29
29
  | **Post-write integrity** | After the AI writes a file, imports and function calls are re-verified. **Two checkpoints.** |
30
30
 
31
+ ## Supported environments
32
+
33
+ **Hooks (automatic, pre-execution)**
34
+
35
+ | Environment | Integration |
36
+ |-------------|-------------|
37
+ | Claude Code | PreToolUse hook |
38
+ | Cursor | beforeShellExecution hook |
39
+ | Gemini CLI / Antigravity | BeforeTool hook |
40
+
41
+ **MCP Server (agent-driven)**
42
+
43
+ | Environment | Integration |
44
+ |-------------|-------------|
45
+ | Claude Code | MCP server |
46
+ | Cursor | MCP server |
47
+ | Windsurf / Devin Desktop | MCP server |
48
+ | Continue | MCP server |
49
+ | Amazon Q | MCP server |
50
+ | Roo Code | MCP server |
51
+ | Claude Desktop | MCP server |
52
+ | Any MCP client | MCP server |
53
+
54
+ **Editor plugins**
55
+
56
+ | Editor | Install |
57
+ |--------|---------|
58
+ | VS Code / Cursor / Devin Desktop | [Open VSX](https://open-vsx.org/extension/golproductions/gol-check) |
59
+ | JetBrains (IntelliJ, WebStorm, PyCharm, GoLand, Rider, PHPStorm, RubyMine) | [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/com.golproductions.check) |
60
+ | Neovim | [check.nvim](https://github.com/golproductions/check.nvim) |
61
+ | Emacs | [check.el](https://github.com/golproductions/check.el) |
62
+ | Sublime Text | [GOLCheck](https://github.com/golproductions/check-sublime) |
63
+ | Zed | [check-zed](https://github.com/golproductions/check-zed) |
64
+
65
+ **Direct API**
66
+
67
+ ```
68
+ POST https://triage.golproductions.com/preflight
69
+ ```
70
+
71
+ ## MCP Server
72
+
73
+ Run Check as an MCP server for direct agent integration:
74
+
75
+ ```
76
+ npx @golproductions/check check-mcp
77
+ ```
78
+
79
+ Exposes two tools:
80
+ - **Check** — validates a command, returns `RUNNABLE` or `INVALID`
81
+ - **CheckAndExecute** — validates then executes, blocking invalid commands before they reach the shell
82
+
31
83
  ## How it works
32
84
 
33
85
  ```
34
- AI writes code
86
+ AI generates code
35
87
  ↓
36
- Check intercepts (pre-execution hook)
88
+ Check intercepts (pre-execution)
37
89
  ↓
38
90
  Verifies against your actual project
39
91
  ↓
@@ -42,18 +94,18 @@ Real → allowed | Not real → blocked
42
94
  After file write → second verification pass
43
95
  ```
44
96
 
45
- Check runs as a **PreToolUse** and **PostToolUse** hook. Your AI never knows it's there. Sub-100ms response time.
97
+ Sub-100ms. Your AI never knows it's there.
46
98
 
47
99
  ## Why not just use another guardrail?
48
100
 
49
- | | Check | Security firewalls (AEGIS, Pipelock) | LLM guardrails (Guardrails AI, Lakera) | Eval platforms (Galileo, Braintrust) |
101
+ | | Check | Security firewalls | LLM guardrails | Eval platforms |
50
102
  |---|---|---|---|---|
51
103
  | **Checks code correctness** | Yes | No — checks safety | No — checks format | No — scores after |
52
104
  | **Knows your project** | Yes | No | No | No |
53
105
  | **Pre-execution** | Yes | Yes | Varies | No |
54
106
  | **Post-write verification** | Yes | No | No | No |
55
107
  | **No AI inside** | Yes | Varies | Uses LLMs | Uses LLMs |
56
- | **Per-check pricing** | $0.0068 AUD | Free (self-hosted) | Enterprise pricing | SaaS pricing |
108
+ | **Per-check pricing** | $0.0068 AUD | Free (self-hosted) | Enterprise | SaaS |
57
109
 
58
110
  Every other tool checks the AI. **Check checks the code.**
59
111
 
@@ -69,27 +121,12 @@ Every other tool checks the AI. **Check checks the code.**
69
121
  | $25 | ~3,676 | $0.0068 |
70
122
  | $50 | ~7,352 | $0.0068 |
71
123
 
72
- ## MCP Server
73
-
74
- Check also runs as an MCP (Model Context Protocol) server for direct integration:
75
-
76
- ```
77
- check-mcp
78
- ```
79
-
80
124
  ## Links
81
125
 
82
126
  - [Product page](https://www.golproductions.com/check.html)
83
127
  - [Pricing](https://www.golproductions.com/pricing.html)
84
128
  - [Updates](https://www.golproductions.com/updates.html)
85
-
86
- ## Supported IDEs
87
-
88
- - Claude Code
89
- - Cursor
90
- - Antigravity
91
-
92
- More coming: Windsurf, Cline, Continue, Zed, Aider, JetBrains, GitHub Copilot.
129
+ - [Blog](https://www.golproductions.com/blog/)
93
130
 
94
131
  ## License
95
132
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@golproductions/check",
3
- "version": "3.0.4",
4
- "description": "The anti-hallucination layer for AI agents. Supports Claude Code, Antigravity, and Cursor.",
3
+ "version": "3.0.6",
4
+ "description": "Anti-hallucination firewall for AI agents. Validates commands, imports, and function calls before execution. Supports Claude Code, Cursor, Gemini CLI, Windsurf, JetBrains, Neovim, Emacs, Sublime Text, Zed, and any MCP client.",
5
5
  "bin": {
6
6
  "check": "src/index.js",
7
7
  "check-mcp": "src/mcp.js"
@@ -32,6 +32,12 @@
32
32
  "cursor",
33
33
  "antigravity",
34
34
  "windsurf",
35
+ "devin-desktop",
36
+ "gemini-cli",
37
+ "amazon-q",
38
+ "continue-dev",
39
+ "roo-code",
40
+ "cline",
35
41
  "ai-guardrails",
36
42
  "llm-validation",
37
43
  "mcp",
package/src/index.js CHANGED
@@ -37,6 +37,8 @@ async function install() {
37
37
  const binaryPath = join(hooksDir, "truth-gate" + ext);
38
38
  await downloadBinary(binaryPath);
39
39
 
40
+ const mcpEntry = { command: "npx", args: ["@golproductions/check", "--mcp"], env: { GOL_CLIENT_ID: key } };
41
+
40
42
  const targets = [
41
43
  {
42
44
  name: "Claude Code",
@@ -58,17 +60,19 @@ async function install() {
58
60
  }
59
61
  },
60
62
  {
61
- name: "Antigravity IDE",
62
- dir: join(home, ".gemini", "config"),
63
- file: "hooks.json",
63
+ name: "Gemini CLI / Antigravity",
64
+ dir: join(home, ".gemini"),
65
+ file: "settings.json",
64
66
  config: (existing) => {
65
- existing["check-gate"] = {
66
- enabled: true,
67
- PreToolUse: [{
68
- matcher: "run_command",
69
- hooks: [{ type: "command", command: "node " + scriptPath }]
70
- }]
71
- };
67
+ existing.hooks = existing.hooks || {};
68
+ existing.hooks.BeforeTool = existing.hooks.BeforeTool || [];
69
+ const hooks = existing.hooks.BeforeTool;
70
+ if (!hooks.find(h => h.hooks?.some(hh => hh.name === "check-gate"))) {
71
+ hooks.push({
72
+ matcher: ".*",
73
+ hooks: [{ type: "command", command: "node " + scriptPath, name: "check-gate" }]
74
+ });
75
+ }
72
76
  return existing;
73
77
  }
74
78
  },
@@ -102,12 +106,64 @@ async function install() {
102
106
  existing.env.GOL_CLIENT_ID = key;
103
107
  return existing;
104
108
  }
109
+ },
110
+ {
111
+ name: "Windsurf (MCP)",
112
+ dir: join(home, ".codeium", "windsurf"),
113
+ file: "mcp_config.json",
114
+ config: (existing) => {
115
+ existing.mcpServers = existing.mcpServers || {};
116
+ existing.mcpServers.Check = mcpEntry;
117
+ return existing;
118
+ }
119
+ },
120
+ {
121
+ name: "Continue (MCP)",
122
+ dir: join(process.cwd(), ".continue", "mcpServers"),
123
+ file: "check.json",
124
+ config: () => {
125
+ return { mcpServers: { Check: mcpEntry } };
126
+ }
127
+ },
128
+ {
129
+ name: "Amazon Q Developer (MCP)",
130
+ dir: join(home, ".aws", "amazonq"),
131
+ file: "mcp.json",
132
+ config: (existing) => {
133
+ existing.mcpServers = existing.mcpServers || {};
134
+ existing.mcpServers.Check = { type: "stdio", ...mcpEntry };
135
+ return existing;
136
+ }
137
+ },
138
+ {
139
+ name: "Roo Code (project MCP)",
140
+ dir: join(process.cwd(), ".roo"),
141
+ file: "mcp.json",
142
+ config: (existing) => {
143
+ existing.mcpServers = existing.mcpServers || {};
144
+ existing.mcpServers.Check = mcpEntry;
145
+ return existing;
146
+ }
147
+ },
148
+ {
149
+ name: "Project MCP (shared)",
150
+ dir: process.cwd(),
151
+ file: ".mcp.json",
152
+ config: (existing) => {
153
+ existing.mcpServers = existing.mcpServers || {};
154
+ existing.mcpServers.Check = mcpEntry;
155
+ return existing;
156
+ }
105
157
  }
106
158
  ];
107
159
 
160
+ const mcpTargets = ["Windsurf (MCP)", "Continue (MCP)", "Amazon Q Developer (MCP)", "Roo Code (project MCP)", "Project MCP (shared)"];
161
+
108
162
  let hasClaude = false;
109
163
  for (const t of targets) {
110
- if (!existsSync(t.dir)) continue;
164
+ const isMcp = mcpTargets.includes(t.name);
165
+ if (!isMcp && !existsSync(t.dir)) continue;
166
+ if (isMcp) mkdirSync(t.dir, { recursive: true });
111
167
  const filepath = join(t.dir, t.file);
112
168
  let existing = {};
113
169
  try { existing = JSON.parse(readFileSync(filepath, "utf8")); } catch {}
@@ -147,31 +203,37 @@ if (process.argv.includes("--mcp")) { await import("./mcp.js"); process.exit(0);
147
203
 
148
204
  function detect(p) {
149
205
  if (typeof p.command === "string" && !p.tool_input) return "cursor";
150
- if (p.hook_event_name === "BeforeTool") return "gemini";
151
- if (p.toolCall?.argumentsJson) return "antigravity";
206
+ if (p.hook_event_name === "BeforeTool" || p.toolCall?.argumentsJson) return "gemini";
152
207
  return "claude";
153
208
  }
154
209
 
155
210
  function cmd(p, f) {
156
211
  if (f === "cursor") return p.command;
157
- if (f === "antigravity") {
158
- try {
159
- const a = typeof p.toolCall.argumentsJson === "string" ? JSON.parse(p.toolCall.argumentsJson) : p.toolCall.argumentsJson;
160
- return a.command || a.CommandLine || a.command_line;
161
- } catch { return null; }
212
+ if (f === "gemini") {
213
+ if (p.tool_input?.command) return p.tool_input.command;
214
+ if (p.toolCall?.argumentsJson) {
215
+ try {
216
+ const a = typeof p.toolCall.argumentsJson === "string" ? JSON.parse(p.toolCall.argumentsJson) : p.toolCall.argumentsJson;
217
+ return a.command || a.CommandLine || a.command_line;
218
+ } catch { return null; }
219
+ }
220
+ return null;
162
221
  }
163
222
  return p.tool_input?.command;
164
223
  }
165
224
 
166
225
  function out(f, ok, reason) {
167
226
  if (ok) {
168
- const r = { cursor: { permission: "allow" }, gemini: { decision: "allow" }, antigravity: { decision: "allow" }, claude: { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow" } } };
169
- process.stdout.write(JSON.stringify(r[f]));
227
+ const r = { cursor: { permission: "allow" }, gemini: { decision: "allow" }, claude: { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow" } } };
228
+ process.stdout.write(JSON.stringify(r[f] || r.claude));
170
229
  process.exit(0);
171
230
  }
172
- if (f === "gemini" || f === "antigravity") { process.stderr.write(reason + "\n"); process.exit(2); }
231
+ if (f === "gemini") {
232
+ process.stdout.write(JSON.stringify({ decision: "deny", reason }));
233
+ process.exit(2);
234
+ }
173
235
  const r = { cursor: { permission: "deny", user_message: reason, agent_message: reason }, claude: { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason } } };
174
- process.stdout.write(JSON.stringify(r[f]));
236
+ process.stdout.write(JSON.stringify(r[f] || r.claude));
175
237
  process.exit(0);
176
238
  }
177
239