@golproductions/check 1.3.2 → 1.3.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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +40 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golproductions/check",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
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,7 +6,7 @@ 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.2";
9
+ const VERSION = "1.3.4";
10
10
  const API = "https://triage.golproductions.com/preflight";
11
11
  const LOG_API = "https://triage.golproductions.com/log";
12
12
  const CLIENT_ID = process.env.GOL_CLIENT_ID || "";
@@ -155,7 +155,7 @@ function binaryExists(base) {
155
155
  } catch { return false; }
156
156
  }
157
157
 
158
- function respond(platform, allowed, reason) {
158
+ async function respond(platform, allowed, reason) {
159
159
  if (allowed) {
160
160
  const out = {
161
161
  cursor: { permission: "allow" },
@@ -163,10 +163,12 @@ function respond(platform, allowed, reason) {
163
163
  claude: { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow" } }
164
164
  };
165
165
  process.stdout.write(JSON.stringify(out[platform]));
166
+ await _logPromise;
166
167
  process.exit(0);
167
168
  }
168
169
  if (platform === "gemini") {
169
170
  process.stderr.write(reason + "\n");
171
+ await _logPromise;
170
172
  process.exit(2);
171
173
  }
172
174
  const out = {
@@ -174,9 +176,12 @@ function respond(platform, allowed, reason) {
174
176
  claude: { hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason } }
175
177
  };
176
178
  process.stdout.write(JSON.stringify(out[platform]));
179
+ await _logPromise;
177
180
  process.exit(0);
178
181
  }
179
182
 
183
+ let _logPromise = Promise.resolve();
184
+
180
185
  function logEvent(event) {
181
186
  if (!CLIENT_ID) return;
182
187
  const log = {
@@ -190,7 +195,7 @@ function logEvent(event) {
190
195
  if (event.verdict === "deny") {
191
196
  log.tokens_saved_est = 6000;
192
197
  }
193
- fetch(LOG_API, {
198
+ _logPromise = fetch(LOG_API, {
194
199
  method: "POST",
195
200
  headers: {
196
201
  "Content-Type": "application/json",
@@ -209,22 +214,46 @@ async function main() {
209
214
  input = input.replace(/^/, "").trim();
210
215
 
211
216
  let parsed;
212
- try { parsed = JSON.parse(input); } catch { respond("claude", true); return; }
217
+ try { parsed = JSON.parse(input); } catch {
218
+ logEvent({ verdict: "allow", reason: "parse_failed", binary: "", platform, cmd: input.slice(0, 100) });
219
+ respond("claude", true);
220
+ return;
221
+ }
213
222
 
214
223
  platform = detectPlatform(parsed);
215
224
  const command = extractCommand(parsed, platform);
216
- if (!command) { respond(platform, true); return; }
225
+ if (!command) {
226
+ logEvent({ verdict: "allow", reason: "no_command", binary: "", platform, cmd: "" });
227
+ respond(platform, true);
228
+ return;
229
+ }
217
230
 
218
231
  const trimmed = command.trim();
219
232
  const first = trimmed.split(/\s+/)[0];
220
233
 
221
- if (SKIP.has(first)) { respond(platform, true); return; }
234
+ if (SKIP.has(first)) {
235
+ logEvent({ verdict: "allow", reason: "skip_builtin", binary: first, platform, cmd: trimmed.slice(0, 100) });
236
+ respond(platform, true);
237
+ return;
238
+ }
222
239
 
223
240
  const toolName = parsed.tool_name;
224
241
  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; }
242
+ if (first.startsWith("$") || first.startsWith("(") || first.startsWith("[") || first.startsWith("@")) {
243
+ logEvent({ verdict: "allow", reason: "ps_syntax", binary: first.slice(0, 30), platform, cmd: trimmed.slice(0, 100) });
244
+ respond(platform, true);
245
+ return;
246
+ }
247
+ if (PS_KEYWORDS.has(first)) {
248
+ logEvent({ verdict: "allow", reason: "ps_keyword", binary: first, platform, cmd: trimmed.slice(0, 100) });
249
+ respond(platform, true);
250
+ return;
251
+ }
252
+ if (PS_VERB_PREFIXES.some(p => first.startsWith(p))) {
253
+ logEvent({ verdict: "allow", reason: "ps_cmdlet", binary: first, platform, cmd: trimmed.slice(0, 100) });
254
+ respond(platform, true);
255
+ return;
256
+ }
228
257
  }
229
258
 
230
259
  if (!CLIENT_ID) {
@@ -269,7 +298,8 @@ async function main() {
269
298
  logEvent({ verdict: "deny", reason: "api_rejected", binary: base, platform, cmd: trimmed.slice(0, 100) });
270
299
  respond(platform, false, "Check: command is invalid");
271
300
  }
272
- } catch {
301
+ } catch (e) {
302
+ logEvent({ verdict: "allow", reason: "error_fallback", binary: "", platform, cmd: String(e).slice(0, 100) });
273
303
  respond(platform, true);
274
304
  }
275
305
  }