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
package/dist/output.js ADDED
@@ -0,0 +1,292 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatTable = formatTable;
4
+ exports.formatSummary = formatSummary;
5
+ exports.formatReport = formatReport;
6
+ exports.formatFullReport = formatFullReport;
7
+ exports.formatJson = formatJson;
8
+ exports.formatCredits = formatCredits;
9
+ exports.formatScanResult = formatScanResult;
10
+ exports.spinner = spinner;
11
+ const RESET = '\x1b[0m';
12
+ const BOLD = '\x1b[1m';
13
+ const DIM = '\x1b[2m';
14
+ const RED = '\x1b[31m';
15
+ const GREEN = '\x1b[32m';
16
+ const YELLOW = '\x1b[33m';
17
+ const CYAN = '\x1b[36m';
18
+ const WHITE = '\x1b[37m';
19
+ const BG_RED = '\x1b[41m';
20
+ const BG_GREEN = '\x1b[42m';
21
+ const BG_YELLOW = '\x1b[43m';
22
+ function scoreColor(score) {
23
+ if (score >= 80)
24
+ return GREEN;
25
+ if (score >= 50)
26
+ return YELLOW;
27
+ return RED;
28
+ }
29
+ function severityColor(s) {
30
+ if (s === 'critical' || s === 'high')
31
+ return RED;
32
+ if (s === 'medium')
33
+ return YELLOW;
34
+ return DIM;
35
+ }
36
+ function pad(str, len) {
37
+ return str.length >= len ? str.slice(0, len) : str + ' '.repeat(len - str.length);
38
+ }
39
+ function padLeft(str, len) {
40
+ return str.length >= len ? str : ' '.repeat(len - str.length) + str;
41
+ }
42
+ function truncate(str, max) {
43
+ if (str.length <= max)
44
+ return str;
45
+ return str.slice(0, max - 1) + '…';
46
+ }
47
+ function blockText(value, max = 1200) {
48
+ const text = (value || '').trim();
49
+ if (!text)
50
+ return ' (empty)';
51
+ return truncate(text, max)
52
+ .split('\n')
53
+ .map(line => ` ${line}`)
54
+ .join('\n');
55
+ }
56
+ function line(char = '─', len = 72) {
57
+ return char.repeat(len);
58
+ }
59
+ function formatTable(result) {
60
+ const { score, results, sessionId } = result;
61
+ const attacks = results.attacks;
62
+ const passed = attacks.filter(a => a.analysis.passed).length;
63
+ const failed = attacks.length - passed;
64
+ const lines = [];
65
+ lines.push('');
66
+ lines.push(`${BOLD}${CYAN} BotGuard Security Scan${RESET}`);
67
+ lines.push(` ${DIM}${line('─', 50)}${RESET}`);
68
+ lines.push('');
69
+ // Score
70
+ const sc = scoreColor(score);
71
+ const badge = score >= 80 ? `${BG_GREEN}${WHITE}${BOLD} PASS ${RESET}` : score >= 50 ? `${BG_YELLOW}${WHITE}${BOLD} WARN ${RESET}` : `${BG_RED}${WHITE}${BOLD} FAIL ${RESET}`;
72
+ lines.push(` ${badge} Score: ${sc}${BOLD}${score}/100${RESET}`);
73
+ lines.push('');
74
+ // Summary
75
+ lines.push(` ${GREEN}✓ Passed:${RESET} ${passed} ${RED}✗ Failed:${RESET} ${failed} Total: ${attacks.length}`);
76
+ lines.push(` ${DIM}Violations: ${results.totalViolations} (${RED}${results.highSeverityCount} high${RESET}${DIM}, ${YELLOW}${results.mediumSeverityCount} med${RESET}${DIM}, ${results.lowSeverityCount} low)${RESET}`);
77
+ lines.push('');
78
+ // Category breakdown
79
+ const categories = new Map();
80
+ for (const atk of attacks) {
81
+ const cat = atk.attack.category || 'unknown';
82
+ const entry = categories.get(cat) || { passed: 0, failed: 0 };
83
+ if (atk.analysis.passed)
84
+ entry.passed++;
85
+ else
86
+ entry.failed++;
87
+ categories.set(cat, entry);
88
+ }
89
+ lines.push(` ${BOLD}Category Breakdown${RESET}`);
90
+ lines.push(` ${DIM}${line('─', 50)}${RESET}`);
91
+ lines.push(` ${DIM}${pad('Category', 24)} ${padLeft('Pass', 6)} ${padLeft('Fail', 6)} ${padLeft('Rate', 8)}${RESET}`);
92
+ for (const [cat, data] of [...categories.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
93
+ const total = data.passed + data.failed;
94
+ const rate = Math.round((data.passed / total) * 100);
95
+ const rc = rate >= 80 ? GREEN : rate >= 50 ? YELLOW : RED;
96
+ lines.push(` ${pad(cat, 24)} ${padLeft(String(data.passed), 6)} ${padLeft(String(data.failed), 6)} ${rc}${padLeft(rate + '%', 8)}${RESET}`);
97
+ }
98
+ // Failed attacks detail
99
+ const failedAttacks = attacks.filter(a => !a.analysis.passed);
100
+ if (failedAttacks.length > 0) {
101
+ lines.push('');
102
+ lines.push(` ${BOLD}${RED}Failed Attacks${RESET}`);
103
+ lines.push(` ${DIM}${line('─', 50)}${RESET}`);
104
+ const shown = failedAttacks.slice(0, 15);
105
+ for (const atk of shown) {
106
+ const sev = atk.attack.severity || 'medium';
107
+ const sc = severityColor(sev);
108
+ const name = atk.attack.name || atk.attack.targetedRule;
109
+ const reason = atk.analysis.reason || '';
110
+ lines.push(` ${sc}● ${sev.toUpperCase().padEnd(8)}${RESET} ${truncate(name, 36)}`);
111
+ if (reason) {
112
+ lines.push(` ${DIM}${truncate(reason, 60)}${RESET}`);
113
+ }
114
+ }
115
+ if (failedAttacks.length > 15) {
116
+ lines.push(` ${DIM}... and ${failedAttacks.length - 15} more${RESET}`);
117
+ }
118
+ }
119
+ lines.push('');
120
+ lines.push(` ${DIM}Session: ${sessionId}${RESET}`);
121
+ lines.push(` ${DIM}Web reports: https://fullcourtdefense.ai/history${RESET}`);
122
+ lines.push('');
123
+ return lines.join('\n');
124
+ }
125
+ function formatSummary(result) {
126
+ const { score, results } = result;
127
+ const passed = results.attacks.filter(a => a.analysis.passed).length;
128
+ const failed = results.attacks.length - passed;
129
+ const status = score >= 80 ? 'PASS' : score >= 50 ? 'WARN' : 'FAIL';
130
+ return `[${status}] Score: ${score}/100 | Passed: ${passed} | Failed: ${failed} | Violations: ${results.totalViolations}`;
131
+ }
132
+ function formatReport(result) {
133
+ const { score, results, sessionId, agentDescription, createdAt } = result;
134
+ const attacks = results.attacks;
135
+ const passed = attacks.filter(a => a.analysis.passed).length;
136
+ const failed = attacks.length - passed;
137
+ const status = score >= 80 ? 'PASS' : score >= 50 ? 'WARN' : 'FAIL';
138
+ const failedAttacks = attacks.filter(a => !a.analysis.passed);
139
+ const protectedAttacks = attacks.filter(a => a.analysis.passed && /protected/i.test(a.analysis.reason || ''));
140
+ const allowedAttacks = attacks.filter(a => a.analysis.passed && !/protected/i.test(a.analysis.reason || ''));
141
+ const lines = [];
142
+ lines.push('');
143
+ lines.push(`${BOLD}${CYAN}FullCourtDefense Local Scan Report${RESET}`);
144
+ lines.push(line('=', 72));
145
+ lines.push(`Status: ${status}`);
146
+ lines.push(`Score: ${score}/100`);
147
+ lines.push(`Passed: ${passed}`);
148
+ lines.push(`Failed: ${failed}`);
149
+ lines.push(`Protected by Shield: ${protectedAttacks.length}`);
150
+ lines.push(`Allowed by Shield: ${allowedAttacks.length}`);
151
+ lines.push(`Violations: ${results.totalViolations} (${results.highSeverityCount} high, ${results.mediumSeverityCount} medium, ${results.lowSeverityCount} low)`);
152
+ lines.push(`Target: ${agentDescription}`);
153
+ lines.push(`Session: ${sessionId}`);
154
+ lines.push(`Created: ${createdAt}`);
155
+ lines.push('');
156
+ if (failedAttacks.length > 0) {
157
+ lines.push(`${BOLD}${RED}Failures Requiring Review${RESET}`);
158
+ lines.push(line('-', 72));
159
+ failedAttacks.slice(0, 25).forEach((atk, index) => {
160
+ const violation = atk.analysis.violations[0];
161
+ lines.push(`[${index + 1}/${failedAttacks.length}] FAIL ${atk.attack.name || atk.attack.targetedRule}`);
162
+ lines.push(`Category: ${atk.attack.category || 'unknown'} | Severity: ${atk.attack.severity || atk.analysis.severity}`);
163
+ lines.push(`Analysis: ${atk.analysis.reason || violation?.description || 'Failed security check'}`);
164
+ if (violation)
165
+ lines.push(`Rule: ${violation.rule}`);
166
+ lines.push('Attack sent:');
167
+ lines.push(blockText(atk.attack.attack));
168
+ lines.push('Captured response:');
169
+ lines.push(blockText(atk.agentResponse));
170
+ lines.push('');
171
+ });
172
+ if (failedAttacks.length > 25) {
173
+ lines.push(`... ${failedAttacks.length - 25} more failures hidden. Use --format full-report for every row.`);
174
+ lines.push('');
175
+ }
176
+ }
177
+ if (failedAttacks.length === 0) {
178
+ lines.push(`${BOLD}${GREEN}No failed tests.${RESET}`);
179
+ lines.push('');
180
+ }
181
+ if (protectedAttacks.length > 0) {
182
+ lines.push(`${BOLD}${GREEN}Protected Samples${RESET}`);
183
+ lines.push(line('-', 72));
184
+ protectedAttacks.slice(0, 10).forEach((atk, index) => {
185
+ lines.push(`[${index + 1}/${protectedAttacks.length}] PASS ${atk.attack.name || atk.attack.targetedRule}`);
186
+ lines.push(`Analysis: ${atk.analysis.reason || 'Protected by Shield.'}`);
187
+ lines.push('');
188
+ });
189
+ if (protectedAttacks.length > 10) {
190
+ lines.push(`... ${protectedAttacks.length - 10} more protected tests hidden. Use --format full-report for every row.`);
191
+ lines.push('');
192
+ }
193
+ }
194
+ lines.push(`Web reports: https://fullcourtdefense.ai/history`);
195
+ lines.push(`Full local evidence: rerun with --format full-report or --format json`);
196
+ return lines.join('\n');
197
+ }
198
+ function formatFullReport(result) {
199
+ const { score, results, sessionId, agentDescription, createdAt } = result;
200
+ const attacks = results.attacks;
201
+ const passed = attacks.filter(a => a.analysis.passed).length;
202
+ const failed = attacks.length - passed;
203
+ const status = score >= 80 ? 'PASS' : score >= 50 ? 'WARN' : 'FAIL';
204
+ const lines = [];
205
+ lines.push('');
206
+ lines.push(`${BOLD}${CYAN}FullCourtDefense Local Scan Report${RESET}`);
207
+ lines.push(line('=', 72));
208
+ lines.push(`Status: ${status}`);
209
+ lines.push(`Score: ${score}/100`);
210
+ lines.push(`Passed: ${passed}`);
211
+ lines.push(`Failed: ${failed}`);
212
+ lines.push(`Violations: ${results.totalViolations} (${results.highSeverityCount} high, ${results.mediumSeverityCount} medium, ${results.lowSeverityCount} low)`);
213
+ lines.push(`Target: ${agentDescription}`);
214
+ lines.push(`Session: ${sessionId}`);
215
+ lines.push(`Created: ${createdAt}`);
216
+ lines.push('');
217
+ const failedAttacks = attacks.filter(a => !a.analysis.passed);
218
+ const passedAttacks = attacks.filter(a => a.analysis.passed);
219
+ if (failedAttacks.length > 0) {
220
+ lines.push(`${BOLD}${RED}Failed Tests${RESET}`);
221
+ lines.push(line('-', 72));
222
+ failedAttacks.forEach((atk, index) => {
223
+ const violation = atk.analysis.violations[0];
224
+ lines.push(`[${index + 1}/${failedAttacks.length}] FAIL ${atk.attack.name || atk.attack.targetedRule}`);
225
+ lines.push(`Category: ${atk.attack.category || 'unknown'} | Severity: ${atk.attack.severity || atk.analysis.severity}`);
226
+ lines.push(`Analysis: ${atk.analysis.reason || violation?.description || 'Failed security check'}`);
227
+ if (violation)
228
+ lines.push(`Rule: ${violation.rule}`);
229
+ lines.push('Attack sent:');
230
+ lines.push(blockText(atk.attack.attack));
231
+ lines.push('Captured response:');
232
+ lines.push(blockText(atk.agentResponse));
233
+ lines.push('');
234
+ });
235
+ }
236
+ if (passedAttacks.length > 0) {
237
+ lines.push(`${BOLD}${GREEN}Passed Tests${RESET}`);
238
+ lines.push(line('-', 72));
239
+ passedAttacks.forEach((atk, index) => {
240
+ lines.push(`[${index + 1}/${passedAttacks.length}] PASS ${atk.attack.name || atk.attack.targetedRule}`);
241
+ lines.push(`Category: ${atk.attack.category || 'unknown'} | Severity: ${atk.attack.severity || atk.analysis.severity}`);
242
+ lines.push(`Analysis: ${atk.analysis.reason || 'Passed security check'}`);
243
+ lines.push('Attack sent:');
244
+ lines.push(blockText(atk.attack.attack));
245
+ lines.push('Captured response:');
246
+ lines.push(blockText(atk.agentResponse));
247
+ lines.push('');
248
+ });
249
+ }
250
+ lines.push(`Web reports: https://fullcourtdefense.ai/history`);
251
+ return lines.join('\n');
252
+ }
253
+ function formatJson(result) {
254
+ return JSON.stringify(result, null, 2);
255
+ }
256
+ function formatCredits(credits) {
257
+ const lines = [];
258
+ lines.push('');
259
+ lines.push(`${BOLD}${CYAN} BotGuard Credits${RESET}`);
260
+ lines.push(` ${DIM}${line('─', 40)}${RESET}`);
261
+ lines.push(` Plan: ${BOLD}${credits.plan}${RESET}`);
262
+ lines.push(` Used: ${credits.creditsUsed} / ${credits.monthlyCredits}`);
263
+ lines.push(` Remaining: ${BOLD}${credits.remainingCredits}${RESET}`);
264
+ lines.push('');
265
+ return lines.join('\n');
266
+ }
267
+ function formatScanResult(result, format) {
268
+ switch (format) {
269
+ case 'json': return formatJson(result);
270
+ case 'full-report': return formatFullReport(result);
271
+ case 'report': return formatReport(result);
272
+ case 'summary': return formatSummary(result);
273
+ case 'table':
274
+ default: return formatTable(result);
275
+ }
276
+ }
277
+ function spinner(message) {
278
+ const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
279
+ let i = 0;
280
+ const interval = setInterval(() => {
281
+ process.stderr.write(`\r ${CYAN}${frames[i++ % frames.length]}${RESET} ${message}`);
282
+ }, 80);
283
+ return {
284
+ stop(finalMsg) {
285
+ clearInterval(interval);
286
+ process.stderr.write(`\r${' '.repeat(message.length + 10)}\r`);
287
+ if (finalMsg) {
288
+ process.stderr.write(` ${GREEN}✓${RESET} ${finalMsg}\n`);
289
+ }
290
+ },
291
+ };
292
+ }
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "fullcourtdefense-cli",
3
+ "version": "1.0.2",
4
+ "description": "Full Court Defense CLI — security scanning for AI agents from your terminal",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "fullcourtdefense": "dist/index.js",
8
+ "botguard": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc && node scripts/copy-attack-corpus.js",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "keywords": [
19
+ "llm",
20
+ "security",
21
+ "guardrails",
22
+ "ai-safety",
23
+ "prompt-injection",
24
+ "cli",
25
+ "red-teaming",
26
+ "owasp",
27
+ "mcp",
28
+ "rag"
29
+ ],
30
+ "license": "MIT",
31
+ "devDependencies": {
32
+ "@types/node": "^25.3.0",
33
+ "typescript": "^5.3.0"
34
+ },
35
+ "engines": {
36
+ "node": ">=18.0.0"
37
+ },
38
+ "dependencies": {
39
+ "yaml": "^2.8.4"
40
+ }
41
+ }