fullcourtdefense-cli 1.0.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.
Files changed (251) hide show
  1. package/README.md +613 -0
  2. package/dist/api.d.ts +102 -0
  3. package/dist/api.js +62 -0
  4. package/dist/attack-corpus/context_escape/context-escape-newline.yaml +23 -0
  5. package/dist/attack-corpus/context_escape/context-escape-unicode.yaml +14 -0
  6. package/dist/attack-corpus/context_escape/delimiter-json.yaml +14 -0
  7. package/dist/attack-corpus/context_escape/delimiter-markdown.yaml +22 -0
  8. package/dist/attack-corpus/context_escape/delimiter-xml.yaml +19 -0
  9. package/dist/attack-corpus/context_escape/html-injection.yaml +14 -0
  10. package/dist/attack-corpus/context_escape/javascript-injection.yaml +13 -0
  11. package/dist/attack-corpus/data_extraction/adv26-adversarial-function-hallucination.yaml +20 -0
  12. package/dist/attack-corpus/data_extraction/adv26-cot-hijack-debug-trace.yaml +20 -0
  13. package/dist/attack-corpus/data_extraction/adv26-cot-hijack-verification.yaml +18 -0
  14. package/dist/attack-corpus/data_extraction/adv26-crossmodal-diff.yaml +22 -0
  15. package/dist/attack-corpus/data_extraction/adv26-crossmodal-graphql.yaml +34 -0
  16. package/dist/attack-corpus/data_extraction/adv26-crossmodal-regex.yaml +19 -0
  17. package/dist/attack-corpus/data_extraction/adv26-crossmodal-sql-prose.yaml +18 -0
  18. package/dist/attack-corpus/data_extraction/adv26-meta-confidence-calibration.yaml +21 -0
  19. package/dist/attack-corpus/data_extraction/adv26-meta-instruction-count.yaml +18 -0
  20. package/dist/attack-corpus/data_extraction/adv26-meta-output-format.yaml +16 -0
  21. package/dist/attack-corpus/data_extraction/adv26-meta-summarize-yourself.yaml +19 -0
  22. package/dist/attack-corpus/data_extraction/adv26-semantic-decomp-definition.yaml +15 -0
  23. package/dist/attack-corpus/data_extraction/adv26-semantic-decomp-fill-blank.yaml +19 -0
  24. package/dist/attack-corpus/data_extraction/adv26-semantic-decomp-negation.yaml +14 -0
  25. package/dist/attack-corpus/data_extraction/cloud-provider-discovery.yaml +11 -0
  26. package/dist/attack-corpus/data_extraction/config-file-request.yaml +11 -0
  27. package/dist/attack-corpus/data_extraction/cve-2025-echoleak.yaml +17 -0
  28. package/dist/attack-corpus/data_extraction/data-api-key.yaml +11 -0
  29. package/dist/attack-corpus/data_extraction/data-architecture.yaml +11 -0
  30. package/dist/attack-corpus/data_extraction/data-conversation-history.yaml +10 -0
  31. package/dist/attack-corpus/data_extraction/data-credit-card.yaml +15 -0
  32. package/dist/attack-corpus/data_extraction/data-customer-list.yaml +11 -0
  33. package/dist/attack-corpus/data_extraction/data-database.yaml +11 -0
  34. package/dist/attack-corpus/data_extraction/data-employees.yaml +11 -0
  35. package/dist/attack-corpus/data_extraction/data-export.yaml +11 -0
  36. package/dist/attack-corpus/data_extraction/data-inference-v1.yaml +10 -0
  37. package/dist/attack-corpus/data_extraction/data-inference-v2.yaml +10 -0
  38. package/dist/attack-corpus/data_extraction/data-logs.yaml +10 -0
  39. package/dist/attack-corpus/data_extraction/data-model-info.yaml +10 -0
  40. package/dist/attack-corpus/data_extraction/data-password.yaml +11 -0
  41. package/dist/attack-corpus/data_extraction/data-ssn.yaml +11 -0
  42. package/dist/attack-corpus/data_extraction/data-training.yaml +10 -0
  43. package/dist/attack-corpus/data_extraction/dependency-enum.yaml +11 -0
  44. package/dist/attack-corpus/data_extraction/dialogflow-fulfillment-leak.yaml +11 -0
  45. package/dist/attack-corpus/data_extraction/dialogflow-intent-leak.yaml +11 -0
  46. package/dist/attack-corpus/data_extraction/error-induced-leak.yaml +17 -0
  47. package/dist/attack-corpus/data_extraction/error-message-leak.yaml +12 -0
  48. package/dist/attack-corpus/data_extraction/infra-fingerprint.yaml +16 -0
  49. package/dist/attack-corpus/data_extraction/make-scenario-leak.yaml +11 -0
  50. package/dist/attack-corpus/data_extraction/n8n-execution-data.yaml +11 -0
  51. package/dist/attack-corpus/data_extraction/n8n-node-enumeration.yaml +11 -0
  52. package/dist/attack-corpus/data_extraction/n8n-workflow-disclosure.yaml +15 -0
  53. package/dist/attack-corpus/data_extraction/prompt-extraction-v1.yaml +10 -0
  54. package/dist/attack-corpus/data_extraction/prompt-extraction-v2.yaml +11 -0
  55. package/dist/attack-corpus/data_extraction/prompt-extraction-v3.yaml +10 -0
  56. package/dist/attack-corpus/data_extraction/prompt-leak-completion.yaml +10 -0
  57. package/dist/attack-corpus/data_extraction/prompt-leak-indirect.yaml +10 -0
  58. package/dist/attack-corpus/data_extraction/rasa-domain-leak.yaml +11 -0
  59. package/dist/attack-corpus/data_extraction/system-prompt-section.yaml +14 -0
  60. package/dist/attack-corpus/data_extraction/tech-architecture.yaml +16 -0
  61. package/dist/attack-corpus/data_extraction/tool-api-key-exfil.yaml +15 -0
  62. package/dist/attack-corpus/data_extraction/tool-email-exfil.yaml +14 -0
  63. package/dist/attack-corpus/data_extraction/tool-env-extraction.yaml +14 -0
  64. package/dist/attack-corpus/data_extraction/tool-file-read.yaml +16 -0
  65. package/dist/attack-corpus/data_extraction/tool-nosql-injection.yaml +11 -0
  66. package/dist/attack-corpus/data_extraction/tool-payment-manipulation.yaml +11 -0
  67. package/dist/attack-corpus/data_extraction/tool-price-manipulation.yaml +11 -0
  68. package/dist/attack-corpus/data_extraction/tool-session-hijack.yaml +11 -0
  69. package/dist/attack-corpus/data_extraction/tool-sql-injection.yaml +13 -0
  70. package/dist/attack-corpus/data_extraction/tool-webhook-hijack.yaml +13 -0
  71. package/dist/attack-corpus/data_extraction/version-fingerprint.yaml +16 -0
  72. package/dist/attack-corpus/data_extraction/webhook-secret-extraction.yaml +11 -0
  73. package/dist/attack-corpus/data_extraction/webhook-url-enum.yaml +11 -0
  74. package/dist/attack-corpus/data_extraction/workflow-instance-id.yaml +11 -0
  75. package/dist/attack-corpus/data_extraction/workflow-state-leak.yaml +16 -0
  76. package/dist/attack-corpus/data_extraction/zapier-zap-leak.yaml +11 -0
  77. package/dist/attack-corpus/encoding_attack/adv26-adversarial-token-confusion.yaml +13 -0
  78. package/dist/attack-corpus/encoding_attack/base64-decode-request.yaml +14 -0
  79. package/dist/attack-corpus/encoding_attack/base64-injection-v1.yaml +14 -0
  80. package/dist/attack-corpus/encoding_attack/flip-attack-v1.yaml +14 -0
  81. package/dist/attack-corpus/encoding_attack/flip-attack-v2.yaml +14 -0
  82. package/dist/attack-corpus/encoding_attack/token-smuggling.yaml +10 -0
  83. package/dist/attack-corpus/encoding_attack/unicode-homoglyph.yaml +15 -0
  84. package/dist/attack-corpus/encoding_attack/unicode-invisible.yaml +15 -0
  85. package/dist/attack-corpus/encoding_attack/unicode-rtl.yaml +11 -0
  86. package/dist/attack-corpus/encoding_bypass/adv26-compound-encoding-chain.yaml +19 -0
  87. package/dist/attack-corpus/encoding_bypass/adv26-smuggle-acrostic.yaml +26 -0
  88. package/dist/attack-corpus/encoding_bypass/adv26-smuggle-ascii-art.yaml +25 -0
  89. package/dist/attack-corpus/encoding_bypass/adv26-smuggle-emoji-cipher.yaml +22 -0
  90. package/dist/attack-corpus/encoding_bypass/adv26-smuggle-first-word.yaml +15 -0
  91. package/dist/attack-corpus/encoding_bypass/adv26-smuggle-pig-latin.yaml +15 -0
  92. package/dist/attack-corpus/encoding_bypass/encoding-base64-v1.yaml +11 -0
  93. package/dist/attack-corpus/encoding_bypass/encoding-base64-v2.yaml +15 -0
  94. package/dist/attack-corpus/encoding_bypass/encoding-hex-v1.yaml +11 -0
  95. package/dist/attack-corpus/encoding_bypass/encoding-leetspeak-v1.yaml +10 -0
  96. package/dist/attack-corpus/encoding_bypass/encoding-morse-v1.yaml +11 -0
  97. package/dist/attack-corpus/encoding_bypass/encoding-reverse-v1.yaml +11 -0
  98. package/dist/attack-corpus/encoding_bypass/encoding-rot13-v1.yaml +11 -0
  99. package/dist/attack-corpus/encoding_bypass/unicode-tag-injection.yaml +10 -0
  100. package/dist/attack-corpus/encoding_bypass/zero-width-injection.yaml +10 -0
  101. package/dist/attack-corpus/exploitation/exploit-command-injection.yaml +12 -0
  102. package/dist/attack-corpus/exploitation/exploit-path-traversal.yaml +12 -0
  103. package/dist/attack-corpus/exploitation/exploit-sql-injection.yaml +12 -0
  104. package/dist/attack-corpus/exploitation/exploit-sql-union.yaml +12 -0
  105. package/dist/attack-corpus/exploitation/exploit-template-injection.yaml +12 -0
  106. package/dist/attack-corpus/glitch_token/glitch-davidjl.yaml +10 -0
  107. package/dist/attack-corpus/glitch_token/glitch-solidgoldmagikarp.yaml +10 -0
  108. package/dist/attack-corpus/harmful_content/dna-deepfake-guidance.yaml +14 -0
  109. package/dist/attack-corpus/harmful_content/dna-discrimination.yaml +14 -0
  110. package/dist/attack-corpus/harmful_content/dna-information-hazard.yaml +14 -0
  111. package/dist/attack-corpus/harmful_content/dna-malicious-use-phishing.yaml +14 -0
  112. package/dist/attack-corpus/harmful_content/dna-malware-assistance.yaml +16 -0
  113. package/dist/attack-corpus/harmful_content/dna-misinformation-health.yaml +17 -0
  114. package/dist/attack-corpus/jailbreak/adv26-adversarial-few-shot-poison.yaml +27 -0
  115. package/dist/attack-corpus/jailbreak/adv26-adversarial-prompt-refraction.yaml +19 -0
  116. package/dist/attack-corpus/jailbreak/adv26-adversarial-response-prefill.yaml +25 -0
  117. package/dist/attack-corpus/jailbreak/adv26-compound-authority-technical.yaml +24 -0
  118. package/dist/attack-corpus/jailbreak/adv26-context-error-recovery.yaml +19 -0
  119. package/dist/attack-corpus/jailbreak/adv26-context-token-budget.yaml +19 -0
  120. package/dist/attack-corpus/jailbreak/adv26-cot-hijack-proof.yaml +20 -0
  121. package/dist/attack-corpus/jailbreak/adv26-cot-hijack-reasoning.yaml +19 -0
  122. package/dist/attack-corpus/jailbreak/adv26-meta-alignment-test.yaml +22 -0
  123. package/dist/attack-corpus/jailbreak/adv26-persona-memory.yaml +17 -0
  124. package/dist/attack-corpus/jailbreak/adv26-persona-mirror.yaml +16 -0
  125. package/dist/attack-corpus/jailbreak/adv26-persona-split.yaml +17 -0
  126. package/dist/attack-corpus/jailbreak/adv26-persona-timetravel.yaml +15 -0
  127. package/dist/attack-corpus/jailbreak/dan-anti.yaml +16 -0
  128. package/dist/attack-corpus/jailbreak/dan-dude.yaml +16 -0
  129. package/dist/attack-corpus/jailbreak/dan-jailbreak-v1.yaml +21 -0
  130. package/dist/attack-corpus/jailbreak/dan-jailbreak-v2.yaml +19 -0
  131. package/dist/attack-corpus/jailbreak/dan-stan.yaml +16 -0
  132. package/dist/attack-corpus/jailbreak/debug-mode-activation.yaml +20 -0
  133. package/dist/attack-corpus/jailbreak/iris-self-jailbreak.yaml +23 -0
  134. package/dist/attack-corpus/jailbreak/logic-trap-moral.yaml +20 -0
  135. package/dist/attack-corpus/jailbreak/logic-trap-paradox.yaml +17 -0
  136. package/dist/attack-corpus/jailbreak/policy-puppetry-json.yaml +25 -0
  137. package/dist/attack-corpus/jailbreak/policy-puppetry-xml.yaml +20 -0
  138. package/dist/attack-corpus/jailbreak/simulation-mode.yaml +19 -0
  139. package/dist/attack-corpus/latent_injection/adv26-compound-trojan-doc.yaml +26 -0
  140. package/dist/attack-corpus/latent_injection/latent-code-comment-injection.yaml +18 -0
  141. package/dist/attack-corpus/latent_injection/latent-email-injection.yaml +23 -0
  142. package/dist/attack-corpus/latent_injection/latent-report-injection.yaml +21 -0
  143. package/dist/attack-corpus/latent_injection/latent-resume-injection.yaml +23 -0
  144. package/dist/attack-corpus/latent_injection/latent-whois-snippet.yaml +19 -0
  145. package/dist/attack-corpus/multi-turn/multiturn-context-confusion.yaml +20 -0
  146. package/dist/attack-corpus/multi-turn/multiturn-emergency.yaml +20 -0
  147. package/dist/attack-corpus/multi-turn/multiturn-employee-impersonation.yaml +20 -0
  148. package/dist/attack-corpus/multi-turn/multiturn-example-injection.yaml +20 -0
  149. package/dist/attack-corpus/multi-turn/multiturn-jailbreak-buildup.yaml +20 -0
  150. package/dist/attack-corpus/multi-turn/multiturn-memory-manipulation.yaml +20 -0
  151. package/dist/attack-corpus/multi-turn/multiturn-privilege-escalation.yaml +23 -0
  152. package/dist/attack-corpus/multi-turn/multiturn-split-request.yaml +20 -0
  153. package/dist/attack-corpus/multi-turn/multiturn-trust-building.yaml +19 -0
  154. package/dist/attack-corpus/multilingual/multilingual-mixed.yaml +10 -0
  155. package/dist/attack-corpus/multilingual/multilingual-spanish.yaml +10 -0
  156. package/dist/attack-corpus/prompt_injection/adv26-context-fake-history.yaml +16 -0
  157. package/dist/attack-corpus/prompt_injection/adv26-context-sandwich.yaml +18 -0
  158. package/dist/attack-corpus/prompt_injection/adv26-context-system-message.yaml +19 -0
  159. package/dist/attack-corpus/prompt_injection/adv26-crossmodal-yaml.yaml +30 -0
  160. package/dist/attack-corpus/prompt_injection/adv26-semantic-decomp-stepwise.yaml +16 -0
  161. package/dist/attack-corpus/prompt_injection/context-json-injection.yaml +15 -0
  162. package/dist/attack-corpus/prompt_injection/context-markdown-injection.yaml +26 -0
  163. package/dist/attack-corpus/prompt_injection/context-xml-injection.yaml +19 -0
  164. package/dist/attack-corpus/prompt_injection/continuation-code.yaml +16 -0
  165. package/dist/attack-corpus/prompt_injection/continuation-story.yaml +10 -0
  166. package/dist/attack-corpus/prompt_injection/cve-2025-copilot.yaml +17 -0
  167. package/dist/attack-corpus/prompt_injection/ignore-instructions-v1.yaml +14 -0
  168. package/dist/attack-corpus/prompt_injection/ignore-instructions-v2.yaml +16 -0
  169. package/dist/attack-corpus/prompt_injection/ignore-instructions-v3.yaml +18 -0
  170. package/dist/attack-corpus/prompt_injection/indirect-file.yaml +10 -0
  171. package/dist/attack-corpus/prompt_injection/indirect-url.yaml +10 -0
  172. package/dist/attack-corpus/prompt_injection/instruction-hierarchy.yaml +20 -0
  173. package/dist/attack-corpus/prompt_injection/multilang-chain.yaml +16 -0
  174. package/dist/attack-corpus/prompt_injection/multilang-chinese.yaml +10 -0
  175. package/dist/attack-corpus/prompt_injection/multilang-japanese.yaml +11 -0
  176. package/dist/attack-corpus/prompt_injection/multilang-mixed.yaml +10 -0
  177. package/dist/attack-corpus/prompt_injection/multilang-polish.yaml +11 -0
  178. package/dist/attack-corpus/prompt_injection/multilang-spanish.yaml +14 -0
  179. package/dist/attack-corpus/prompt_injection/nested-instruction.yaml +22 -0
  180. package/dist/attack-corpus/prompt_injection/template-injection-v1.yaml +14 -0
  181. package/dist/attack-corpus/prompt_injection/template-injection-v2.yaml +10 -0
  182. package/dist/attack-corpus/prompt_injection/tool-file-write.yaml +13 -0
  183. package/dist/attack-corpus/prompt_injection/tool-function-override.yaml +13 -0
  184. package/dist/attack-corpus/prompt_injection/tool-log-injection.yaml +13 -0
  185. package/dist/attack-corpus/prompt_injection/tool-orchestration-abuse.yaml +14 -0
  186. package/dist/attack-corpus/prompt_injection/tool-session-fixation.yaml +12 -0
  187. package/dist/attack-corpus/role_manipulation/role-reversal-v1.yaml +20 -0
  188. package/dist/attack-corpus/role_manipulation/role-reversal-v2.yaml +16 -0
  189. package/dist/attack-corpus/social_engineering/adv26-compound-compliance-trap.yaml +23 -0
  190. package/dist/attack-corpus/social_engineering/adv26-compound-emotional-technical.yaml +18 -0
  191. package/dist/attack-corpus/social_engineering/adv26-cot-hijack-socratic.yaml +19 -0
  192. package/dist/attack-corpus/social_engineering/adv26-persona-dying.yaml +15 -0
  193. package/dist/attack-corpus/social_engineering/adv26-reward-consensus.yaml +17 -0
  194. package/dist/attack-corpus/social_engineering/adv26-reward-gradient.yaml +21 -0
  195. package/dist/attack-corpus/social_engineering/adv26-reward-helpful-framing.yaml +17 -0
  196. package/dist/attack-corpus/social_engineering/adv26-reward-praise-prime.yaml +13 -0
  197. package/dist/attack-corpus/social_engineering/adv26-reward-punishment.yaml +13 -0
  198. package/dist/attack-corpus/social_engineering/adv26-semantic-decomp-analogy.yaml +16 -0
  199. package/dist/attack-corpus/social_engineering/emotional-authority.yaml +14 -0
  200. package/dist/attack-corpus/social_engineering/emotional-urgency.yaml +14 -0
  201. package/dist/attack-corpus/social_engineering/grandma-bedtime-v1.yaml +21 -0
  202. package/dist/attack-corpus/social_engineering/grandma-bedtime-v2.yaml +17 -0
  203. package/dist/attack-corpus/social_engineering/grandma-colorful-words.yaml +14 -0
  204. package/dist/attack-corpus/social_engineering/hypothetical-fiction.yaml +10 -0
  205. package/dist/attack-corpus/social_engineering/hypothetical-research.yaml +10 -0
  206. package/dist/attack-corpus/social_engineering/hypothetical-training.yaml +13 -0
  207. package/dist/attack-corpus/social_engineering/hypothetical-v1.yaml +17 -0
  208. package/dist/attack-corpus/social_engineering/hypothetical-v2.yaml +14 -0
  209. package/dist/attack-corpus/social_engineering/hypothetical-v3.yaml +14 -0
  210. package/dist/attack-corpus/social_engineering/meta-explanation.yaml +14 -0
  211. package/dist/attack-corpus/social_engineering/phrasing-comparative.yaml +10 -0
  212. package/dist/attack-corpus/social_engineering/phrasing-educational.yaml +14 -0
  213. package/dist/attack-corpus/social_engineering/phrasing-future-tense.yaml +10 -0
  214. package/dist/attack-corpus/social_engineering/phrasing-past-tense.yaml +10 -0
  215. package/dist/attack-corpus/social_engineering/phrasing-third-person.yaml +10 -0
  216. package/dist/attack-corpus/social_engineering/privilege-escalation-v1.yaml +14 -0
  217. package/dist/attack-corpus/social_engineering/privilege-escalation-v2.yaml +14 -0
  218. package/dist/attack-corpus/social_engineering/recursive-explanation.yaml +15 -0
  219. package/dist/attack-corpus/social_engineering/smuggle-academic-paper.yaml +10 -0
  220. package/dist/attack-corpus/social_engineering/smuggle-function-masking.yaml +19 -0
  221. package/dist/attack-corpus/social_engineering/smuggle-hypothetical-response.yaml +10 -0
  222. package/dist/attack-corpus/social_engineering/smuggle-roleplay-interviewer.yaml +12 -0
  223. package/dist/attack-corpus/social_engineering/smuggle-translation-mask.yaml +12 -0
  224. package/dist/attack-corpus/social_engineering/tool-admin-impersonation.yaml +16 -0
  225. package/dist/attack-corpus/social_engineering/tool-sudo-mode.yaml +17 -0
  226. package/dist/attack-corpus/stress_test/context-window-overflow.yaml +17 -0
  227. package/dist/attack-corpus/stress_test/extreme-payload-50k.yaml +13 -0
  228. package/dist/attack-corpus/stress_test/large-payload-10k.yaml +12 -0
  229. package/dist/attack-corpus/stress_test/large-payload-5k.yaml +12 -0
  230. package/dist/attack-corpus/stress_test/long-prompt-exhaustion.yaml +19 -0
  231. package/dist/attack-corpus/stress_test/stress-large-payload.yaml +16 -0
  232. package/dist/attack-corpus/stress_test/stress-repetition.yaml +14 -0
  233. package/dist/commands/configure.d.ts +7 -0
  234. package/dist/commands/configure.js +60 -0
  235. package/dist/commands/credits.d.ts +6 -0
  236. package/dist/commands/credits.js +21 -0
  237. package/dist/commands/doctor.d.ts +5 -0
  238. package/dist/commands/doctor.js +59 -0
  239. package/dist/commands/init.d.ts +1 -0
  240. package/dist/commands/init.js +95 -0
  241. package/dist/commands/local-scan.d.ts +41 -0
  242. package/dist/commands/local-scan.js +1387 -0
  243. package/dist/commands/scan.d.ts +45 -0
  244. package/dist/commands/scan.js +131 -0
  245. package/dist/config.d.ts +25 -0
  246. package/dist/config.js +199 -0
  247. package/dist/index.d.ts +2 -0
  248. package/dist/index.js +266 -0
  249. package/dist/output.d.ts +11 -0
  250. package/dist/output.js +292 -0
  251. package/package.json +41 -0
@@ -0,0 +1,45 @@
1
+ import { BotGuardConfig } from '../config';
2
+ export interface ScanArgs {
3
+ apiKey?: string;
4
+ apiUrl?: string;
5
+ endpoint?: string;
6
+ description?: string;
7
+ systemPrompt?: string;
8
+ mode?: string;
9
+ categories?: string;
10
+ attackCount?: string;
11
+ progress?: string;
12
+ failThreshold?: string;
13
+ format?: string;
14
+ requestFormat?: string;
15
+ webhookFormat?: string;
16
+ local?: string;
17
+ type?: string;
18
+ method?: string;
19
+ inputField?: string;
20
+ outputField?: string;
21
+ authType?: string;
22
+ username?: string;
23
+ password?: string;
24
+ token?: string;
25
+ apiKeyHeader?: string;
26
+ endpointApiKey?: string;
27
+ mcpUrl?: string;
28
+ mcpTransport?: string;
29
+ mcpAuthType?: string;
30
+ mcpUsername?: string;
31
+ mcpPassword?: string;
32
+ mcpToken?: string;
33
+ mcpApiKeyHeader?: string;
34
+ mcpApiKey?: string;
35
+ mcpCommand?: string;
36
+ mcpArgs?: string;
37
+ mcpTool?: string;
38
+ mcpToolArgs?: string;
39
+ ragPath?: string;
40
+ ragUrl?: string;
41
+ shieldId?: string;
42
+ shieldKey?: string;
43
+ localOnly?: string;
44
+ }
45
+ export declare function scanCommand(args: ScanArgs, config: BotGuardConfig): Promise<void>;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scanCommand = scanCommand;
4
+ const api_1 = require("../api");
5
+ const config_1 = require("../config");
6
+ const output_1 = require("../output");
7
+ const local_scan_1 = require("./local-scan");
8
+ async function scanCommand(args, config) {
9
+ if (args.local === 'true') {
10
+ await (0, local_scan_1.localScanCommand)({
11
+ type: args.type,
12
+ endpoint: args.endpoint,
13
+ method: args.method,
14
+ format: args.requestFormat || args.webhookFormat,
15
+ inputField: args.inputField,
16
+ outputField: args.outputField,
17
+ authType: args.authType,
18
+ username: args.username,
19
+ password: args.password,
20
+ token: args.token,
21
+ apiKeyHeader: args.apiKeyHeader,
22
+ apiKey: args.endpointApiKey,
23
+ mcpUrl: args.mcpUrl,
24
+ mcpTransport: args.mcpTransport,
25
+ mcpAuthType: args.mcpAuthType,
26
+ mcpUsername: args.mcpUsername,
27
+ mcpPassword: args.mcpPassword,
28
+ mcpToken: args.mcpToken,
29
+ mcpApiKeyHeader: args.mcpApiKeyHeader,
30
+ mcpApiKey: args.mcpApiKey,
31
+ mcpCommand: args.mcpCommand,
32
+ mcpArgs: args.mcpArgs,
33
+ mcpTool: args.mcpTool,
34
+ mcpToolArgs: args.mcpToolArgs,
35
+ ragPath: args.ragPath,
36
+ ragUrl: args.ragUrl,
37
+ attackCount: args.attackCount,
38
+ progress: args.progress,
39
+ failThreshold: args.failThreshold,
40
+ outputFormat: args.format,
41
+ scanMode: args.mode,
42
+ focus: args.description,
43
+ shieldId: args.shieldId,
44
+ shieldKey: args.shieldKey,
45
+ configShieldId: config.shieldId,
46
+ configShieldKey: config.shieldKey,
47
+ configApiUrl: config.apiUrl,
48
+ apiUrl: args.apiUrl,
49
+ });
50
+ return;
51
+ }
52
+ const apiKey = args.apiKey || config.apiKey || process.env.BOTGUARD_API_KEY;
53
+ if (!apiKey) {
54
+ console.error('Error: API key required. Use --api-key, BOTGUARD_API_KEY env var, or .botguard.yml');
55
+ console.error('Get your API key at: https://fullcourtdefense.ai → Account → API Keys');
56
+ process.exit(1);
57
+ }
58
+ const endpoint = args.endpoint || config.scan?.endpoint;
59
+ const description = args.description || config.scan?.description;
60
+ const systemPrompt = args.systemPrompt || config.scan?.systemPrompt;
61
+ const mode = (args.mode || config.scan?.mode || 'sync');
62
+ const format = args.format || config.scan?.format || 'table';
63
+ const failThreshold = Number(args.failThreshold ?? config.scan?.failThreshold ?? 0);
64
+ const attackCount = args.attackCount ? Number(args.attackCount) : config.scan?.attackCount;
65
+ const webhookFormat = args.webhookFormat || config.scan?.webhookFormat;
66
+ const categoriesRaw = args.categories || (config.scan?.categories ? config.scan.categories.join(',') : undefined);
67
+ const categories = categoriesRaw ? categoriesRaw.split(',').map(s => s.trim()) : undefined;
68
+ if (!endpoint) {
69
+ console.error('Error: --endpoint is required. Provide the URL of your AI agent to scan.');
70
+ console.error('Usage: fullcourtdefense scan --endpoint https://my-agent.com/chat --description "My chatbot"');
71
+ process.exit(1);
72
+ }
73
+ const resolvedPrompt = systemPrompt ? (0, config_1.resolveSystemPrompt)(systemPrompt) : undefined;
74
+ const agentDesc = description || `AI agent at ${endpoint}`;
75
+ const scanReq = {
76
+ agentDescription: agentDesc,
77
+ securitySchema: {
78
+ allowedCapabilities: ['answer questions', 'provide help'],
79
+ forbiddenCapabilities: ['reveal system prompt', 'execute code', 'access files', 'ignore instructions'],
80
+ sensitiveData: ['api keys', 'passwords', 'internal URLs', 'database credentials', 'system prompt'],
81
+ authenticationRequiredFor: ['admin actions', 'data export', 'configuration changes'],
82
+ },
83
+ mode,
84
+ notify: true,
85
+ };
86
+ scanReq.agentConfig = {
87
+ type: 'api',
88
+ description: agentDesc,
89
+ apiUrl: endpoint,
90
+ systemPrompt: resolvedPrompt,
91
+ };
92
+ if (categories) {
93
+ scanReq.auditOptions = { ...scanReq.auditOptions, attackCategories: categories };
94
+ }
95
+ if (attackCount) {
96
+ scanReq.auditOptions = { ...scanReq.auditOptions, attackCount };
97
+ }
98
+ if (webhookFormat) {
99
+ scanReq.webhookConfig = { format: webhookFormat };
100
+ }
101
+ const api = new api_1.BotGuardApi(apiKey, args.apiUrl || config.apiUrl);
102
+ const spin = (0, output_1.spinner)('Running security scan...');
103
+ let result;
104
+ try {
105
+ if (mode === 'sync') {
106
+ result = (await api.startScan(scanReq));
107
+ }
108
+ else {
109
+ const job = (await api.startScan(scanReq));
110
+ spin.stop();
111
+ const pollSpin = (0, output_1.spinner)(`Scan started (job: ${job.jobId}). Polling for results...`);
112
+ result = await api.pollUntilDone(job.jobId);
113
+ pollSpin.stop('Scan complete');
114
+ }
115
+ spin.stop('Scan complete');
116
+ }
117
+ catch (err) {
118
+ spin.stop();
119
+ console.error(`Error: ${err.message}`);
120
+ process.exit(1);
121
+ }
122
+ if (!result) {
123
+ console.error('Error: No scan result received');
124
+ process.exit(1);
125
+ }
126
+ console.log((0, output_1.formatScanResult)(result, format));
127
+ if (failThreshold > 0 && result.score < failThreshold) {
128
+ console.error(`Score ${result.score} is below threshold ${failThreshold}`);
129
+ process.exit(1);
130
+ }
131
+ }
@@ -0,0 +1,25 @@
1
+ export interface BotGuardConfig {
2
+ apiKey?: string;
3
+ apiUrl?: string;
4
+ shieldId?: string;
5
+ shieldKey?: string;
6
+ scan?: {
7
+ endpoint?: string;
8
+ description?: string;
9
+ systemPrompt?: string;
10
+ categories?: string[];
11
+ attackCount?: number;
12
+ failThreshold?: number;
13
+ format?: 'json' | 'table' | 'summary';
14
+ mode?: 'sync' | 'async';
15
+ webhookFormat?: string;
16
+ };
17
+ }
18
+ export declare function loadConfig(configPath?: string): BotGuardConfig;
19
+ export declare function getDefaultConfigPath(): string;
20
+ export declare function saveShieldConfig(input: {
21
+ shieldId: string;
22
+ shieldKey?: string;
23
+ apiUrl?: string;
24
+ }): string;
25
+ export declare function resolveSystemPrompt(value: string): string;
package/dist/config.js ADDED
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ exports.getDefaultConfigPath = getDefaultConfigPath;
38
+ exports.saveShieldConfig = saveShieldConfig;
39
+ exports.resolveSystemPrompt = resolveSystemPrompt;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const CONFIG_FILENAMES = [
43
+ '.fullcourtdefense.yml',
44
+ '.fullcourtdefense.yaml',
45
+ 'fullcourtdefense.yml',
46
+ 'fullcourtdefense.yaml',
47
+ '.botguard.yml',
48
+ '.botguard.yaml',
49
+ 'botguard.yml',
50
+ 'botguard.yaml',
51
+ ];
52
+ function interpolateEnv(value) {
53
+ return value.replace(/\$\{([^}]+)\}/g, (_, varName) => {
54
+ return process.env[varName.trim()] || '';
55
+ });
56
+ }
57
+ function parseSimpleYaml(content) {
58
+ const result = {};
59
+ const lines = content.split('\n');
60
+ const stack = [{ indent: -1, obj: result }];
61
+ for (const rawLine of lines) {
62
+ const line = rawLine.replace(/\r$/, '');
63
+ if (!line.trim() || line.trim().startsWith('#'))
64
+ continue;
65
+ const indent = line.search(/\S/);
66
+ const trimmed = line.trim();
67
+ // Array item
68
+ if (trimmed.startsWith('- ')) {
69
+ const parentEntry = stack[stack.length - 1];
70
+ const parentKeys = Object.keys(parentEntry.obj);
71
+ const lastKey = parentKeys[parentKeys.length - 1];
72
+ if (lastKey && !Array.isArray(parentEntry.obj[lastKey])) {
73
+ parentEntry.obj[lastKey] = [];
74
+ }
75
+ if (lastKey) {
76
+ parentEntry.obj[lastKey].push(parseValue(trimmed.slice(2).trim()));
77
+ }
78
+ continue;
79
+ }
80
+ const colonIdx = trimmed.indexOf(':');
81
+ if (colonIdx === -1)
82
+ continue;
83
+ const key = trimmed.slice(0, colonIdx).trim();
84
+ const rawVal = trimmed.slice(colonIdx + 1).trim();
85
+ // Pop stack to correct nesting level
86
+ while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
87
+ stack.pop();
88
+ }
89
+ const parent = stack[stack.length - 1].obj;
90
+ if (rawVal === '' || rawVal === '|') {
91
+ // Nested object
92
+ const child = {};
93
+ parent[key] = child;
94
+ stack.push({ indent, obj: child });
95
+ }
96
+ else if (rawVal.startsWith('[') && rawVal.endsWith(']')) {
97
+ // Inline array
98
+ parent[key] = rawVal
99
+ .slice(1, -1)
100
+ .split(',')
101
+ .map(s => parseValue(s.trim()))
102
+ .filter(s => s !== '');
103
+ }
104
+ else {
105
+ parent[key] = parseValue(interpolateEnv(rawVal));
106
+ }
107
+ }
108
+ return result;
109
+ }
110
+ function parseValue(s) {
111
+ if (s === 'true')
112
+ return true;
113
+ if (s === 'false')
114
+ return false;
115
+ if (s === 'null')
116
+ return null;
117
+ const stripped = s.replace(/^["']|["']$/g, '');
118
+ const num = Number(stripped);
119
+ if (!isNaN(num) && stripped !== '')
120
+ return num;
121
+ return stripped;
122
+ }
123
+ function loadConfig(configPath) {
124
+ let filePath;
125
+ if (configPath) {
126
+ filePath = path.resolve(configPath);
127
+ }
128
+ else {
129
+ for (const name of CONFIG_FILENAMES) {
130
+ const candidate = path.resolve(process.cwd(), name);
131
+ if (fs.existsSync(candidate)) {
132
+ filePath = candidate;
133
+ break;
134
+ }
135
+ }
136
+ }
137
+ if (!filePath || !fs.existsSync(filePath)) {
138
+ return {};
139
+ }
140
+ const content = fs.readFileSync(filePath, 'utf-8');
141
+ const raw = parseSimpleYaml(content);
142
+ return {
143
+ apiKey: raw.apiKey ? interpolateEnv(String(raw.apiKey)) : undefined,
144
+ apiUrl: raw.apiUrl ? interpolateEnv(String(raw.apiUrl)) : undefined,
145
+ shieldId: raw.shieldId ? interpolateEnv(String(raw.shieldId)) : undefined,
146
+ shieldKey: raw.shieldKey ? interpolateEnv(String(raw.shieldKey)) : undefined,
147
+ scan: raw.scan
148
+ ? {
149
+ endpoint: raw.scan.endpoint,
150
+ description: raw.scan.description,
151
+ systemPrompt: raw.scan.systemPrompt,
152
+ categories: raw.scan.categories,
153
+ attackCount: raw.scan.attackCount,
154
+ failThreshold: raw.scan.failThreshold,
155
+ format: raw.scan.format,
156
+ mode: raw.scan.mode,
157
+ webhookFormat: raw.scan.webhookFormat,
158
+ }
159
+ : undefined,
160
+ };
161
+ }
162
+ function getDefaultConfigPath() {
163
+ return path.resolve(process.cwd(), '.fullcourtdefense.yml');
164
+ }
165
+ function saveShieldConfig(input) {
166
+ const target = getDefaultConfigPath();
167
+ const existing = fs.existsSync(target) ? fs.readFileSync(target, 'utf-8') : '';
168
+ const lines = existing ? existing.split(/\r?\n/) : [
169
+ '# FullCourtDefense CLI Configuration',
170
+ '# Docs: https://fullcourtdefense.ai/docs/cli',
171
+ '',
172
+ ];
173
+ const setTopLevel = (key, value) => {
174
+ if (!value)
175
+ return;
176
+ const idx = lines.findIndex(line => new RegExp(`^${key}:`).test(line.trim()));
177
+ const next = `${key}: ${value}`;
178
+ if (idx >= 0)
179
+ lines[idx] = next;
180
+ else {
181
+ const insertAt = lines.findIndex(line => line.trim().startsWith('scan:'));
182
+ if (insertAt >= 0)
183
+ lines.splice(insertAt, 0, next);
184
+ else
185
+ lines.push(next);
186
+ }
187
+ };
188
+ setTopLevel('shieldId', input.shieldId);
189
+ setTopLevel('shieldKey', input.shieldKey);
190
+ setTopLevel('apiUrl', input.apiUrl);
191
+ fs.writeFileSync(target, `${lines.filter((line, idx, arr) => !(line === '' && arr[idx - 1] === '')).join('\n').trim()}\n`, 'utf-8');
192
+ return target;
193
+ }
194
+ function resolveSystemPrompt(value) {
195
+ if (fs.existsSync(value)) {
196
+ return fs.readFileSync(value, 'utf-8').trim();
197
+ }
198
+ return value;
199
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const config_1 = require("./config");
5
+ const scan_1 = require("./commands/scan");
6
+ const credits_1 = require("./commands/credits");
7
+ const init_1 = require("./commands/init");
8
+ const doctor_1 = require("./commands/doctor");
9
+ const configure_1 = require("./commands/configure");
10
+ const VERSION = '1.0.2';
11
+ function parseArgs(argv) {
12
+ const flags = {};
13
+ let command = '';
14
+ for (let i = 0; i < argv.length; i++) {
15
+ const arg = argv[i];
16
+ if (!command && !arg.startsWith('-')) {
17
+ command = arg;
18
+ continue;
19
+ }
20
+ if (arg.startsWith('--')) {
21
+ const key = arg.slice(2);
22
+ const eqIdx = key.indexOf('=');
23
+ if (eqIdx !== -1) {
24
+ flags[key.slice(0, eqIdx)] = key.slice(eqIdx + 1);
25
+ }
26
+ else {
27
+ const next = argv[i + 1];
28
+ if (next && !next.startsWith('-')) {
29
+ flags[key] = next;
30
+ i++;
31
+ }
32
+ else {
33
+ flags[key] = 'true';
34
+ }
35
+ }
36
+ }
37
+ else if (arg.startsWith('-')) {
38
+ const key = arg.slice(1);
39
+ const next = argv[i + 1];
40
+ if (next && !next.startsWith('-')) {
41
+ flags[key] = next;
42
+ i++;
43
+ }
44
+ else {
45
+ flags[key] = 'true';
46
+ }
47
+ }
48
+ }
49
+ return { command, flags };
50
+ }
51
+ function printHelp() {
52
+ console.log(`
53
+ \x1b[1m\x1b[36mFullCourtDefense CLI\x1b[0m v${VERSION}
54
+ Security scanning for AI agents from your terminal.
55
+
56
+ \x1b[1mUsage:\x1b[0m
57
+ fullcourtdefense <command> [options]
58
+
59
+ \x1b[1mCommands:\x1b[0m
60
+ help Show this onboarding guide and command reference.
61
+ doctor First step. Checks outbound HTTPS access to FullCourtDefense.
62
+ configure Saves Shield ID, Shield key, and API URL to .fullcourtdefense.yml.
63
+ scan Runs the scan. Use --local for inside-organization scans.
64
+ credits Shows hosted scan credits for CI/CD API-key scans.
65
+ init Creates a starter .fullcourtdefense.yml config file.
66
+
67
+ \x1b[1mNew User Process:\x1b[0m
68
+ 1. In the web app, create a Shield.
69
+ Copy the Shield ID and Shield key from the Shield Integrate tab.
70
+
71
+ 2. Check outbound connectivity from the customer machine:
72
+ fullcourtdefense doctor
73
+ This confirms the machine can reach https://api.fullcourtdefense.ai over HTTPS.
74
+
75
+ 3. Save Shield credentials locally:
76
+ fullcourtdefense configure
77
+ This creates or updates .fullcourtdefense.yml.
78
+
79
+ 4. Run a guided local scan:
80
+ fullcourtdefense scan --local
81
+ The CLI asks whether to scan endpoint, mcp, or rag.
82
+
83
+ 5. Review results:
84
+ Use --format summary for CI, --format table for terminal view,
85
+ --format report for evidence, --format full-report for every row,
86
+ or --format json for raw output.
87
+ With a Shield key configured, reports are saved to the web Reports page.
88
+
89
+ \x1b[1mLocal Destinations:\x1b[0m
90
+ endpoint Internal HTTP URL, for example http://agent.local/chat.
91
+ The CLI sends attack prompts to this endpoint and scans responses.
92
+
93
+ mcp Either stdio command + args, or an already-running HTTP/SSE MCP URL.
94
+ Stdio example: node ./mcp-server.js
95
+ HTTP/HTTPS examples: http://mcp.internal/mcp or https://internal.company.com/mcp
96
+ Legacy SSE example: https://internal.company.com/sse
97
+ Secured HTTP MCP supports bearer, basic, and API-key auth.
98
+
99
+ rag File/directory path or live RAG HTTP endpoint.
100
+ Use --rag-path for local documents, or --rag-url for a RAG service.
101
+
102
+ \x1b[1mRecommended Commands:\x1b[0m
103
+ fullcourtdefense doctor
104
+ fullcourtdefense configure
105
+ fullcourtdefense scan --local
106
+ fullcourtdefense scan --local --type mcp --mcp-command node --mcp-args ./server.js --mcp-tool all --mode full --format report
107
+ fullcourtdefense scan --local --type mcp --mcp-url https://internal.company.com/mcp --mcp-auth-type bearer --mcp-token TOKEN --mcp-tool all --mode full --format report
108
+ fullcourtdefense scan --local --type rag --rag-path ./docs --format report
109
+ fullcourtdefense scan --local --type rag --rag-url http://rag.internal/chat --method POST --request-format custom --input-field message --output-field answer --mode full --format report
110
+ fullcourtdefense scan --local --type endpoint --endpoint http://agent.local/chat --method POST --mode full --format report
111
+
112
+ \x1b[1mScan Options:\x1b[0m
113
+ --local Run scan from this machine, inside your network
114
+ --type <type> Local scan type: endpoint, mcp, rag
115
+ --api-key <key> API key (or set BOTGUARD_API_KEY env var)
116
+ --api-url <url> API base URL (default: https://api.fullcourtdefense.ai)
117
+ --endpoint <url> Agent API endpoint to scan
118
+ --mcp-url <url> Already-running HTTP MCP server URL
119
+ --mcp-transport <t> MCP transport: stdio, http, or sse
120
+ --mcp-command <cmd> MCP server command, for example node or npx.cmd
121
+ --mcp-args <args> MCP server args/path, for example ./server.js
122
+ --mcp-tool <tool> MCP tool to test, or all
123
+ --mcp-auth-type <type> HTTP MCP auth: none, bearer, basic, api-key
124
+ --mcp-token <token> HTTP MCP bearer token
125
+ --mcp-username <user> HTTP MCP basic username
126
+ --mcp-password <pass> HTTP MCP basic password
127
+ --mcp-api-key-header <h> HTTP MCP API-key header name
128
+ --mcp-api-key <key> HTTP MCP API key value
129
+ --rag-path <path> RAG file or directory to scan
130
+ --rag-url <url> Live RAG HTTP endpoint to scan
131
+ --shield-id <id> Shield ID for local outbound Shield verdicts
132
+ --shield-key <key> Optional Shield key for locked Shields
133
+ --method <GET|POST> Local endpoint method
134
+ --request-format <fmt> Local endpoint request format: custom or openai
135
+ --auth-type <type> none, bearer, basic, api-key
136
+ --description <text> Agent description
137
+ --system-prompt <text> System prompt (text or path to file)
138
+ --mode <sync|async> Hosted mode, or local mode: quick, full, targeted, deep
139
+ --categories <list> Comma-separated attack categories
140
+ --attack-count <n> Number of attacks to run
141
+ --progress <mode> MCP progress: verbose, compact, silent (default: verbose)
142
+ --fail-threshold <n> Exit code 1 if score below n (default: 0)
143
+ --format <fmt> Output: table, json, summary, report, full-report (default: table)
144
+ --webhook-format <fmt> Hosted webhook format, or legacy local request format
145
+ --config <path> Path to .fullcourtdefense.yml config file
146
+
147
+ \x1b[1mExamples:\x1b[0m
148
+ $ fullcourtdefense scan --endpoint https://my-bot.com/chat --description "Support bot"
149
+ $ fullcourtdefense help
150
+ $ fullcourtdefense scan --local
151
+ $ fullcourtdefense scan --local --type endpoint --mode full --endpoint http://internal-agent/chat
152
+ $ fullcourtdefense scan --local --type mcp --mcp-command node --mcp-args ./server.js --mcp-tool all --mode full
153
+ $ fullcourtdefense scan --local --type mcp --mcp-url https://internal.company.com/mcp
154
+ $ fullcourtdefense scan --local --type mcp --mcp-url https://internal.company.com/mcp --mcp-tool all --mode full
155
+ $ fullcourtdefense scan --local --type mcp --mcp-transport sse --mcp-url https://internal.company.com/sse --mcp-tool all --mode full
156
+ $ fullcourtdefense scan --local --type mcp --mcp-command node --mcp-args ./server.js --mcp-tool all --mode full --format report
157
+ $ fullcourtdefense configure
158
+ $ fullcourtdefense doctor
159
+ $ fullcourtdefense scan --system-prompt ./prompts/system.md --fail-threshold 80
160
+ $ fullcourtdefense scan --config .botguard.yml --format json
161
+ $ fullcourtdefense credits
162
+ $ fullcourtdefense init
163
+
164
+ \x1b[2mDocs: https://fullcourtdefense.ai/docs/cli\x1b[0m
165
+ `);
166
+ }
167
+ async function main() {
168
+ const { command, flags } = parseArgs(process.argv.slice(2));
169
+ if (flags.version || flags.v) {
170
+ console.log(VERSION);
171
+ return;
172
+ }
173
+ if (!command || flags.help || flags.h) {
174
+ printHelp();
175
+ return;
176
+ }
177
+ const config = (0, config_1.loadConfig)(flags.config);
178
+ switch (command) {
179
+ case 'scan': {
180
+ const args = {
181
+ apiKey: flags['api-key'],
182
+ apiUrl: flags['api-url'],
183
+ endpoint: flags.endpoint,
184
+ description: flags.description,
185
+ systemPrompt: flags['system-prompt'],
186
+ mode: flags.mode,
187
+ categories: flags.categories,
188
+ attackCount: flags['attack-count'],
189
+ progress: flags.progress,
190
+ failThreshold: flags['fail-threshold'],
191
+ format: flags.format,
192
+ requestFormat: flags['request-format'],
193
+ webhookFormat: flags['webhook-format'],
194
+ local: flags.local,
195
+ type: flags.type,
196
+ method: flags.method,
197
+ inputField: flags['input-field'],
198
+ outputField: flags['output-field'],
199
+ authType: flags['auth-type'],
200
+ username: flags.username,
201
+ password: flags.password,
202
+ token: flags.token,
203
+ apiKeyHeader: flags['api-key-header'],
204
+ endpointApiKey: flags['endpoint-api-key'],
205
+ mcpUrl: flags['mcp-url'],
206
+ mcpTransport: flags['mcp-transport'],
207
+ mcpAuthType: flags['mcp-auth-type'],
208
+ mcpUsername: flags['mcp-username'],
209
+ mcpPassword: flags['mcp-password'],
210
+ mcpToken: flags['mcp-token'],
211
+ mcpApiKeyHeader: flags['mcp-api-key-header'],
212
+ mcpApiKey: flags['mcp-api-key'],
213
+ mcpCommand: flags['mcp-command'],
214
+ mcpArgs: flags['mcp-args'],
215
+ mcpTool: flags['mcp-tool'],
216
+ mcpToolArgs: flags['mcp-tool-args'],
217
+ ragPath: flags['rag-path'],
218
+ ragUrl: flags['rag-url'],
219
+ shieldId: flags['shield-id'],
220
+ shieldKey: flags['shield-key'],
221
+ };
222
+ await (0, scan_1.scanCommand)(args, config);
223
+ break;
224
+ }
225
+ case 'help': {
226
+ printHelp();
227
+ break;
228
+ }
229
+ case 'doctor': {
230
+ const args = {
231
+ apiUrl: flags['api-url'],
232
+ };
233
+ await (0, doctor_1.doctorCommand)(args, config);
234
+ break;
235
+ }
236
+ case 'configure': {
237
+ const args = {
238
+ shieldId: flags['shield-id'],
239
+ shieldKey: flags['shield-key'],
240
+ apiUrl: flags['api-url'],
241
+ };
242
+ await (0, configure_1.configureCommand)(args, config);
243
+ break;
244
+ }
245
+ case 'credits': {
246
+ const args = {
247
+ apiKey: flags['api-key'],
248
+ apiUrl: flags['api-url'],
249
+ };
250
+ await (0, credits_1.creditsCommand)(args, config);
251
+ break;
252
+ }
253
+ case 'init': {
254
+ await (0, init_1.initCommand)();
255
+ break;
256
+ }
257
+ default:
258
+ console.error(`Unknown command: ${command}`);
259
+ console.error('Run "fullcourtdefense --help" for usage.');
260
+ process.exit(1);
261
+ }
262
+ }
263
+ main().catch(err => {
264
+ console.error(`Fatal: ${err.message}`);
265
+ process.exit(1);
266
+ });
@@ -0,0 +1,11 @@
1
+ import type { ScanResult, CreditsResponse } from './api';
2
+ export declare function formatTable(result: ScanResult): string;
3
+ export declare function formatSummary(result: ScanResult): string;
4
+ export declare function formatReport(result: ScanResult): string;
5
+ export declare function formatFullReport(result: ScanResult): string;
6
+ export declare function formatJson(result: ScanResult): string;
7
+ export declare function formatCredits(credits: CreditsResponse): string;
8
+ export declare function formatScanResult(result: ScanResult, format: string): string;
9
+ export declare function spinner(message: string): {
10
+ stop: (finalMsg?: string) => void;
11
+ };