@commitguard/cli 0.0.13 → 0.0.15
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/README.md +167 -0
- package/dist/index.mjs +64 -43
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# CommitGuard
|
|
2
|
+
|
|
3
|
+
Protect your codebase with every commit. CommitGuard automatically analyzes your code for security vulnerabilities, performance issues, and code quality problems before they enter your repository. Grab your free API key at https://commitguard.ai.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Get CommitGuard running in under 60 seconds. It works seamlessly with any git repository and integrates automatically with VSCode and other git clients.
|
|
8
|
+
|
|
9
|
+
### Quick Start
|
|
10
|
+
|
|
11
|
+
**1. Install CommitGuard globally**
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @commitguard/cli
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**2. Navigate to your project**
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd your-project
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**3. Initialize CommitGuard**
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
commitguard init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**4. Commit as usual**
|
|
30
|
+
|
|
31
|
+
CommitGuard now runs automatically on every commit. It works with all git integrations including VSCode, terminal, and other git clients.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git commit -m "Add new feature"
|
|
35
|
+
[CommitGuard] Analyzing commit...
|
|
36
|
+
✓ Commit passed all checks
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
### Bypassing Checks
|
|
42
|
+
|
|
43
|
+
To bypass CommitGuard checks for a specific commit, add `--skip` to your commit message:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
git commit -m "Add new feature --skip"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The `--skip` flag is automatically removed from the final commit message. When using git in your terminal, you'll be prompted to confirm if you want to bypass checks.
|
|
50
|
+
|
|
51
|
+
### Configuring Checks
|
|
52
|
+
|
|
53
|
+
View or update CommitGuard preferences for your repository:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
commitguard config
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
On the Pro plan, you can add custom rules through the config comand.
|
|
60
|
+
|
|
61
|
+
## CLI Commands
|
|
62
|
+
|
|
63
|
+
### `commitguard init`
|
|
64
|
+
|
|
65
|
+
Install CommitGuard in your current repository.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
$ commitguard init
|
|
69
|
+
✓ CommitGuard installed successfully
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `commitguard remove`
|
|
73
|
+
|
|
74
|
+
Remove CommitGuard from the current repository.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
$ commitguard remove
|
|
78
|
+
✓ CommitGuard removed
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `commitguard config`
|
|
82
|
+
|
|
83
|
+
View or update CommitGuard preferences for the current repository. Pro plan users can add custom rules.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
$ commitguard config
|
|
87
|
+
Select enabled checks for this project:
|
|
88
|
+
Security, Performance, Code Quality, Architecture
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `commitguard keys`
|
|
92
|
+
|
|
93
|
+
Manage your global API key for CommitGuard.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
$ commitguard keys
|
|
97
|
+
Current API key: sk-ant-***************
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## What Happens After Installation?
|
|
101
|
+
|
|
102
|
+
- Every commit is analyzed before it's created.
|
|
103
|
+
- No config files are added to your project
|
|
104
|
+
- Bypass checks anytime with `--skip` in your commit message
|
|
105
|
+
- Works seamlessly with all git clients and IDEs
|
|
106
|
+
|
|
107
|
+
## Troubleshooting
|
|
108
|
+
|
|
109
|
+
<details>
|
|
110
|
+
<summary><strong>CommitGuard isn't running on commits</strong></summary>
|
|
111
|
+
|
|
112
|
+
Try reinstalling the hooks:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
commitguard remove
|
|
116
|
+
commitguard init
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Verify that the hooks are installed:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
ls -la .git/hooks/
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
You should see a `pre-commit` hook file.
|
|
126
|
+
</details>
|
|
127
|
+
|
|
128
|
+
<details>
|
|
129
|
+
<summary><strong>How do I skip a single commit?</strong></summary>
|
|
130
|
+
|
|
131
|
+
Add `--skip` to your commit message:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
git commit -m "Emergency fix --skip"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The `--skip` flag is automatically removed from the final message.
|
|
138
|
+
</details>
|
|
139
|
+
|
|
140
|
+
<details>
|
|
141
|
+
<summary><strong>How do I completely remove CommitGuard?</strong></summary>
|
|
142
|
+
|
|
143
|
+
Remove the hooks and uninstall the package:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
commitguard remove
|
|
147
|
+
npm uninstall -g @commitguard/cli
|
|
148
|
+
```
|
|
149
|
+
</details>
|
|
150
|
+
|
|
151
|
+
## Features
|
|
152
|
+
|
|
153
|
+
- **Security Analysis** - Detect vulnerabilities before they reach your repo
|
|
154
|
+
- **Performance Checks** - Identify performance bottlenecks early
|
|
155
|
+
- **Code Quality** - Maintain consistent code standards
|
|
156
|
+
- **Architecture Review** - Ensure architectural patterns are followed
|
|
157
|
+
- **Zero Configuration** - Works out of the box
|
|
158
|
+
- **Universal Compatibility** - Works with any git workflow
|
|
159
|
+
-- **Custom Rules** - Add your own custom checks to the code reviews
|
|
160
|
+
|
|
161
|
+
## Support
|
|
162
|
+
|
|
163
|
+
For issues, feature requests, or questions related to this package please open an issue or email us at hello@commitguard.ai
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT
|
package/dist/index.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import stringWidth from "string-width";
|
|
|
17
17
|
import "dotenv/config";
|
|
18
18
|
|
|
19
19
|
//#region package.json
|
|
20
|
-
var version = "0.0.
|
|
20
|
+
var version = "0.0.15";
|
|
21
21
|
var package_default = {
|
|
22
22
|
name: "@commitguard/cli",
|
|
23
23
|
type: "module",
|
|
@@ -347,54 +347,75 @@ async function manageGlobalKey() {
|
|
|
347
347
|
|
|
348
348
|
//#endregion
|
|
349
349
|
//#region src/utils/api.ts
|
|
350
|
-
|
|
350
|
+
const DEFAULT_TIMEOUT = 2e4;
|
|
351
|
+
async function sendToCommitGuard(diff, eslint, config$1) {
|
|
351
352
|
const apiKey = process.env.COMMITGUARD_API_KEY || getGlobalKey() || null;
|
|
352
353
|
if (!apiKey) throw new Error("No API key found. Set one globally with \"commitguard keys\" or add COMMITGUARD_API_KEY to your .env file. Get your free API key at https://commitguard.ai");
|
|
353
354
|
const apiUrl = process.env.COMMITGUARD_API_URL || "https://api.commitguard.ai/v1/analyze";
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
"
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
355
|
+
const controller = new AbortController();
|
|
356
|
+
const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
|
|
357
|
+
try {
|
|
358
|
+
const response = await fetch(apiUrl, {
|
|
359
|
+
method: "POST",
|
|
360
|
+
headers: {
|
|
361
|
+
"Content-Type": "application/json",
|
|
362
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
363
|
+
"User-Agent": "commitguard-cli"
|
|
364
|
+
},
|
|
365
|
+
body: JSON.stringify({
|
|
366
|
+
diff,
|
|
367
|
+
eslint,
|
|
368
|
+
config: config$1
|
|
369
|
+
}),
|
|
370
|
+
signal: controller.signal
|
|
371
|
+
});
|
|
372
|
+
clearTimeout(timeoutId);
|
|
373
|
+
if (!response.ok) {
|
|
374
|
+
const errorText = await response.text();
|
|
375
|
+
let errorMessage = "Failed to analyze commit";
|
|
376
|
+
if (response.status === 401) errorMessage = "Invalid API key. Check your key with \"commitguard keys\" or get a new one at https://commitguard.ai";
|
|
377
|
+
else if (response.status === 429) errorMessage = "Rate limit exceeded. Please try again later";
|
|
378
|
+
else if (response.status === 500) errorMessage = "CommitGuard service error. Please try again later";
|
|
379
|
+
else if (response.status >= 400 && response.status < 500) errorMessage = `Request error: ${errorText || "Invalid request"}`;
|
|
380
|
+
else errorMessage = `Service unavailable (${response.status}). Please try again later`;
|
|
381
|
+
throw new Error(errorMessage);
|
|
382
|
+
}
|
|
383
|
+
return await response.json();
|
|
384
|
+
} catch (error) {
|
|
385
|
+
clearTimeout(timeoutId);
|
|
386
|
+
if (error instanceof Error && error.name === "AbortError") throw new Error(`Request timed out after ${DEFAULT_TIMEOUT}ms`);
|
|
387
|
+
throw error;
|
|
376
388
|
}
|
|
377
|
-
return await response.json();
|
|
378
389
|
}
|
|
379
390
|
async function bypassCommitGuard() {
|
|
380
391
|
const apiKey = process.env.COMMITGUARD_API_KEY || getGlobalKey() || null;
|
|
381
392
|
if (!apiKey) throw new Error("No API key found. Set one globally with \"commitguard keys\" or add COMMITGUARD_API_KEY to your .env file. Get your free API key at https://commitguard.ai");
|
|
382
393
|
const apiUrl = process.env.COMMITGUARD_API_BYPASS_URL || "https://api.commitguard.ai/v1/bypass";
|
|
383
394
|
const diff = getLastDiff();
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
"
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
395
|
+
const controller = new AbortController();
|
|
396
|
+
const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);
|
|
397
|
+
try {
|
|
398
|
+
const response = await fetch(apiUrl, {
|
|
399
|
+
method: "POST",
|
|
400
|
+
headers: {
|
|
401
|
+
"Content-Type": "application/json",
|
|
402
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
403
|
+
"User-Agent": "commitguard-cli"
|
|
404
|
+
},
|
|
405
|
+
body: JSON.stringify({ diff }),
|
|
406
|
+
signal: controller.signal
|
|
407
|
+
});
|
|
408
|
+
clearTimeout(timeoutId);
|
|
409
|
+
if (!response.ok) {
|
|
410
|
+
const errorText = await response.text();
|
|
411
|
+
throw new Error(`API request failed (${response.status}): ${errorText}`);
|
|
412
|
+
}
|
|
413
|
+
return await response.json();
|
|
414
|
+
} catch (error) {
|
|
415
|
+
clearTimeout(timeoutId);
|
|
416
|
+
if (error instanceof Error && error.name === "AbortError") throw new Error(`Request timed out after ${DEFAULT_TIMEOUT}ms`);
|
|
417
|
+
throw error;
|
|
396
418
|
}
|
|
397
|
-
return await response.json();
|
|
398
419
|
}
|
|
399
420
|
|
|
400
421
|
//#endregion
|
|
@@ -533,7 +554,7 @@ async function manageConfig() {
|
|
|
533
554
|
}
|
|
534
555
|
let customRule = currentConfig.customRule;
|
|
535
556
|
if (currentConfig.customRule) {
|
|
536
|
-
|
|
557
|
+
log.info(`Current custom rule: ${currentConfig.customRule}`);
|
|
537
558
|
const editCustomRule = await confirm({
|
|
538
559
|
message: "Would you like to edit the custom rule? (Currently only available to pro users)",
|
|
539
560
|
initialValue: false
|
|
@@ -676,13 +697,13 @@ async function getEslintRules({ startDir = process.cwd(), overrideCache = false
|
|
|
676
697
|
} catch {}
|
|
677
698
|
return null;
|
|
678
699
|
});
|
|
679
|
-
const config = (await Promise.all(loaders)).find((r) => r !== null) ?? {
|
|
700
|
+
const config$1 = (await Promise.all(loaders)).find((r) => r !== null) ?? {
|
|
680
701
|
rules: {},
|
|
681
702
|
source: null
|
|
682
703
|
};
|
|
683
|
-
cache.setKey(cacheKey, config);
|
|
704
|
+
cache.setKey(cacheKey, config$1);
|
|
684
705
|
cache.save(true);
|
|
685
|
-
return config;
|
|
706
|
+
return config$1;
|
|
686
707
|
}
|
|
687
708
|
|
|
688
709
|
//#endregion
|
|
@@ -845,6 +866,7 @@ async function removeHooks() {
|
|
|
845
866
|
//#endregion
|
|
846
867
|
//#region src/utils/staged.ts
|
|
847
868
|
const CACHE_PATH = join(".git", "commitguard-cache.json");
|
|
869
|
+
const config = loadConfig();
|
|
848
870
|
const CATEGORY_LABELS = {
|
|
849
871
|
security: "🚨 [SECURITY]",
|
|
850
872
|
performance: "🚀 [PERFORMANCE]",
|
|
@@ -912,7 +934,6 @@ async function onStaged() {
|
|
|
912
934
|
const existingCache = readCache();
|
|
913
935
|
if (existingCache && existingCache.hash === diffHash) return;
|
|
914
936
|
try {
|
|
915
|
-
const config = loadConfig();
|
|
916
937
|
const response = await sendToCommitGuard(diff, (await getEslintRules()).rules, config);
|
|
917
938
|
writeCache({
|
|
918
939
|
hash: diffHash,
|