antigravity-ai-kit 2.1.0 → 3.0.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/.agent/README.md +4 -4
- package/.agent/agents/README.md +16 -12
- package/.agent/agents/architect.md +1 -0
- package/.agent/agents/backend-specialist.md +11 -0
- package/.agent/agents/code-reviewer.md +1 -0
- package/.agent/agents/database-architect.md +11 -0
- package/.agent/agents/devops-engineer.md +11 -0
- package/.agent/agents/e2e-runner.md +1 -0
- package/.agent/agents/explorer-agent.md +11 -0
- package/.agent/agents/frontend-specialist.md +11 -0
- package/.agent/agents/mobile-developer.md +11 -0
- package/.agent/agents/performance-optimizer.md +11 -0
- package/.agent/agents/planner.md +1 -0
- package/.agent/agents/refactor-cleaner.md +1 -0
- package/.agent/agents/reliability-engineer.md +11 -0
- package/.agent/agents/security-reviewer.md +1 -0
- package/.agent/agents/sprint-orchestrator.md +10 -0
- package/.agent/agents/tdd-guide.md +1 -0
- package/.agent/commands/code-review.md +1 -0
- package/.agent/commands/debug.md +1 -0
- package/.agent/commands/deploy.md +1 -0
- package/.agent/commands/help.md +252 -31
- package/.agent/commands/plan.md +1 -0
- package/.agent/commands/status.md +1 -0
- package/.agent/commands/tdd.md +1 -0
- package/.agent/contexts/brainstorm.md +26 -0
- package/.agent/contexts/debug.md +28 -0
- package/.agent/contexts/implement.md +29 -0
- package/.agent/contexts/review.md +27 -0
- package/.agent/contexts/ship.md +28 -0
- package/.agent/engine/identity.json +13 -0
- package/.agent/engine/loading-rules.json +23 -1
- package/.agent/engine/marketplace-index.json +29 -0
- package/.agent/engine/reliability-config.json +14 -0
- package/.agent/engine/sdlc-map.json +44 -0
- package/.agent/engine/workflow-state.json +28 -2
- package/.agent/hooks/hooks.json +27 -25
- package/.agent/manifest.json +12 -4
- package/.agent/rules.md +2 -1
- package/.agent/skills/README.md +10 -5
- package/.agent/skills/i18n-localization/SKILL.md +191 -0
- package/.agent/skills/mcp-integration/SKILL.md +224 -0
- package/.agent/skills/parallel-agents/SKILL.md +1 -1
- package/.agent/skills/shell-conventions/SKILL.md +92 -0
- package/.agent/skills/ui-ux-pro-max/SKILL.md +557 -0
- package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/.agent/templates/adr-template.md +32 -0
- package/.agent/templates/bug-report.md +37 -0
- package/.agent/templates/feature-request.md +32 -0
- package/.agent/workflows/README.md +92 -78
- package/.agent/workflows/brainstorm.md +154 -100
- package/.agent/workflows/create.md +142 -75
- package/.agent/workflows/debug.md +157 -98
- package/.agent/workflows/deploy.md +195 -144
- package/.agent/workflows/enhance.md +157 -65
- package/.agent/workflows/orchestrate.md +171 -114
- package/.agent/workflows/plan.md +147 -72
- package/.agent/workflows/preview.md +140 -83
- package/.agent/workflows/quality-gate.md +196 -0
- package/.agent/workflows/retrospective.md +197 -0
- package/.agent/workflows/review.md +188 -0
- package/.agent/workflows/status.md +142 -91
- package/.agent/workflows/test.md +168 -95
- package/.agent/workflows/ui-ux-pro-max.md +181 -127
- package/README.md +215 -78
- package/bin/ag-kit.js +344 -10
- package/lib/agent-registry.js +214 -0
- package/lib/agent-reputation.js +351 -0
- package/lib/cli-commands.js +235 -0
- package/lib/conflict-detector.js +245 -0
- package/lib/engineering-manager.js +354 -0
- package/lib/error-budget.js +294 -0
- package/lib/hook-system.js +252 -0
- package/lib/identity.js +245 -0
- package/lib/loading-engine.js +208 -0
- package/lib/marketplace.js +298 -0
- package/lib/plugin-system.js +604 -0
- package/lib/security-scanner.js +309 -0
- package/lib/self-healing.js +434 -0
- package/lib/session-manager.js +261 -0
- package/lib/skill-sandbox.js +244 -0
- package/lib/task-governance.js +523 -0
- package/lib/task-model.js +317 -0
- package/lib/updater.js +201 -0
- package/lib/verify.js +240 -0
- package/lib/workflow-engine.js +353 -0
- package/lib/workflow-persistence.js +160 -0
- package/package.json +7 -3
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antigravity AI Kit — Enhanced Security Scanner
|
|
3
|
+
*
|
|
4
|
+
* Runtime injection detection, secret scanning, and anomaly alerting
|
|
5
|
+
* for agent and skill files.
|
|
6
|
+
*
|
|
7
|
+
* @module lib/security-scanner
|
|
8
|
+
* @author Emre Dursun
|
|
9
|
+
* @since v3.0.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
|
|
17
|
+
const AGENT_DIR = '.agent';
|
|
18
|
+
|
|
19
|
+
/** Paths that are known-safe and should be excluded from injection/secret scanning */
|
|
20
|
+
const ALLOWLISTED_DIRS = ['decisions', 'engine'];
|
|
21
|
+
|
|
22
|
+
/** Prompt injection patterns */
|
|
23
|
+
const INJECTION_PATTERNS = [
|
|
24
|
+
{ pattern: /ignore\s+(all\s+)?previous\s+instructions/gi, name: 'ignore-previous', severity: 'critical' },
|
|
25
|
+
{ pattern: /system\s+override/gi, name: 'system-override', severity: 'critical' },
|
|
26
|
+
{ pattern: /you\s+are\s+now\s+a/gi, name: 'role-hijacking', severity: 'critical' },
|
|
27
|
+
{ pattern: /act\s+as\s+(if\s+you\s+are|a\s+different)/gi, name: 'persona-override', severity: 'high' },
|
|
28
|
+
{ pattern: /forget\s+(everything|your|all)/gi, name: 'memory-wipe', severity: 'critical' },
|
|
29
|
+
{ pattern: /disregard\s+(all|your|the)/gi, name: 'disregard-instructions', severity: 'high' },
|
|
30
|
+
{ pattern: /\bDAN\b.*\bjailbreak\b/gi, name: 'jailbreak-reference', severity: 'critical' },
|
|
31
|
+
{ pattern: /bypass\s+(safety|security|filter|restriction)/gi, name: 'bypass-safety', severity: 'critical' },
|
|
32
|
+
{ pattern: /pretend\s+(you|that)\s+(are|have)\s+no\s+(restrictions|rules|limits)/gi, name: 'pretend-no-rules', severity: 'high' },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
/** Secret patterns */
|
|
36
|
+
const SECRET_PATTERNS = [
|
|
37
|
+
{ pattern: /(?:api[_-]?key|apikey)\s*[:=]\s*['"][A-Za-z0-9_\-]{20,}['"]/gi, name: 'api-key', severity: 'critical' },
|
|
38
|
+
{ pattern: /ghp_[A-Za-z0-9_]{36,}/g, name: 'github-pat', severity: 'critical' },
|
|
39
|
+
{ pattern: /gho_[A-Za-z0-9_]{36,}/g, name: 'github-oauth', severity: 'critical' },
|
|
40
|
+
{ pattern: /sk-[A-Za-z0-9]{32,}/g, name: 'openai-key', severity: 'critical' },
|
|
41
|
+
{ pattern: /AKIA[A-Z0-9]{16}/g, name: 'aws-access-key', severity: 'critical' },
|
|
42
|
+
{ pattern: /-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----/g, name: 'private-key', severity: 'critical' },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
/** Maximum expected file size for agent/skill files (100KB) */
|
|
46
|
+
const MAX_EXPECTED_SIZE = 100 * 1024;
|
|
47
|
+
/** Minimum expected file size for legitimate files */
|
|
48
|
+
const MIN_EXPECTED_SIZE = 50;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @typedef {object} SecurityFinding
|
|
52
|
+
* @property {string} type - Finding type (injection, secret, anomaly)
|
|
53
|
+
* @property {string} name - Pattern name
|
|
54
|
+
* @property {'critical' | 'high' | 'medium' | 'low'} severity - Finding severity
|
|
55
|
+
* @property {string} file - File where finding was detected
|
|
56
|
+
* @property {number} [line] - Line number
|
|
57
|
+
* @property {string} detail - Description of the finding
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @typedef {object} SecurityReport
|
|
62
|
+
* @property {number} filesScanned - Total files scanned
|
|
63
|
+
* @property {number} criticalCount - Critical findings count
|
|
64
|
+
* @property {number} highCount - High findings count
|
|
65
|
+
* @property {number} mediumCount - Medium findings count
|
|
66
|
+
* @property {number} lowCount - Low findings count
|
|
67
|
+
* @property {SecurityFinding[]} findings - All findings
|
|
68
|
+
* @property {boolean} clean - Whether no critical/high findings exist
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Recursively collects scannable files from a directory.
|
|
73
|
+
*
|
|
74
|
+
* @param {string} dirPath - Directory to scan
|
|
75
|
+
* @param {string} projectRoot - Project root for relative paths
|
|
76
|
+
* @returns {string[]}
|
|
77
|
+
*/
|
|
78
|
+
function collectFiles(dirPath, projectRoot) {
|
|
79
|
+
/** @type {string[]} */
|
|
80
|
+
const files = [];
|
|
81
|
+
|
|
82
|
+
if (!fs.existsSync(dirPath)) {
|
|
83
|
+
return files;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
87
|
+
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
90
|
+
|
|
91
|
+
if (entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== '.git') {
|
|
92
|
+
files.push(...collectFiles(fullPath, projectRoot));
|
|
93
|
+
} else if (entry.isFile() && (entry.name.endsWith('.md') || entry.name.endsWith('.json') || entry.name.endsWith('.js'))) {
|
|
94
|
+
files.push(fullPath);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return files;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Scans for prompt injection patterns.
|
|
103
|
+
*
|
|
104
|
+
* @param {string} projectRoot - Root directory of the project
|
|
105
|
+
* @returns {SecurityFinding[]}
|
|
106
|
+
*/
|
|
107
|
+
function scanForInjection(projectRoot) {
|
|
108
|
+
const agentDir = path.join(projectRoot, AGENT_DIR);
|
|
109
|
+
const files = collectFiles(agentDir, projectRoot);
|
|
110
|
+
/** @type {SecurityFinding[]} */
|
|
111
|
+
const findings = [];
|
|
112
|
+
|
|
113
|
+
for (const file of files) {
|
|
114
|
+
const relativePath = path.relative(path.join(projectRoot, AGENT_DIR), file);
|
|
115
|
+
|
|
116
|
+
// Skip allowlisted directories (governance docs, engine configs)
|
|
117
|
+
if (ALLOWLISTED_DIRS.some((dir) => relativePath.startsWith(dir + path.sep) || relativePath.startsWith(dir + '/'))) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
121
|
+
const lines = content.split('\n');
|
|
122
|
+
|
|
123
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
124
|
+
const line = lines[lineIndex];
|
|
125
|
+
|
|
126
|
+
for (const { pattern, name, severity } of INJECTION_PATTERNS) {
|
|
127
|
+
// Reset regex lastIndex for global patterns
|
|
128
|
+
pattern.lastIndex = 0;
|
|
129
|
+
if (pattern.test(line)) {
|
|
130
|
+
findings.push({
|
|
131
|
+
type: 'injection',
|
|
132
|
+
name,
|
|
133
|
+
severity,
|
|
134
|
+
file: path.relative(projectRoot, file),
|
|
135
|
+
line: lineIndex + 1,
|
|
136
|
+
detail: `Prompt injection pattern "${name}" detected`,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return findings;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Scans for hardcoded secrets.
|
|
148
|
+
*
|
|
149
|
+
* @param {string} projectRoot - Root directory of the project
|
|
150
|
+
* @returns {SecurityFinding[]}
|
|
151
|
+
*/
|
|
152
|
+
function scanForSecrets(projectRoot) {
|
|
153
|
+
const agentDir = path.join(projectRoot, AGENT_DIR);
|
|
154
|
+
const files = collectFiles(agentDir, projectRoot);
|
|
155
|
+
/** @type {SecurityFinding[]} */
|
|
156
|
+
const findings = [];
|
|
157
|
+
|
|
158
|
+
for (const file of files) {
|
|
159
|
+
const relativePath = path.relative(path.join(projectRoot, AGENT_DIR), file);
|
|
160
|
+
|
|
161
|
+
// Skip allowlisted directories and skill documentation
|
|
162
|
+
if (ALLOWLISTED_DIRS.some((dir) => relativePath.startsWith(dir + path.sep) || relativePath.startsWith(dir + '/'))) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Skip files in skills that mention password in example/testing contexts
|
|
167
|
+
const isSkillDoc = relativePath.includes('skills' + path.sep) || relativePath.includes('skills/');
|
|
168
|
+
|
|
169
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
170
|
+
const lines = content.split('\n');
|
|
171
|
+
|
|
172
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
173
|
+
const line = lines[lineIndex];
|
|
174
|
+
|
|
175
|
+
for (const { pattern, name, severity } of SECRET_PATTERNS) {
|
|
176
|
+
pattern.lastIndex = 0;
|
|
177
|
+
if (pattern.test(line)) {
|
|
178
|
+
findings.push({
|
|
179
|
+
type: 'secret',
|
|
180
|
+
name,
|
|
181
|
+
severity,
|
|
182
|
+
file: path.relative(projectRoot, file),
|
|
183
|
+
line: lineIndex + 1,
|
|
184
|
+
detail: `Potential ${name} found — never commit secrets`,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return findings;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Scans for file anomalies (unusual sizes, unexpected file types).
|
|
196
|
+
*
|
|
197
|
+
* @param {string} projectRoot - Root directory of the project
|
|
198
|
+
* @returns {SecurityFinding[]}
|
|
199
|
+
*/
|
|
200
|
+
function scanForAnomalies(projectRoot) {
|
|
201
|
+
const agentDir = path.join(projectRoot, AGENT_DIR);
|
|
202
|
+
/** @type {SecurityFinding[]} */
|
|
203
|
+
const findings = [];
|
|
204
|
+
|
|
205
|
+
if (!fs.existsSync(agentDir)) {
|
|
206
|
+
return findings;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const allFiles = collectAllFiles(agentDir);
|
|
210
|
+
|
|
211
|
+
for (const file of allFiles) {
|
|
212
|
+
const stats = fs.statSync(file);
|
|
213
|
+
const relativePath = path.relative(projectRoot, file);
|
|
214
|
+
const ext = path.extname(file).toLowerCase();
|
|
215
|
+
|
|
216
|
+
// Check for binary files in agent directories
|
|
217
|
+
const textExtensions = ['.md', '.json', '.js', '.ts', '.yaml', '.yml', '.txt', '.csv', '.toml'];
|
|
218
|
+
if (!textExtensions.includes(ext) && ext !== '') {
|
|
219
|
+
findings.push({
|
|
220
|
+
type: 'anomaly',
|
|
221
|
+
name: 'unexpected-file-type',
|
|
222
|
+
severity: 'medium',
|
|
223
|
+
file: relativePath,
|
|
224
|
+
detail: `Unexpected file type "${ext}" in agent directory`,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Check for oversized files
|
|
229
|
+
if (stats.size > MAX_EXPECTED_SIZE) {
|
|
230
|
+
findings.push({
|
|
231
|
+
type: 'anomaly',
|
|
232
|
+
name: 'oversized-file',
|
|
233
|
+
severity: 'high',
|
|
234
|
+
file: relativePath,
|
|
235
|
+
detail: `File size ${Math.round(stats.size / 1024)}KB exceeds ${MAX_EXPECTED_SIZE / 1024}KB limit`,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Check for suspiciously small files (possible stubs)
|
|
240
|
+
if (stats.size < MIN_EXPECTED_SIZE && stats.size > 0 && textExtensions.includes(ext)) {
|
|
241
|
+
findings.push({
|
|
242
|
+
type: 'anomaly',
|
|
243
|
+
name: 'tiny-file',
|
|
244
|
+
severity: 'low',
|
|
245
|
+
file: relativePath,
|
|
246
|
+
detail: `File is only ${stats.size} bytes — possible incomplete stub`,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return findings;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Collects ALL files (not just text) from a directory.
|
|
256
|
+
*
|
|
257
|
+
* @param {string} dirPath - Directory to scan
|
|
258
|
+
* @returns {string[]}
|
|
259
|
+
*/
|
|
260
|
+
function collectAllFiles(dirPath) {
|
|
261
|
+
/** @type {string[]} */
|
|
262
|
+
const files = [];
|
|
263
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
264
|
+
|
|
265
|
+
for (const entry of entries) {
|
|
266
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
267
|
+
|
|
268
|
+
if (entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== '.git') {
|
|
269
|
+
files.push(...collectAllFiles(fullPath));
|
|
270
|
+
} else if (entry.isFile()) {
|
|
271
|
+
files.push(fullPath);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return files;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Generates a comprehensive security report.
|
|
280
|
+
*
|
|
281
|
+
* @param {string} projectRoot - Root directory of the project
|
|
282
|
+
* @returns {SecurityReport}
|
|
283
|
+
*/
|
|
284
|
+
function getSecurityReport(projectRoot) {
|
|
285
|
+
const injectionFindings = scanForInjection(projectRoot);
|
|
286
|
+
const secretFindings = scanForSecrets(projectRoot);
|
|
287
|
+
const anomalyFindings = scanForAnomalies(projectRoot);
|
|
288
|
+
|
|
289
|
+
const allFindings = [...injectionFindings, ...secretFindings, ...anomalyFindings];
|
|
290
|
+
const agentDir = path.join(projectRoot, AGENT_DIR);
|
|
291
|
+
const filesScanned = fs.existsSync(agentDir) ? collectAllFiles(agentDir).length : 0;
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
filesScanned,
|
|
295
|
+
criticalCount: allFindings.filter((f) => f.severity === 'critical').length,
|
|
296
|
+
highCount: allFindings.filter((f) => f.severity === 'high').length,
|
|
297
|
+
mediumCount: allFindings.filter((f) => f.severity === 'medium').length,
|
|
298
|
+
lowCount: allFindings.filter((f) => f.severity === 'low').length,
|
|
299
|
+
findings: allFindings,
|
|
300
|
+
clean: allFindings.filter((f) => f.severity === 'critical' || f.severity === 'high').length === 0,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
module.exports = {
|
|
305
|
+
scanForInjection,
|
|
306
|
+
scanForSecrets,
|
|
307
|
+
scanForAnomalies,
|
|
308
|
+
getSecurityReport,
|
|
309
|
+
};
|