agentverify 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AI Blockchain Ventures LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # agentverify
2
+
3
+ **Execution trust analysis for AI agents — CLI and SDK**
4
+
5
+ Scan AI agent configurations for security issues, credential exposure, and governance gaps. Results save automatically to your Agent Verify dashboard.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g agentverify
11
+ ```
12
+
13
+ ## CLI Usage
14
+
15
+ ### Scan a directory
16
+
17
+ ```bash
18
+ agentverify scan ./agents --key av_your_key
19
+ ```
20
+
21
+ ### Scan a single file
22
+
23
+ ```bash
24
+ agentverify scan --file agent.json --key av_your_key
25
+ ```
26
+
27
+ ### Use environment variable
28
+
29
+ ```bash
30
+ export AGENTVERIFY_API_KEY=av_your_key
31
+ agentverify scan ./agents
32
+ ```
33
+
34
+ ### JSON output (for CI/CD)
35
+
36
+ ```bash
37
+ agentverify scan . --key av_your_key --json
38
+ ```
39
+
40
+ ## SDK Usage
41
+
42
+ ```ts
43
+ import { scan, scanMany } from 'agentverify'
44
+ ```
45
+
46
+ ### Scan a single file
47
+
48
+ ```ts
49
+ const result = await scan(
50
+ { content: agentCode, fileName: 'agent.js' },
51
+ { apiKey: process.env.AGENTVERIFY_API_KEY }
52
+ )
53
+
54
+ console.log(result.verdict) // 'VERIFIED' | 'NOT VERIFIED'
55
+ console.log(result.riskScore) // 0-100
56
+ console.log(result.findings) // Array of security findings
57
+ ```
58
+
59
+ ### Scan multiple files
60
+
61
+ ```ts
62
+ const results = await scanMany(
63
+ [
64
+ { content: agent1Code, fileName: 'agent1.js' },
65
+ { content: agent2Code, fileName: 'agent2.js' },
66
+ ],
67
+ { apiKey: process.env.AGENTVERIFY_API_KEY }
68
+ )
69
+ ```
70
+
71
+ ## CI/CD Integration
72
+
73
+ ### GitHub Actions
74
+
75
+ ```yaml
76
+ - name: Scan agents
77
+ run: npx agentverify scan ./agents --key ${{ secrets.AGENTVERIFY_API_KEY }} --json
78
+ ```
79
+
80
+ ## Get your API key
81
+
82
+ Sign up at https://agentverify.ai and go to Dashboard → API
83
+
84
+ ## License
85
+
86
+ MIT — AI Blockchain Ventures LLC
@@ -0,0 +1,75 @@
1
+ // src/sdk.ts
2
+ var DEFAULT_API_URL = "https://agentverify-api.agentverify.workers.dev/v1/scan";
3
+ var DEFAULT_TIMEOUT = 3e4;
4
+ async function scan(input, options) {
5
+ const { apiKey, apiUrl = DEFAULT_API_URL, timeout = DEFAULT_TIMEOUT } = options;
6
+ if (!apiKey) {
7
+ throw new Error(
8
+ "API key required. Generate one at https://agentverify.ai/dashboard"
9
+ );
10
+ }
11
+ if (!input.content || input.content.trim().length === 0) {
12
+ throw new Error("content is required and cannot be empty");
13
+ }
14
+ const controller = new AbortController();
15
+ const timer = setTimeout(() => controller.abort(), timeout);
16
+ try {
17
+ const response = await fetch(apiUrl, {
18
+ method: "POST",
19
+ headers: {
20
+ "Authorization": `Bearer ${apiKey}`,
21
+ "Content-Type": "application/json",
22
+ "User-Agent": "agentverify-sdk/1.0.0"
23
+ },
24
+ body: JSON.stringify({
25
+ content: input.content,
26
+ fileName: input.fileName ?? "agent",
27
+ platform: input.platform
28
+ }),
29
+ signal: controller.signal
30
+ });
31
+ if (response.status === 401) {
32
+ throw new Error(
33
+ "Invalid API key. Generate one at https://agentverify.ai/dashboard"
34
+ );
35
+ }
36
+ if (response.status === 400) {
37
+ const err = await response.json().catch(() => ({}));
38
+ throw new Error(err.error ?? "Invalid request");
39
+ }
40
+ if (!response.ok) {
41
+ throw new Error(`API error: ${response.status} ${response.statusText}`);
42
+ }
43
+ const data = await response.json();
44
+ return data;
45
+ } catch (err) {
46
+ if (err instanceof Error && err.name === "AbortError") {
47
+ throw new Error(`Request timed out after ${timeout}ms`);
48
+ }
49
+ throw err;
50
+ } finally {
51
+ clearTimeout(timer);
52
+ }
53
+ }
54
+ async function scanMany(inputs, options, concurrency = 3) {
55
+ const results = [];
56
+ for (let i = 0; i < inputs.length; i += concurrency) {
57
+ const batch = inputs.slice(i, i + concurrency);
58
+ const batchResults = await Promise.allSettled(
59
+ batch.map((input) => scan(input, options))
60
+ );
61
+ batchResults.forEach((res, j) => {
62
+ if (res.status === "fulfilled") {
63
+ results.push({ input: batch[j], result: res.value, error: null });
64
+ } else {
65
+ results.push({ input: batch[j], result: null, error: res.reason instanceof Error ? res.reason.message : String(res.reason) });
66
+ }
67
+ });
68
+ }
69
+ return results;
70
+ }
71
+
72
+ export {
73
+ scan,
74
+ scanMany
75
+ };
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/cli.ts
5
+ var import_fs = require("fs");
6
+ var import_path = require("path");
7
+
8
+ // src/sdk.ts
9
+ var DEFAULT_API_URL = "https://agentverify-api.agentverify.workers.dev/v1/scan";
10
+ var DEFAULT_TIMEOUT = 3e4;
11
+ async function scan(input, options) {
12
+ const { apiKey, apiUrl = DEFAULT_API_URL, timeout = DEFAULT_TIMEOUT } = options;
13
+ if (!apiKey) {
14
+ throw new Error(
15
+ "API key required. Generate one at https://agentverify.ai/dashboard"
16
+ );
17
+ }
18
+ if (!input.content || input.content.trim().length === 0) {
19
+ throw new Error("content is required and cannot be empty");
20
+ }
21
+ const controller = new AbortController();
22
+ const timer = setTimeout(() => controller.abort(), timeout);
23
+ try {
24
+ const response = await fetch(apiUrl, {
25
+ method: "POST",
26
+ headers: {
27
+ "Authorization": `Bearer ${apiKey}`,
28
+ "Content-Type": "application/json",
29
+ "User-Agent": "agentverify-sdk/1.0.0"
30
+ },
31
+ body: JSON.stringify({
32
+ content: input.content,
33
+ fileName: input.fileName ?? "agent",
34
+ platform: input.platform
35
+ }),
36
+ signal: controller.signal
37
+ });
38
+ if (response.status === 401) {
39
+ throw new Error(
40
+ "Invalid API key. Generate one at https://agentverify.ai/dashboard"
41
+ );
42
+ }
43
+ if (response.status === 400) {
44
+ const err = await response.json().catch(() => ({}));
45
+ throw new Error(err.error ?? "Invalid request");
46
+ }
47
+ if (!response.ok) {
48
+ throw new Error(`API error: ${response.status} ${response.statusText}`);
49
+ }
50
+ const data = await response.json();
51
+ return data;
52
+ } catch (err) {
53
+ if (err instanceof Error && err.name === "AbortError") {
54
+ throw new Error(`Request timed out after ${timeout}ms`);
55
+ }
56
+ throw err;
57
+ } finally {
58
+ clearTimeout(timer);
59
+ }
60
+ }
61
+
62
+ // src/cli.ts
63
+ var VERSION = "1.0.0";
64
+ var API_URL = "https://agentverify-api.agentverify.workers.dev/v1/scan";
65
+ var c = {
66
+ reset: "\x1B[0m",
67
+ bold: "\x1B[1m",
68
+ dim: "\x1B[2m",
69
+ red: "\x1B[31m",
70
+ green: "\x1B[32m",
71
+ yellow: "\x1B[33m",
72
+ cyan: "\x1B[36m",
73
+ white: "\x1B[37m",
74
+ gray: "\x1B[90m"
75
+ };
76
+ var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".ts", ".py", ".json", ".yaml", ".yml", ".md", ".mjs", ".cjs"]);
77
+ var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".next", "vendor", "coverage", ".cache"]);
78
+ function collectFiles(dir) {
79
+ const files = [];
80
+ try {
81
+ const entries = (0, import_fs.readdirSync)(dir);
82
+ for (const entry of entries) {
83
+ if (SKIP_DIRS.has(entry)) continue;
84
+ const fullPath = (0, import_path.join)(dir, entry);
85
+ const stat = (0, import_fs.statSync)(fullPath);
86
+ if (stat.isDirectory()) {
87
+ files.push(...collectFiles(fullPath));
88
+ } else if (SUPPORTED_EXTENSIONS.has((0, import_path.extname)(entry).toLowerCase())) {
89
+ files.push(fullPath);
90
+ }
91
+ }
92
+ } catch {
93
+ }
94
+ return files;
95
+ }
96
+ function parseArgs(argv) {
97
+ const args = argv.slice(2);
98
+ const result = {
99
+ command: args[0] ?? "",
100
+ dir: ".",
101
+ key: "",
102
+ file: "",
103
+ json: false,
104
+ help: false,
105
+ version: false
106
+ };
107
+ if (result.command === "--help" || result.command === "-h") {
108
+ result.command = "";
109
+ result.help = true;
110
+ }
111
+ if (result.command === "--version" || result.command === "-v") {
112
+ result.command = "";
113
+ result.version = true;
114
+ }
115
+ for (let i = 1; i < args.length; i++) {
116
+ const arg = args[i];
117
+ if (arg === "--key" || arg === "-k") result.key = args[++i] ?? "";
118
+ else if (arg === "--file" || arg === "-f") result.file = args[++i] ?? "";
119
+ else if (arg === "--json") result.json = true;
120
+ else if (arg === "--help" || arg === "-h") result.help = true;
121
+ else if (arg === "--version" || arg === "-v") result.version = true;
122
+ else if (!arg.startsWith("-")) result.dir = arg;
123
+ }
124
+ if (!result.key) result.key = process.env.AGENTVERIFY_API_KEY ?? "";
125
+ return result;
126
+ }
127
+ function printHelp() {
128
+ console.log(`
129
+ ${c.bold}${c.cyan}Agent Verify${c.reset} ${c.gray}v${VERSION}${c.reset}
130
+ ${c.gray}Execution trust analysis for AI agents${c.reset}
131
+
132
+ ${c.bold}Usage:${c.reset}
133
+ agentverify scan [dir] --key <api-key>
134
+ agentverify scan --file <file> --key <api-key>
135
+
136
+ ${c.bold}Commands:${c.reset}
137
+ scan Scan agent files in a directory or a single file
138
+
139
+ ${c.bold}Options:${c.reset}
140
+ --key, -k API key (or set AGENTVERIFY_API_KEY env var)
141
+ --file, -f Scan a single file instead of a directory
142
+ --json Output results as JSON
143
+ --version, -v Print version
144
+ --help, -h Show this help message
145
+
146
+ ${c.bold}Examples:${c.reset}
147
+ ${c.gray}# Scan all agent files in current directory${c.reset}
148
+ agentverify scan . --key av_your_key
149
+
150
+ ${c.gray}# Scan a specific file${c.reset}
151
+ agentverify scan --file agent.json --key av_your_key
152
+
153
+ ${c.gray}# Use environment variable for key${c.reset}
154
+ AGENTVERIFY_API_KEY=av_your_key agentverify scan ./agents
155
+
156
+ ${c.gray}# Output as JSON (useful for CI/CD)${c.reset}
157
+ agentverify scan . --key av_your_key --json
158
+
159
+ ${c.bold}Get your API key:${c.reset}
160
+ https://agentverify.ai/dashboard
161
+
162
+ ${c.bold}Docs:${c.reset}
163
+ https://github.com/AI-Blockchain-Ventures/agentverify
164
+ `);
165
+ }
166
+ function printVerdict(result, fileName) {
167
+ const verified = result.verdict === "VERIFIED";
168
+ const icon = verified ? `${c.green}\u2713${c.reset}` : `${c.red}\u2717${c.reset}`;
169
+ const verdict = verified ? `${c.green}VERIFIED${c.reset} ` : `${c.red}NOT VERIFIED${c.reset}`;
170
+ const score = verified ? `${c.green}${result.riskScore}/100${c.reset}` : result.riskScore >= 50 ? `${c.yellow}${result.riskScore}/100${c.reset}` : `${c.red}${result.riskScore}/100${c.reset}`;
171
+ const findings = result.findings.length > 0 ? `${c.gray}\u2014 ${result.findings.length} finding${result.findings.length === 1 ? "" : "s"}${c.reset}` : "";
172
+ const name = fileName.padEnd(30);
173
+ console.log(` ${icon} ${verdict} ${name} score: ${score} ${findings}`);
174
+ if (result.saved && result.reportId) {
175
+ console.log(` ${c.gray}\u2192 Report: https://agentverify.ai/report/${result.reportId}${c.reset}`);
176
+ }
177
+ }
178
+ async function runScan(args) {
179
+ if (!args.key) {
180
+ console.error(`
181
+ ${c.red}Error:${c.reset} API key required
182
+ `);
183
+ console.error(` Set with --key av_your_key or AGENTVERIFY_API_KEY env var`);
184
+ console.error(` Get your key at https://agentverify.ai/dashboard
185
+ `);
186
+ process.exit(1);
187
+ }
188
+ let files = [];
189
+ if (args.file) {
190
+ files = [args.file];
191
+ } else {
192
+ const dir = args.dir;
193
+ console.log(`
194
+ ${c.bold}Agent Verify${c.reset} ${c.gray}v${VERSION}${c.reset}`);
195
+ console.log(`${c.gray}Scanning ${dir}...${c.reset}
196
+ `);
197
+ files = collectFiles(dir);
198
+ if (files.length === 0) {
199
+ console.log(`${c.yellow}No agent files found in ${dir}${c.reset}`);
200
+ console.log(`${c.gray}Supported: .js .ts .py .json .yaml .yml .md${c.reset}
201
+ `);
202
+ process.exit(0);
203
+ }
204
+ }
205
+ const jsonResults = [];
206
+ let verified = 0;
207
+ let notVerified = 0;
208
+ let errors = 0;
209
+ const CONCURRENCY = 3;
210
+ for (let i = 0; i < files.length; i += CONCURRENCY) {
211
+ const batch = files.slice(i, i + CONCURRENCY);
212
+ const batchResults = await Promise.allSettled(
213
+ batch.map(async (filePath) => {
214
+ const content = (0, import_fs.readFileSync)(filePath, "utf-8");
215
+ const relPath = (0, import_path.relative)(args.dir === "." ? process.cwd() : args.dir, filePath);
216
+ const result = await scan(
217
+ { content, fileName: relPath },
218
+ { apiKey: args.key, apiUrl: API_URL }
219
+ );
220
+ return { filePath, relPath, result };
221
+ })
222
+ );
223
+ for (let j = 0; j < batchResults.length; j++) {
224
+ const outcome = batchResults[j];
225
+ if (outcome.status === "fulfilled") {
226
+ const { relPath, result } = outcome.value;
227
+ if (!args.json) printVerdict(result, relPath);
228
+ jsonResults.push({ file: relPath, result, error: null });
229
+ if (result.verdict === "VERIFIED") verified++;
230
+ else notVerified++;
231
+ } else {
232
+ const filePath = batch[j];
233
+ const relPath = (0, import_path.relative)(args.dir, filePath);
234
+ const errMsg = outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason);
235
+ if (!args.json) {
236
+ console.log(` ${c.yellow}\u26A0${c.reset} ${c.yellow}WARNING${c.reset} ${relPath.padEnd(30)} ${c.gray}${errMsg}${c.reset}`);
237
+ }
238
+ jsonResults.push({ file: relPath, result: null, error: errMsg });
239
+ errors++;
240
+ }
241
+ }
242
+ }
243
+ if (args.json) {
244
+ console.log(JSON.stringify({ results: jsonResults, summary: { total: files.length, verified, notVerified, errors } }, null, 2));
245
+ return;
246
+ }
247
+ console.log(`
248
+ ${c.gray}${"\u2500".repeat(60)}${c.reset}`);
249
+ console.log(`${c.bold}Agent Verify Scan Complete${c.reset}`);
250
+ console.log(`${c.gray}Files scanned:${c.reset} ${files.length}`);
251
+ console.log(`${c.green}Verified:${c.reset} ${verified}`);
252
+ if (notVerified > 0) console.log(`${c.red}Not Verified:${c.reset} ${notVerified}`);
253
+ if (errors > 0) console.log(`${c.yellow}Errors:${c.reset} ${errors}`);
254
+ console.log(`${c.gray}${"\u2500".repeat(60)}${c.reset}`);
255
+ console.log(`
256
+ ${c.gray}View reports: https://agentverify.ai/dashboard${c.reset}
257
+ `);
258
+ if (notVerified > 0) process.exit(1);
259
+ }
260
+ async function main() {
261
+ const args = parseArgs(process.argv);
262
+ if (args.version) {
263
+ console.log(`agentverify v${VERSION}`);
264
+ process.exit(0);
265
+ }
266
+ if (args.help || !args.command) {
267
+ printHelp();
268
+ process.exit(0);
269
+ }
270
+ if (args.command === "scan") {
271
+ await runScan(args);
272
+ } else {
273
+ console.error(`
274
+ ${c.red}Unknown command: ${args.command}${c.reset}`);
275
+ console.error(`Run ${c.cyan}agentverify --help${c.reset} for usage
276
+ `);
277
+ process.exit(1);
278
+ }
279
+ }
280
+ main().catch((err) => {
281
+ console.error(`
282
+ ${c.red}Fatal error:${c.reset}`, err instanceof Error ? err.message : err);
283
+ process.exit(1);
284
+ });
package/dist/cli.mjs ADDED
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ scan
4
+ } from "./chunk-JWWQ7MRK.mjs";
5
+
6
+ // src/cli.ts
7
+ import { readFileSync, readdirSync, statSync } from "fs";
8
+ import { join, relative, extname } from "path";
9
+ var VERSION = "1.0.0";
10
+ var API_URL = "https://agentverify-api.agentverify.workers.dev/v1/scan";
11
+ var c = {
12
+ reset: "\x1B[0m",
13
+ bold: "\x1B[1m",
14
+ dim: "\x1B[2m",
15
+ red: "\x1B[31m",
16
+ green: "\x1B[32m",
17
+ yellow: "\x1B[33m",
18
+ cyan: "\x1B[36m",
19
+ white: "\x1B[37m",
20
+ gray: "\x1B[90m"
21
+ };
22
+ var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".ts", ".py", ".json", ".yaml", ".yml", ".md", ".mjs", ".cjs"]);
23
+ var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".next", "vendor", "coverage", ".cache"]);
24
+ function collectFiles(dir) {
25
+ const files = [];
26
+ try {
27
+ const entries = readdirSync(dir);
28
+ for (const entry of entries) {
29
+ if (SKIP_DIRS.has(entry)) continue;
30
+ const fullPath = join(dir, entry);
31
+ const stat = statSync(fullPath);
32
+ if (stat.isDirectory()) {
33
+ files.push(...collectFiles(fullPath));
34
+ } else if (SUPPORTED_EXTENSIONS.has(extname(entry).toLowerCase())) {
35
+ files.push(fullPath);
36
+ }
37
+ }
38
+ } catch {
39
+ }
40
+ return files;
41
+ }
42
+ function parseArgs(argv) {
43
+ const args = argv.slice(2);
44
+ const result = {
45
+ command: args[0] ?? "",
46
+ dir: ".",
47
+ key: "",
48
+ file: "",
49
+ json: false,
50
+ help: false,
51
+ version: false
52
+ };
53
+ if (result.command === "--help" || result.command === "-h") {
54
+ result.command = "";
55
+ result.help = true;
56
+ }
57
+ if (result.command === "--version" || result.command === "-v") {
58
+ result.command = "";
59
+ result.version = true;
60
+ }
61
+ for (let i = 1; i < args.length; i++) {
62
+ const arg = args[i];
63
+ if (arg === "--key" || arg === "-k") result.key = args[++i] ?? "";
64
+ else if (arg === "--file" || arg === "-f") result.file = args[++i] ?? "";
65
+ else if (arg === "--json") result.json = true;
66
+ else if (arg === "--help" || arg === "-h") result.help = true;
67
+ else if (arg === "--version" || arg === "-v") result.version = true;
68
+ else if (!arg.startsWith("-")) result.dir = arg;
69
+ }
70
+ if (!result.key) result.key = process.env.AGENTVERIFY_API_KEY ?? "";
71
+ return result;
72
+ }
73
+ function printHelp() {
74
+ console.log(`
75
+ ${c.bold}${c.cyan}Agent Verify${c.reset} ${c.gray}v${VERSION}${c.reset}
76
+ ${c.gray}Execution trust analysis for AI agents${c.reset}
77
+
78
+ ${c.bold}Usage:${c.reset}
79
+ agentverify scan [dir] --key <api-key>
80
+ agentverify scan --file <file> --key <api-key>
81
+
82
+ ${c.bold}Commands:${c.reset}
83
+ scan Scan agent files in a directory or a single file
84
+
85
+ ${c.bold}Options:${c.reset}
86
+ --key, -k API key (or set AGENTVERIFY_API_KEY env var)
87
+ --file, -f Scan a single file instead of a directory
88
+ --json Output results as JSON
89
+ --version, -v Print version
90
+ --help, -h Show this help message
91
+
92
+ ${c.bold}Examples:${c.reset}
93
+ ${c.gray}# Scan all agent files in current directory${c.reset}
94
+ agentverify scan . --key av_your_key
95
+
96
+ ${c.gray}# Scan a specific file${c.reset}
97
+ agentverify scan --file agent.json --key av_your_key
98
+
99
+ ${c.gray}# Use environment variable for key${c.reset}
100
+ AGENTVERIFY_API_KEY=av_your_key agentverify scan ./agents
101
+
102
+ ${c.gray}# Output as JSON (useful for CI/CD)${c.reset}
103
+ agentverify scan . --key av_your_key --json
104
+
105
+ ${c.bold}Get your API key:${c.reset}
106
+ https://agentverify.ai/dashboard
107
+
108
+ ${c.bold}Docs:${c.reset}
109
+ https://github.com/AI-Blockchain-Ventures/agentverify
110
+ `);
111
+ }
112
+ function printVerdict(result, fileName) {
113
+ const verified = result.verdict === "VERIFIED";
114
+ const icon = verified ? `${c.green}\u2713${c.reset}` : `${c.red}\u2717${c.reset}`;
115
+ const verdict = verified ? `${c.green}VERIFIED${c.reset} ` : `${c.red}NOT VERIFIED${c.reset}`;
116
+ const score = verified ? `${c.green}${result.riskScore}/100${c.reset}` : result.riskScore >= 50 ? `${c.yellow}${result.riskScore}/100${c.reset}` : `${c.red}${result.riskScore}/100${c.reset}`;
117
+ const findings = result.findings.length > 0 ? `${c.gray}\u2014 ${result.findings.length} finding${result.findings.length === 1 ? "" : "s"}${c.reset}` : "";
118
+ const name = fileName.padEnd(30);
119
+ console.log(` ${icon} ${verdict} ${name} score: ${score} ${findings}`);
120
+ if (result.saved && result.reportId) {
121
+ console.log(` ${c.gray}\u2192 Report: https://agentverify.ai/report/${result.reportId}${c.reset}`);
122
+ }
123
+ }
124
+ async function runScan(args) {
125
+ if (!args.key) {
126
+ console.error(`
127
+ ${c.red}Error:${c.reset} API key required
128
+ `);
129
+ console.error(` Set with --key av_your_key or AGENTVERIFY_API_KEY env var`);
130
+ console.error(` Get your key at https://agentverify.ai/dashboard
131
+ `);
132
+ process.exit(1);
133
+ }
134
+ let files = [];
135
+ if (args.file) {
136
+ files = [args.file];
137
+ } else {
138
+ const dir = args.dir;
139
+ console.log(`
140
+ ${c.bold}Agent Verify${c.reset} ${c.gray}v${VERSION}${c.reset}`);
141
+ console.log(`${c.gray}Scanning ${dir}...${c.reset}
142
+ `);
143
+ files = collectFiles(dir);
144
+ if (files.length === 0) {
145
+ console.log(`${c.yellow}No agent files found in ${dir}${c.reset}`);
146
+ console.log(`${c.gray}Supported: .js .ts .py .json .yaml .yml .md${c.reset}
147
+ `);
148
+ process.exit(0);
149
+ }
150
+ }
151
+ const jsonResults = [];
152
+ let verified = 0;
153
+ let notVerified = 0;
154
+ let errors = 0;
155
+ const CONCURRENCY = 3;
156
+ for (let i = 0; i < files.length; i += CONCURRENCY) {
157
+ const batch = files.slice(i, i + CONCURRENCY);
158
+ const batchResults = await Promise.allSettled(
159
+ batch.map(async (filePath) => {
160
+ const content = readFileSync(filePath, "utf-8");
161
+ const relPath = relative(args.dir === "." ? process.cwd() : args.dir, filePath);
162
+ const result = await scan(
163
+ { content, fileName: relPath },
164
+ { apiKey: args.key, apiUrl: API_URL }
165
+ );
166
+ return { filePath, relPath, result };
167
+ })
168
+ );
169
+ for (let j = 0; j < batchResults.length; j++) {
170
+ const outcome = batchResults[j];
171
+ if (outcome.status === "fulfilled") {
172
+ const { relPath, result } = outcome.value;
173
+ if (!args.json) printVerdict(result, relPath);
174
+ jsonResults.push({ file: relPath, result, error: null });
175
+ if (result.verdict === "VERIFIED") verified++;
176
+ else notVerified++;
177
+ } else {
178
+ const filePath = batch[j];
179
+ const relPath = relative(args.dir, filePath);
180
+ const errMsg = outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason);
181
+ if (!args.json) {
182
+ console.log(` ${c.yellow}\u26A0${c.reset} ${c.yellow}WARNING${c.reset} ${relPath.padEnd(30)} ${c.gray}${errMsg}${c.reset}`);
183
+ }
184
+ jsonResults.push({ file: relPath, result: null, error: errMsg });
185
+ errors++;
186
+ }
187
+ }
188
+ }
189
+ if (args.json) {
190
+ console.log(JSON.stringify({ results: jsonResults, summary: { total: files.length, verified, notVerified, errors } }, null, 2));
191
+ return;
192
+ }
193
+ console.log(`
194
+ ${c.gray}${"\u2500".repeat(60)}${c.reset}`);
195
+ console.log(`${c.bold}Agent Verify Scan Complete${c.reset}`);
196
+ console.log(`${c.gray}Files scanned:${c.reset} ${files.length}`);
197
+ console.log(`${c.green}Verified:${c.reset} ${verified}`);
198
+ if (notVerified > 0) console.log(`${c.red}Not Verified:${c.reset} ${notVerified}`);
199
+ if (errors > 0) console.log(`${c.yellow}Errors:${c.reset} ${errors}`);
200
+ console.log(`${c.gray}${"\u2500".repeat(60)}${c.reset}`);
201
+ console.log(`
202
+ ${c.gray}View reports: https://agentverify.ai/dashboard${c.reset}
203
+ `);
204
+ if (notVerified > 0) process.exit(1);
205
+ }
206
+ async function main() {
207
+ const args = parseArgs(process.argv);
208
+ if (args.version) {
209
+ console.log(`agentverify v${VERSION}`);
210
+ process.exit(0);
211
+ }
212
+ if (args.help || !args.command) {
213
+ printHelp();
214
+ process.exit(0);
215
+ }
216
+ if (args.command === "scan") {
217
+ await runScan(args);
218
+ } else {
219
+ console.error(`
220
+ ${c.red}Unknown command: ${args.command}${c.reset}`);
221
+ console.error(`Run ${c.cyan}agentverify --help${c.reset} for usage
222
+ `);
223
+ process.exit(1);
224
+ }
225
+ }
226
+ main().catch((err) => {
227
+ console.error(`
228
+ ${c.red}Fatal error:${c.reset}`, err instanceof Error ? err.message : err);
229
+ process.exit(1);
230
+ });
package/dist/sdk.d.mts ADDED
@@ -0,0 +1,61 @@
1
+ interface ScanInput {
2
+ content: string;
3
+ fileName?: string;
4
+ platform?: string;
5
+ }
6
+ interface Finding {
7
+ title: string;
8
+ category: 'A' | 'B';
9
+ severity: 'critical' | 'high' | 'medium' | 'low';
10
+ whatIsWrong: string;
11
+ whyItMatters: string;
12
+ recommendedFix: string;
13
+ evidence?: string;
14
+ }
15
+ interface ScanResult {
16
+ verdict: 'VERIFIED' | 'NOT VERIFIED';
17
+ riskScore: number;
18
+ riskLevel: 'Low Risk' | 'Moderate Risk' | 'High Risk';
19
+ findings: Finding[];
20
+ reportId: string;
21
+ scannedAt: string;
22
+ saved: boolean;
23
+ reportUrl?: string;
24
+ }
25
+ interface ScanOptions {
26
+ apiKey: string;
27
+ apiUrl?: string;
28
+ timeout?: number;
29
+ }
30
+
31
+ /**
32
+ * Scan an agent configuration for execution trust issues.
33
+ *
34
+ * @example
35
+ * import { scan } from 'agentverify'
36
+ *
37
+ * const result = await scan(
38
+ * { content: agentCode, fileName: 'agent.js' },
39
+ * { apiKey: process.env.AGENTVERIFY_API_KEY }
40
+ * )
41
+ *
42
+ * console.log(result.verdict) // 'VERIFIED' | 'NOT VERIFIED'
43
+ * console.log(result.riskScore) // 0-100
44
+ * console.log(result.findings) // Array of findings
45
+ */
46
+ declare function scan(input: ScanInput, options: ScanOptions): Promise<ScanResult>;
47
+ /**
48
+ * Scan multiple files concurrently.
49
+ *
50
+ * @example
51
+ * import { scanMany } from 'agentverify'
52
+ *
53
+ * const results = await scanMany(files, { apiKey: 'av_...' })
54
+ */
55
+ declare function scanMany(inputs: ScanInput[], options: ScanOptions, concurrency?: number): Promise<Array<{
56
+ input: ScanInput;
57
+ result: ScanResult | null;
58
+ error: string | null;
59
+ }>>;
60
+
61
+ export { type Finding, type ScanInput, type ScanOptions, type ScanResult, scan, scanMany };
package/dist/sdk.d.ts ADDED
@@ -0,0 +1,61 @@
1
+ interface ScanInput {
2
+ content: string;
3
+ fileName?: string;
4
+ platform?: string;
5
+ }
6
+ interface Finding {
7
+ title: string;
8
+ category: 'A' | 'B';
9
+ severity: 'critical' | 'high' | 'medium' | 'low';
10
+ whatIsWrong: string;
11
+ whyItMatters: string;
12
+ recommendedFix: string;
13
+ evidence?: string;
14
+ }
15
+ interface ScanResult {
16
+ verdict: 'VERIFIED' | 'NOT VERIFIED';
17
+ riskScore: number;
18
+ riskLevel: 'Low Risk' | 'Moderate Risk' | 'High Risk';
19
+ findings: Finding[];
20
+ reportId: string;
21
+ scannedAt: string;
22
+ saved: boolean;
23
+ reportUrl?: string;
24
+ }
25
+ interface ScanOptions {
26
+ apiKey: string;
27
+ apiUrl?: string;
28
+ timeout?: number;
29
+ }
30
+
31
+ /**
32
+ * Scan an agent configuration for execution trust issues.
33
+ *
34
+ * @example
35
+ * import { scan } from 'agentverify'
36
+ *
37
+ * const result = await scan(
38
+ * { content: agentCode, fileName: 'agent.js' },
39
+ * { apiKey: process.env.AGENTVERIFY_API_KEY }
40
+ * )
41
+ *
42
+ * console.log(result.verdict) // 'VERIFIED' | 'NOT VERIFIED'
43
+ * console.log(result.riskScore) // 0-100
44
+ * console.log(result.findings) // Array of findings
45
+ */
46
+ declare function scan(input: ScanInput, options: ScanOptions): Promise<ScanResult>;
47
+ /**
48
+ * Scan multiple files concurrently.
49
+ *
50
+ * @example
51
+ * import { scanMany } from 'agentverify'
52
+ *
53
+ * const results = await scanMany(files, { apiKey: 'av_...' })
54
+ */
55
+ declare function scanMany(inputs: ScanInput[], options: ScanOptions, concurrency?: number): Promise<Array<{
56
+ input: ScanInput;
57
+ result: ScanResult | null;
58
+ error: string | null;
59
+ }>>;
60
+
61
+ export { type Finding, type ScanInput, type ScanOptions, type ScanResult, scan, scanMany };
package/dist/sdk.js ADDED
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/sdk.ts
21
+ var sdk_exports = {};
22
+ __export(sdk_exports, {
23
+ scan: () => scan,
24
+ scanMany: () => scanMany
25
+ });
26
+ module.exports = __toCommonJS(sdk_exports);
27
+ var DEFAULT_API_URL = "https://agentverify-api.agentverify.workers.dev/v1/scan";
28
+ var DEFAULT_TIMEOUT = 3e4;
29
+ async function scan(input, options) {
30
+ const { apiKey, apiUrl = DEFAULT_API_URL, timeout = DEFAULT_TIMEOUT } = options;
31
+ if (!apiKey) {
32
+ throw new Error(
33
+ "API key required. Generate one at https://agentverify.ai/dashboard"
34
+ );
35
+ }
36
+ if (!input.content || input.content.trim().length === 0) {
37
+ throw new Error("content is required and cannot be empty");
38
+ }
39
+ const controller = new AbortController();
40
+ const timer = setTimeout(() => controller.abort(), timeout);
41
+ try {
42
+ const response = await fetch(apiUrl, {
43
+ method: "POST",
44
+ headers: {
45
+ "Authorization": `Bearer ${apiKey}`,
46
+ "Content-Type": "application/json",
47
+ "User-Agent": "agentverify-sdk/1.0.0"
48
+ },
49
+ body: JSON.stringify({
50
+ content: input.content,
51
+ fileName: input.fileName ?? "agent",
52
+ platform: input.platform
53
+ }),
54
+ signal: controller.signal
55
+ });
56
+ if (response.status === 401) {
57
+ throw new Error(
58
+ "Invalid API key. Generate one at https://agentverify.ai/dashboard"
59
+ );
60
+ }
61
+ if (response.status === 400) {
62
+ const err = await response.json().catch(() => ({}));
63
+ throw new Error(err.error ?? "Invalid request");
64
+ }
65
+ if (!response.ok) {
66
+ throw new Error(`API error: ${response.status} ${response.statusText}`);
67
+ }
68
+ const data = await response.json();
69
+ return data;
70
+ } catch (err) {
71
+ if (err instanceof Error && err.name === "AbortError") {
72
+ throw new Error(`Request timed out after ${timeout}ms`);
73
+ }
74
+ throw err;
75
+ } finally {
76
+ clearTimeout(timer);
77
+ }
78
+ }
79
+ async function scanMany(inputs, options, concurrency = 3) {
80
+ const results = [];
81
+ for (let i = 0; i < inputs.length; i += concurrency) {
82
+ const batch = inputs.slice(i, i + concurrency);
83
+ const batchResults = await Promise.allSettled(
84
+ batch.map((input) => scan(input, options))
85
+ );
86
+ batchResults.forEach((res, j) => {
87
+ if (res.status === "fulfilled") {
88
+ results.push({ input: batch[j], result: res.value, error: null });
89
+ } else {
90
+ results.push({ input: batch[j], result: null, error: res.reason instanceof Error ? res.reason.message : String(res.reason) });
91
+ }
92
+ });
93
+ }
94
+ return results;
95
+ }
96
+ // Annotate the CommonJS export names for ESM import in node:
97
+ 0 && (module.exports = {
98
+ scan,
99
+ scanMany
100
+ });
package/dist/sdk.mjs ADDED
@@ -0,0 +1,8 @@
1
+ import {
2
+ scan,
3
+ scanMany
4
+ } from "./chunk-JWWQ7MRK.mjs";
5
+ export {
6
+ scan,
7
+ scanMany
8
+ };
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "agentverify",
3
+ "version": "1.0.0",
4
+ "description": "CLI and SDK for Agent Verify — execution trust analysis for AI agents",
5
+ "bin": {
6
+ "agentverify": "./dist/cli.js"
7
+ },
8
+ "main": "./dist/sdk.js",
9
+ "module": "./dist/sdk.mjs",
10
+ "types": "./dist/sdk.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/sdk.d.ts",
14
+ "import": "./dist/sdk.mjs",
15
+ "require": "./dist/sdk.js"
16
+ },
17
+ "./cli": "./dist/cli.js"
18
+ },
19
+ "files": ["dist", "README.md", "LICENSE"],
20
+ "scripts": {
21
+ "build": "tsup src/cli.ts src/sdk.ts --format cjs,esm --dts --clean",
22
+ "dev": "tsup src/cli.ts src/sdk.ts --format cjs,esm --dts --watch",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "engines": { "node": ">=18.0.0" },
26
+ "keywords": [
27
+ "ai", "agents", "security", "verification", "a2spa",
28
+ "agent-security", "llm", "ai-safety", "cli"
29
+ ],
30
+ "author": "AI Blockchain Ventures LLC",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/AI-Blockchain-Ventures/agentverify"
35
+ },
36
+ "homepage": "https://agentverify.ai",
37
+ "devDependencies": {
38
+ "tsup": "^8.0.0",
39
+ "typescript": "^5.0.0",
40
+ "@types/node": "^20.0.0"
41
+ }
42
+ }