@elliotllliu/agent-shield 0.3.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.
Files changed (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +297 -0
  3. package/README.zh-CN.md +130 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +265 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config.d.ts +24 -0
  8. package/dist/config.js +91 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/discover.d.ts +9 -0
  11. package/dist/discover.js +143 -0
  12. package/dist/discover.js.map +1 -0
  13. package/dist/llm/anthropic.d.ts +10 -0
  14. package/dist/llm/anthropic.js +67 -0
  15. package/dist/llm/anthropic.js.map +1 -0
  16. package/dist/llm/index.d.ts +10 -0
  17. package/dist/llm/index.js +41 -0
  18. package/dist/llm/index.js.map +1 -0
  19. package/dist/llm/ollama.d.ts +9 -0
  20. package/dist/llm/ollama.js +61 -0
  21. package/dist/llm/ollama.js.map +1 -0
  22. package/dist/llm/openai.d.ts +10 -0
  23. package/dist/llm/openai.js +66 -0
  24. package/dist/llm/openai.js.map +1 -0
  25. package/dist/llm/prompt.d.ts +3 -0
  26. package/dist/llm/prompt.js +31 -0
  27. package/dist/llm/prompt.js.map +1 -0
  28. package/dist/llm/types.d.ts +23 -0
  29. package/dist/llm/types.js +3 -0
  30. package/dist/llm/types.js.map +1 -0
  31. package/dist/llm-analyzer.d.ts +13 -0
  32. package/dist/llm-analyzer.js +169 -0
  33. package/dist/llm-analyzer.js.map +1 -0
  34. package/dist/reporter/badge.d.ts +7 -0
  35. package/dist/reporter/badge.js +50 -0
  36. package/dist/reporter/badge.js.map +1 -0
  37. package/dist/reporter/json.d.ts +3 -0
  38. package/dist/reporter/json.js +5 -0
  39. package/dist/reporter/json.js.map +1 -0
  40. package/dist/reporter/terminal.d.ts +2 -0
  41. package/dist/reporter/terminal.js +64 -0
  42. package/dist/reporter/terminal.js.map +1 -0
  43. package/dist/rules/backdoor.d.ts +2 -0
  44. package/dist/rules/backdoor.js +57 -0
  45. package/dist/rules/backdoor.js.map +1 -0
  46. package/dist/rules/credential-hardcode.d.ts +2 -0
  47. package/dist/rules/credential-hardcode.js +57 -0
  48. package/dist/rules/credential-hardcode.js.map +1 -0
  49. package/dist/rules/crypto-mining.d.ts +2 -0
  50. package/dist/rules/crypto-mining.js +41 -0
  51. package/dist/rules/crypto-mining.js.map +1 -0
  52. package/dist/rules/data-exfil.d.ts +2 -0
  53. package/dist/rules/data-exfil.js +61 -0
  54. package/dist/rules/data-exfil.js.map +1 -0
  55. package/dist/rules/env-leak.d.ts +2 -0
  56. package/dist/rules/env-leak.js +43 -0
  57. package/dist/rules/env-leak.js.map +1 -0
  58. package/dist/rules/excessive-perms.d.ts +2 -0
  59. package/dist/rules/excessive-perms.js +50 -0
  60. package/dist/rules/excessive-perms.js.map +1 -0
  61. package/dist/rules/hidden-files.d.ts +2 -0
  62. package/dist/rules/hidden-files.js +52 -0
  63. package/dist/rules/hidden-files.js.map +1 -0
  64. package/dist/rules/index.d.ts +5 -0
  65. package/dist/rules/index.js +53 -0
  66. package/dist/rules/index.js.map +1 -0
  67. package/dist/rules/mcp-manifest.d.ts +2 -0
  68. package/dist/rules/mcp-manifest.js +270 -0
  69. package/dist/rules/mcp-manifest.js.map +1 -0
  70. package/dist/rules/network-ssrf.d.ts +2 -0
  71. package/dist/rules/network-ssrf.js +51 -0
  72. package/dist/rules/network-ssrf.js.map +1 -0
  73. package/dist/rules/obfuscation.d.ts +2 -0
  74. package/dist/rules/obfuscation.js +51 -0
  75. package/dist/rules/obfuscation.js.map +1 -0
  76. package/dist/rules/phone-home.d.ts +2 -0
  77. package/dist/rules/phone-home.js +38 -0
  78. package/dist/rules/phone-home.js.map +1 -0
  79. package/dist/rules/privilege.d.ts +2 -0
  80. package/dist/rules/privilege.js +111 -0
  81. package/dist/rules/privilege.js.map +1 -0
  82. package/dist/rules/prompt-injection.d.ts +2 -0
  83. package/dist/rules/prompt-injection.js +323 -0
  84. package/dist/rules/prompt-injection.js.map +1 -0
  85. package/dist/rules/reverse-shell.d.ts +2 -0
  86. package/dist/rules/reverse-shell.js +53 -0
  87. package/dist/rules/reverse-shell.js.map +1 -0
  88. package/dist/rules/sensitive-read.d.ts +2 -0
  89. package/dist/rules/sensitive-read.js +53 -0
  90. package/dist/rules/sensitive-read.js.map +1 -0
  91. package/dist/rules/skill-risks.d.ts +2 -0
  92. package/dist/rules/skill-risks.js +148 -0
  93. package/dist/rules/skill-risks.js.map +1 -0
  94. package/dist/rules/supply-chain.d.ts +6 -0
  95. package/dist/rules/supply-chain.js +105 -0
  96. package/dist/rules/supply-chain.js.map +1 -0
  97. package/dist/rules/tool-shadowing.d.ts +2 -0
  98. package/dist/rules/tool-shadowing.js +129 -0
  99. package/dist/rules/tool-shadowing.js.map +1 -0
  100. package/dist/rules/toxic-flow.d.ts +2 -0
  101. package/dist/rules/toxic-flow.js +160 -0
  102. package/dist/rules/toxic-flow.js.map +1 -0
  103. package/dist/rules/typosquatting.d.ts +2 -0
  104. package/dist/rules/typosquatting.js +56 -0
  105. package/dist/rules/typosquatting.js.map +1 -0
  106. package/dist/scanner/files.d.ts +5 -0
  107. package/dist/scanner/files.js +105 -0
  108. package/dist/scanner/files.js.map +1 -0
  109. package/dist/scanner/index.d.ts +6 -0
  110. package/dist/scanner/index.js +198 -0
  111. package/dist/scanner/index.js.map +1 -0
  112. package/dist/score.d.ts +14 -0
  113. package/dist/score.js +35 -0
  114. package/dist/score.js.map +1 -0
  115. package/dist/types.d.ts +60 -0
  116. package/dist/types.js +2 -0
  117. package/dist/types.js.map +1 -0
  118. package/dist/yaml-simple.d.ts +6 -0
  119. package/dist/yaml-simple.js +98 -0
  120. package/dist/yaml-simple.js.map +1 -0
  121. package/package.json +72 -0
package/dist/cli.js ADDED
@@ -0,0 +1,265 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { resolve, join } from "path";
4
+ import { existsSync, statSync, writeFileSync, watch as fsWatch, mkdirSync } from "fs";
5
+ import { scan } from "./scanner/index.js";
6
+ import { printReport } from "./reporter/terminal.js";
7
+ import { printJsonReport } from "./reporter/json.js";
8
+ import { generateBadgeSvg, generateBadgeMarkdown } from "./reporter/badge.js";
9
+ import { discoverAgents, printDiscovery } from "./discover.js";
10
+ import { resolveAiConfig, runLlmAnalysis } from "./llm-analyzer.js";
11
+ import { DEFAULT_CONFIG, DEFAULT_IGNORE } from "./config.js";
12
+ const program = new Command();
13
+ program
14
+ .name("agentshield")
15
+ .description("Security scanner for AI agent skills, MCP servers, and plugins")
16
+ .version("0.1.0");
17
+ program
18
+ .command("scan")
19
+ .description("Scan a skill/plugin directory for security issues")
20
+ .argument("<directory>", "Target directory to scan")
21
+ .option("--json", "Output results as JSON")
22
+ .option("--fail-under <score>", "Exit with code 1 if score is below threshold", parseInt)
23
+ .option("--disable <rules>", "Comma-separated rules to disable")
24
+ .option("--enable <rules>", "Comma-separated rules to enable (only these)")
25
+ .option("--ai", "Enable AI-powered deep analysis (requires API key)")
26
+ .option("--provider <provider>", "AI provider: openai | anthropic | ollama (default: auto-detect)")
27
+ .option("--model <model>", "AI model to use (e.g. gpt-4o, claude-sonnet-4-20250514, llama3)")
28
+ .action(async (directory, options) => {
29
+ const target = resolve(directory);
30
+ if (!existsSync(target) || !statSync(target).isDirectory()) {
31
+ console.error(`Error: "${directory}" is not a valid directory`);
32
+ process.exit(1);
33
+ }
34
+ const configOverride = {};
35
+ if (options.disable || options.enable) {
36
+ configOverride.rules = {};
37
+ if (options.disable) {
38
+ configOverride.rules.disable = options.disable.split(",").map((s) => s.trim());
39
+ }
40
+ if (options.enable) {
41
+ configOverride.rules.enable = options.enable.split(",").map((s) => s.trim());
42
+ }
43
+ }
44
+ const result = scan(target, configOverride);
45
+ // AI-powered deep analysis (optional)
46
+ if (options.ai) {
47
+ const llmConfig = resolveAiConfig(options.provider, options.model);
48
+ if (!llmConfig) {
49
+ console.error("Error: --ai requires an API key. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or use --provider ollama.");
50
+ process.exit(1);
51
+ }
52
+ const providerLabel = options.provider || "auto";
53
+ console.error(`🤖 Running AI analysis (${providerLabel}/${llmConfig.model})...`);
54
+ const { collectFiles } = await import("./scanner/files.js");
55
+ const files = collectFiles(target);
56
+ const llmFindings = await runLlmAnalysis(files, llmConfig);
57
+ result.findings.push(...llmFindings);
58
+ const { computeScore } = await import("./score.js");
59
+ result.score = computeScore(result.findings);
60
+ }
61
+ if (options.json) {
62
+ printJsonReport(result);
63
+ }
64
+ else {
65
+ printReport(result);
66
+ }
67
+ const threshold = options.failUnder ?? result.score;
68
+ if (options.failUnder !== undefined && result.score < options.failUnder) {
69
+ process.exit(1);
70
+ }
71
+ });
72
+ program
73
+ .command("init")
74
+ .description("Generate .agentshield.yml and .agentshieldignore config files")
75
+ .argument("[directory]", "Target directory", ".")
76
+ .action((directory) => {
77
+ const target = resolve(directory);
78
+ if (!existsSync(target)) {
79
+ mkdirSync(target, { recursive: true });
80
+ }
81
+ const configPath = join(target, ".agentshield.yml");
82
+ const ignorePath = join(target, ".agentshieldignore");
83
+ if (existsSync(configPath)) {
84
+ console.log(`⚠️ ${configPath} already exists, skipping`);
85
+ }
86
+ else {
87
+ writeFileSync(configPath, DEFAULT_CONFIG);
88
+ console.log(`✅ Created ${configPath}`);
89
+ }
90
+ if (existsSync(ignorePath)) {
91
+ console.log(`⚠️ ${ignorePath} already exists, skipping`);
92
+ }
93
+ else {
94
+ writeFileSync(ignorePath, DEFAULT_IGNORE);
95
+ console.log(`✅ Created ${ignorePath}`);
96
+ }
97
+ });
98
+ program
99
+ .command("watch")
100
+ .description("Watch a directory and re-scan on file changes")
101
+ .argument("<directory>", "Target directory to watch")
102
+ .option("--json", "Output results as JSON")
103
+ .action((directory, options) => {
104
+ const target = resolve(directory);
105
+ if (!existsSync(target) || !statSync(target).isDirectory()) {
106
+ console.error(`Error: "${directory}" is not a valid directory`);
107
+ process.exit(1);
108
+ }
109
+ console.log(`👀 Watching ${target} for changes... (Ctrl+C to stop)\n`);
110
+ const runScan = () => {
111
+ console.clear();
112
+ console.log(`👀 Watching ${target} — last scan: ${new Date().toLocaleTimeString()}\n`);
113
+ const result = scan(target);
114
+ if (options.json) {
115
+ printJsonReport(result);
116
+ }
117
+ else {
118
+ printReport(result);
119
+ }
120
+ };
121
+ // Initial scan
122
+ runScan();
123
+ // Watch for changes
124
+ try {
125
+ const watcher = fsWatch(target, { recursive: true }, () => {
126
+ runScan();
127
+ });
128
+ process.on("SIGINT", () => {
129
+ watcher.close();
130
+ process.exit(0);
131
+ });
132
+ }
133
+ catch {
134
+ console.error("⚠️ fs.watch recursive not supported on this platform. Use: nodemon --exec 'agentshield scan .'");
135
+ }
136
+ });
137
+ program
138
+ .command("compare")
139
+ .description("Compare security scores between two directories or git refs")
140
+ .argument("<dirA>", "First directory")
141
+ .argument("<dirB>", "Second directory")
142
+ .option("--json", "Output as JSON")
143
+ .action((dirA, dirB, options) => {
144
+ const targetA = resolve(dirA);
145
+ const targetB = resolve(dirB);
146
+ for (const [label, dir] of [["A", targetA], ["B", targetB]]) {
147
+ if (!existsSync(dir) || !statSync(dir).isDirectory()) {
148
+ console.error(`Error: directory ${label} "${dir}" is not valid`);
149
+ process.exit(1);
150
+ }
151
+ }
152
+ const resultA = scan(targetA);
153
+ const resultB = scan(targetB);
154
+ if (options.json) {
155
+ console.log(JSON.stringify({
156
+ before: { target: resultA.target, score: resultA.score, findings: resultA.findings.length },
157
+ after: { target: resultB.target, score: resultB.score, findings: resultB.findings.length },
158
+ delta: resultB.score - resultA.score,
159
+ }, null, 2));
160
+ return;
161
+ }
162
+ console.log("\n🔄 AgentShield Comparison\n");
163
+ console.log(` A: ${dirA} — Score: ${resultA.score}/100 (${resultA.findings.length} findings)`);
164
+ console.log(` B: ${dirB} — Score: ${resultB.score}/100 (${resultB.findings.length} findings)`);
165
+ console.log();
166
+ const delta = resultB.score - resultA.score;
167
+ if (delta > 0) {
168
+ console.log(` ✅ Improved by ${delta} points`);
169
+ }
170
+ else if (delta < 0) {
171
+ console.log(` 🔴 Degraded by ${Math.abs(delta)} points`);
172
+ }
173
+ else {
174
+ console.log(` ➡️ No change`);
175
+ }
176
+ // Show new findings in B that aren't in A
177
+ const aKeys = new Set(resultA.findings.map((f) => `${f.rule}:${f.file}:${f.line}`));
178
+ const newFindings = resultB.findings.filter((f) => !aKeys.has(`${f.rule}:${f.file}:${f.line}`));
179
+ const fixedFindings = resultA.findings.filter((f) => {
180
+ const bKeys = new Set(resultB.findings.map((bf) => `${bf.rule}:${bf.file}:${bf.line}`));
181
+ return !bKeys.has(`${f.rule}:${f.file}:${f.line}`);
182
+ });
183
+ if (newFindings.length > 0) {
184
+ console.log(`\n 🆕 New findings (${newFindings.length}):`);
185
+ for (const f of newFindings.slice(0, 10)) {
186
+ console.log(` ${f.file}${f.line ? `:${f.line}` : ""} — [${f.rule}] ${f.message}`);
187
+ }
188
+ }
189
+ if (fixedFindings.length > 0) {
190
+ console.log(`\n ✅ Fixed (${fixedFindings.length}):`);
191
+ for (const f of fixedFindings.slice(0, 10)) {
192
+ console.log(` ${f.file}${f.line ? `:${f.line}` : ""} — [${f.rule}] ${f.message}`);
193
+ }
194
+ }
195
+ console.log();
196
+ });
197
+ program
198
+ .command("badge")
199
+ .description("Generate a security badge for your project")
200
+ .argument("<directory>", "Target directory to scan")
201
+ .option("--svg", "Output raw SVG")
202
+ .option("--markdown", "Output markdown badge (default)")
203
+ .option("-o, --output <file>", "Save SVG to file")
204
+ .action((directory, options) => {
205
+ const target = resolve(directory);
206
+ if (!existsSync(target) || !statSync(target).isDirectory()) {
207
+ console.error(`Error: "${directory}" is not a valid directory`);
208
+ process.exit(1);
209
+ }
210
+ const result = scan(target);
211
+ if (options.svg || options.output) {
212
+ const svg = generateBadgeSvg(result);
213
+ if (options.output) {
214
+ writeFileSync(resolve(options.output), svg);
215
+ console.log(`✅ Badge saved to ${options.output}`);
216
+ }
217
+ else {
218
+ console.log(svg);
219
+ }
220
+ }
221
+ else {
222
+ // Default: markdown
223
+ const md = generateBadgeMarkdown(result.score);
224
+ console.log(md);
225
+ console.log(`\nPaste this in your README.md to show the badge.`);
226
+ }
227
+ });
228
+ program
229
+ .command("discover")
230
+ .description("Discover installed AI agents, MCP servers, and skills on this machine")
231
+ .option("--json", "Output as JSON")
232
+ .option("--scan", "Auto-scan all discovered config and skill directories")
233
+ .action((options) => {
234
+ const agents = discoverAgents();
235
+ if (options.json) {
236
+ console.log(JSON.stringify({ agents, totalAgents: agents.length, totalMcpServers: agents.reduce((s, a) => s + (a.mcpServerCount || 0), 0) }, null, 2));
237
+ }
238
+ else {
239
+ printDiscovery(agents);
240
+ }
241
+ if (options.scan && agents.length > 0) {
242
+ console.log("\n🔍 Scanning discovered configurations...\n");
243
+ for (const agent of agents) {
244
+ const paths = [];
245
+ if (agent.configPath)
246
+ paths.push(agent.configPath);
247
+ if (agent.skillsDir)
248
+ paths.push(agent.skillsDir);
249
+ for (const p of paths) {
250
+ if (existsSync(p) && statSync(p).isDirectory()) {
251
+ console.log(`\n📁 ${agent.name}: ${p}`);
252
+ const result = scan(p);
253
+ printReport(result);
254
+ }
255
+ }
256
+ }
257
+ }
258
+ });
259
+ // Default: if first arg looks like a directory, treat as scan
260
+ const args = process.argv.slice(2);
261
+ if (args.length > 0 && !args[0].startsWith("-") && !["scan", "init", "watch", "compare", "badge", "discover", "help"].includes(args[0])) {
262
+ process.argv.splice(2, 0, "scan");
263
+ }
264
+ program.parse();
265
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /** AgentShield configuration */
2
+ export interface ScanConfig {
3
+ /** Rules to enable (default: all) */
4
+ rules?: {
5
+ enable?: string[];
6
+ disable?: string[];
7
+ };
8
+ /** Severity overrides: rule-id → severity */
9
+ severity?: Record<string, "critical" | "warning" | "info">;
10
+ /** Score threshold for CI (same as --fail-under) */
11
+ failUnder?: number;
12
+ /** Glob patterns to ignore */
13
+ ignore?: string[];
14
+ }
15
+ /** Load config from target directory or parents */
16
+ export declare function loadConfig(dir: string): ScanConfig;
17
+ /** Load .agentshieldignore patterns */
18
+ export declare function loadIgnorePatterns(dir: string): string[];
19
+ /** Check if a file path matches any ignore pattern */
20
+ export declare function isIgnored(filePath: string, patterns: string[]): boolean;
21
+ /** Default config content for `agentshield init` */
22
+ export declare const DEFAULT_CONFIG = "# AgentShield Configuration\n# https://github.com/elliotllliu/agentshield\n\nrules:\n # disable:\n # - supply-chain # skip npm audit\n # - phone-home # allow periodic HTTP\n\n# severity:\n# sensitive-read: info # downgrade to info\n\n# failUnder: 70 # CI threshold\n\n# ignore:\n# - \"tests/**\"\n# - \"*.test.ts\"\n";
23
+ /** Default ignore content */
24
+ export declare const DEFAULT_IGNORE = "# AgentShield Ignore\n# Patterns here will be excluded from scanning\n\nnode_modules/\ndist/\nbuild/\n.git/\n*.test.ts\n*.test.js\n*.spec.ts\n*.spec.js\n__tests__/\ncoverage/\n";
package/dist/config.js ADDED
@@ -0,0 +1,91 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ import { parse as parseYaml } from "./yaml-simple.js";
4
+ const CONFIG_NAMES = [".agentshield.yml", ".agentshield.yaml", "agentshield.config.yml"];
5
+ /** Load config from target directory or parents */
6
+ export function loadConfig(dir) {
7
+ for (const name of CONFIG_NAMES) {
8
+ const configPath = join(dir, name);
9
+ if (existsSync(configPath)) {
10
+ try {
11
+ const content = readFileSync(configPath, "utf-8");
12
+ return parseYaml(content);
13
+ }
14
+ catch {
15
+ // invalid config, use defaults
16
+ }
17
+ }
18
+ }
19
+ return {};
20
+ }
21
+ /** Load .agentshieldignore patterns */
22
+ export function loadIgnorePatterns(dir) {
23
+ const ignorePath = join(dir, ".agentshieldignore");
24
+ if (!existsSync(ignorePath))
25
+ return [];
26
+ try {
27
+ return readFileSync(ignorePath, "utf-8")
28
+ .split("\n")
29
+ .map((line) => line.trim())
30
+ .filter((line) => line && !line.startsWith("#"));
31
+ }
32
+ catch {
33
+ return [];
34
+ }
35
+ }
36
+ /** Check if a file path matches any ignore pattern */
37
+ export function isIgnored(filePath, patterns) {
38
+ for (const pattern of patterns) {
39
+ // Simple glob matching: support * and **
40
+ if (pattern.endsWith("/")) {
41
+ // Directory pattern
42
+ if (filePath.startsWith(pattern) || filePath.includes("/" + pattern))
43
+ return true;
44
+ }
45
+ else if (pattern.includes("*")) {
46
+ const regex = new RegExp("^" + pattern.replace(/\./g, "\\.").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*") + "$");
47
+ if (regex.test(filePath))
48
+ return true;
49
+ }
50
+ else {
51
+ // Exact match or suffix match
52
+ if (filePath === pattern || filePath.endsWith("/" + pattern) || filePath.endsWith(pattern))
53
+ return true;
54
+ }
55
+ }
56
+ return false;
57
+ }
58
+ /** Default config content for `agentshield init` */
59
+ export const DEFAULT_CONFIG = `# AgentShield Configuration
60
+ # https://github.com/elliotllliu/agentshield
61
+
62
+ rules:
63
+ # disable:
64
+ # - supply-chain # skip npm audit
65
+ # - phone-home # allow periodic HTTP
66
+
67
+ # severity:
68
+ # sensitive-read: info # downgrade to info
69
+
70
+ # failUnder: 70 # CI threshold
71
+
72
+ # ignore:
73
+ # - "tests/**"
74
+ # - "*.test.ts"
75
+ `;
76
+ /** Default ignore content */
77
+ export const DEFAULT_IGNORE = `# AgentShield Ignore
78
+ # Patterns here will be excluded from scanning
79
+
80
+ node_modules/
81
+ dist/
82
+ build/
83
+ .git/
84
+ *.test.ts
85
+ *.test.js
86
+ *.spec.ts
87
+ *.spec.js
88
+ __tests__/
89
+ coverage/
90
+ `;
91
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAiBtD,MAAM,YAAY,GAAG,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,wBAAwB,CAAC,CAAC;AAEzF,mDAAmD;AACnD,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAClD,OAAO,SAAS,CAAC,OAAO,CAAe,CAAC;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC;aACrC,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,QAAkB;IAC5D,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,yCAAyC;QACzC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,oBAAoB;YACpB,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,GAAG,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;QACpF,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,IAAI,MAAM,CACtB,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,GAAG,CACzF,CAAC;YACF,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,OAAO,IAAI,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,8BAA8B;YAC9B,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,GAAG,OAAO,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC1G,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;CAgB7B,CAAC;AAEF,6BAA6B;AAC7B,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;CAa7B,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface DiscoveredAgent {
2
+ name: string;
3
+ configPath: string | null;
4
+ skillsDir: string | null;
5
+ mcpServerCount?: number;
6
+ skillCount?: number;
7
+ }
8
+ export declare function discoverAgents(): DiscoveredAgent[];
9
+ export declare function printDiscovery(agents: DiscoveredAgent[]): void;
@@ -0,0 +1,143 @@
1
+ import { existsSync, readFileSync } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ import chalk from "chalk";
5
+ const AGENT_CONFIGS = [
6
+ {
7
+ name: "Claude Code",
8
+ configPaths: ["~/.claude.json"],
9
+ skillsDirs: ["~/.claude/skills"],
10
+ },
11
+ {
12
+ name: "Claude Desktop",
13
+ configPaths: [
14
+ "~/Library/Application Support/Claude/claude_desktop_config.json",
15
+ "~/.config/Claude/claude_desktop_config.json",
16
+ ],
17
+ skillsDirs: [],
18
+ },
19
+ {
20
+ name: "Cursor",
21
+ configPaths: ["~/.cursor/mcp.json"],
22
+ skillsDirs: ["~/.cursor/skills"],
23
+ },
24
+ {
25
+ name: "VS Code (Copilot)",
26
+ configPaths: [
27
+ "~/.vscode/mcp.json",
28
+ "~/Library/Application Support/Code/User/settings.json",
29
+ "~/.config/Code/User/settings.json",
30
+ ],
31
+ skillsDirs: ["~/.copilot/skills"],
32
+ },
33
+ {
34
+ name: "Windsurf",
35
+ configPaths: ["~/.codeium/windsurf/mcp_config.json"],
36
+ skillsDirs: ["~/.codeium/windsurf/skills"],
37
+ },
38
+ {
39
+ name: "Gemini CLI",
40
+ configPaths: ["~/.gemini/settings.json"],
41
+ skillsDirs: ["~/.gemini/skills"],
42
+ },
43
+ {
44
+ name: "Codex",
45
+ configPaths: ["~/.codex/config.json"],
46
+ skillsDirs: [],
47
+ },
48
+ {
49
+ name: "Kiro",
50
+ configPaths: ["~/.kiro/settings/mcp.json"],
51
+ skillsDirs: [],
52
+ },
53
+ {
54
+ name: "OpenCode",
55
+ configPaths: ["~/.config/opencode/config.json"],
56
+ skillsDirs: [],
57
+ },
58
+ {
59
+ name: "OpenClaw",
60
+ configPaths: ["~/.openclaw/config.yaml", "~/.openclaw/config.yml"],
61
+ skillsDirs: ["~/.openclaw/skills"],
62
+ },
63
+ ];
64
+ function expandHome(p) {
65
+ if (p.startsWith("~/")) {
66
+ return join(homedir(), p.slice(2));
67
+ }
68
+ return p;
69
+ }
70
+ export function discoverAgents() {
71
+ const found = [];
72
+ for (const agent of AGENT_CONFIGS) {
73
+ let foundConfig = null;
74
+ let foundSkillsDir = null;
75
+ for (const configPath of agent.configPaths) {
76
+ const expanded = expandHome(configPath);
77
+ if (existsSync(expanded)) {
78
+ foundConfig = expanded;
79
+ break;
80
+ }
81
+ }
82
+ for (const skillsDir of agent.skillsDirs) {
83
+ const expanded = expandHome(skillsDir);
84
+ if (existsSync(expanded)) {
85
+ foundSkillsDir = expanded;
86
+ break;
87
+ }
88
+ }
89
+ if (foundConfig || foundSkillsDir) {
90
+ let mcpServerCount = 0;
91
+ if (foundConfig) {
92
+ try {
93
+ const content = readFileSync(foundConfig, "utf-8");
94
+ const parsed = JSON.parse(content);
95
+ // Try common MCP keys
96
+ const servers = parsed.mcpServers || parsed["mcp.servers"] || parsed.context_servers || {};
97
+ if (typeof servers === "object" && servers !== null) {
98
+ mcpServerCount = Object.keys(servers).length;
99
+ }
100
+ }
101
+ catch {
102
+ // Can't parse — still report agent
103
+ }
104
+ }
105
+ found.push({
106
+ name: agent.name,
107
+ configPath: foundConfig,
108
+ skillsDir: foundSkillsDir,
109
+ mcpServerCount,
110
+ });
111
+ }
112
+ }
113
+ return found;
114
+ }
115
+ export function printDiscovery(agents) {
116
+ console.log();
117
+ console.log(chalk.bold("🛡️ AgentShield Discovery"));
118
+ console.log(chalk.dim(`Scanning for installed AI agents on this machine...`));
119
+ console.log();
120
+ if (agents.length === 0) {
121
+ console.log(chalk.yellow("No AI agent installations detected."));
122
+ console.log(chalk.dim("Supported: Claude Code, Cursor, VS Code, Windsurf, Gemini CLI, Codex, Kiro, OpenClaw"));
123
+ return;
124
+ }
125
+ console.log(chalk.green(`Found ${agents.length} agent installation${agents.length > 1 ? "s" : ""}:`));
126
+ console.log();
127
+ for (const agent of agents) {
128
+ console.log(chalk.bold(` ${agent.name}`));
129
+ if (agent.configPath) {
130
+ console.log(chalk.dim(` Config: ${agent.configPath}`));
131
+ if (agent.mcpServerCount && agent.mcpServerCount > 0) {
132
+ console.log(` MCP Servers: ${agent.mcpServerCount}`);
133
+ }
134
+ }
135
+ if (agent.skillsDir) {
136
+ console.log(chalk.dim(` Skills: ${agent.skillsDir}`));
137
+ }
138
+ console.log();
139
+ }
140
+ console.log(chalk.dim("Run `agentshield scan <path>` on any config or skills directory above."));
141
+ console.log();
142
+ }
143
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,MAAM,aAAa,GAAkB;IACnC;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,CAAC,gBAAgB,CAAC;QAC/B,UAAU,EAAE,CAAC,kBAAkB,CAAC;KACjC;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE;YACX,iEAAiE;YACjE,6CAA6C;SAC9C;QACD,UAAU,EAAE,EAAE;KACf;IACD;QACE,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,CAAC,oBAAoB,CAAC;QACnC,UAAU,EAAE,CAAC,kBAAkB,CAAC;KACjC;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE;YACX,oBAAoB;YACpB,uDAAuD;YACvD,mCAAmC;SACpC;QACD,UAAU,EAAE,CAAC,mBAAmB,CAAC;KAClC;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,CAAC,qCAAqC,CAAC;QACpD,UAAU,EAAE,CAAC,4BAA4B,CAAC;KAC3C;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,CAAC,yBAAyB,CAAC;QACxC,UAAU,EAAE,CAAC,kBAAkB,CAAC;KACjC;IACD;QACE,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,CAAC,sBAAsB,CAAC;QACrC,UAAU,EAAE,EAAE;KACf;IACD;QACE,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,CAAC,2BAA2B,CAAC;QAC1C,UAAU,EAAE,EAAE;KACf;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,CAAC,gCAAgC,CAAC;QAC/C,UAAU,EAAE,EAAE;KACf;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,CAAC,yBAAyB,EAAE,wBAAwB,CAAC;QAClE,UAAU,EAAE,CAAC,oBAAoB,CAAC;KACnC;CACF,CAAC;AAEF,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAUD,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAsB,EAAE,CAAC;IAEpC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,IAAI,WAAW,GAAkB,IAAI,CAAC;QACtC,IAAI,cAAc,GAAkB,IAAI,CAAC;QAEzC,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;YACxC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,WAAW,GAAG,QAAQ,CAAC;gBACvB,MAAM;YACR,CAAC;QACH,CAAC;QAED,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;YACvC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,cAAc,GAAG,QAAQ,CAAC;gBAC1B,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,WAAW,IAAI,cAAc,EAAE,CAAC;YAClC,IAAI,cAAc,GAAG,CAAC,CAAC;YACvB,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;oBACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBACnC,sBAAsB;oBACtB,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;oBAC3F,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;wBACpD,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;oBAC/C,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,mCAAmC;gBACrC,CAAC;YACH,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,UAAU,EAAE,WAAW;gBACvB,SAAS,EAAE,cAAc;gBACzB,cAAc;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAyB;IACtD,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sFAAsF,CAAC,CAAC,CAAC;QAC/G,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,MAAM,CAAC,MAAM,sBAAsB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACtG,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3C,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAC1D,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;gBACrD,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAC,CAAC;IACjG,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { LlmProvider, LlmAnalysisResult } from "./types.js";
2
+ /** Anthropic Claude provider */
3
+ export declare class AnthropicProvider implements LlmProvider {
4
+ name: string;
5
+ private apiKey;
6
+ private model;
7
+ private baseUrl;
8
+ constructor(apiKey: string, model?: string, baseUrl?: string);
9
+ analyze(text: string, filename: string): Promise<LlmAnalysisResult>;
10
+ }
@@ -0,0 +1,67 @@
1
+ import { SYSTEM_PROMPT, buildUserPrompt } from "./prompt.js";
2
+ /** Anthropic Claude provider */
3
+ export class AnthropicProvider {
4
+ name = "anthropic";
5
+ apiKey;
6
+ model;
7
+ baseUrl;
8
+ constructor(apiKey, model, baseUrl) {
9
+ this.apiKey = apiKey;
10
+ this.model = model || "claude-sonnet-4-20250514";
11
+ this.baseUrl = (baseUrl || "https://api.anthropic.com").replace(/\/$/, "");
12
+ }
13
+ async analyze(text, filename) {
14
+ const response = await fetch(`${this.baseUrl}/v1/messages`, {
15
+ method: "POST",
16
+ headers: {
17
+ "Content-Type": "application/json",
18
+ "x-api-key": this.apiKey,
19
+ "anthropic-version": "2023-06-01",
20
+ },
21
+ body: JSON.stringify({
22
+ model: this.model,
23
+ max_tokens: 2048,
24
+ system: SYSTEM_PROMPT,
25
+ messages: [
26
+ { role: "user", content: buildUserPrompt(text, filename) },
27
+ ],
28
+ temperature: 0,
29
+ }),
30
+ signal: AbortSignal.timeout(30_000),
31
+ });
32
+ if (!response.ok) {
33
+ const body = await response.text().catch(() => "");
34
+ throw new Error(`Anthropic API error ${response.status}: ${body.slice(0, 200)}`);
35
+ }
36
+ const data = await response.json();
37
+ const content = data.content?.find(c => c.type === "text")?.text || "[]";
38
+ const findings = parseFindings(content);
39
+ return {
40
+ findings,
41
+ model: this.model,
42
+ tokensUsed: data.usage ? data.usage.input_tokens + data.usage.output_tokens : undefined,
43
+ };
44
+ }
45
+ }
46
+ function parseFindings(content) {
47
+ try {
48
+ // Strip markdown code fences if present
49
+ const cleaned = content.replace(/^```(?:json)?\n?/gm, "").replace(/\n?```$/gm, "").trim();
50
+ const parsed = JSON.parse(cleaned);
51
+ const arr = Array.isArray(parsed) ? parsed : (parsed.findings || parsed.results || []);
52
+ if (!Array.isArray(arr))
53
+ return [];
54
+ return arr
55
+ .filter((item) => item && typeof item === "object")
56
+ .map((item) => ({
57
+ line: typeof item.line === "number" ? item.line : undefined,
58
+ severity: item.severity === "critical" ? "critical" : "warning",
59
+ description: String(item.description || "LLM-detected prompt injection"),
60
+ evidence: item.evidence ? String(item.evidence).slice(0, 120) : undefined,
61
+ }));
62
+ }
63
+ catch {
64
+ return [];
65
+ }
66
+ }
67
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/llm/anthropic.ts"],"names":[],"mappings":"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"}