codeproof 1.1.0 → 1.1.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/commands/help.js CHANGED
@@ -7,21 +7,17 @@ import { formatBlock } from "../ui/formatting.js";
7
7
  const HELP_TEXT = `Usage: codeproof <command>
8
8
 
9
9
  Commands:
10
- init Initialize CodeProof in a Git repository
11
- run Run CodeProof checks
12
- report@dashboard Send latest report and show dashboard link
13
- move-secret Move high-risk secrets to .env
14
- ignore Temporarily disable commit enforcement
15
- apply Re-enable commit enforcement
16
- whoami Show the local CodeProof client ID
17
- help Show this help menu
18
- -h, --help Show this help menu
10
+ codeproof init Initialize CodeProof in a Git repository
11
+ codeproof run Run CodeProof checks
12
+ codeproof report@dashboard Send latest report and show dashboard link
13
+ codeproof move-secret Move high-risk secrets to .env
14
+ codeproof ignore Temporarily disable commit enforcement
15
+ codeproof apply Re-enable commit enforcement
16
+ codeproof whoami Show the local CodeProof client ID
17
+ codeproof help Show this help menu
18
+ codeproof -h, --help Show this help menu
19
+
19
20
 
20
- Examples:
21
- codeproof init
22
- codeproof run
23
- codeproof move-secret --yes
24
- codeproof help
25
21
  `;
26
22
 
27
23
  /**
package/commands/run.js CHANGED
@@ -13,6 +13,7 @@ import { sendReportToServer } from "../utils/apiClient.js";
13
13
  import { resolveFeatureFlags, isVerbose } from "../core/featureFlags.js";
14
14
  import { getClientId } from "../core/identity.js";
15
15
  import { getEnforcementState } from "../core/enforcement.js";
16
+ import { checkUsageOrThrow } from "../core/usageCheck.js";
16
17
  import {
17
18
  reportFeatureDisabled,
18
19
  warnExperimentalOnce,
@@ -67,6 +68,22 @@ export async function runCli({ args = [], cwd }) {
67
68
  process.exit(1);
68
69
  }
69
70
 
71
+ const clientId = getClientId();
72
+ try {
73
+ const usage = await checkUsageOrThrow({ clientId, config });
74
+ if (!usage.allowed) {
75
+ const limit = usage.limit ?? 20;
76
+ const used = usage.used ?? limit;
77
+ logError(`Free limit reached (${used}/${limit} runs/month).`);
78
+ logError("Upgrade to premium to continue.");
79
+ process.exit(1);
80
+ }
81
+ } catch (error) {
82
+ logError("Usage check failed. Unable to reach CodeProof server.");
83
+ logError(error?.message || "Usage enforcement failed.");
84
+ process.exit(1);
85
+ }
86
+
70
87
  const scanMode = String(config.scanMode).toLowerCase();
71
88
  let targets = [];
72
89
 
@@ -0,0 +1,98 @@
1
+ import http from "http";
2
+ import https from "https";
3
+
4
+ const DEFAULT_API_BASE = "http://127.0.0.1:4000/api";
5
+
6
+ function resolveApiBase(config) {
7
+ const envBase = typeof process.env.CODEPROOF_API_BASE === "string"
8
+ ? process.env.CODEPROOF_API_BASE.trim()
9
+ : "";
10
+ if (envBase) {
11
+ return envBase.replace(/\/+$/, "");
12
+ }
13
+
14
+ const endpoint = typeof config?.integration?.endpointUrl === "string"
15
+ ? config.integration.endpointUrl.trim()
16
+ : "";
17
+
18
+ if (endpoint) {
19
+ try {
20
+ const url = new URL(endpoint);
21
+ return `${url.origin}/api`;
22
+ } catch {
23
+ return DEFAULT_API_BASE;
24
+ }
25
+ }
26
+
27
+ return DEFAULT_API_BASE;
28
+ }
29
+
30
+ export async function checkUsageOrThrow({ clientId, config }) {
31
+ const apiBase = resolveApiBase(config);
32
+ const endpoint = `${apiBase}/usage/check-and-increment`;
33
+ const payload = JSON.stringify({ clientId });
34
+
35
+ return new Promise((resolve, reject) => {
36
+ try {
37
+ const url = new URL(endpoint);
38
+ const transport = url.protocol === "http:" ? http : https;
39
+ const portNumber = url.port
40
+ ? parseInt(url.port, 10)
41
+ : url.protocol === "http:"
42
+ ? 80
43
+ : 443;
44
+
45
+ const request = transport.request(
46
+ {
47
+ method: "POST",
48
+ hostname: url.hostname,
49
+ port: portNumber,
50
+ path: `${url.pathname}${url.search}`,
51
+ headers: {
52
+ "Content-Type": "application/json",
53
+ "Content-Length": Buffer.byteLength(payload),
54
+ },
55
+ timeout: 5000,
56
+ },
57
+ (res) => {
58
+ let body = "";
59
+ res.on("data", (chunk) => {
60
+ body += chunk;
61
+ });
62
+ res.on("end", () => {
63
+ if (res.statusCode !== 200) {
64
+ reject(new Error(`Usage check failed (${res.statusCode})`));
65
+ return;
66
+ }
67
+
68
+ try {
69
+ const data = body ? JSON.parse(body) : null;
70
+ if (!data || typeof data.allowed !== "boolean") {
71
+ reject(new Error("Invalid usage response"));
72
+ return;
73
+ }
74
+ resolve(data);
75
+ } catch (error) {
76
+ reject(new Error("Invalid usage response"));
77
+ }
78
+ });
79
+ res.resume();
80
+ }
81
+ );
82
+
83
+ request.on("timeout", () => {
84
+ request.destroy();
85
+ reject(new Error("Usage check timeout"));
86
+ });
87
+
88
+ request.on("error", (err) => {
89
+ reject(new Error(`Usage check error: ${err.message}`));
90
+ });
91
+
92
+ request.write(payload);
93
+ request.end();
94
+ } catch (error) {
95
+ reject(new Error("Usage check failed"));
96
+ }
97
+ });
98
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeproof",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "CodeProof CLI",
5
5
  "type": "module",
6
6
  "bin": {