javi-forge 1.5.0 → 1.6.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/README.md +191 -3
- package/ci-local/hooks/pre-push +17 -13
- package/dist/commands/analyze.d.ts +1 -1
- package/dist/commands/analyze.js +15 -15
- package/dist/commands/atlassian-mcp.d.ts +42 -0
- package/dist/commands/atlassian-mcp.js +98 -0
- package/dist/commands/ci.d.ts +3 -3
- package/dist/commands/ci.js +185 -147
- package/dist/commands/crash-recovery.d.ts +34 -0
- package/dist/commands/crash-recovery.js +123 -0
- package/dist/commands/doctor.d.ts +2 -2
- package/dist/commands/doctor.js +113 -61
- package/dist/commands/harness-audit.d.ts +35 -0
- package/dist/commands/harness-audit.js +277 -0
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +415 -118
- package/dist/commands/llmstxt.d.ts +1 -1
- package/dist/commands/llmstxt.js +36 -34
- package/dist/commands/parallel-batch.d.ts +42 -0
- package/dist/commands/parallel-batch.js +90 -0
- package/dist/commands/plugin.d.ts +26 -1
- package/dist/commands/plugin.js +138 -24
- package/dist/commands/secret-scanner.d.ts +30 -0
- package/dist/commands/secret-scanner.js +272 -0
- package/dist/commands/security-analysis.d.ts +74 -0
- package/dist/commands/security-analysis.js +487 -0
- package/dist/commands/security.d.ts +31 -0
- package/dist/commands/security.js +445 -0
- package/dist/commands/skill-scanner.d.ts +63 -0
- package/dist/commands/skill-scanner.js +383 -0
- package/dist/commands/skills.d.ts +139 -0
- package/dist/commands/skills.js +895 -0
- package/dist/commands/supply-chain.d.ts +23 -0
- package/dist/commands/supply-chain.js +126 -0
- package/dist/commands/tdd-pipeline.d.ts +17 -0
- package/dist/commands/tdd-pipeline.js +144 -0
- package/dist/commands/tdd.d.ts +21 -0
- package/dist/commands/tdd.js +120 -0
- package/dist/commands/team-presets.d.ts +53 -0
- package/dist/commands/team-presets.js +201 -0
- package/dist/commands/workflow.d.ts +23 -0
- package/dist/commands/workflow.js +114 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.js +208 -37
- package/dist/index.js +400 -54
- package/dist/lib/agent-skills.d.ts +73 -0
- package/dist/lib/agent-skills.js +260 -0
- package/dist/lib/auto-skill-install.d.ts +37 -0
- package/dist/lib/auto-skill-install.js +92 -0
- package/dist/lib/auto-wire.d.ts +20 -0
- package/dist/lib/auto-wire.js +240 -0
- package/dist/lib/claudemd.d.ts +20 -0
- package/dist/lib/claudemd.js +222 -0
- package/dist/lib/codex-export.d.ts +16 -0
- package/dist/lib/codex-export.js +109 -0
- package/dist/lib/common.d.ts +1 -1
- package/dist/lib/common.js +52 -44
- package/dist/lib/context.d.ts +27 -0
- package/dist/lib/context.js +204 -0
- package/dist/lib/docker.d.ts +1 -1
- package/dist/lib/docker.js +141 -112
- package/dist/lib/frontmatter.d.ts +1 -1
- package/dist/lib/frontmatter.js +29 -15
- package/dist/lib/plugin.d.ts +19 -1
- package/dist/lib/plugin.js +174 -47
- package/dist/lib/skill-publish.d.ts +40 -0
- package/dist/lib/skill-publish.js +146 -0
- package/dist/lib/stack-detector.d.ts +38 -0
- package/dist/lib/stack-detector.js +207 -0
- package/dist/lib/template.d.ts +16 -1
- package/dist/lib/template.js +46 -17
- package/dist/lib/workflow/discovery.d.ts +19 -0
- package/dist/lib/workflow/discovery.js +68 -0
- package/dist/lib/workflow/index.d.ts +5 -0
- package/dist/lib/workflow/index.js +5 -0
- package/dist/lib/workflow/parser.d.ts +16 -0
- package/dist/lib/workflow/parser.js +198 -0
- package/dist/lib/workflow/renderer.d.ts +9 -0
- package/dist/lib/workflow/renderer.js +152 -0
- package/dist/lib/workflow/validator.d.ts +10 -0
- package/dist/lib/workflow/validator.js +189 -0
- package/dist/tasks/index.d.ts +4 -0
- package/dist/tasks/index.js +4 -0
- package/dist/tasks/scaffold-tasks.d.ts +3 -0
- package/dist/tasks/scaffold-tasks.js +14 -0
- package/dist/tasks/task-id.d.ts +30 -0
- package/dist/tasks/task-id.js +55 -0
- package/dist/tasks/task-tracker.d.ts +15 -0
- package/dist/tasks/task-tracker.js +81 -0
- package/dist/types/index.d.ts +252 -5
- package/dist/types/index.js +11 -1
- package/dist/ui/AnalyzeUI.d.ts +1 -1
- package/dist/ui/AnalyzeUI.js +38 -39
- package/dist/ui/App.d.ts +5 -3
- package/dist/ui/App.js +92 -46
- package/dist/ui/AutoSkills.d.ts +9 -0
- package/dist/ui/AutoSkills.js +124 -0
- package/dist/ui/CI.d.ts +2 -2
- package/dist/ui/CI.js +24 -26
- package/dist/ui/CIContext.d.ts +1 -1
- package/dist/ui/CIContext.js +3 -2
- package/dist/ui/CISelector.d.ts +2 -2
- package/dist/ui/CISelector.js +23 -15
- package/dist/ui/Doctor.d.ts +1 -1
- package/dist/ui/Doctor.js +35 -29
- package/dist/ui/Header.d.ts +1 -1
- package/dist/ui/Header.js +14 -14
- package/dist/ui/HookProfileSelector.d.ts +9 -0
- package/dist/ui/HookProfileSelector.js +54 -0
- package/dist/ui/LlmsTxt.d.ts +1 -1
- package/dist/ui/LlmsTxt.js +31 -22
- package/dist/ui/MemorySelector.d.ts +2 -2
- package/dist/ui/MemorySelector.js +28 -16
- package/dist/ui/NameInput.d.ts +1 -1
- package/dist/ui/NameInput.js +21 -21
- package/dist/ui/OptionSelector.d.ts +8 -2
- package/dist/ui/OptionSelector.js +83 -26
- package/dist/ui/Plugin.d.ts +4 -3
- package/dist/ui/Plugin.js +89 -29
- package/dist/ui/Progress.d.ts +3 -3
- package/dist/ui/Progress.js +23 -22
- package/dist/ui/Skills.d.ts +11 -0
- package/dist/ui/Skills.js +148 -0
- package/dist/ui/StackSelector.d.ts +2 -2
- package/dist/ui/StackSelector.js +26 -16
- package/dist/ui/Summary.d.ts +3 -3
- package/dist/ui/Summary.js +60 -50
- package/dist/ui/Welcome.d.ts +1 -1
- package/dist/ui/Welcome.js +15 -16
- package/dist/ui/theme.d.ts +1 -1
- package/dist/ui/theme.js +6 -6
- package/package.json +9 -6
- package/templates/common/atlassian/mcp-atlassian-snippet.json +16 -0
- package/templates/common/repoforge/mcp-repoforge-snippet.json +11 -0
- package/templates/common/repoforge/repoforge.yaml +34 -0
- package/templates/github/deploy-docker-zero-downtime.yml +140 -0
- package/templates/github/repoforge-graph.yml +45 -0
- package/templates/gitlab/deploy-docker-zero-downtime.yml +57 -0
- package/templates/local-ai/.env.example +17 -0
- package/templates/local-ai/docker-compose.yml +95 -0
- package/templates/security-hooks/claude-settings-security.json +30 -0
- package/templates/security-hooks/commit-msg-signing +29 -0
- package/templates/security-hooks/pre-commit-permissions +74 -0
- package/templates/security-hooks/pre-commit-secrets +74 -0
- package/templates/security-hooks/pre-push-branch-protection +62 -0
- package/templates/security-hooks/pre-push-deps +83 -0
- package/templates/security-hooks/pre-push-signing +67 -0
- package/templates/woodpecker/deploy-docker-zero-downtime.yml +50 -0
- package/templates/workflows/ci-pipeline.dot +15 -0
- package/templates/workflows/feature-flow.dot +21 -0
- package/templates/workflows/release.dot +16 -0
- package/dist/__integration__/helpers.d.ts +0 -20
- package/dist/__integration__/helpers.d.ts.map +0 -1
- package/dist/__integration__/helpers.js +0 -31
- package/dist/__integration__/helpers.js.map +0 -1
- package/dist/commands/analyze.d.ts.map +0 -1
- package/dist/commands/analyze.js.map +0 -1
- package/dist/commands/ci.d.ts.map +0 -1
- package/dist/commands/ci.js.map +0 -1
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/llmstxt.d.ts.map +0 -1
- package/dist/commands/llmstxt.js.map +0 -1
- package/dist/commands/plugin.d.ts.map +0 -1
- package/dist/commands/plugin.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/common.d.ts.map +0 -1
- package/dist/lib/common.js.map +0 -1
- package/dist/lib/docker.d.ts.map +0 -1
- package/dist/lib/docker.js.map +0 -1
- package/dist/lib/frontmatter.d.ts.map +0 -1
- package/dist/lib/frontmatter.js.map +0 -1
- package/dist/lib/plugin.d.ts.map +0 -1
- package/dist/lib/plugin.js.map +0 -1
- package/dist/lib/template.d.ts.map +0 -1
- package/dist/lib/template.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/ui/AnalyzeUI.d.ts.map +0 -1
- package/dist/ui/AnalyzeUI.js.map +0 -1
- package/dist/ui/App.d.ts.map +0 -1
- package/dist/ui/App.js.map +0 -1
- package/dist/ui/CI.d.ts.map +0 -1
- package/dist/ui/CI.js.map +0 -1
- package/dist/ui/CIContext.d.ts.map +0 -1
- package/dist/ui/CIContext.js.map +0 -1
- package/dist/ui/CISelector.d.ts.map +0 -1
- package/dist/ui/CISelector.js.map +0 -1
- package/dist/ui/Doctor.d.ts.map +0 -1
- package/dist/ui/Doctor.js.map +0 -1
- package/dist/ui/Header.d.ts.map +0 -1
- package/dist/ui/Header.js.map +0 -1
- package/dist/ui/LlmsTxt.d.ts.map +0 -1
- package/dist/ui/LlmsTxt.js.map +0 -1
- package/dist/ui/MemorySelector.d.ts.map +0 -1
- package/dist/ui/MemorySelector.js.map +0 -1
- package/dist/ui/NameInput.d.ts.map +0 -1
- package/dist/ui/NameInput.js.map +0 -1
- package/dist/ui/OptionSelector.d.ts.map +0 -1
- package/dist/ui/OptionSelector.js.map +0 -1
- package/dist/ui/Plugin.d.ts.map +0 -1
- package/dist/ui/Plugin.js.map +0 -1
- package/dist/ui/Progress.d.ts.map +0 -1
- package/dist/ui/Progress.js.map +0 -1
- package/dist/ui/StackSelector.d.ts.map +0 -1
- package/dist/ui/StackSelector.js.map +0 -1
- package/dist/ui/Summary.d.ts.map +0 -1
- package/dist/ui/Summary.js.map +0 -1
- package/dist/ui/Welcome.d.ts.map +0 -1
- package/dist/ui/Welcome.js.map +0 -1
- package/dist/ui/theme.d.ts.map +0 -1
- package/dist/ui/theme.js.map +0 -1
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret scanner — detects leaked credentials in source files using
|
|
3
|
+
* a curated regex bundle. Designed for pre-commit hooks and CI gates.
|
|
4
|
+
*/
|
|
5
|
+
import fs from "fs-extra";
|
|
6
|
+
import path from "path";
|
|
7
|
+
// ── Regex Bundle ──
|
|
8
|
+
export const SECRET_PATTERNS = [
|
|
9
|
+
// AWS
|
|
10
|
+
{
|
|
11
|
+
id: "aws-access-key",
|
|
12
|
+
label: "AWS Access Key ID",
|
|
13
|
+
pattern: /\bAKIA[0-9A-Z]{16}\b/,
|
|
14
|
+
severity: "critical",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: "aws-secret-key",
|
|
18
|
+
label: "AWS Secret Access Key",
|
|
19
|
+
pattern: /(?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=])/,
|
|
20
|
+
severity: "critical",
|
|
21
|
+
},
|
|
22
|
+
// Google
|
|
23
|
+
{
|
|
24
|
+
id: "gcp-api-key",
|
|
25
|
+
label: "Google API Key",
|
|
26
|
+
pattern: /\bAIza[0-9A-Za-z_-]{35}\b/,
|
|
27
|
+
severity: "high",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "gcp-oauth",
|
|
31
|
+
label: "Google OAuth Client Secret",
|
|
32
|
+
pattern: /\bGOCSPX-[A-Za-z0-9_-]{28}\b/,
|
|
33
|
+
severity: "critical",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "gcp-sa-key",
|
|
37
|
+
label: "GCP Service Account Key",
|
|
38
|
+
pattern: /"type":\s*"service_account"/,
|
|
39
|
+
severity: "critical",
|
|
40
|
+
},
|
|
41
|
+
// GitHub
|
|
42
|
+
{
|
|
43
|
+
id: "github-pat",
|
|
44
|
+
label: "GitHub Personal Access Token",
|
|
45
|
+
pattern: /\bghp_[A-Za-z0-9]{36}\b/,
|
|
46
|
+
severity: "critical",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "github-oauth",
|
|
50
|
+
label: "GitHub OAuth Token",
|
|
51
|
+
pattern: /\bgho_[A-Za-z0-9]{36}\b/,
|
|
52
|
+
severity: "critical",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "github-app-token",
|
|
56
|
+
label: "GitHub App Token",
|
|
57
|
+
pattern: /\bghu_[A-Za-z0-9]{36}\b/,
|
|
58
|
+
severity: "high",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "github-fine-pat",
|
|
62
|
+
label: "GitHub Fine-Grained PAT",
|
|
63
|
+
pattern: /\bgithub_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{59}\b/,
|
|
64
|
+
severity: "critical",
|
|
65
|
+
},
|
|
66
|
+
// Stripe
|
|
67
|
+
{
|
|
68
|
+
id: "stripe-secret",
|
|
69
|
+
label: "Stripe Secret Key",
|
|
70
|
+
pattern: /\bsk_live_[A-Za-z0-9]{24,}\b/,
|
|
71
|
+
severity: "critical",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "stripe-restricted",
|
|
75
|
+
label: "Stripe Restricted Key",
|
|
76
|
+
pattern: /\brk_live_[A-Za-z0-9]{24,}\b/,
|
|
77
|
+
severity: "critical",
|
|
78
|
+
},
|
|
79
|
+
// Slack
|
|
80
|
+
{
|
|
81
|
+
id: "slack-bot-token",
|
|
82
|
+
label: "Slack Bot Token",
|
|
83
|
+
pattern: /\bxoxb-[0-9]{10,}-[0-9]{10,}-[A-Za-z0-9]{24,}\b/,
|
|
84
|
+
severity: "high",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "slack-webhook",
|
|
88
|
+
label: "Slack Webhook URL",
|
|
89
|
+
pattern: /https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/,
|
|
90
|
+
severity: "high",
|
|
91
|
+
},
|
|
92
|
+
// Generic
|
|
93
|
+
{
|
|
94
|
+
id: "private-key",
|
|
95
|
+
label: "Private Key",
|
|
96
|
+
pattern: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,
|
|
97
|
+
severity: "critical",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "jwt-token",
|
|
101
|
+
label: "JSON Web Token",
|
|
102
|
+
pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/,
|
|
103
|
+
severity: "high",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "bearer-token",
|
|
107
|
+
label: "Bearer Token",
|
|
108
|
+
pattern: /[Bb]earer\s+[A-Za-z0-9_-]{20,}/,
|
|
109
|
+
severity: "medium",
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: "password-assign",
|
|
113
|
+
label: "Password Assignment",
|
|
114
|
+
pattern: /(?:password|passwd|pwd|secret)\s*[:=]\s*['"][^'"]{8,}['"]/,
|
|
115
|
+
severity: "high",
|
|
116
|
+
},
|
|
117
|
+
// Cloud providers
|
|
118
|
+
{
|
|
119
|
+
id: "azure-connection",
|
|
120
|
+
label: "Azure Connection String",
|
|
121
|
+
pattern: /DefaultEndpointsProtocol=https;AccountName=[^;]+;AccountKey=[A-Za-z0-9+/=]+/,
|
|
122
|
+
severity: "critical",
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: "sendgrid-key",
|
|
126
|
+
label: "SendGrid API Key",
|
|
127
|
+
pattern: /\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}\b/,
|
|
128
|
+
severity: "high",
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: "twilio-key",
|
|
132
|
+
label: "Twilio API Key",
|
|
133
|
+
pattern: /\bSK[0-9a-fA-F]{32}\b/,
|
|
134
|
+
severity: "high",
|
|
135
|
+
},
|
|
136
|
+
// Database
|
|
137
|
+
{
|
|
138
|
+
id: "db-connection",
|
|
139
|
+
label: "Database Connection String",
|
|
140
|
+
pattern: /(?:mongodb|postgres|mysql|redis):\/\/[^:\s]+:[^@\s]+@[^\s]+/,
|
|
141
|
+
severity: "critical",
|
|
142
|
+
},
|
|
143
|
+
// Anthropic / OpenAI
|
|
144
|
+
{
|
|
145
|
+
id: "anthropic-key",
|
|
146
|
+
label: "Anthropic API Key",
|
|
147
|
+
pattern: /\bsk-ant-api03-[A-Za-z0-9_-]{93}\b/,
|
|
148
|
+
severity: "critical",
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "openai-key",
|
|
152
|
+
label: "OpenAI API Key",
|
|
153
|
+
pattern: /\bsk-[A-Za-z0-9]{48,}\b/,
|
|
154
|
+
severity: "critical",
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
// ── Masking ──
|
|
158
|
+
export function maskSecret(value) {
|
|
159
|
+
if (value.length <= 8)
|
|
160
|
+
return "****";
|
|
161
|
+
return `${value.slice(0, 4)}...${value.slice(-2)}`;
|
|
162
|
+
}
|
|
163
|
+
// ── File filtering ──
|
|
164
|
+
const BINARY_EXTENSIONS = new Set([
|
|
165
|
+
".png",
|
|
166
|
+
".jpg",
|
|
167
|
+
".jpeg",
|
|
168
|
+
".gif",
|
|
169
|
+
".ico",
|
|
170
|
+
".svg",
|
|
171
|
+
".woff",
|
|
172
|
+
".woff2",
|
|
173
|
+
".ttf",
|
|
174
|
+
".eot",
|
|
175
|
+
".mp3",
|
|
176
|
+
".mp4",
|
|
177
|
+
".zip",
|
|
178
|
+
".gz",
|
|
179
|
+
".tar",
|
|
180
|
+
".pdf",
|
|
181
|
+
".exe",
|
|
182
|
+
".dll",
|
|
183
|
+
".so",
|
|
184
|
+
".dylib",
|
|
185
|
+
".o",
|
|
186
|
+
".a",
|
|
187
|
+
]);
|
|
188
|
+
const SKIP_DIRS = new Set([
|
|
189
|
+
"node_modules",
|
|
190
|
+
".git",
|
|
191
|
+
"dist",
|
|
192
|
+
"build",
|
|
193
|
+
".next",
|
|
194
|
+
"__pycache__",
|
|
195
|
+
"target",
|
|
196
|
+
"vendor",
|
|
197
|
+
".venv",
|
|
198
|
+
"venv",
|
|
199
|
+
".tox",
|
|
200
|
+
".mypy_cache",
|
|
201
|
+
"coverage",
|
|
202
|
+
".nyc_output",
|
|
203
|
+
".cache",
|
|
204
|
+
]);
|
|
205
|
+
export function shouldScanFile(filePath) {
|
|
206
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
207
|
+
if (BINARY_EXTENSIONS.has(ext))
|
|
208
|
+
return false;
|
|
209
|
+
if (filePath.includes("lock") && (ext === ".json" || ext === ".yaml"))
|
|
210
|
+
return false;
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
export function shouldSkipDir(dirName) {
|
|
214
|
+
return SKIP_DIRS.has(dirName);
|
|
215
|
+
}
|
|
216
|
+
// ── Scanner ──
|
|
217
|
+
export function scanContent(content, filePath, patterns = SECRET_PATTERNS) {
|
|
218
|
+
const findings = [];
|
|
219
|
+
const lines = content.split("\n");
|
|
220
|
+
for (let i = 0; i < lines.length; i++) {
|
|
221
|
+
const line = lines[i];
|
|
222
|
+
for (const pat of patterns) {
|
|
223
|
+
const match = pat.pattern.exec(line);
|
|
224
|
+
if (match) {
|
|
225
|
+
findings.push({
|
|
226
|
+
patternId: pat.id,
|
|
227
|
+
label: pat.label,
|
|
228
|
+
severity: pat.severity,
|
|
229
|
+
file: filePath,
|
|
230
|
+
line: i + 1,
|
|
231
|
+
match: maskSecret(match[0]),
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return findings;
|
|
237
|
+
}
|
|
238
|
+
async function collectFiles(dir) {
|
|
239
|
+
const results = [];
|
|
240
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
241
|
+
for (const entry of entries) {
|
|
242
|
+
if (entry.isDirectory()) {
|
|
243
|
+
if (!shouldSkipDir(entry.name)) {
|
|
244
|
+
results.push(...(await collectFiles(path.join(dir, entry.name))));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else if (entry.isFile() && shouldScanFile(entry.name)) {
|
|
248
|
+
results.push(path.join(dir, entry.name));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return results;
|
|
252
|
+
}
|
|
253
|
+
export async function scanDirectory(dir, patterns = SECRET_PATTERNS) {
|
|
254
|
+
const files = await collectFiles(dir);
|
|
255
|
+
const allFindings = [];
|
|
256
|
+
for (const file of files) {
|
|
257
|
+
try {
|
|
258
|
+
const content = await fs.readFile(file, "utf-8");
|
|
259
|
+
const rel = path.relative(dir, file);
|
|
260
|
+
allFindings.push(...scanContent(content, rel, patterns));
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
// Skip unreadable files
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
findings: allFindings,
|
|
268
|
+
filesScanned: files.length,
|
|
269
|
+
patternsUsed: patterns.length,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=secret-scanner.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trail of Bits security analysis patterns for CI pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Integrates static analysis via CodeQL/Semgrep rule patterns for
|
|
5
|
+
* vulnerability detection, variant analysis, and structured reporting
|
|
6
|
+
* with severity levels (critical, high, medium, low).
|
|
7
|
+
*/
|
|
8
|
+
import type { SecuritySeverity } from "../types/index.js";
|
|
9
|
+
export type AnalysisEngine = "semgrep" | "codeql";
|
|
10
|
+
export interface SecurityAnalysisFinding {
|
|
11
|
+
ruleId: string;
|
|
12
|
+
engine: AnalysisEngine;
|
|
13
|
+
severity: SecuritySeverity;
|
|
14
|
+
message: string;
|
|
15
|
+
file: string;
|
|
16
|
+
line: number;
|
|
17
|
+
column?: number;
|
|
18
|
+
category: string;
|
|
19
|
+
cwe?: string;
|
|
20
|
+
owasp?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SecurityAnalysisReport {
|
|
23
|
+
engine: AnalysisEngine;
|
|
24
|
+
timestamp: string;
|
|
25
|
+
projectDir: string;
|
|
26
|
+
findings: SecurityAnalysisFinding[];
|
|
27
|
+
summary: SecurityAnalysisSummary;
|
|
28
|
+
}
|
|
29
|
+
export interface SecurityAnalysisSummary {
|
|
30
|
+
total: number;
|
|
31
|
+
bySeverity: Record<SecuritySeverity, number>;
|
|
32
|
+
byCategory: Record<string, number>;
|
|
33
|
+
passed: boolean;
|
|
34
|
+
failThreshold: SecuritySeverity;
|
|
35
|
+
}
|
|
36
|
+
export interface SecurityAnalysisOptions {
|
|
37
|
+
/** Minimum severity to cause CI failure (default: "high") */
|
|
38
|
+
failThreshold?: SecuritySeverity;
|
|
39
|
+
/** Custom rules directory (Semgrep YAML or CodeQL QL files) */
|
|
40
|
+
rulesDir?: string;
|
|
41
|
+
/** Specific rule IDs to include (empty = all) */
|
|
42
|
+
includeRules?: string[];
|
|
43
|
+
/** Specific rule IDs to exclude */
|
|
44
|
+
excludeRules?: string[];
|
|
45
|
+
/** Target directories to scan (default: ["."]) */
|
|
46
|
+
targetDirs?: string[];
|
|
47
|
+
}
|
|
48
|
+
export interface SemgrepRule {
|
|
49
|
+
id: string;
|
|
50
|
+
severity: SecuritySeverity;
|
|
51
|
+
message: string;
|
|
52
|
+
category: string;
|
|
53
|
+
pattern: string;
|
|
54
|
+
languages: string[];
|
|
55
|
+
cwe?: string;
|
|
56
|
+
owasp?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Trail of Bits-inspired static analysis rules ported to pattern matching.
|
|
60
|
+
* These cover the most common vulnerability classes found in security audits.
|
|
61
|
+
*/
|
|
62
|
+
export declare const BUILTIN_RULES: SemgrepRule[];
|
|
63
|
+
export declare function detectFileLanguage(filePath: string): string | null;
|
|
64
|
+
export declare function matchRule(rule: SemgrepRule, content: string, filePath: string): SecurityAnalysisFinding[];
|
|
65
|
+
export declare function collectFiles(dir: string): Promise<string[]>;
|
|
66
|
+
export declare function severityAtOrAbove(severity: SecuritySeverity, threshold: SecuritySeverity): boolean;
|
|
67
|
+
export declare function buildSummary(findings: SecurityAnalysisFinding[], failThreshold: SecuritySeverity): SecurityAnalysisSummary;
|
|
68
|
+
export declare function buildReport(findings: SecurityAnalysisFinding[], projectDir: string, options?: SecurityAnalysisOptions): SecurityAnalysisReport;
|
|
69
|
+
export declare function filterRules(rules: SemgrepRule[], options?: SecurityAnalysisOptions): SemgrepRule[];
|
|
70
|
+
export declare function loadCustomRules(rulesDir: string): Promise<SemgrepRule[]>;
|
|
71
|
+
export declare function runSecurityAnalysis(projectDir: string, options?: SecurityAnalysisOptions): Promise<SecurityAnalysisReport>;
|
|
72
|
+
export declare function formatReportText(report: SecurityAnalysisReport): string;
|
|
73
|
+
export declare function formatReportJson(report: SecurityAnalysisReport): string;
|
|
74
|
+
//# sourceMappingURL=security-analysis.d.ts.map
|