guardvibe 0.12.0 → 1.1.0
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 +90 -64
- package/build/cli.js +337 -30
- package/build/cli.js.map +1 -1
- package/build/data/rules/ai-security.d.ts.map +1 -1
- package/build/data/rules/ai-security.js +111 -0
- package/build/data/rules/ai-security.js.map +1 -1
- package/build/data/rules/cve-versions.d.ts +3 -0
- package/build/data/rules/cve-versions.d.ts.map +1 -0
- package/build/data/rules/cve-versions.js +148 -0
- package/build/data/rules/cve-versions.js.map +1 -0
- package/build/data/rules/index.d.ts.map +1 -1
- package/build/data/rules/index.js +2 -0
- package/build/data/rules/index.js.map +1 -1
- package/build/index.js +0 -0
- package/build/tools/check-project.js +1 -1
- package/build/tools/check-project.js.map +1 -1
- package/build/tools/compliance-report.js +1 -1
- package/build/tools/compliance-report.js.map +1 -1
- package/build/tools/export-sarif.js +1 -1
- package/build/tools/export-sarif.js.map +1 -1
- package/build/tools/scan-directory.js +1 -1
- package/build/tools/scan-directory.js.map +1 -1
- package/build/tools/scan-staged.js +1 -1
- package/build/tools/scan-staged.js.map +1 -1
- package/package.json +14 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GuardVibe
|
|
2
2
|
|
|
3
|
-
**The security MCP built for vibe coding.**
|
|
3
|
+
**The security MCP built for vibe coding.** 193 security rules covering the entire AI-generated code journey — from first line to production deployment.
|
|
4
4
|
|
|
5
5
|
Works with **Claude Code, Cursor, Gemini CLI, Codex, Windsurf**, and any MCP-compatible coding agent.
|
|
6
6
|
|
|
@@ -8,13 +8,54 @@ Works with **Claude Code, Cursor, Gemini CLI, Codex, Windsurf**, and any MCP-com
|
|
|
8
8
|
|
|
9
9
|
Most security tools are built for enterprise security teams. GuardVibe is built for **you** — the developer using AI to build and ship web apps fast.
|
|
10
10
|
|
|
11
|
-
- **
|
|
11
|
+
- **193 security rules** purpose-built for the stacks AI agents generate
|
|
12
12
|
- **Zero setup friction** — `npx guardvibe` and you're scanning
|
|
13
13
|
- **No account required** — runs 100% locally, no API keys, no cloud
|
|
14
14
|
- **Understands your stack** — not generic SAST, but rules that know Next.js, Supabase, Stripe, Clerk, and the tools you actually use
|
|
15
|
+
- **CVE version intelligence** — detects known vulnerable package versions in package.json
|
|
16
|
+
- **AI agent security** — detects MCP server vulnerabilities, excessive AI permissions, indirect prompt injection
|
|
17
|
+
- **Pre-commit hook** — block insecure code before it reaches your repo
|
|
18
|
+
- **CI/CD ready** — GitHub Actions workflow with SARIF upload to Security tab
|
|
15
19
|
- **Agent-friendly output** — JSON format for AI agents, Markdown for humans, SARIF for CI/CD
|
|
16
20
|
- **Plugin system** — extend with community or premium rule packs
|
|
17
21
|
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### MCP setup (recommended)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx guardvibe init claude # Claude Code
|
|
28
|
+
npx guardvibe init cursor # Cursor
|
|
29
|
+
npx guardvibe init gemini # Gemini CLI
|
|
30
|
+
npx guardvibe init all # All platforms
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Pre-commit hook
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx guardvibe hook install # Blocks commits with critical/high findings
|
|
37
|
+
npx guardvibe hook uninstall # Remove hook
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### CI/CD (GitHub Actions)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx guardvibe ci github # Generates .github/workflows/guardvibe.yml
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Manual MCP config
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"guardvibe": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": ["-y", "guardvibe"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
18
59
|
## What GuardVibe Scans
|
|
19
60
|
|
|
20
61
|
### Application Code
|
|
@@ -32,8 +73,17 @@ Stripe (webhook signatures, secret keys, client-side pricing), Polar.sh, LemonSq
|
|
|
32
73
|
### Third-Party Services
|
|
33
74
|
Resend (email injection), Upstash Redis, Pinecone, PostHog, Google Analytics (PII tracking)
|
|
34
75
|
|
|
35
|
-
### AI
|
|
36
|
-
|
|
76
|
+
### AI Security
|
|
77
|
+
Prompt injection detection, LLM output sinks (eval, SQL, exec), system prompt leaks, MCP server SSRF/path traversal/command injection, excessive AI agent permissions, indirect prompt injection via external data
|
|
78
|
+
|
|
79
|
+
### Mobile
|
|
80
|
+
React Native, Expo — AsyncStorage secrets, deep link token exposure, hardcoded API URLs, ATS configuration
|
|
81
|
+
|
|
82
|
+
### Firebase
|
|
83
|
+
Firestore security rules, Firebase Admin SDK exposure, storage rules, custom token validation
|
|
84
|
+
|
|
85
|
+
### CVE Version Intelligence
|
|
86
|
+
Detects known vulnerable versions in package.json: Next.js (CVE-2024-34351, CVE-2024-46982, CVE-2025-29927), React, Express, Axios, jsonwebtoken, lodash, node-fetch, tar, xml2js, crypto-js
|
|
37
87
|
|
|
38
88
|
### Deployment & Config
|
|
39
89
|
Vercel (vercel.json, cron secrets, headers), Next.js config, Docker, Docker Compose, Fly.io, Render, Netlify, Cloudflare
|
|
@@ -44,45 +94,14 @@ Dockerfile security, GitHub Actions CI/CD, Terraform (S3, IAM, RDS, security gro
|
|
|
44
94
|
### Secrets & Environment
|
|
45
95
|
API keys (AWS, GitHub, Stripe, OpenAI, Resend), .env management, .gitignore coverage, high-entropy detection, NEXT_PUBLIC exposure
|
|
46
96
|
|
|
47
|
-
### Webhooks
|
|
48
|
-
Signature verification
|
|
49
|
-
|
|
50
|
-
### SEO & Web
|
|
51
|
-
Open redirects, robots.txt exposure, source maps, meta tag injection
|
|
97
|
+
### Webhooks & Web Security
|
|
98
|
+
Signature verification, open redirects, robots.txt exposure, source maps, meta tag injection, CSP headers
|
|
52
99
|
|
|
53
100
|
### Compliance
|
|
54
101
|
SOC2, PCI-DSS, HIPAA control mapping with compliance reports
|
|
55
102
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
### Auto setup
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
npx guardvibe init claude
|
|
62
|
-
npx guardvibe init cursor
|
|
63
|
-
npx guardvibe init gemini
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Manual MCP setup
|
|
67
|
-
|
|
68
|
-
**Claude Code**
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
claude mcp add guardvibe -- npx guardvibe
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**Cursor / VS Code / Gemini CLI**
|
|
75
|
-
|
|
76
|
-
```json
|
|
77
|
-
{
|
|
78
|
-
"mcpServers": {
|
|
79
|
-
"guardvibe": {
|
|
80
|
-
"command": "npx",
|
|
81
|
-
"args": ["-y", "guardvibe"]
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
```
|
|
103
|
+
### Supply Chain
|
|
104
|
+
Malicious postinstall scripts, unpinned GitHub Actions, typosquat detection
|
|
86
105
|
|
|
87
106
|
## Tools (11 MCP tools)
|
|
88
107
|
|
|
@@ -102,43 +121,52 @@ claude mcp add guardvibe -- npx guardvibe
|
|
|
102
121
|
|
|
103
122
|
All scanning tools support `format: "json"` for machine-readable output.
|
|
104
123
|
|
|
105
|
-
## Security Rules (
|
|
124
|
+
## Security Rules (193 rules across 20 modules)
|
|
106
125
|
|
|
107
126
|
| Category | Rules | Coverage |
|
|
108
127
|
|----------|-------|----------|
|
|
109
|
-
| Core OWASP |
|
|
110
|
-
| Next.js App Router |
|
|
111
|
-
| Auth (Clerk / Auth.js / Supabase Auth) |
|
|
112
|
-
| Database (Supabase / Prisma / Drizzle) |
|
|
128
|
+
| Core OWASP | 25 | SQL injection, XSS, CSRF, command injection, eval, CORS, SSRF, hardcoded secrets |
|
|
129
|
+
| Next.js App Router | 13 | Server Actions, secret exposure, auth bypass, redirects, innerHTML |
|
|
130
|
+
| Auth (Clerk / Auth.js / Supabase Auth) | 16 | Middleware, secret keys, session storage, role checks, SSR cookies, admin protection |
|
|
131
|
+
| Database (Supabase / Prisma / Drizzle) | 8 | Raw queries, client exposure, service role leaks |
|
|
113
132
|
| Deployment Config | 16 | Vercel, Next.js config, Docker Compose, Fly, Render, Netlify |
|
|
114
133
|
| Payments (Stripe / Polar / Lemon) | 9 | Webhook signatures, key exposure, price manipulation |
|
|
115
134
|
| Services (Resend / Upstash / Pinecone / PostHog) | 11 | API key leaks, PII tracking, email injection |
|
|
116
|
-
| Web Security
|
|
117
|
-
|
|
|
135
|
+
| Web Security | 14 | Webhooks, CSP, .env safety, AI key exposure, Cloudflare |
|
|
136
|
+
| React Native / Expo | 10 | AsyncStorage secrets, deep links, ATS, hardcoded URLs |
|
|
137
|
+
| Firebase | 7 | Firestore rules, admin SDK, storage, custom tokens |
|
|
138
|
+
| AI / LLM Security | 14 | Prompt injection, MCP SSRF, excessive agency, indirect injection |
|
|
139
|
+
| CVE Version Intelligence | 12 | Known vulnerable versions in package.json |
|
|
140
|
+
| Shell / Bash | 5 | Pipe to bash, chmod 777, rm -rf, sudo password |
|
|
141
|
+
| SQL | 4 | DROP/DELETE without WHERE, stacked queries, GRANT ALL |
|
|
142
|
+
| Supply Chain | 2 | Malicious install scripts, unpinned actions |
|
|
143
|
+
| Go | 6 | SQL injection, command injection, template escaping |
|
|
118
144
|
| Dockerfile | 5 | Root user, secrets in ENV, untagged images |
|
|
119
|
-
| CI/CD (GitHub Actions) | 4 | Secrets interpolation, unpinned actions |
|
|
145
|
+
| CI/CD (GitHub Actions) | 4 | Secrets interpolation, unpinned actions, write-all permissions |
|
|
120
146
|
| Terraform | 5 | Public S3, open security groups, IAM wildcards |
|
|
147
|
+
| Other Services | 5 | AWS, GCP, MongoDB, Convex, Sentry, Twilio |
|
|
148
|
+
|
|
149
|
+
## CLI Commands
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
npx guardvibe init <platform> # Setup MCP server (claude, cursor, gemini, all)
|
|
153
|
+
npx guardvibe hook install # Install pre-commit hook
|
|
154
|
+
npx guardvibe hook uninstall # Remove pre-commit hook
|
|
155
|
+
npx guardvibe ci github # Generate GitHub Actions workflow
|
|
156
|
+
npx guardvibe-scan # Scan staged files (for pre-commit)
|
|
157
|
+
npx guardvibe-scan --format sarif --output results.sarif # CI mode
|
|
158
|
+
```
|
|
121
159
|
|
|
122
160
|
## Plugin System
|
|
123
161
|
|
|
124
162
|
Extend GuardVibe with custom or community rule packs.
|
|
125
163
|
|
|
126
|
-
**Install a plugin:**
|
|
127
|
-
|
|
128
164
|
```bash
|
|
129
165
|
npm install guardvibe-rules-awesome
|
|
130
166
|
```
|
|
131
167
|
|
|
132
168
|
Plugins matching `guardvibe-rules-*`, `@guardvibe/rules-*`, or `@guardvibe-pro/rules-*` are discovered automatically.
|
|
133
169
|
|
|
134
|
-
**Manual plugin config (.guardviberc):**
|
|
135
|
-
|
|
136
|
-
```json
|
|
137
|
-
{
|
|
138
|
-
"plugins": ["guardvibe-rules-awesome", "./my-custom-rules.js"]
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
170
|
**Create a plugin:**
|
|
143
171
|
|
|
144
172
|
```typescript
|
|
@@ -197,17 +225,15 @@ Supports `//`, `#`, and `<!-- -->` comment styles.
|
|
|
197
225
|
|
|
198
226
|
## How It Works
|
|
199
227
|
|
|
200
|
-
GuardVibe runs as an MCP server that your AI coding agent connects to. When the agent generates code, it can ask GuardVibe to scan it for security issues before committing.
|
|
201
|
-
|
|
202
228
|
```
|
|
203
229
|
You write code with AI
|
|
204
|
-
|
|
230
|
+
|
|
|
205
231
|
AI agent calls GuardVibe MCP tools
|
|
206
|
-
|
|
232
|
+
|
|
|
207
233
|
GuardVibe scans locally (no cloud, no API)
|
|
208
|
-
|
|
234
|
+
|
|
|
209
235
|
Returns findings with severity, OWASP mapping, and fix suggestions
|
|
210
|
-
|
|
236
|
+
|
|
|
211
237
|
AI agent fixes issues before they reach production
|
|
212
238
|
```
|
|
213
239
|
|
|
@@ -221,4 +247,4 @@ Tested on a real 644-file Next.js + Supabase project:
|
|
|
221
247
|
|
|
222
248
|
## License
|
|
223
249
|
|
|
224
|
-
MIT — open source and free to use. Built by [GokLab](https://
|
|
250
|
+
MIT — open source and free to use. Built by [GokLab](https://github.com/goklab).
|
package/build/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
2
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync, unlinkSync } from "fs";
|
|
3
3
|
import { join, dirname } from "path";
|
|
4
4
|
import { homedir } from "os";
|
|
5
5
|
const GUARDVIBE_MCP_CONFIG = {
|
|
@@ -42,7 +42,6 @@ function setupPlatform(name) {
|
|
|
42
42
|
return false;
|
|
43
43
|
const existing = readJsonFile(platform.path);
|
|
44
44
|
if (existing) {
|
|
45
|
-
// Merge - don't overwrite existing MCP servers
|
|
46
45
|
if (!existing.mcpServers) {
|
|
47
46
|
existing.mcpServers = {};
|
|
48
47
|
}
|
|
@@ -54,7 +53,6 @@ function setupPlatform(name) {
|
|
|
54
53
|
writeJsonFile(platform.path, existing);
|
|
55
54
|
}
|
|
56
55
|
else {
|
|
57
|
-
// Create new config
|
|
58
56
|
writeJsonFile(platform.path, {
|
|
59
57
|
mcpServers: {
|
|
60
58
|
guardvibe: GUARDVIBE_MCP_CONFIG,
|
|
@@ -64,55 +62,364 @@ function setupPlatform(name) {
|
|
|
64
62
|
console.log(` [OK] Added MCP server to ${platform.description}`);
|
|
65
63
|
return true;
|
|
66
64
|
}
|
|
65
|
+
// ── Pre-commit hook ──────────────────────────────────────────────────
|
|
66
|
+
const HOOK_SCRIPT = `#!/bin/sh
|
|
67
|
+
# GuardVibe pre-commit security hook
|
|
68
|
+
# Installed by: npx guardvibe hook install
|
|
69
|
+
|
|
70
|
+
echo "🔒 GuardVibe: scanning staged files..."
|
|
71
|
+
|
|
72
|
+
# Run guardvibe scan on staged files
|
|
73
|
+
RESULT=$(npx -y guardvibe-scan 2>&1)
|
|
74
|
+
EXIT_CODE=$?
|
|
75
|
+
|
|
76
|
+
if [ $EXIT_CODE -ne 0 ]; then
|
|
77
|
+
echo ""
|
|
78
|
+
echo "$RESULT"
|
|
79
|
+
echo ""
|
|
80
|
+
echo "❌ GuardVibe: security issues found. Fix them or commit with --no-verify to skip."
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
echo "✅ GuardVibe: all checks passed."
|
|
85
|
+
`;
|
|
86
|
+
function installHook() {
|
|
87
|
+
const gitDir = join(process.cwd(), ".git");
|
|
88
|
+
if (!existsSync(gitDir)) {
|
|
89
|
+
console.error(" [ERR] Not a git repository. Run this from your project root.");
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const hooksDir = join(gitDir, "hooks");
|
|
93
|
+
if (!existsSync(hooksDir)) {
|
|
94
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
95
|
+
}
|
|
96
|
+
const hookPath = join(hooksDir, "pre-commit");
|
|
97
|
+
if (existsSync(hookPath)) {
|
|
98
|
+
const existing = readFileSync(hookPath, "utf-8");
|
|
99
|
+
if (existing.includes("GuardVibe")) {
|
|
100
|
+
console.log(" [OK] GuardVibe pre-commit hook already installed.");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// Append to existing hook
|
|
104
|
+
writeFileSync(hookPath, existing + "\n" + HOOK_SCRIPT, "utf-8");
|
|
105
|
+
console.log(" [OK] GuardVibe added to existing pre-commit hook.");
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
writeFileSync(hookPath, HOOK_SCRIPT, "utf-8");
|
|
109
|
+
chmodSync(hookPath, 0o755);
|
|
110
|
+
console.log(" [OK] Pre-commit hook installed at .git/hooks/pre-commit");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function uninstallHook() {
|
|
114
|
+
const hookPath = join(process.cwd(), ".git", "hooks", "pre-commit");
|
|
115
|
+
if (!existsSync(hookPath)) {
|
|
116
|
+
console.log(" [OK] No pre-commit hook found.");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const content = readFileSync(hookPath, "utf-8");
|
|
120
|
+
if (!content.includes("GuardVibe")) {
|
|
121
|
+
console.log(" [OK] Pre-commit hook exists but doesn't contain GuardVibe.");
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Remove GuardVibe section
|
|
125
|
+
const cleaned = content
|
|
126
|
+
.replace(/\n?# GuardVibe pre-commit security hook[\s\S]*?GuardVibe: all checks passed[."]*\n?/g, "")
|
|
127
|
+
.trim();
|
|
128
|
+
if (!cleaned || cleaned === "#!/bin/sh") {
|
|
129
|
+
unlinkSync(hookPath);
|
|
130
|
+
console.log(" [OK] Pre-commit hook removed.");
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
writeFileSync(hookPath, cleaned + "\n", "utf-8");
|
|
134
|
+
console.log(" [OK] GuardVibe removed from pre-commit hook (other hooks preserved).");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ── GitHub Actions workflow ──────────────────────────────────────────
|
|
138
|
+
const GITHUB_ACTIONS_WORKFLOW = `name: GuardVibe Security Scan
|
|
139
|
+
|
|
140
|
+
on:
|
|
141
|
+
pull_request:
|
|
142
|
+
branches: [main, master]
|
|
143
|
+
push:
|
|
144
|
+
branches: [main, master]
|
|
145
|
+
|
|
146
|
+
permissions:
|
|
147
|
+
contents: read
|
|
148
|
+
security-events: write
|
|
149
|
+
|
|
150
|
+
jobs:
|
|
151
|
+
security-scan:
|
|
152
|
+
name: Security Scan
|
|
153
|
+
runs-on: ubuntu-latest
|
|
154
|
+
steps:
|
|
155
|
+
- uses: actions/checkout@v4
|
|
156
|
+
with:
|
|
157
|
+
persist-credentials: false
|
|
158
|
+
|
|
159
|
+
- uses: actions/setup-node@v4
|
|
160
|
+
with:
|
|
161
|
+
node-version: "22"
|
|
162
|
+
|
|
163
|
+
- name: Install dependencies
|
|
164
|
+
run: npm ci
|
|
165
|
+
|
|
166
|
+
- name: Run GuardVibe security scan
|
|
167
|
+
run: npx -y guardvibe-scan --format sarif --output guardvibe-results.sarif
|
|
168
|
+
|
|
169
|
+
- name: Upload SARIF to GitHub Security
|
|
170
|
+
if: always()
|
|
171
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
172
|
+
with:
|
|
173
|
+
sarif_file: guardvibe-results.sarif
|
|
174
|
+
category: guardvibe
|
|
175
|
+
`;
|
|
176
|
+
function generateGitHubActions() {
|
|
177
|
+
const workflowDir = join(process.cwd(), ".github", "workflows");
|
|
178
|
+
if (!existsSync(workflowDir)) {
|
|
179
|
+
mkdirSync(workflowDir, { recursive: true });
|
|
180
|
+
}
|
|
181
|
+
const workflowPath = join(workflowDir, "guardvibe.yml");
|
|
182
|
+
if (existsSync(workflowPath)) {
|
|
183
|
+
console.log(" [OK] .github/workflows/guardvibe.yml already exists.");
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
writeFileSync(workflowPath, GITHUB_ACTIONS_WORKFLOW, "utf-8");
|
|
187
|
+
console.log(" [OK] Created .github/workflows/guardvibe.yml");
|
|
188
|
+
console.log(" [OK] SARIF results will appear in GitHub Security tab.");
|
|
189
|
+
}
|
|
190
|
+
// ── Scan CLI (for pre-commit hook and CI) ────────────────────────────
|
|
191
|
+
const SCAN_SCRIPT_DETECTED = process.argv[1]?.endsWith("guardvibe-scan") ||
|
|
192
|
+
process.argv[1]?.endsWith("guardvibe-scan.js");
|
|
193
|
+
if (SCAN_SCRIPT_DETECTED) {
|
|
194
|
+
runScan();
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
main();
|
|
198
|
+
}
|
|
199
|
+
function parseArgs(args) {
|
|
200
|
+
const flags = {};
|
|
201
|
+
const positional = [];
|
|
202
|
+
for (let i = 0; i < args.length; i++) {
|
|
203
|
+
if (args[i].startsWith("--")) {
|
|
204
|
+
const key = args[i].slice(2);
|
|
205
|
+
const next = args[i + 1];
|
|
206
|
+
if (next && !next.startsWith("--")) {
|
|
207
|
+
flags[key] = next;
|
|
208
|
+
i++;
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
flags[key] = true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
positional.push(args[i]);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return { flags, positional };
|
|
219
|
+
}
|
|
220
|
+
async function runScan() {
|
|
221
|
+
const args = process.argv.slice(2);
|
|
222
|
+
const { flags } = parseArgs(args);
|
|
223
|
+
const format = flags.format ?? "markdown";
|
|
224
|
+
const outputFile = flags.output ?? null;
|
|
225
|
+
let result;
|
|
226
|
+
if (format === "sarif") {
|
|
227
|
+
const { exportSarif } = await import("./tools/export-sarif.js");
|
|
228
|
+
result = exportSarif(process.cwd());
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
const { scanStaged } = await import("./tools/scan-staged.js");
|
|
232
|
+
result = scanStaged(process.cwd(), format === "json" ? "json" : "markdown");
|
|
233
|
+
}
|
|
234
|
+
if (outputFile) {
|
|
235
|
+
writeFileSync(outputFile, result, "utf-8");
|
|
236
|
+
console.log(` [OK] Results written to ${outputFile}`);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
console.log(result);
|
|
240
|
+
}
|
|
241
|
+
if (format !== "sarif") {
|
|
242
|
+
const hasBlocking = result.includes("[CRITICAL]") || result.includes("[HIGH]");
|
|
243
|
+
if (hasBlocking)
|
|
244
|
+
process.exit(1);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async function runDirectoryScan(targetPath, flags) {
|
|
248
|
+
const { scanDirectory } = await import("./tools/scan-directory.js");
|
|
249
|
+
const { resolve } = await import("path");
|
|
250
|
+
const format = flags.format ?? "markdown";
|
|
251
|
+
const outputFile = flags.output ?? null;
|
|
252
|
+
const scanPath = resolve(targetPath);
|
|
253
|
+
let result;
|
|
254
|
+
if (format === "sarif") {
|
|
255
|
+
const { exportSarif } = await import("./tools/export-sarif.js");
|
|
256
|
+
result = exportSarif(scanPath);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
result = scanDirectory(scanPath, true, [], format === "json" ? "json" : "markdown");
|
|
260
|
+
}
|
|
261
|
+
if (outputFile) {
|
|
262
|
+
writeFileSync(outputFile, result, "utf-8");
|
|
263
|
+
console.log(` [OK] Results written to ${outputFile}`);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
console.log(result);
|
|
267
|
+
}
|
|
268
|
+
if (format !== "sarif") {
|
|
269
|
+
const hasBlocking = result.includes("[CRITICAL]") || result.includes("[HIGH]");
|
|
270
|
+
if (hasBlocking)
|
|
271
|
+
process.exit(1);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
async function runFileCheck(filePath, flags) {
|
|
275
|
+
const { checkCode } = await import("./tools/check-code.js");
|
|
276
|
+
const { resolve, extname, basename } = await import("path");
|
|
277
|
+
const resolved = resolve(filePath);
|
|
278
|
+
if (!existsSync(resolved)) {
|
|
279
|
+
console.error(` [ERR] File not found: ${resolved}`);
|
|
280
|
+
process.exit(1);
|
|
281
|
+
}
|
|
282
|
+
const content = readFileSync(resolved, "utf-8");
|
|
283
|
+
const ext = extname(resolved).toLowerCase();
|
|
284
|
+
const extMap = {
|
|
285
|
+
".js": "javascript", ".jsx": "javascript", ".mjs": "javascript", ".cjs": "javascript",
|
|
286
|
+
".ts": "typescript", ".tsx": "typescript", ".mts": "typescript", ".cts": "typescript",
|
|
287
|
+
".py": "python", ".go": "go", ".html": "html", ".sql": "sql",
|
|
288
|
+
".sh": "shell", ".bash": "shell", ".yml": "yaml", ".yaml": "yaml",
|
|
289
|
+
".tf": "terraform", ".toml": "toml", ".json": "json",
|
|
290
|
+
};
|
|
291
|
+
let language = extMap[ext];
|
|
292
|
+
if (!language && basename(resolved).startsWith("Dockerfile"))
|
|
293
|
+
language = "dockerfile";
|
|
294
|
+
if (!language) {
|
|
295
|
+
console.error(` [ERR] Unsupported file type: ${ext}`);
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
298
|
+
const format = flags.format ?? "markdown";
|
|
299
|
+
const result = checkCode(content, language, undefined, resolved, undefined, format === "json" ? "json" : "markdown");
|
|
300
|
+
const outputFile = flags.output ?? null;
|
|
301
|
+
if (outputFile) {
|
|
302
|
+
writeFileSync(outputFile, result, "utf-8");
|
|
303
|
+
console.log(` [OK] Results written to ${outputFile}`);
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
console.log(result);
|
|
307
|
+
}
|
|
308
|
+
const hasBlocking = result.includes("[CRITICAL]") || result.includes("[HIGH]");
|
|
309
|
+
if (hasBlocking)
|
|
310
|
+
process.exit(1);
|
|
311
|
+
}
|
|
312
|
+
// ── Main CLI ─────────────────────────────────────────────────────────
|
|
67
313
|
function printUsage() {
|
|
68
314
|
console.log(`
|
|
69
|
-
GuardVibe Security -
|
|
315
|
+
GuardVibe Security - CLI
|
|
70
316
|
|
|
71
317
|
Usage:
|
|
72
|
-
npx guardvibe
|
|
318
|
+
npx guardvibe scan [path] Scan a directory for security issues
|
|
319
|
+
npx guardvibe check <file> Scan a single file
|
|
320
|
+
npx guardvibe init <platform> Setup MCP server
|
|
321
|
+
npx guardvibe hook install Install pre-commit hook
|
|
322
|
+
npx guardvibe hook uninstall Remove pre-commit hook
|
|
323
|
+
npx guardvibe ci github Generate GitHub Actions workflow
|
|
73
324
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
325
|
+
Options:
|
|
326
|
+
--format <type> Output format: markdown (default), json, sarif
|
|
327
|
+
--output <file> Write results to file instead of stdout
|
|
328
|
+
|
|
329
|
+
MCP Platforms:
|
|
330
|
+
claude Claude Code (.claude.json)
|
|
331
|
+
gemini Gemini CLI (~/.gemini/settings.json)
|
|
332
|
+
cursor Cursor (.cursor/mcp.json)
|
|
333
|
+
all All platforms
|
|
79
334
|
|
|
80
335
|
Examples:
|
|
336
|
+
npx guardvibe scan .
|
|
337
|
+
npx guardvibe scan ./src --format json
|
|
338
|
+
npx guardvibe scan . --format sarif --output results.sarif
|
|
339
|
+
npx guardvibe check src/app/api/route.ts
|
|
340
|
+
npx guardvibe check package.json
|
|
81
341
|
npx guardvibe init claude
|
|
82
|
-
npx guardvibe
|
|
342
|
+
npx guardvibe hook install
|
|
343
|
+
npx guardvibe ci github
|
|
83
344
|
`);
|
|
84
345
|
}
|
|
85
|
-
function main() {
|
|
346
|
+
async function main() {
|
|
86
347
|
const args = process.argv.slice(2);
|
|
87
348
|
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|
88
349
|
printUsage();
|
|
89
350
|
process.exit(0);
|
|
90
351
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
352
|
+
const command = args[0];
|
|
353
|
+
if (command === "init") {
|
|
354
|
+
const platform = args[1]?.toLowerCase();
|
|
355
|
+
if (!platform) {
|
|
356
|
+
console.error(" Please specify a platform: claude, gemini, cursor, or all");
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
console.log(`\n GuardVibe Security Setup\n`);
|
|
360
|
+
if (platform === "all") {
|
|
361
|
+
for (const name of Object.keys(platforms)) {
|
|
362
|
+
setupPlatform(name);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
else if (platforms[platform]) {
|
|
366
|
+
setupPlatform(platform);
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
console.error(` Unknown platform: ${platform}`);
|
|
370
|
+
console.error(` Available: claude, gemini, cursor, all`);
|
|
371
|
+
process.exit(1);
|
|
372
|
+
}
|
|
373
|
+
console.log(`\n [OK] Ready! Start coding securely.\n`);
|
|
95
374
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
console.
|
|
99
|
-
|
|
375
|
+
else if (command === "hook") {
|
|
376
|
+
const action = args[1]?.toLowerCase();
|
|
377
|
+
console.log(`\n GuardVibe Pre-Commit Hook\n`);
|
|
378
|
+
if (action === "install") {
|
|
379
|
+
installHook();
|
|
380
|
+
}
|
|
381
|
+
else if (action === "uninstall") {
|
|
382
|
+
uninstallHook();
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
console.error(" Usage: npx guardvibe hook install|uninstall");
|
|
386
|
+
process.exit(1);
|
|
387
|
+
}
|
|
388
|
+
console.log();
|
|
100
389
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
390
|
+
else if (command === "scan") {
|
|
391
|
+
const cliArgs = args.slice(1);
|
|
392
|
+
const { flags, positional } = parseArgs(cliArgs);
|
|
393
|
+
const targetPath = positional[0] ?? ".";
|
|
394
|
+
await runDirectoryScan(targetPath, flags);
|
|
395
|
+
}
|
|
396
|
+
else if (command === "check") {
|
|
397
|
+
const cliArgs = args.slice(1);
|
|
398
|
+
const { flags, positional } = parseArgs(cliArgs);
|
|
399
|
+
const filePath = positional[0];
|
|
400
|
+
if (!filePath) {
|
|
401
|
+
console.error(" Please specify a file: npx guardvibe check <file>");
|
|
402
|
+
process.exit(1);
|
|
105
403
|
}
|
|
404
|
+
await runFileCheck(filePath, flags);
|
|
106
405
|
}
|
|
107
|
-
else if (
|
|
108
|
-
|
|
406
|
+
else if (command === "ci") {
|
|
407
|
+
const provider = args[1]?.toLowerCase();
|
|
408
|
+
console.log(`\n GuardVibe CI/CD Setup\n`);
|
|
409
|
+
if (provider === "github") {
|
|
410
|
+
generateGitHubActions();
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
console.error(" Usage: npx guardvibe ci github");
|
|
414
|
+
console.error(" (more CI providers coming soon)");
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
console.log();
|
|
109
418
|
}
|
|
110
419
|
else {
|
|
111
|
-
console.error(` Unknown
|
|
112
|
-
|
|
420
|
+
console.error(` Unknown command: ${command}`);
|
|
421
|
+
printUsage();
|
|
113
422
|
process.exit(1);
|
|
114
423
|
}
|
|
115
|
-
console.log(`\n [OK] Ready! Start coding securely.\n`);
|
|
116
424
|
}
|
|
117
|
-
main();
|
|
118
425
|
//# sourceMappingURL=cli.js.map
|
package/build/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|