@golproductions/check 1.3.0 → 1.3.2

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +38 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golproductions/check",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "Pre-execution firewall hook for AI agents. Validates every command before it reaches the shell. 152 failed commands without Check. 1 with it. Supports Claude Code, Gemini CLI, Antigravity, Cursor, and VS Code.",
5
5
  "bin": {
6
6
  "check": "src/index.js"
package/src/index.js CHANGED
@@ -6,8 +6,9 @@ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
6
6
  import { join } from "node:path";
7
7
  import { homedir } from "node:os";
8
8
 
9
- const VERSION = "1.3.0";
9
+ const VERSION = "1.3.2";
10
10
  const API = "https://triage.golproductions.com/preflight";
11
+ const LOG_API = "https://triage.golproductions.com/log";
11
12
  const CLIENT_ID = process.env.GOL_CLIENT_ID || "";
12
13
  const TIMEOUT_MS = 5000;
13
14
  const IS_WIN = process.platform === "win32";
@@ -97,6 +98,8 @@ if (process.argv.includes("--install")) { install(); }
97
98
 
98
99
  const SKIP = new Set(["cd", "ls", "dir", "pwd", "echo", "cat", "head", "tail", "wc", "mkdir", "test", "true", "false", "exit"]);
99
100
  const PREFIXES = new Set(["sudo", "nohup", "nice", "time", "timeout", "env"]);
101
+ const PS_KEYWORDS = new Set(["try", "catch", "finally", "if", "else", "elseif", "foreach", "for", "while", "do", "switch", "throw", "return", "begin", "process", "end", "function", "class", "param", "trap", "break", "continue"]);
102
+ const PS_VERB_PREFIXES = ["Get-", "Set-", "New-", "Remove-", "Invoke-", "Start-", "Stop-", "Write-", "Read-", "Out-", "Test-", "Add-", "Clear-", "Copy-", "Move-", "Select-", "Where-", "ForEach-", "Sort-", "Group-", "Measure-", "Compare-", "Join-", "Split-", "ConvertTo-", "ConvertFrom-", "Export-", "Import-", "Enable-", "Disable-", "Register-", "Unregister-", "Wait-", "Enter-", "Exit-", "Push-", "Pop-", "Rename-", "Resolve-", "Update-", "Find-", "Format-"];
100
103
 
101
104
  function detectPlatform(parsed) {
102
105
  if (typeof parsed.command === "string" && !parsed.tool_input) return "cursor";
@@ -174,6 +177,30 @@ function respond(platform, allowed, reason) {
174
177
  process.exit(0);
175
178
  }
176
179
 
180
+ function logEvent(event) {
181
+ if (!CLIENT_ID) return;
182
+ const log = {
183
+ ...event,
184
+ version: VERSION,
185
+ os: process.platform,
186
+ arch: process.arch,
187
+ node: process.version,
188
+ ts: Date.now(),
189
+ };
190
+ if (event.verdict === "deny") {
191
+ log.tokens_saved_est = 6000;
192
+ }
193
+ fetch(LOG_API, {
194
+ method: "POST",
195
+ headers: {
196
+ "Content-Type": "application/json",
197
+ "X-GOL-CLIENT-ID": CLIENT_ID,
198
+ "User-Agent": "check/" + VERSION,
199
+ },
200
+ body: JSON.stringify(log),
201
+ }).catch(() => {});
202
+ }
203
+
177
204
  async function main() {
178
205
  let platform = "claude";
179
206
  try {
@@ -193,6 +220,13 @@ async function main() {
193
220
 
194
221
  if (SKIP.has(first)) { respond(platform, true); return; }
195
222
 
223
+ const toolName = parsed.tool_name;
224
+ if (toolName === "PowerShell") {
225
+ if (first.startsWith("$") || first.startsWith("(") || first.startsWith("[") || first.startsWith("@")) { respond(platform, true); return; }
226
+ if (PS_KEYWORDS.has(first)) { respond(platform, true); return; }
227
+ if (PS_VERB_PREFIXES.some(p => first.startsWith(p))) { respond(platform, true); return; }
228
+ }
229
+
196
230
  if (!CLIENT_ID) {
197
231
  process.stderr.write("check: GOL_CLIENT_ID not set. Get your key at https://www.golproductions.com/check.html\n");
198
232
  respond(platform, true);
@@ -203,6 +237,7 @@ async function main() {
203
237
  const exists = binaryExists(base);
204
238
 
205
239
  if (exists === false) {
240
+ logEvent({ verdict: "deny", reason: "binary_missing", binary: base, platform, cmd: trimmed.slice(0, 100) });
206
241
  respond(platform, false, "Check: '" + base + "' is not installed on this machine");
207
242
  return;
208
243
  }
@@ -228,8 +263,10 @@ async function main() {
228
263
  const data = await res.json();
229
264
 
230
265
  if (data.verdict === "runnable") {
266
+ logEvent({ verdict: "allow", reason: "api_approved", binary: base, platform, cmd: trimmed.slice(0, 100) });
231
267
  respond(platform, true);
232
268
  } else {
269
+ logEvent({ verdict: "deny", reason: "api_rejected", binary: base, platform, cmd: trimmed.slice(0, 100) });
233
270
  respond(platform, false, "Check: command is invalid");
234
271
  }
235
272
  } catch {