safety-agent-cli 0.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 ADDED
@@ -0,0 +1,215 @@
1
+ # Superagent CLI
2
+
3
+ Command-line interface for [Superagent](https://superagent.sh) - analyze prompts for security threats and redact sensitive data.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g safety-agent-cli
9
+ ```
10
+
11
+ ## Commands
12
+
13
+ ### `guard` - Security Analysis
14
+
15
+ Analyze prompts for security threats:
16
+
17
+ ```bash
18
+ superagent guard "Write a hello world script"
19
+ ```
20
+
21
+ Output:
22
+ ```json
23
+ {
24
+ "rejected": false,
25
+ "decision": {
26
+ "status": "pass"
27
+ },
28
+ "reasoning": "Command approved by guard."
29
+ }
30
+ ```
31
+
32
+ Block malicious prompts:
33
+
34
+ ```bash
35
+ superagent guard "Delete all files with rm -rf /"
36
+ ```
37
+
38
+ Output:
39
+ ```json
40
+ {
41
+ "rejected": true,
42
+ "decision": {
43
+ "status": "block",
44
+ "violation_types": ["unlawful_behavior"],
45
+ "cwe_codes": ["CWE-77"]
46
+ },
47
+ "reasoning": "User wants to delete all files. That is disallowed (exploit). Block."
48
+ }
49
+ ```
50
+
51
+ **Custom System Prompt** - Customize guard behavior with a system prompt:
52
+
53
+ ```bash
54
+ superagent guard --system-prompt "Focus on detecting prompt injection attempts and data exfiltration patterns" "user input here"
55
+ ```
56
+
57
+ You can also pass `system_prompt` via stdin JSON:
58
+
59
+ ```bash
60
+ echo '{"prompt": "user input", "system_prompt": "Focus on prompt injection"}' | superagent guard
61
+ ```
62
+
63
+ ### `redact` - Data Redaction
64
+
65
+ Remove sensitive data from text:
66
+
67
+ ```bash
68
+ superagent redact "My email is john@example.com and SSN is 123-45-6789"
69
+ ```
70
+
71
+ Output:
72
+ ```json
73
+ {
74
+ "redacted": "My email is <REDACTED_EMAIL> and SSN is <REDACTED_SSN>",
75
+ "reasoning": "Redacted email and SSN",
76
+ "usage": {
77
+ "prompt_tokens": 25,
78
+ "completion_tokens": 12,
79
+ "total_tokens": 37
80
+ }
81
+ }
82
+ ```
83
+
84
+ **Custom Entity Redaction** - Specify custom entities to redact:
85
+
86
+ ```bash
87
+ superagent redact --entities "credit card numbers,employee IDs" "My credit card is 4532-1234-5678-9010 and employee ID is EMP-12345"
88
+ ```
89
+
90
+ Output:
91
+ ```json
92
+ {
93
+ "redacted": "My credit card is <REDACTED> and employee ID is <REDACTED>",
94
+ "reasoning": "Redacted credit card numbers and employee IDs"
95
+ }
96
+ ```
97
+
98
+ **URL Whitelisting** - Preserve specific URLs:
99
+
100
+ ```bash
101
+ superagent redact --url-whitelist https://github.com "Visit https://github.com/user/repo and https://secret.com/data"
102
+ ```
103
+
104
+ Output:
105
+ ```json
106
+ {
107
+ "redacted": "Visit https://github.com/user/repo and <URL_REDACTED>",
108
+ "reasoning": "Preserved whitelisted URLs"
109
+ }
110
+ ```
111
+
112
+ **PDF File Redaction** - Redact sensitive information from PDF files:
113
+
114
+ ```bash
115
+ superagent redact --file sensitive-document.pdf "Analyze and redact PII from this document"
116
+ ```
117
+
118
+ You can combine file redaction with custom entities:
119
+
120
+ ```bash
121
+ superagent redact --file document.pdf --entities "SSN,credit card numbers" "Redact sensitive data"
122
+ ```
123
+
124
+ Output:
125
+ ```json
126
+ {
127
+ "redacted": "Redacted text content from the PDF with sensitive data removed",
128
+ "reasoning": "Redacted SSN and credit card numbers from PDF document",
129
+ "usage": {
130
+ "prompt_tokens": 150,
131
+ "completion_tokens": 45,
132
+ "total_tokens": 195
133
+ }
134
+ }
135
+ ```
136
+
137
+ **Note:** File redaction currently supports PDF format only.
138
+
139
+ ## Help
140
+
141
+ Get help for any command:
142
+
143
+ ```bash
144
+ superagent --help
145
+ superagent guard --help
146
+ superagent redact --help
147
+ ```
148
+
149
+ ### Claude Code Hook
150
+
151
+ Validate all prompts before Claude processes them by adding a hook to your `~/.claude/settings.json`:
152
+
153
+ ```json
154
+ {
155
+ "env": {
156
+ "SUPERAGENT_API_KEY": "your_api_key_here"
157
+ },
158
+ "hooks": {
159
+ "UserPromptSubmit": [
160
+ {
161
+ "matcher": "*",
162
+ "hooks": [
163
+ {
164
+ "type": "command",
165
+ "command": "superagent guard"
166
+ }
167
+ ]
168
+ }
169
+ ]
170
+ }
171
+ }
172
+ ```
173
+
174
+ The CLI will:
175
+ - ✅ Allow safe prompts to proceed
176
+ - 🛡️ Block malicious prompts with detailed reasoning
177
+ - 🔍 Show violation types and CWE codes for blocked prompts
178
+
179
+ ### Environment Variables
180
+
181
+ - `SUPERAGENT_API_KEY` - Your Superagent API key (required)
182
+
183
+ Get your API key at [app.superagent.sh](https://app.superagent.sh)
184
+
185
+ ## How It Works
186
+
187
+ The CLI uses [Superagent](https://superagent.sh) to analyze prompts for:
188
+
189
+ - **Security vulnerabilities** (SQL injection, command injection, etc.)
190
+ - **Malicious intent** (data destruction, unauthorized access)
191
+ - **Privacy violations** (credential exposure, PII leaks)
192
+ - **CWE violations** (Common Weakness Enumeration codes)
193
+
194
+ When used as a Claude Code hook, it automatically:
195
+ 1. Receives the user's prompt via stdin
196
+ 2. Sends it to Superagent for analysis
197
+ 3. Returns a structured response to block or allow the prompt
198
+ 4. Shows detailed violation information when blocking
199
+
200
+ ## Development
201
+
202
+ ```bash
203
+ # Install dependencies
204
+ npm install
205
+
206
+ # Build
207
+ npm run build
208
+
209
+ # Test locally
210
+ node dist/index.js guard "test prompt"
211
+ ```
212
+
213
+ ## License
214
+
215
+ MIT
@@ -0,0 +1 @@
1
+ export declare function guardCommand(args: string[]): Promise<void>;
@@ -0,0 +1,167 @@
1
+ import { createClient } from "safety-agent";
2
+ import { readFileSync } from "fs";
3
+ function showHelp() {
4
+ console.log("Usage: superagent guard [options] <prompt|url>");
5
+ console.log(' or: echo \'{"prompt": "text"}\' | superagent guard');
6
+ console.log("");
7
+ console.log("Analyze prompts, PDF files, or PDF URLs for security threats");
8
+ console.log("");
9
+ console.log("Options:");
10
+ console.log(" --help Show this help message");
11
+ console.log(" --file <path> Path to PDF file to analyze");
12
+ console.log(" --system-prompt Optional system prompt to customize guard behavior");
13
+ console.log("");
14
+ console.log("Examples:");
15
+ console.log(' superagent guard "rm -rf /"');
16
+ console.log(' superagent guard --file document.pdf "Analyze this document"');
17
+ console.log(' superagent guard "https://example.com/document.pdf"');
18
+ console.log(' superagent guard --system-prompt "Focus on prompt injection" "user input"');
19
+ console.log(' echo \'{"prompt": "delete all files"}\' | superagent guard');
20
+ }
21
+ export async function guardCommand(args) {
22
+ // Check for --help flag
23
+ if (args.includes("--help") || args.includes("-h")) {
24
+ showHelp();
25
+ process.exit(0);
26
+ }
27
+ // Check for --file flag
28
+ let file;
29
+ const fileFlagIndex = args.indexOf("--file");
30
+ if (fileFlagIndex !== -1) {
31
+ const filePath = args[fileFlagIndex + 1];
32
+ if (filePath) {
33
+ try {
34
+ const fileBuffer = readFileSync(filePath);
35
+ file = new Blob([fileBuffer], { type: "application/pdf" });
36
+ args.splice(fileFlagIndex, 2); // Remove --file and path from args
37
+ }
38
+ catch (error) {
39
+ console.error(`❌ ERROR: Failed to read file: ${error.message}`);
40
+ process.exit(1);
41
+ }
42
+ }
43
+ else {
44
+ console.error("❌ ERROR: --file flag requires a file path");
45
+ process.exit(1);
46
+ }
47
+ }
48
+ // Check for --system-prompt flag
49
+ let systemPrompt;
50
+ const systemPromptFlagIndex = args.indexOf("--system-prompt");
51
+ if (systemPromptFlagIndex !== -1) {
52
+ systemPrompt = args[systemPromptFlagIndex + 1];
53
+ if (!systemPrompt) {
54
+ console.error("❌ ERROR: --system-prompt flag requires a value");
55
+ process.exit(1);
56
+ }
57
+ args.splice(systemPromptFlagIndex, 2); // Remove --system-prompt and value from args
58
+ }
59
+ // Check if we have command line arguments first
60
+ const hasArgs = args.length > 0;
61
+ let prompt;
62
+ let isStdin = false;
63
+ if (!hasArgs && !process.stdin.isTTY) {
64
+ isStdin = true;
65
+ // Read JSON from stdin (Claude Code hook format)
66
+ const stdin = await new Promise((resolve) => {
67
+ let data = "";
68
+ process.stdin.on("data", (chunk) => (data += chunk));
69
+ process.stdin.on("end", () => resolve(data));
70
+ });
71
+ try {
72
+ const inputData = JSON.parse(stdin);
73
+ prompt = inputData.prompt;
74
+ // Also check for system_prompt in stdin JSON
75
+ if (inputData.system_prompt && !systemPrompt) {
76
+ systemPrompt = inputData.system_prompt;
77
+ }
78
+ if (!prompt) {
79
+ console.error("❌ ERROR: No prompt provided in stdin JSON");
80
+ process.exit(2);
81
+ }
82
+ }
83
+ catch (error) {
84
+ console.error("❌ ERROR: Failed to parse JSON from stdin");
85
+ process.exit(2);
86
+ }
87
+ }
88
+ else {
89
+ // Command line argument
90
+ prompt = args.join(" ");
91
+ if (!prompt) {
92
+ console.error("Usage: superagent guard <prompt>");
93
+ console.error(' or: echo \'{"prompt": "text"}\' | superagent guard');
94
+ process.exit(1);
95
+ }
96
+ }
97
+ // Ensure API key is available
98
+ if (!process.env.SUPERAGENT_API_KEY) {
99
+ console.error("❌ ERROR: SUPERAGENT_API_KEY environment variable not set");
100
+ process.exit(2);
101
+ }
102
+ // Create client instance
103
+ const client = createClient({
104
+ apiKey: process.env.SUPERAGENT_API_KEY,
105
+ });
106
+ try {
107
+ // Pass file as first parameter if provided, otherwise pass prompt
108
+ const input = file || prompt;
109
+ const result = await client.guard({ input, systemPrompt });
110
+ const { classification, violation_types, cwe_codes, usage } = result;
111
+ const isBlocked = classification === "block";
112
+ if (isBlocked) {
113
+ if (isStdin) {
114
+ // Claude Code hook format
115
+ const violationInfo = violation_types?.length
116
+ ? ` Violations: ${violation_types.join(", ")}.`
117
+ : "";
118
+ const cweInfo = cwe_codes?.length
119
+ ? ` CWE: ${cwe_codes.join(", ")}.`
120
+ : "";
121
+ const response = {
122
+ decision: "block",
123
+ reason: `🛡️ Superagent Guard blocked this prompt.${violationInfo}${cweInfo}`,
124
+ hookSpecificOutput: {
125
+ hookEventName: "UserPromptSubmit",
126
+ additionalContext: `Blocked by Superagent Guard`,
127
+ },
128
+ };
129
+ console.log(JSON.stringify(response));
130
+ }
131
+ else {
132
+ // CLI output - JSON format matching SDK
133
+ const output = {
134
+ classification,
135
+ violation_types,
136
+ cwe_codes,
137
+ usage,
138
+ };
139
+ console.log(JSON.stringify(output, null, 2));
140
+ process.exit(1);
141
+ }
142
+ }
143
+ else {
144
+ if (!isStdin) {
145
+ // CLI output - JSON format matching SDK
146
+ const output = {
147
+ classification,
148
+ violation_types,
149
+ cwe_codes,
150
+ usage,
151
+ };
152
+ console.log(JSON.stringify(output, null, 2));
153
+ }
154
+ }
155
+ process.exit(0);
156
+ }
157
+ catch (error) {
158
+ console.error(`⚠️ Guard check failed: ${error.message}`);
159
+ if (isStdin) {
160
+ console.error("Allowing prompt to proceed...");
161
+ process.exit(0);
162
+ }
163
+ else {
164
+ process.exit(2);
165
+ }
166
+ }
167
+ }
@@ -0,0 +1 @@
1
+ export declare function redactCommand(args: string[]): Promise<void>;
@@ -0,0 +1,103 @@
1
+ import { createClient } from "safety-agent";
2
+ export async function redactCommand(args) {
3
+ // Check for --entities flag
4
+ const entitiesFlagIndex = args.indexOf("--entities");
5
+ let entities;
6
+ if (entitiesFlagIndex !== -1) {
7
+ // Get the value after --entities (comma-separated entities)
8
+ const entitiesValue = args[entitiesFlagIndex + 1];
9
+ if (entitiesValue) {
10
+ entities = entitiesValue.split(",").map((entity) => entity.trim());
11
+ // Remove --entities and its value from args
12
+ args.splice(entitiesFlagIndex, 2);
13
+ }
14
+ else {
15
+ console.error("❌ ERROR: --entities requires a comma-separated list of entity types");
16
+ process.exit(1);
17
+ }
18
+ }
19
+ // Check for --rewrite flag
20
+ const rewriteFlagIndex = args.indexOf("--rewrite");
21
+ let rewrite;
22
+ if (rewriteFlagIndex !== -1) {
23
+ rewrite = true;
24
+ // Remove --rewrite from args
25
+ args.splice(rewriteFlagIndex, 1);
26
+ }
27
+ // Check if we have command line arguments first
28
+ const hasArgs = args.length > 0;
29
+ let text;
30
+ let isStdin = false;
31
+ if (!hasArgs && !process.stdin.isTTY) {
32
+ isStdin = true;
33
+ // Read JSON from stdin
34
+ const stdin = await new Promise((resolve) => {
35
+ let data = "";
36
+ process.stdin.on("data", (chunk) => (data += chunk));
37
+ process.stdin.on("end", () => resolve(data));
38
+ });
39
+ try {
40
+ const inputData = JSON.parse(stdin);
41
+ text = inputData.text || inputData.prompt;
42
+ // Check for rewrite in stdin JSON
43
+ if (inputData.rewrite !== undefined) {
44
+ rewrite = Boolean(inputData.rewrite);
45
+ }
46
+ if (!text) {
47
+ console.error("❌ ERROR: No text provided in stdin JSON");
48
+ process.exit(2);
49
+ }
50
+ }
51
+ catch (error) {
52
+ console.error("❌ ERROR: Failed to parse JSON from stdin");
53
+ process.exit(2);
54
+ }
55
+ }
56
+ else {
57
+ // Command line argument
58
+ text = args.join(" ");
59
+ 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]');
62
+ console.error("");
63
+ console.error("Options:");
64
+ console.error(" --entities <entities> Comma-separated list of entity types to redact");
65
+ console.error(" --rewrite Naturally rewrite content instead of using placeholders");
66
+ console.error("");
67
+ console.error("Examples:");
68
+ console.error(' superagent redact "My email is john@example.com"');
69
+ console.error(' superagent redact --entities "emails,phones" "Contact: john@example.com, 555-1234"');
70
+ console.error(' superagent redact --rewrite "Contact me at john@example.com"');
71
+ process.exit(1);
72
+ }
73
+ }
74
+ // Ensure API key is available
75
+ if (!process.env.SUPERAGENT_API_KEY) {
76
+ console.error("❌ ERROR: SUPERAGENT_API_KEY environment variable not set");
77
+ process.exit(2);
78
+ }
79
+ // Create client instance
80
+ const client = createClient({
81
+ apiKey: process.env.SUPERAGENT_API_KEY,
82
+ });
83
+ try {
84
+ const result = await client.redact({
85
+ input: text,
86
+ model: "openai/gpt-4o-mini",
87
+ entities,
88
+ rewrite,
89
+ });
90
+ // JSON output
91
+ const output = {
92
+ redacted: result.redacted,
93
+ findings: result.findings,
94
+ usage: result.usage,
95
+ };
96
+ console.log(JSON.stringify(output, null, 2));
97
+ process.exit(0);
98
+ }
99
+ catch (error) {
100
+ console.error(`⚠️ Redact failed: ${error.message}`);
101
+ process.exit(2);
102
+ }
103
+ }
@@ -0,0 +1 @@
1
+ export declare function verifyCommand(args: string[]): Promise<void>;
@@ -0,0 +1,137 @@
1
+ import { createClient } from 'superagent-ai';
2
+ function showHelp() {
3
+ console.log('Usage: superagent verify [options] <text>');
4
+ console.log(' or: echo \'{"text": "...", "sources": [...]}\' | superagent verify');
5
+ console.log('');
6
+ console.log('Verify claims in text against source materials');
7
+ console.log('');
8
+ console.log('Options:');
9
+ console.log(' --help Show this help message');
10
+ console.log(' --sources <json> JSON string containing array of sources');
11
+ console.log('');
12
+ console.log('Source format:');
13
+ console.log(' [{"name": "Source Name", "content": "...", "url": "https://..."}]');
14
+ console.log('');
15
+ console.log('Examples:');
16
+ console.log(' superagent verify --sources \'[{"name":"About","content":"Founded in 2020"}]\' "The company was founded in 2020"');
17
+ console.log(' echo \'{"text": "...", "sources": [...]}\' | superagent verify');
18
+ }
19
+ export async function verifyCommand(args) {
20
+ // Check for --help flag
21
+ if (args.includes('--help') || args.includes('-h')) {
22
+ showHelp();
23
+ process.exit(0);
24
+ }
25
+ // Check for --sources flag
26
+ let sources;
27
+ const sourcesFlagIndex = args.indexOf('--sources');
28
+ if (sourcesFlagIndex !== -1) {
29
+ const sourcesJson = args[sourcesFlagIndex + 1];
30
+ if (sourcesJson) {
31
+ try {
32
+ sources = JSON.parse(sourcesJson);
33
+ if (!Array.isArray(sources)) {
34
+ console.error('❌ ERROR: --sources must be a JSON array');
35
+ process.exit(1);
36
+ }
37
+ // Remove --sources and its value from args
38
+ args.splice(sourcesFlagIndex, 2);
39
+ }
40
+ catch (error) {
41
+ console.error(`❌ ERROR: Failed to parse sources JSON: ${error.message}`);
42
+ process.exit(1);
43
+ }
44
+ }
45
+ else {
46
+ console.error('❌ ERROR: --sources flag requires a JSON string');
47
+ process.exit(1);
48
+ }
49
+ }
50
+ // Check if we have command line arguments first
51
+ const hasArgs = args.length > 0;
52
+ let text;
53
+ let isStdin = false;
54
+ if (!hasArgs && !process.stdin.isTTY) {
55
+ isStdin = true;
56
+ // Read JSON from stdin
57
+ const stdin = await new Promise((resolve) => {
58
+ let data = '';
59
+ process.stdin.on('data', chunk => data += chunk);
60
+ process.stdin.on('end', () => resolve(data));
61
+ });
62
+ try {
63
+ const inputData = JSON.parse(stdin);
64
+ text = inputData.text;
65
+ // Get sources from stdin if not provided via command line
66
+ if (!sources && inputData.sources) {
67
+ sources = inputData.sources;
68
+ }
69
+ if (!text) {
70
+ console.error('❌ ERROR: No text provided in stdin JSON');
71
+ process.exit(2);
72
+ }
73
+ }
74
+ catch (error) {
75
+ console.error('❌ ERROR: Failed to parse JSON from stdin');
76
+ process.exit(2);
77
+ }
78
+ }
79
+ else {
80
+ // Command line argument
81
+ text = args.join(' ');
82
+ if (!text) {
83
+ showHelp();
84
+ process.exit(1);
85
+ }
86
+ }
87
+ // Validate sources
88
+ if (!sources || !Array.isArray(sources) || sources.length === 0) {
89
+ console.error('❌ ERROR: sources are required. Use --sources flag or provide via stdin');
90
+ console.error('');
91
+ showHelp();
92
+ process.exit(1);
93
+ }
94
+ // Validate each source
95
+ for (const source of sources) {
96
+ if (!source.content || typeof source.content !== 'string') {
97
+ console.error('❌ ERROR: Each source must have a "content" field (string)');
98
+ process.exit(1);
99
+ }
100
+ if (!source.name || typeof source.name !== 'string') {
101
+ console.error('❌ ERROR: Each source must have a "name" field (string)');
102
+ process.exit(1);
103
+ }
104
+ if (source.url !== undefined && typeof source.url !== 'string') {
105
+ console.error('❌ ERROR: If provided, "url" must be a string');
106
+ process.exit(1);
107
+ }
108
+ }
109
+ // Ensure API key is available
110
+ if (!process.env.SUPERAGENT_API_KEY) {
111
+ console.error('❌ ERROR: SUPERAGENT_API_KEY environment variable not set');
112
+ process.exit(2);
113
+ }
114
+ // Create client instance
115
+ const client = createClient({
116
+ apiKey: process.env.SUPERAGENT_API_KEY,
117
+ });
118
+ try {
119
+ const result = await client.verify(text, sources);
120
+ const output = {
121
+ claims: result.claims,
122
+ usage: result.usage,
123
+ };
124
+ console.log(JSON.stringify(output, null, 2));
125
+ process.exit(0);
126
+ }
127
+ catch (error) {
128
+ console.error(`⚠️ Verify failed: ${error.message}`);
129
+ if (isStdin) {
130
+ console.error('Allowing to proceed...');
131
+ process.exit(0);
132
+ }
133
+ else {
134
+ process.exit(2);
135
+ }
136
+ }
137
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import { guardCommand } from './commands/guard.js';
3
+ import { redactCommand } from './commands/redact.js';
4
+ function showHelp() {
5
+ console.log('Usage: superagent <command> [options]');
6
+ console.log('');
7
+ console.log('AI security and privacy toolkit');
8
+ console.log('');
9
+ console.log('Commands:');
10
+ console.log(' guard Analyze prompts for security threats');
11
+ console.log(' redact Remove sensitive data from text');
12
+ console.log('');
13
+ console.log('Options:');
14
+ console.log(' --help Show help for a command');
15
+ console.log('');
16
+ console.log('Examples:');
17
+ console.log(' superagent guard --help');
18
+ console.log(' superagent redact --help');
19
+ console.log(' superagent guard "rm -rf /"');
20
+ console.log(' superagent redact "My email is john@example.com"');
21
+ }
22
+ const args = process.argv.slice(2);
23
+ const command = args[0];
24
+ if (!command || command === '--help' || command === '-h') {
25
+ showHelp();
26
+ process.exit(0);
27
+ }
28
+ switch (command) {
29
+ case 'guard':
30
+ await guardCommand(args.slice(1));
31
+ break;
32
+ case 'redact':
33
+ await redactCommand(args.slice(1));
34
+ break;
35
+ default:
36
+ console.error(`Unknown command: ${command}`);
37
+ console.error('');
38
+ showHelp();
39
+ process.exit(1);
40
+ }
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "safety-agent-cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for Superagent - validate prompts and tool calls for security",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "superagent": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "test": "vitest run",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": [
21
+ "superagent",
22
+ "guard",
23
+ "cli",
24
+ "security",
25
+ "claude-code",
26
+ "hooks",
27
+ "ai-safety"
28
+ ],
29
+ "author": "Superagent",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/superagent-ai/superagent"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^20.11.0",
37
+ "dotenv": "^16.3.1",
38
+ "typescript": "^5.4.0",
39
+ "vitest": "^2.1.0"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "dependencies": {
45
+ "safety-agent": "^0.1.0"
46
+ }
47
+ }