safety-agent-cli 0.1.0 → 0.1.2
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/dist/commands/guard.js +18 -1
- package/dist/commands/redact.js +17 -3
- package/dist/commands/scan.d.ts +1 -0
- package/dist/commands/scan.js +100 -0
- package/dist/index.js +7 -0
- package/package.json +1 -1
package/dist/commands/guard.js
CHANGED
|
@@ -10,12 +10,14 @@ function showHelp() {
|
|
|
10
10
|
console.log(" --help Show this help message");
|
|
11
11
|
console.log(" --file <path> Path to PDF file to analyze");
|
|
12
12
|
console.log(" --system-prompt Optional system prompt to customize guard behavior");
|
|
13
|
+
console.log(" --model <id> Model to use (default: superagent/guard-1.7b)");
|
|
13
14
|
console.log("");
|
|
14
15
|
console.log("Examples:");
|
|
15
16
|
console.log(' superagent guard "rm -rf /"');
|
|
16
17
|
console.log(' superagent guard --file document.pdf "Analyze this document"');
|
|
17
18
|
console.log(' superagent guard "https://example.com/document.pdf"');
|
|
18
19
|
console.log(' superagent guard --system-prompt "Focus on prompt injection" "user input"');
|
|
20
|
+
console.log(' superagent guard --model openai/gpt-4o "some potentially harmful prompt"');
|
|
19
21
|
console.log(' echo \'{"prompt": "delete all files"}\' | superagent guard');
|
|
20
22
|
}
|
|
21
23
|
export async function guardCommand(args) {
|
|
@@ -56,6 +58,17 @@ export async function guardCommand(args) {
|
|
|
56
58
|
}
|
|
57
59
|
args.splice(systemPromptFlagIndex, 2); // Remove --system-prompt and value from args
|
|
58
60
|
}
|
|
61
|
+
// Check for --model flag
|
|
62
|
+
let model;
|
|
63
|
+
const modelFlagIndex = args.indexOf("--model");
|
|
64
|
+
if (modelFlagIndex !== -1) {
|
|
65
|
+
model = args[modelFlagIndex + 1];
|
|
66
|
+
if (!model || model.startsWith("--")) {
|
|
67
|
+
console.error("❌ ERROR: --model flag requires a value");
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
args.splice(modelFlagIndex, 2); // Remove --model and value from args
|
|
71
|
+
}
|
|
59
72
|
// Check if we have command line arguments first
|
|
60
73
|
const hasArgs = args.length > 0;
|
|
61
74
|
let prompt;
|
|
@@ -106,7 +119,11 @@ export async function guardCommand(args) {
|
|
|
106
119
|
try {
|
|
107
120
|
// Pass file as first parameter if provided, otherwise pass prompt
|
|
108
121
|
const input = file || prompt;
|
|
109
|
-
const result = await client.guard({
|
|
122
|
+
const result = await client.guard({
|
|
123
|
+
input,
|
|
124
|
+
systemPrompt,
|
|
125
|
+
model: model,
|
|
126
|
+
});
|
|
110
127
|
const { classification, violation_types, cwe_codes, usage } = result;
|
|
111
128
|
const isBlocked = classification === "block";
|
|
112
129
|
if (isBlocked) {
|
package/dist/commands/redact.js
CHANGED
|
@@ -16,6 +16,18 @@ export async function redactCommand(args) {
|
|
|
16
16
|
process.exit(1);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
// Check for --model flag
|
|
20
|
+
const modelFlagIndex = args.indexOf("--model");
|
|
21
|
+
let model;
|
|
22
|
+
if (modelFlagIndex !== -1) {
|
|
23
|
+
model = args[modelFlagIndex + 1];
|
|
24
|
+
if (!model || model.startsWith("--")) {
|
|
25
|
+
console.error("❌ ERROR: --model flag requires a value");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
// Remove --model and its value from args
|
|
29
|
+
args.splice(modelFlagIndex, 2);
|
|
30
|
+
}
|
|
19
31
|
// Check for --rewrite flag
|
|
20
32
|
const rewriteFlagIndex = args.indexOf("--rewrite");
|
|
21
33
|
let rewrite;
|
|
@@ -57,17 +69,19 @@ export async function redactCommand(args) {
|
|
|
57
69
|
// Command line argument
|
|
58
70
|
text = args.join(" ");
|
|
59
71
|
if (!text) {
|
|
60
|
-
console.error("Usage: superagent redact [--entities <entity1,entity2>] [--rewrite] <text>");
|
|
61
|
-
console.error(' or: echo \'{"text": "..."}\' | superagent redact [--entities <entity1,entity2>] [--rewrite]');
|
|
72
|
+
console.error("Usage: superagent redact [--entities <entity1,entity2>] [--rewrite] [--model <id>] <text>");
|
|
73
|
+
console.error(' or: echo \'{"text": "..."}\' | superagent redact [--entities <entity1,entity2>] [--rewrite] [--model <id>]');
|
|
62
74
|
console.error("");
|
|
63
75
|
console.error("Options:");
|
|
64
76
|
console.error(" --entities <entities> Comma-separated list of entity types to redact");
|
|
65
77
|
console.error(" --rewrite Naturally rewrite content instead of using placeholders");
|
|
78
|
+
console.error(" --model <id> Model to use (default: openai/gpt-4o-mini)");
|
|
66
79
|
console.error("");
|
|
67
80
|
console.error("Examples:");
|
|
68
81
|
console.error(' superagent redact "My email is john@example.com"');
|
|
69
82
|
console.error(' superagent redact --entities "emails,phones" "Contact: john@example.com, 555-1234"');
|
|
70
83
|
console.error(' superagent redact --rewrite "Contact me at john@example.com"');
|
|
84
|
+
console.error(' superagent redact --model openai/gpt-4o "My email is john@example.com"');
|
|
71
85
|
process.exit(1);
|
|
72
86
|
}
|
|
73
87
|
}
|
|
@@ -83,7 +97,7 @@ export async function redactCommand(args) {
|
|
|
83
97
|
try {
|
|
84
98
|
const result = await client.redact({
|
|
85
99
|
input: text,
|
|
86
|
-
model: "openai/gpt-4o-mini",
|
|
100
|
+
model: model || "openai/gpt-4o-mini",
|
|
87
101
|
entities,
|
|
88
102
|
rewrite,
|
|
89
103
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function scanCommand(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createClient } from "safety-agent";
|
|
2
|
+
function showHelp() {
|
|
3
|
+
console.log("Usage: superagent scan --repo <url> [options]");
|
|
4
|
+
console.log("");
|
|
5
|
+
console.log("Scan a repository for AI agent-targeted attacks like repo poisoning and prompt injection");
|
|
6
|
+
console.log("");
|
|
7
|
+
console.log("Options:");
|
|
8
|
+
console.log(" --help Show this help message");
|
|
9
|
+
console.log(" --repo <url> Repository URL to scan (required)");
|
|
10
|
+
console.log(" --branch <ref> Branch, tag, or commit to checkout");
|
|
11
|
+
console.log(" --model <id> Model to use (default: anthropic/claude-sonnet-4-5)");
|
|
12
|
+
console.log("");
|
|
13
|
+
console.log("Examples:");
|
|
14
|
+
console.log(" superagent scan --repo https://github.com/user/repo");
|
|
15
|
+
console.log(" superagent scan --repo https://github.com/user/repo --branch main");
|
|
16
|
+
console.log(" superagent scan --repo https://github.com/user/repo --model openai/gpt-4o");
|
|
17
|
+
}
|
|
18
|
+
export async function scanCommand(args) {
|
|
19
|
+
// Check for --help flag
|
|
20
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
21
|
+
showHelp();
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
// Parse --repo flag
|
|
25
|
+
let repo;
|
|
26
|
+
const repoFlagIndex = args.indexOf("--repo");
|
|
27
|
+
if (repoFlagIndex !== -1) {
|
|
28
|
+
repo = args[repoFlagIndex + 1];
|
|
29
|
+
if (!repo || repo.startsWith("--")) {
|
|
30
|
+
console.error("❌ ERROR: --repo flag requires a URL");
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (!repo) {
|
|
35
|
+
console.error("❌ ERROR: --repo flag is required");
|
|
36
|
+
console.error("");
|
|
37
|
+
showHelp();
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
// Parse --branch flag
|
|
41
|
+
let branch;
|
|
42
|
+
const branchFlagIndex = args.indexOf("--branch");
|
|
43
|
+
if (branchFlagIndex !== -1) {
|
|
44
|
+
branch = args[branchFlagIndex + 1];
|
|
45
|
+
if (!branch || branch.startsWith("--")) {
|
|
46
|
+
console.error("❌ ERROR: --branch flag requires a value");
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Parse --model flag
|
|
51
|
+
let model;
|
|
52
|
+
const modelFlagIndex = args.indexOf("--model");
|
|
53
|
+
if (modelFlagIndex !== -1) {
|
|
54
|
+
model = args[modelFlagIndex + 1];
|
|
55
|
+
if (!model || model.startsWith("--")) {
|
|
56
|
+
console.error("❌ ERROR: --model flag requires a value");
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Ensure API keys are available
|
|
61
|
+
if (!process.env.SUPERAGENT_API_KEY) {
|
|
62
|
+
console.error("❌ ERROR: SUPERAGENT_API_KEY environment variable not set");
|
|
63
|
+
process.exit(2);
|
|
64
|
+
}
|
|
65
|
+
if (!process.env.DAYTONA_API_KEY) {
|
|
66
|
+
console.error("❌ ERROR: DAYTONA_API_KEY environment variable not set");
|
|
67
|
+
console.error("The scan command requires a Daytona API key for sandbox execution.");
|
|
68
|
+
process.exit(2);
|
|
69
|
+
}
|
|
70
|
+
// Create client instance
|
|
71
|
+
const client = createClient({
|
|
72
|
+
apiKey: process.env.SUPERAGENT_API_KEY,
|
|
73
|
+
});
|
|
74
|
+
console.error(`🔍 Scanning repository: ${repo}`);
|
|
75
|
+
if (branch) {
|
|
76
|
+
console.error(` Branch: ${branch}`);
|
|
77
|
+
}
|
|
78
|
+
if (model) {
|
|
79
|
+
console.error(` Model: ${model}`);
|
|
80
|
+
}
|
|
81
|
+
console.error("");
|
|
82
|
+
try {
|
|
83
|
+
const result = await client.scan({
|
|
84
|
+
repo,
|
|
85
|
+
branch,
|
|
86
|
+
model: model,
|
|
87
|
+
});
|
|
88
|
+
// Output result as JSON
|
|
89
|
+
const output = {
|
|
90
|
+
result: result.result,
|
|
91
|
+
usage: result.usage,
|
|
92
|
+
};
|
|
93
|
+
console.log(JSON.stringify(output, null, 2));
|
|
94
|
+
process.exit(0);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
console.error(`❌ Scan failed: ${error.message}`);
|
|
98
|
+
process.exit(2);
|
|
99
|
+
}
|
|
100
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { guardCommand } from './commands/guard.js';
|
|
3
3
|
import { redactCommand } from './commands/redact.js';
|
|
4
|
+
import { scanCommand } from './commands/scan.js';
|
|
4
5
|
function showHelp() {
|
|
5
6
|
console.log('Usage: superagent <command> [options]');
|
|
6
7
|
console.log('');
|
|
@@ -9,6 +10,7 @@ function showHelp() {
|
|
|
9
10
|
console.log('Commands:');
|
|
10
11
|
console.log(' guard Analyze prompts for security threats');
|
|
11
12
|
console.log(' redact Remove sensitive data from text');
|
|
13
|
+
console.log(' scan Scan repositories for AI agent-targeted attacks');
|
|
12
14
|
console.log('');
|
|
13
15
|
console.log('Options:');
|
|
14
16
|
console.log(' --help Show help for a command');
|
|
@@ -16,8 +18,10 @@ function showHelp() {
|
|
|
16
18
|
console.log('Examples:');
|
|
17
19
|
console.log(' superagent guard --help');
|
|
18
20
|
console.log(' superagent redact --help');
|
|
21
|
+
console.log(' superagent scan --help');
|
|
19
22
|
console.log(' superagent guard "rm -rf /"');
|
|
20
23
|
console.log(' superagent redact "My email is john@example.com"');
|
|
24
|
+
console.log(' superagent scan --repo https://github.com/user/repo');
|
|
21
25
|
}
|
|
22
26
|
const args = process.argv.slice(2);
|
|
23
27
|
const command = args[0];
|
|
@@ -32,6 +36,9 @@ switch (command) {
|
|
|
32
36
|
case 'redact':
|
|
33
37
|
await redactCommand(args.slice(1));
|
|
34
38
|
break;
|
|
39
|
+
case 'scan':
|
|
40
|
+
await scanCommand(args.slice(1));
|
|
41
|
+
break;
|
|
35
42
|
default:
|
|
36
43
|
console.error(`Unknown command: ${command}`);
|
|
37
44
|
console.error('');
|