raxe 0.4.6__py3-none-any.whl

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 (668) hide show
  1. raxe/__init__.py +101 -0
  2. raxe/application/__init__.py +48 -0
  3. raxe/application/ab_testing.py +170 -0
  4. raxe/application/analytics/__init__.py +30 -0
  5. raxe/application/analytics/achievement_service.py +444 -0
  6. raxe/application/analytics/repositories.py +172 -0
  7. raxe/application/analytics/retention_service.py +267 -0
  8. raxe/application/analytics/statistics_service.py +419 -0
  9. raxe/application/analytics/streak_service.py +283 -0
  10. raxe/application/apply_policy.py +291 -0
  11. raxe/application/eager_l2.py +503 -0
  12. raxe/application/preloader.py +353 -0
  13. raxe/application/scan_merger.py +321 -0
  14. raxe/application/scan_pipeline.py +1059 -0
  15. raxe/application/scan_pipeline_async.py +403 -0
  16. raxe/application/session_tracker.py +458 -0
  17. raxe/application/telemetry_manager.py +357 -0
  18. raxe/application/telemetry_orchestrator.py +1210 -0
  19. raxe/async_sdk/__init__.py +34 -0
  20. raxe/async_sdk/cache.py +286 -0
  21. raxe/async_sdk/client.py +556 -0
  22. raxe/async_sdk/wrappers/__init__.py +23 -0
  23. raxe/async_sdk/wrappers/openai.py +238 -0
  24. raxe/cli/__init__.py +21 -0
  25. raxe/cli/auth.py +1047 -0
  26. raxe/cli/branding.py +235 -0
  27. raxe/cli/config.py +334 -0
  28. raxe/cli/custom_rules.py +458 -0
  29. raxe/cli/doctor.py +686 -0
  30. raxe/cli/error_handler.py +665 -0
  31. raxe/cli/event.py +648 -0
  32. raxe/cli/exit_codes.py +57 -0
  33. raxe/cli/expiry_warning.py +302 -0
  34. raxe/cli/export.py +183 -0
  35. raxe/cli/history.py +247 -0
  36. raxe/cli/l2_formatter.py +872 -0
  37. raxe/cli/main.py +1137 -0
  38. raxe/cli/models.py +590 -0
  39. raxe/cli/output.py +403 -0
  40. raxe/cli/privacy.py +84 -0
  41. raxe/cli/profiler.py +262 -0
  42. raxe/cli/progress.py +379 -0
  43. raxe/cli/progress_context.py +101 -0
  44. raxe/cli/repl.py +394 -0
  45. raxe/cli/rules.py +542 -0
  46. raxe/cli/setup_wizard.py +721 -0
  47. raxe/cli/stats.py +292 -0
  48. raxe/cli/suppress.py +501 -0
  49. raxe/cli/telemetry.py +1384 -0
  50. raxe/cli/test.py +130 -0
  51. raxe/cli/tune.py +315 -0
  52. raxe/cli/validate.py +218 -0
  53. raxe/domain/__init__.py +30 -0
  54. raxe/domain/analytics/__init__.py +97 -0
  55. raxe/domain/analytics/achievements.py +306 -0
  56. raxe/domain/analytics/models.py +120 -0
  57. raxe/domain/analytics/retention.py +168 -0
  58. raxe/domain/analytics/statistics.py +207 -0
  59. raxe/domain/analytics/streaks.py +173 -0
  60. raxe/domain/engine/__init__.py +15 -0
  61. raxe/domain/engine/executor.py +396 -0
  62. raxe/domain/engine/matcher.py +212 -0
  63. raxe/domain/inline_suppression.py +176 -0
  64. raxe/domain/ml/__init__.py +133 -0
  65. raxe/domain/ml/embedding_cache.py +309 -0
  66. raxe/domain/ml/gemma_detector.py +921 -0
  67. raxe/domain/ml/gemma_models.py +346 -0
  68. raxe/domain/ml/l2_config.py +428 -0
  69. raxe/domain/ml/l2_output_schema.py +443 -0
  70. raxe/domain/ml/manifest_loader.py +309 -0
  71. raxe/domain/ml/manifest_schema.py +345 -0
  72. raxe/domain/ml/model_metadata.py +263 -0
  73. raxe/domain/ml/model_registry.py +786 -0
  74. raxe/domain/ml/protocol.py +282 -0
  75. raxe/domain/ml/scoring_models.py +419 -0
  76. raxe/domain/ml/stub_detector.py +397 -0
  77. raxe/domain/ml/threat_scorer.py +757 -0
  78. raxe/domain/ml/tokenizer_registry.py +372 -0
  79. raxe/domain/ml/voting/__init__.py +89 -0
  80. raxe/domain/ml/voting/config.py +595 -0
  81. raxe/domain/ml/voting/engine.py +465 -0
  82. raxe/domain/ml/voting/head_voters.py +378 -0
  83. raxe/domain/ml/voting/models.py +222 -0
  84. raxe/domain/models.py +82 -0
  85. raxe/domain/packs/__init__.py +17 -0
  86. raxe/domain/packs/models.py +304 -0
  87. raxe/domain/policies/__init__.py +20 -0
  88. raxe/domain/policies/evaluator.py +212 -0
  89. raxe/domain/policies/models.py +223 -0
  90. raxe/domain/rules/__init__.py +32 -0
  91. raxe/domain/rules/custom.py +286 -0
  92. raxe/domain/rules/models.py +273 -0
  93. raxe/domain/rules/schema.py +166 -0
  94. raxe/domain/rules/validator.py +556 -0
  95. raxe/domain/suppression.py +801 -0
  96. raxe/domain/suppression_factory.py +174 -0
  97. raxe/domain/telemetry/__init__.py +116 -0
  98. raxe/domain/telemetry/backpressure.py +424 -0
  99. raxe/domain/telemetry/event_creator.py +362 -0
  100. raxe/domain/telemetry/events.py +1282 -0
  101. raxe/domain/telemetry/priority.py +263 -0
  102. raxe/domain/telemetry/scan_telemetry_builder.py +670 -0
  103. raxe/infrastructure/__init__.py +25 -0
  104. raxe/infrastructure/analytics/__init__.py +18 -0
  105. raxe/infrastructure/analytics/aggregator.py +484 -0
  106. raxe/infrastructure/analytics/aggregator_optimized.py +184 -0
  107. raxe/infrastructure/analytics/engine.py +748 -0
  108. raxe/infrastructure/analytics/repository.py +409 -0
  109. raxe/infrastructure/analytics/streaks.py +467 -0
  110. raxe/infrastructure/analytics/views.py +178 -0
  111. raxe/infrastructure/cloud/__init__.py +9 -0
  112. raxe/infrastructure/config/__init__.py +56 -0
  113. raxe/infrastructure/config/endpoints.py +641 -0
  114. raxe/infrastructure/config/scan_config.py +352 -0
  115. raxe/infrastructure/config/yaml_config.py +459 -0
  116. raxe/infrastructure/database/__init__.py +10 -0
  117. raxe/infrastructure/database/connection.py +200 -0
  118. raxe/infrastructure/database/models.py +325 -0
  119. raxe/infrastructure/database/scan_history.py +764 -0
  120. raxe/infrastructure/ml/__init__.py +0 -0
  121. raxe/infrastructure/ml/download_progress.py +438 -0
  122. raxe/infrastructure/ml/model_downloader.py +457 -0
  123. raxe/infrastructure/models/__init__.py +16 -0
  124. raxe/infrastructure/models/discovery.py +461 -0
  125. raxe/infrastructure/packs/__init__.py +13 -0
  126. raxe/infrastructure/packs/loader.py +407 -0
  127. raxe/infrastructure/packs/registry.py +381 -0
  128. raxe/infrastructure/policies/__init__.py +16 -0
  129. raxe/infrastructure/policies/api_client.py +256 -0
  130. raxe/infrastructure/policies/validator.py +227 -0
  131. raxe/infrastructure/policies/yaml_loader.py +250 -0
  132. raxe/infrastructure/rules/__init__.py +18 -0
  133. raxe/infrastructure/rules/custom_loader.py +224 -0
  134. raxe/infrastructure/rules/versioning.py +222 -0
  135. raxe/infrastructure/rules/yaml_loader.py +286 -0
  136. raxe/infrastructure/security/__init__.py +31 -0
  137. raxe/infrastructure/security/auth.py +145 -0
  138. raxe/infrastructure/security/policy_validator.py +124 -0
  139. raxe/infrastructure/security/signatures.py +171 -0
  140. raxe/infrastructure/suppression/__init__.py +36 -0
  141. raxe/infrastructure/suppression/composite_repository.py +154 -0
  142. raxe/infrastructure/suppression/sqlite_repository.py +231 -0
  143. raxe/infrastructure/suppression/yaml_composite_repository.py +156 -0
  144. raxe/infrastructure/suppression/yaml_repository.py +510 -0
  145. raxe/infrastructure/telemetry/__init__.py +79 -0
  146. raxe/infrastructure/telemetry/acquisition.py +179 -0
  147. raxe/infrastructure/telemetry/config.py +254 -0
  148. raxe/infrastructure/telemetry/credential_store.py +947 -0
  149. raxe/infrastructure/telemetry/dual_queue.py +1123 -0
  150. raxe/infrastructure/telemetry/flush_helper.py +343 -0
  151. raxe/infrastructure/telemetry/flush_scheduler.py +776 -0
  152. raxe/infrastructure/telemetry/health_client.py +394 -0
  153. raxe/infrastructure/telemetry/hook.py +347 -0
  154. raxe/infrastructure/telemetry/queue.py +520 -0
  155. raxe/infrastructure/telemetry/sender.py +476 -0
  156. raxe/infrastructure/tracking/__init__.py +13 -0
  157. raxe/infrastructure/tracking/usage.py +389 -0
  158. raxe/integrations/__init__.py +55 -0
  159. raxe/integrations/availability.py +143 -0
  160. raxe/integrations/registry.py +122 -0
  161. raxe/integrations/utils.py +135 -0
  162. raxe/mcp/__init__.py +62 -0
  163. raxe/mcp/cli.py +97 -0
  164. raxe/mcp/server.py +409 -0
  165. raxe/monitoring/__init__.py +51 -0
  166. raxe/monitoring/metrics.py +372 -0
  167. raxe/monitoring/profiler.py +388 -0
  168. raxe/monitoring/server.py +136 -0
  169. raxe/packs/core/v1.0.0/pack.yaml +1394 -0
  170. raxe/packs/core/v1.0.0/rules/PI/pi-001@1.0.0.yaml +49 -0
  171. raxe/packs/core/v1.0.0/rules/PI/pi-006@1.0.0.yaml +48 -0
  172. raxe/packs/core/v1.0.0/rules/PI/pi-014@1.0.0.yaml +54 -0
  173. raxe/packs/core/v1.0.0/rules/PI/pi-017@1.0.0.yaml +52 -0
  174. raxe/packs/core/v1.0.0/rules/PI/pi-022@1.0.0.yaml +67 -0
  175. raxe/packs/core/v1.0.0/rules/PI/pi-023@1.0.0.yaml +91 -0
  176. raxe/packs/core/v1.0.0/rules/PI/pi-024@1.0.0.yaml +80 -0
  177. raxe/packs/core/v1.0.0/rules/PI/pi-025@1.0.0.yaml +81 -0
  178. raxe/packs/core/v1.0.0/rules/PI/pi-026@1.0.0.yaml +50 -0
  179. raxe/packs/core/v1.0.0/rules/PI/pi-027@1.0.0.yaml +77 -0
  180. raxe/packs/core/v1.0.0/rules/PI/pi-028@1.0.0.yaml +52 -0
  181. raxe/packs/core/v1.0.0/rules/PI/pi-029@1.0.0.yaml +51 -0
  182. raxe/packs/core/v1.0.0/rules/PI/pi-030@1.0.0.yaml +55 -0
  183. raxe/packs/core/v1.0.0/rules/PI/pi-033@1.0.0.yaml +50 -0
  184. raxe/packs/core/v1.0.0/rules/PI/pi-034@1.0.0.yaml +50 -0
  185. raxe/packs/core/v1.0.0/rules/PI/pi-035@1.0.0.yaml +50 -0
  186. raxe/packs/core/v1.0.0/rules/PI/pi-046@1.0.0.yaml +50 -0
  187. raxe/packs/core/v1.0.0/rules/PI/pi-047@1.0.0.yaml +50 -0
  188. raxe/packs/core/v1.0.0/rules/PI/pi-048@1.0.0.yaml +50 -0
  189. raxe/packs/core/v1.0.0/rules/PI/pi-049@1.0.0.yaml +50 -0
  190. raxe/packs/core/v1.0.0/rules/PI/pi-050@1.0.0.yaml +50 -0
  191. raxe/packs/core/v1.0.0/rules/PI/pi-068@1.0.0.yaml +50 -0
  192. raxe/packs/core/v1.0.0/rules/PI/pi-078@1.0.0.yaml +50 -0
  193. raxe/packs/core/v1.0.0/rules/PI/pi-2001@1.0.0.yaml +35 -0
  194. raxe/packs/core/v1.0.0/rules/PI/pi-2004@1.0.0.yaml +39 -0
  195. raxe/packs/core/v1.0.0/rules/PI/pi-201@1.0.0.yaml +43 -0
  196. raxe/packs/core/v1.0.0/rules/PI/pi-202@1.0.0.yaml +47 -0
  197. raxe/packs/core/v1.0.0/rules/PI/pi-203@1.0.0.yaml +46 -0
  198. raxe/packs/core/v1.0.0/rules/PI/pi-3007@1.0.0.yaml +44 -0
  199. raxe/packs/core/v1.0.0/rules/PI/pi-3016@1.0.0.yaml +44 -0
  200. raxe/packs/core/v1.0.0/rules/PI/pi-3026@1.0.0.yaml +39 -0
  201. raxe/packs/core/v1.0.0/rules/PI/pi-3027@1.0.0.yaml +64 -0
  202. raxe/packs/core/v1.0.0/rules/PI/pi-3028@1.0.0.yaml +51 -0
  203. raxe/packs/core/v1.0.0/rules/PI/pi-3029@1.0.0.yaml +53 -0
  204. raxe/packs/core/v1.0.0/rules/PI/pi-3030@1.0.0.yaml +50 -0
  205. raxe/packs/core/v1.0.0/rules/PI/pi-3031@1.0.0.yaml +50 -0
  206. raxe/packs/core/v1.0.0/rules/PI/pi-3032@1.0.0.yaml +50 -0
  207. raxe/packs/core/v1.0.0/rules/PI/pi-3033@1.0.0.yaml +56 -0
  208. raxe/packs/core/v1.0.0/rules/PI/pi-3034@1.0.0.yaml +50 -0
  209. raxe/packs/core/v1.0.0/rules/PI/pi-79@1.0.0.yaml +38 -0
  210. raxe/packs/core/v1.0.0/rules/PI/pi-80@1.0.0.yaml +38 -0
  211. raxe/packs/core/v1.0.0/rules/PI/pi-81@1.0.0.yaml +38 -0
  212. raxe/packs/core/v1.0.0/rules/PI/pi-82@1.0.0.yaml +38 -0
  213. raxe/packs/core/v1.0.0/rules/PI/pi-83@1.0.0.yaml +38 -0
  214. raxe/packs/core/v1.0.0/rules/PI/pi-84@1.0.0.yaml +38 -0
  215. raxe/packs/core/v1.0.0/rules/PI/pi-85@1.0.0.yaml +38 -0
  216. raxe/packs/core/v1.0.0/rules/PI/pi-86@1.0.0.yaml +38 -0
  217. raxe/packs/core/v1.0.0/rules/PI/pi-87@1.0.0.yaml +38 -0
  218. raxe/packs/core/v1.0.0/rules/PI/pi-88@1.0.0.yaml +38 -0
  219. raxe/packs/core/v1.0.0/rules/PI/pi-89@1.0.0.yaml +38 -0
  220. raxe/packs/core/v1.0.0/rules/PI/pi-90@1.0.0.yaml +38 -0
  221. raxe/packs/core/v1.0.0/rules/PI/pi-91@1.0.0.yaml +38 -0
  222. raxe/packs/core/v1.0.0/rules/PI/pi-92@1.0.0.yaml +38 -0
  223. raxe/packs/core/v1.0.0/rules/PI/pi-93@1.0.0.yaml +38 -0
  224. raxe/packs/core/v1.0.0/rules/PI/pi-94@1.0.0.yaml +38 -0
  225. raxe/packs/core/v1.0.0/rules/PI/pi-95@1.0.0.yaml +38 -0
  226. raxe/packs/core/v1.0.0/rules/PI/pi-96@1.0.0.yaml +38 -0
  227. raxe/packs/core/v1.0.0/rules/PI/pi-97@1.0.0.yaml +38 -0
  228. raxe/packs/core/v1.0.0/rules/PI/pi-98@1.0.0.yaml +38 -0
  229. raxe/packs/core/v1.0.0/rules/cmd/cmd-001@1.0.0.yaml +48 -0
  230. raxe/packs/core/v1.0.0/rules/cmd/cmd-007@1.0.0.yaml +48 -0
  231. raxe/packs/core/v1.0.0/rules/cmd/cmd-015@1.0.0.yaml +56 -0
  232. raxe/packs/core/v1.0.0/rules/cmd/cmd-016@1.0.0.yaml +46 -0
  233. raxe/packs/core/v1.0.0/rules/cmd/cmd-017@1.0.0.yaml +57 -0
  234. raxe/packs/core/v1.0.0/rules/cmd/cmd-021@1.0.0.yaml +46 -0
  235. raxe/packs/core/v1.0.0/rules/cmd/cmd-022@1.0.0.yaml +46 -0
  236. raxe/packs/core/v1.0.0/rules/cmd/cmd-023@1.0.0.yaml +78 -0
  237. raxe/packs/core/v1.0.0/rules/cmd/cmd-024@1.0.0.yaml +46 -0
  238. raxe/packs/core/v1.0.0/rules/cmd/cmd-025@1.0.0.yaml +93 -0
  239. raxe/packs/core/v1.0.0/rules/cmd/cmd-026@1.0.0.yaml +81 -0
  240. raxe/packs/core/v1.0.0/rules/cmd/cmd-027@1.0.0.yaml +82 -0
  241. raxe/packs/core/v1.0.0/rules/cmd/cmd-028@1.0.0.yaml +46 -0
  242. raxe/packs/core/v1.0.0/rules/cmd/cmd-033@1.0.0.yaml +48 -0
  243. raxe/packs/core/v1.0.0/rules/cmd/cmd-036@1.0.0.yaml +47 -0
  244. raxe/packs/core/v1.0.0/rules/cmd/cmd-037@1.0.0.yaml +44 -0
  245. raxe/packs/core/v1.0.0/rules/cmd/cmd-052@1.0.0.yaml +43 -0
  246. raxe/packs/core/v1.0.0/rules/cmd/cmd-054@1.0.0.yaml +44 -0
  247. raxe/packs/core/v1.0.0/rules/cmd/cmd-056@1.0.0.yaml +43 -0
  248. raxe/packs/core/v1.0.0/rules/cmd/cmd-065@1.0.0.yaml +46 -0
  249. raxe/packs/core/v1.0.0/rules/cmd/cmd-075@1.0.0.yaml +45 -0
  250. raxe/packs/core/v1.0.0/rules/cmd/cmd-079@1.0.0.yaml +44 -0
  251. raxe/packs/core/v1.0.0/rules/cmd/cmd-1080@1.0.0.yaml +41 -0
  252. raxe/packs/core/v1.0.0/rules/cmd/cmd-1090@1.0.0.yaml +41 -0
  253. raxe/packs/core/v1.0.0/rules/cmd/cmd-1104@1.0.0.yaml +44 -0
  254. raxe/packs/core/v1.0.0/rules/cmd/cmd-1105@1.0.0.yaml +41 -0
  255. raxe/packs/core/v1.0.0/rules/cmd/cmd-1112@1.0.0.yaml +44 -0
  256. raxe/packs/core/v1.0.0/rules/cmd/cmd-201@1.0.0.yaml +47 -0
  257. raxe/packs/core/v1.0.0/rules/cmd/cmd-202@1.0.0.yaml +42 -0
  258. raxe/packs/core/v1.0.0/rules/cmd/cmd-203@1.0.0.yaml +43 -0
  259. raxe/packs/core/v1.0.0/rules/cmd/cmd-204@1.0.0.yaml +47 -0
  260. raxe/packs/core/v1.0.0/rules/cmd/cmd-205@1.0.0.yaml +44 -0
  261. raxe/packs/core/v1.0.0/rules/cmd/cmd-206@1.0.0.yaml +47 -0
  262. raxe/packs/core/v1.0.0/rules/cmd/cmd-207@1.0.0.yaml +46 -0
  263. raxe/packs/core/v1.0.0/rules/cmd/cmd-208@1.0.0.yaml +42 -0
  264. raxe/packs/core/v1.0.0/rules/cmd/cmd-209@1.0.0.yaml +38 -0
  265. raxe/packs/core/v1.0.0/rules/cmd/cmd-210@1.0.0.yaml +38 -0
  266. raxe/packs/core/v1.0.0/rules/cmd/cmd-211@1.0.0.yaml +38 -0
  267. raxe/packs/core/v1.0.0/rules/cmd/cmd-212@1.0.0.yaml +38 -0
  268. raxe/packs/core/v1.0.0/rules/cmd/cmd-213@1.0.0.yaml +38 -0
  269. raxe/packs/core/v1.0.0/rules/cmd/cmd-214@1.0.0.yaml +38 -0
  270. raxe/packs/core/v1.0.0/rules/cmd/cmd-215@1.0.0.yaml +38 -0
  271. raxe/packs/core/v1.0.0/rules/cmd/cmd-216@1.0.0.yaml +38 -0
  272. raxe/packs/core/v1.0.0/rules/cmd/cmd-217@1.0.0.yaml +38 -0
  273. raxe/packs/core/v1.0.0/rules/cmd/cmd-218@1.0.0.yaml +38 -0
  274. raxe/packs/core/v1.0.0/rules/cmd/cmd-219@1.0.0.yaml +38 -0
  275. raxe/packs/core/v1.0.0/rules/cmd/cmd-220@1.0.0.yaml +38 -0
  276. raxe/packs/core/v1.0.0/rules/cmd/cmd-221@1.0.0.yaml +38 -0
  277. raxe/packs/core/v1.0.0/rules/cmd/cmd-222@1.0.0.yaml +38 -0
  278. raxe/packs/core/v1.0.0/rules/cmd/cmd-223@1.0.0.yaml +38 -0
  279. raxe/packs/core/v1.0.0/rules/cmd/cmd-224@1.0.0.yaml +38 -0
  280. raxe/packs/core/v1.0.0/rules/cmd/cmd-225@1.0.0.yaml +38 -0
  281. raxe/packs/core/v1.0.0/rules/cmd/cmd-226@1.0.0.yaml +38 -0
  282. raxe/packs/core/v1.0.0/rules/cmd/cmd-227@1.0.0.yaml +38 -0
  283. raxe/packs/core/v1.0.0/rules/cmd/cmd-228@1.0.0.yaml +38 -0
  284. raxe/packs/core/v1.0.0/rules/cmd/cmd-229@1.0.0.yaml +38 -0
  285. raxe/packs/core/v1.0.0/rules/cmd/cmd-230@1.0.0.yaml +38 -0
  286. raxe/packs/core/v1.0.0/rules/cmd/cmd-231@1.0.0.yaml +38 -0
  287. raxe/packs/core/v1.0.0/rules/cmd/cmd-232@1.0.0.yaml +38 -0
  288. raxe/packs/core/v1.0.0/rules/cmd/cmd-233@1.0.0.yaml +38 -0
  289. raxe/packs/core/v1.0.0/rules/cmd/cmd-234@1.0.0.yaml +38 -0
  290. raxe/packs/core/v1.0.0/rules/cmd/cmd-235@1.0.0.yaml +38 -0
  291. raxe/packs/core/v1.0.0/rules/cmd/cmd-236@1.0.0.yaml +38 -0
  292. raxe/packs/core/v1.0.0/rules/cmd/cmd-237@1.0.0.yaml +38 -0
  293. raxe/packs/core/v1.0.0/rules/cmd/cmd-238@1.0.0.yaml +38 -0
  294. raxe/packs/core/v1.0.0/rules/enc/enc-001@1.0.0.yaml +48 -0
  295. raxe/packs/core/v1.0.0/rules/enc/enc-013@1.0.0.yaml +46 -0
  296. raxe/packs/core/v1.0.0/rules/enc/enc-019@1.0.0.yaml +43 -0
  297. raxe/packs/core/v1.0.0/rules/enc/enc-020@1.0.0.yaml +47 -0
  298. raxe/packs/core/v1.0.0/rules/enc/enc-024@1.0.0.yaml +46 -0
  299. raxe/packs/core/v1.0.0/rules/enc/enc-029@1.0.0.yaml +44 -0
  300. raxe/packs/core/v1.0.0/rules/enc/enc-038@1.0.0.yaml +44 -0
  301. raxe/packs/core/v1.0.0/rules/enc/enc-044@1.0.0.yaml +46 -0
  302. raxe/packs/core/v1.0.0/rules/enc/enc-067@1.0.0.yaml +42 -0
  303. raxe/packs/core/v1.0.0/rules/enc/enc-069@1.0.0.yaml +42 -0
  304. raxe/packs/core/v1.0.0/rules/enc/enc-100@1.0.0.yaml +38 -0
  305. raxe/packs/core/v1.0.0/rules/enc/enc-101@1.0.0.yaml +38 -0
  306. raxe/packs/core/v1.0.0/rules/enc/enc-102@1.0.0.yaml +38 -0
  307. raxe/packs/core/v1.0.0/rules/enc/enc-103@1.0.0.yaml +38 -0
  308. raxe/packs/core/v1.0.0/rules/enc/enc-104@1.0.0.yaml +38 -0
  309. raxe/packs/core/v1.0.0/rules/enc/enc-105@1.0.0.yaml +38 -0
  310. raxe/packs/core/v1.0.0/rules/enc/enc-106@1.0.0.yaml +38 -0
  311. raxe/packs/core/v1.0.0/rules/enc/enc-107@1.0.0.yaml +38 -0
  312. raxe/packs/core/v1.0.0/rules/enc/enc-108@1.0.0.yaml +38 -0
  313. raxe/packs/core/v1.0.0/rules/enc/enc-109@1.0.0.yaml +38 -0
  314. raxe/packs/core/v1.0.0/rules/enc/enc-110@1.0.0.yaml +38 -0
  315. raxe/packs/core/v1.0.0/rules/enc/enc-111@1.0.0.yaml +38 -0
  316. raxe/packs/core/v1.0.0/rules/enc/enc-112@1.0.0.yaml +38 -0
  317. raxe/packs/core/v1.0.0/rules/enc/enc-113@1.0.0.yaml +38 -0
  318. raxe/packs/core/v1.0.0/rules/enc/enc-114@1.0.0.yaml +38 -0
  319. raxe/packs/core/v1.0.0/rules/enc/enc-115@1.0.0.yaml +38 -0
  320. raxe/packs/core/v1.0.0/rules/enc/enc-116@1.0.0.yaml +38 -0
  321. raxe/packs/core/v1.0.0/rules/enc/enc-117@1.0.0.yaml +38 -0
  322. raxe/packs/core/v1.0.0/rules/enc/enc-118@1.0.0.yaml +38 -0
  323. raxe/packs/core/v1.0.0/rules/enc/enc-119@1.0.0.yaml +38 -0
  324. raxe/packs/core/v1.0.0/rules/enc/enc-120@1.0.0.yaml +38 -0
  325. raxe/packs/core/v1.0.0/rules/enc/enc-201@1.0.0.yaml +37 -0
  326. raxe/packs/core/v1.0.0/rules/enc/enc-202@1.0.0.yaml +41 -0
  327. raxe/packs/core/v1.0.0/rules/enc/enc-203@1.0.0.yaml +41 -0
  328. raxe/packs/core/v1.0.0/rules/enc/enc-3004@1.0.0.yaml +40 -0
  329. raxe/packs/core/v1.0.0/rules/enc/enc-3006@1.0.0.yaml +40 -0
  330. raxe/packs/core/v1.0.0/rules/enc/enc-3011@1.0.0.yaml +40 -0
  331. raxe/packs/core/v1.0.0/rules/enc/enc-5016@1.0.0.yaml +46 -0
  332. raxe/packs/core/v1.0.0/rules/enc/enc-6001@1.0.0.yaml +53 -0
  333. raxe/packs/core/v1.0.0/rules/enc/enc-6002@1.0.0.yaml +41 -0
  334. raxe/packs/core/v1.0.0/rules/enc/enc-70@1.0.0.yaml +38 -0
  335. raxe/packs/core/v1.0.0/rules/enc/enc-71@1.0.0.yaml +38 -0
  336. raxe/packs/core/v1.0.0/rules/enc/enc-72@1.0.0.yaml +38 -0
  337. raxe/packs/core/v1.0.0/rules/enc/enc-73@1.0.0.yaml +38 -0
  338. raxe/packs/core/v1.0.0/rules/enc/enc-74@1.0.0.yaml +38 -0
  339. raxe/packs/core/v1.0.0/rules/enc/enc-75@1.0.0.yaml +38 -0
  340. raxe/packs/core/v1.0.0/rules/enc/enc-76@1.0.0.yaml +38 -0
  341. raxe/packs/core/v1.0.0/rules/enc/enc-77@1.0.0.yaml +38 -0
  342. raxe/packs/core/v1.0.0/rules/enc/enc-78@1.0.0.yaml +38 -0
  343. raxe/packs/core/v1.0.0/rules/enc/enc-79@1.0.0.yaml +38 -0
  344. raxe/packs/core/v1.0.0/rules/enc/enc-80@1.0.0.yaml +38 -0
  345. raxe/packs/core/v1.0.0/rules/enc/enc-81@1.0.0.yaml +38 -0
  346. raxe/packs/core/v1.0.0/rules/enc/enc-82@1.0.0.yaml +38 -0
  347. raxe/packs/core/v1.0.0/rules/enc/enc-83@1.0.0.yaml +38 -0
  348. raxe/packs/core/v1.0.0/rules/enc/enc-84@1.0.0.yaml +38 -0
  349. raxe/packs/core/v1.0.0/rules/enc/enc-85@1.0.0.yaml +38 -0
  350. raxe/packs/core/v1.0.0/rules/enc/enc-86@1.0.0.yaml +38 -0
  351. raxe/packs/core/v1.0.0/rules/enc/enc-87@1.0.0.yaml +38 -0
  352. raxe/packs/core/v1.0.0/rules/enc/enc-88@1.0.0.yaml +38 -0
  353. raxe/packs/core/v1.0.0/rules/enc/enc-89@1.0.0.yaml +38 -0
  354. raxe/packs/core/v1.0.0/rules/enc/enc-90@1.0.0.yaml +38 -0
  355. raxe/packs/core/v1.0.0/rules/enc/enc-91@1.0.0.yaml +38 -0
  356. raxe/packs/core/v1.0.0/rules/enc/enc-92@1.0.0.yaml +38 -0
  357. raxe/packs/core/v1.0.0/rules/enc/enc-93@1.0.0.yaml +38 -0
  358. raxe/packs/core/v1.0.0/rules/enc/enc-94@1.0.0.yaml +38 -0
  359. raxe/packs/core/v1.0.0/rules/enc/enc-95@1.0.0.yaml +38 -0
  360. raxe/packs/core/v1.0.0/rules/enc/enc-96@1.0.0.yaml +38 -0
  361. raxe/packs/core/v1.0.0/rules/enc/enc-97@1.0.0.yaml +38 -0
  362. raxe/packs/core/v1.0.0/rules/enc/enc-98@1.0.0.yaml +38 -0
  363. raxe/packs/core/v1.0.0/rules/enc/enc-99@1.0.0.yaml +38 -0
  364. raxe/packs/core/v1.0.0/rules/hc/hc-001@1.0.0.yaml +73 -0
  365. raxe/packs/core/v1.0.0/rules/hc/hc-002@1.0.0.yaml +71 -0
  366. raxe/packs/core/v1.0.0/rules/hc/hc-003@1.0.0.yaml +65 -0
  367. raxe/packs/core/v1.0.0/rules/hc/hc-004@1.0.0.yaml +73 -0
  368. raxe/packs/core/v1.0.0/rules/hc/hc-101@1.0.0.yaml +47 -0
  369. raxe/packs/core/v1.0.0/rules/hc/hc-102@1.0.0.yaml +47 -0
  370. raxe/packs/core/v1.0.0/rules/hc/hc-103@1.0.0.yaml +47 -0
  371. raxe/packs/core/v1.0.0/rules/hc/hc-104@1.0.0.yaml +47 -0
  372. raxe/packs/core/v1.0.0/rules/hc/hc-105@1.0.0.yaml +48 -0
  373. raxe/packs/core/v1.0.0/rules/hc/hc-106@1.0.0.yaml +40 -0
  374. raxe/packs/core/v1.0.0/rules/hc/hc-107@1.0.0.yaml +47 -0
  375. raxe/packs/core/v1.0.0/rules/hc/hc-108@1.0.0.yaml +47 -0
  376. raxe/packs/core/v1.0.0/rules/hc/hc-109@1.0.0.yaml +50 -0
  377. raxe/packs/core/v1.0.0/rules/hc/hc-110@1.0.0.yaml +56 -0
  378. raxe/packs/core/v1.0.0/rules/hc/hc-111@1.0.0.yaml +49 -0
  379. raxe/packs/core/v1.0.0/rules/hc/hc-112@1.0.0.yaml +53 -0
  380. raxe/packs/core/v1.0.0/rules/hc/hc-113@1.0.0.yaml +52 -0
  381. raxe/packs/core/v1.0.0/rules/hc/hc-114@1.0.0.yaml +52 -0
  382. raxe/packs/core/v1.0.0/rules/hc/hc-115@1.0.0.yaml +52 -0
  383. raxe/packs/core/v1.0.0/rules/hc/hc-116@1.0.0.yaml +53 -0
  384. raxe/packs/core/v1.0.0/rules/hc/hc-117@1.0.0.yaml +54 -0
  385. raxe/packs/core/v1.0.0/rules/hc/hc-118@1.0.0.yaml +52 -0
  386. raxe/packs/core/v1.0.0/rules/hc/hc-119@1.0.0.yaml +51 -0
  387. raxe/packs/core/v1.0.0/rules/hc/hc-120@1.0.0.yaml +52 -0
  388. raxe/packs/core/v1.0.0/rules/hc/hc-121@1.0.0.yaml +51 -0
  389. raxe/packs/core/v1.0.0/rules/hc/hc-122@1.0.0.yaml +51 -0
  390. raxe/packs/core/v1.0.0/rules/hc/hc-123@1.0.0.yaml +52 -0
  391. raxe/packs/core/v1.0.0/rules/hc/hc-124@1.0.0.yaml +53 -0
  392. raxe/packs/core/v1.0.0/rules/hc/hc-125@1.0.0.yaml +53 -0
  393. raxe/packs/core/v1.0.0/rules/hc/hc-126@1.0.0.yaml +53 -0
  394. raxe/packs/core/v1.0.0/rules/hc/hc-127@1.0.0.yaml +53 -0
  395. raxe/packs/core/v1.0.0/rules/hc/hc-128@1.0.0.yaml +53 -0
  396. raxe/packs/core/v1.0.0/rules/hc/hc-129@1.0.0.yaml +51 -0
  397. raxe/packs/core/v1.0.0/rules/hc/hc-130@1.0.0.yaml +51 -0
  398. raxe/packs/core/v1.0.0/rules/hc/hc-131@1.0.0.yaml +51 -0
  399. raxe/packs/core/v1.0.0/rules/hc/hc-132@1.0.0.yaml +51 -0
  400. raxe/packs/core/v1.0.0/rules/hc/hc-133@1.0.0.yaml +53 -0
  401. raxe/packs/core/v1.0.0/rules/hc/hc-134@1.0.0.yaml +51 -0
  402. raxe/packs/core/v1.0.0/rules/hc/hc-135@1.0.0.yaml +51 -0
  403. raxe/packs/core/v1.0.0/rules/hc/hc-136@1.0.0.yaml +51 -0
  404. raxe/packs/core/v1.0.0/rules/hc/hc-137@1.0.0.yaml +51 -0
  405. raxe/packs/core/v1.0.0/rules/hc/hc-138@1.0.0.yaml +51 -0
  406. raxe/packs/core/v1.0.0/rules/hc/hc-139@1.0.0.yaml +51 -0
  407. raxe/packs/core/v1.0.0/rules/hc/hc-140@1.0.0.yaml +51 -0
  408. raxe/packs/core/v1.0.0/rules/hc/hc-141@1.0.0.yaml +41 -0
  409. raxe/packs/core/v1.0.0/rules/hc/hc-142@1.0.0.yaml +37 -0
  410. raxe/packs/core/v1.0.0/rules/hc/hc-143@1.0.0.yaml +37 -0
  411. raxe/packs/core/v1.0.0/rules/hc/hc-144@1.0.0.yaml +37 -0
  412. raxe/packs/core/v1.0.0/rules/hc/hc-145@1.0.0.yaml +37 -0
  413. raxe/packs/core/v1.0.0/rules/hc/hc-146@1.0.0.yaml +37 -0
  414. raxe/packs/core/v1.0.0/rules/hc/hc-147@1.0.0.yaml +37 -0
  415. raxe/packs/core/v1.0.0/rules/hc/hc-148@1.0.0.yaml +37 -0
  416. raxe/packs/core/v1.0.0/rules/hc/hc-149@1.0.0.yaml +37 -0
  417. raxe/packs/core/v1.0.0/rules/hc/hc-150@1.0.0.yaml +37 -0
  418. raxe/packs/core/v1.0.0/rules/hc/hc-151@1.0.0.yaml +37 -0
  419. raxe/packs/core/v1.0.0/rules/hc/hc-152@1.0.0.yaml +37 -0
  420. raxe/packs/core/v1.0.0/rules/hc/hc-153@1.0.0.yaml +37 -0
  421. raxe/packs/core/v1.0.0/rules/hc/hc-154@1.0.0.yaml +37 -0
  422. raxe/packs/core/v1.0.0/rules/hc/hc-155@1.0.0.yaml +37 -0
  423. raxe/packs/core/v1.0.0/rules/hc/hc-156@1.0.0.yaml +37 -0
  424. raxe/packs/core/v1.0.0/rules/hc/hc-157@1.0.0.yaml +37 -0
  425. raxe/packs/core/v1.0.0/rules/hc/hc-158@1.0.0.yaml +37 -0
  426. raxe/packs/core/v1.0.0/rules/hc/hc-159@1.0.0.yaml +37 -0
  427. raxe/packs/core/v1.0.0/rules/hc/hc-160@1.0.0.yaml +37 -0
  428. raxe/packs/core/v1.0.0/rules/hc/hc-161@1.0.0.yaml +37 -0
  429. raxe/packs/core/v1.0.0/rules/jb/jb-001@1.0.0.yaml +47 -0
  430. raxe/packs/core/v1.0.0/rules/jb/jb-009@1.0.0.yaml +47 -0
  431. raxe/packs/core/v1.0.0/rules/jb/jb-020@1.0.0.yaml +47 -0
  432. raxe/packs/core/v1.0.0/rules/jb/jb-021@1.0.0.yaml +46 -0
  433. raxe/packs/core/v1.0.0/rules/jb/jb-022@1.0.0.yaml +47 -0
  434. raxe/packs/core/v1.0.0/rules/jb/jb-028@1.0.0.yaml +43 -0
  435. raxe/packs/core/v1.0.0/rules/jb/jb-033@1.0.0.yaml +46 -0
  436. raxe/packs/core/v1.0.0/rules/jb/jb-034@1.0.0.yaml +46 -0
  437. raxe/packs/core/v1.0.0/rules/jb/jb-036@1.0.0.yaml +41 -0
  438. raxe/packs/core/v1.0.0/rules/jb/jb-039@1.0.0.yaml +41 -0
  439. raxe/packs/core/v1.0.0/rules/jb/jb-056@1.0.0.yaml +38 -0
  440. raxe/packs/core/v1.0.0/rules/jb/jb-066@1.0.0.yaml +37 -0
  441. raxe/packs/core/v1.0.0/rules/jb/jb-076@1.0.0.yaml +37 -0
  442. raxe/packs/core/v1.0.0/rules/jb/jb-098@1.0.0.yaml +46 -0
  443. raxe/packs/core/v1.0.0/rules/jb/jb-103@1.0.0.yaml +47 -0
  444. raxe/packs/core/v1.0.0/rules/jb/jb-104@1.0.0.yaml +52 -0
  445. raxe/packs/core/v1.0.0/rules/jb/jb-105@1.0.0.yaml +56 -0
  446. raxe/packs/core/v1.0.0/rules/jb/jb-110@1.0.0.yaml +56 -0
  447. raxe/packs/core/v1.0.0/rules/jb/jb-111@1.0.0.yaml +57 -0
  448. raxe/packs/core/v1.0.0/rules/jb/jb-112@1.0.0.yaml +38 -0
  449. raxe/packs/core/v1.0.0/rules/jb/jb-113@1.0.0.yaml +38 -0
  450. raxe/packs/core/v1.0.0/rules/jb/jb-114@1.0.0.yaml +38 -0
  451. raxe/packs/core/v1.0.0/rules/jb/jb-115@1.0.0.yaml +38 -0
  452. raxe/packs/core/v1.0.0/rules/jb/jb-116@1.0.0.yaml +38 -0
  453. raxe/packs/core/v1.0.0/rules/jb/jb-117@1.0.0.yaml +38 -0
  454. raxe/packs/core/v1.0.0/rules/jb/jb-118@1.0.0.yaml +38 -0
  455. raxe/packs/core/v1.0.0/rules/jb/jb-119@1.0.0.yaml +38 -0
  456. raxe/packs/core/v1.0.0/rules/jb/jb-120@1.0.0.yaml +38 -0
  457. raxe/packs/core/v1.0.0/rules/jb/jb-121@1.0.0.yaml +38 -0
  458. raxe/packs/core/v1.0.0/rules/jb/jb-122@1.0.0.yaml +38 -0
  459. raxe/packs/core/v1.0.0/rules/jb/jb-123@1.0.0.yaml +38 -0
  460. raxe/packs/core/v1.0.0/rules/jb/jb-124@1.0.0.yaml +38 -0
  461. raxe/packs/core/v1.0.0/rules/jb/jb-125@1.0.0.yaml +38 -0
  462. raxe/packs/core/v1.0.0/rules/jb/jb-126@1.0.0.yaml +38 -0
  463. raxe/packs/core/v1.0.0/rules/jb/jb-127@1.0.0.yaml +38 -0
  464. raxe/packs/core/v1.0.0/rules/jb/jb-128@1.0.0.yaml +38 -0
  465. raxe/packs/core/v1.0.0/rules/jb/jb-129@1.0.0.yaml +38 -0
  466. raxe/packs/core/v1.0.0/rules/jb/jb-130@1.0.0.yaml +38 -0
  467. raxe/packs/core/v1.0.0/rules/jb/jb-131@1.0.0.yaml +38 -0
  468. raxe/packs/core/v1.0.0/rules/jb/jb-132@1.0.0.yaml +38 -0
  469. raxe/packs/core/v1.0.0/rules/jb/jb-133@1.0.0.yaml +38 -0
  470. raxe/packs/core/v1.0.0/rules/jb/jb-134@1.0.0.yaml +38 -0
  471. raxe/packs/core/v1.0.0/rules/jb/jb-135@1.0.0.yaml +38 -0
  472. raxe/packs/core/v1.0.0/rules/jb/jb-136@1.0.0.yaml +38 -0
  473. raxe/packs/core/v1.0.0/rules/jb/jb-137@1.0.0.yaml +38 -0
  474. raxe/packs/core/v1.0.0/rules/jb/jb-138@1.0.0.yaml +38 -0
  475. raxe/packs/core/v1.0.0/rules/jb/jb-139@1.0.0.yaml +38 -0
  476. raxe/packs/core/v1.0.0/rules/jb/jb-140@1.0.0.yaml +38 -0
  477. raxe/packs/core/v1.0.0/rules/jb/jb-141@1.0.0.yaml +38 -0
  478. raxe/packs/core/v1.0.0/rules/jb/jb-142@1.0.0.yaml +38 -0
  479. raxe/packs/core/v1.0.0/rules/jb/jb-143@1.0.0.yaml +38 -0
  480. raxe/packs/core/v1.0.0/rules/jb/jb-144@1.0.0.yaml +38 -0
  481. raxe/packs/core/v1.0.0/rules/jb/jb-145@1.0.0.yaml +38 -0
  482. raxe/packs/core/v1.0.0/rules/jb/jb-146@1.0.0.yaml +38 -0
  483. raxe/packs/core/v1.0.0/rules/jb/jb-147@1.0.0.yaml +38 -0
  484. raxe/packs/core/v1.0.0/rules/jb/jb-148@1.0.0.yaml +38 -0
  485. raxe/packs/core/v1.0.0/rules/jb/jb-149@1.0.0.yaml +38 -0
  486. raxe/packs/core/v1.0.0/rules/jb/jb-150@1.0.0.yaml +38 -0
  487. raxe/packs/core/v1.0.0/rules/jb/jb-151@1.0.0.yaml +38 -0
  488. raxe/packs/core/v1.0.0/rules/jb/jb-152@1.0.0.yaml +38 -0
  489. raxe/packs/core/v1.0.0/rules/jb/jb-153@1.0.0.yaml +38 -0
  490. raxe/packs/core/v1.0.0/rules/jb/jb-154@1.0.0.yaml +38 -0
  491. raxe/packs/core/v1.0.0/rules/jb/jb-155@1.0.0.yaml +38 -0
  492. raxe/packs/core/v1.0.0/rules/jb/jb-156@1.0.0.yaml +38 -0
  493. raxe/packs/core/v1.0.0/rules/jb/jb-157@1.0.0.yaml +38 -0
  494. raxe/packs/core/v1.0.0/rules/jb/jb-158@1.0.0.yaml +38 -0
  495. raxe/packs/core/v1.0.0/rules/jb/jb-159@1.0.0.yaml +38 -0
  496. raxe/packs/core/v1.0.0/rules/jb/jb-160@1.0.0.yaml +38 -0
  497. raxe/packs/core/v1.0.0/rules/jb/jb-161@1.0.0.yaml +38 -0
  498. raxe/packs/core/v1.0.0/rules/jb/jb-162@1.0.0.yaml +38 -0
  499. raxe/packs/core/v1.0.0/rules/jb/jb-201@1.0.0.yaml +40 -0
  500. raxe/packs/core/v1.0.0/rules/jb/jb-202@1.0.0.yaml +41 -0
  501. raxe/packs/core/v1.0.0/rules/jb/jb-203@1.0.0.yaml +51 -0
  502. raxe/packs/core/v1.0.0/rules/jb/jb-204@1.0.0.yaml +50 -0
  503. raxe/packs/core/v1.0.0/rules/jb/jb-205@1.0.0.yaml +50 -0
  504. raxe/packs/core/v1.0.0/rules/jb/jb-206@1.0.0.yaml +50 -0
  505. raxe/packs/core/v1.0.0/rules/jb/jb-207@1.0.0.yaml +49 -0
  506. raxe/packs/core/v1.0.0/rules/pii/pii-001@1.0.0.yaml +48 -0
  507. raxe/packs/core/v1.0.0/rules/pii/pii-009@1.0.0.yaml +48 -0
  508. raxe/packs/core/v1.0.0/rules/pii/pii-012@1.0.0.yaml +48 -0
  509. raxe/packs/core/v1.0.0/rules/pii/pii-017@1.0.0.yaml +48 -0
  510. raxe/packs/core/v1.0.0/rules/pii/pii-022@1.0.0.yaml +47 -0
  511. raxe/packs/core/v1.0.0/rules/pii/pii-025@1.0.0.yaml +47 -0
  512. raxe/packs/core/v1.0.0/rules/pii/pii-027@1.0.0.yaml +47 -0
  513. raxe/packs/core/v1.0.0/rules/pii/pii-028@1.0.0.yaml +47 -0
  514. raxe/packs/core/v1.0.0/rules/pii/pii-034@1.0.0.yaml +47 -0
  515. raxe/packs/core/v1.0.0/rules/pii/pii-037@1.0.0.yaml +47 -0
  516. raxe/packs/core/v1.0.0/rules/pii/pii-040@1.0.0.yaml +47 -0
  517. raxe/packs/core/v1.0.0/rules/pii/pii-041@1.0.0.yaml +47 -0
  518. raxe/packs/core/v1.0.0/rules/pii/pii-044@1.0.0.yaml +47 -0
  519. raxe/packs/core/v1.0.0/rules/pii/pii-050@1.0.0.yaml +57 -0
  520. raxe/packs/core/v1.0.0/rules/pii/pii-051@1.0.0.yaml +53 -0
  521. raxe/packs/core/v1.0.0/rules/pii/pii-052@1.0.0.yaml +52 -0
  522. raxe/packs/core/v1.0.0/rules/pii/pii-053@1.0.0.yaml +56 -0
  523. raxe/packs/core/v1.0.0/rules/pii/pii-054@1.0.0.yaml +53 -0
  524. raxe/packs/core/v1.0.0/rules/pii/pii-055@1.0.0.yaml +51 -0
  525. raxe/packs/core/v1.0.0/rules/pii/pii-056@1.0.0.yaml +51 -0
  526. raxe/packs/core/v1.0.0/rules/pii/pii-058@1.0.0.yaml +47 -0
  527. raxe/packs/core/v1.0.0/rules/pii/pii-2015@1.0.0.yaml +41 -0
  528. raxe/packs/core/v1.0.0/rules/pii/pii-2025@1.0.0.yaml +35 -0
  529. raxe/packs/core/v1.0.0/rules/pii/pii-2026@1.0.0.yaml +39 -0
  530. raxe/packs/core/v1.0.0/rules/pii/pii-2035@1.0.0.yaml +39 -0
  531. raxe/packs/core/v1.0.0/rules/pii/pii-2037@1.0.0.yaml +39 -0
  532. raxe/packs/core/v1.0.0/rules/pii/pii-2042@1.0.0.yaml +39 -0
  533. raxe/packs/core/v1.0.0/rules/pii/pii-3001@1.0.0.yaml +39 -0
  534. raxe/packs/core/v1.0.0/rules/pii/pii-3002@1.0.0.yaml +41 -0
  535. raxe/packs/core/v1.0.0/rules/pii/pii-3003@1.0.0.yaml +36 -0
  536. raxe/packs/core/v1.0.0/rules/pii/pii-3004@1.0.0.yaml +41 -0
  537. raxe/packs/core/v1.0.0/rules/pii/pii-3005@1.0.0.yaml +39 -0
  538. raxe/packs/core/v1.0.0/rules/pii/pii-3006@1.0.0.yaml +35 -0
  539. raxe/packs/core/v1.0.0/rules/pii/pii-3007@1.0.0.yaml +37 -0
  540. raxe/packs/core/v1.0.0/rules/pii/pii-3008@1.0.0.yaml +35 -0
  541. raxe/packs/core/v1.0.0/rules/pii/pii-3009@1.0.0.yaml +42 -0
  542. raxe/packs/core/v1.0.0/rules/pii/pii-3010@1.0.0.yaml +39 -0
  543. raxe/packs/core/v1.0.0/rules/pii/pii-3011@1.0.0.yaml +35 -0
  544. raxe/packs/core/v1.0.0/rules/pii/pii-3012@1.0.0.yaml +35 -0
  545. raxe/packs/core/v1.0.0/rules/pii/pii-3013@1.0.0.yaml +36 -0
  546. raxe/packs/core/v1.0.0/rules/pii/pii-3014@1.0.0.yaml +36 -0
  547. raxe/packs/core/v1.0.0/rules/pii/pii-3015@1.0.0.yaml +42 -0
  548. raxe/packs/core/v1.0.0/rules/pii/pii-3016@1.0.0.yaml +42 -0
  549. raxe/packs/core/v1.0.0/rules/pii/pii-3017@1.0.0.yaml +40 -0
  550. raxe/packs/core/v1.0.0/rules/pii/pii-3018@1.0.0.yaml +38 -0
  551. raxe/packs/core/v1.0.0/rules/pii/pii-3019@1.0.0.yaml +40 -0
  552. raxe/packs/core/v1.0.0/rules/pii/pii-3020@1.0.0.yaml +40 -0
  553. raxe/packs/core/v1.0.0/rules/pii/pii-3021@1.0.0.yaml +39 -0
  554. raxe/packs/core/v1.0.0/rules/pii/pii-3022@1.0.0.yaml +36 -0
  555. raxe/packs/core/v1.0.0/rules/pii/pii-3023@1.0.0.yaml +41 -0
  556. raxe/packs/core/v1.0.0/rules/pii/pii-3024@1.0.0.yaml +37 -0
  557. raxe/packs/core/v1.0.0/rules/pii/pii-3025@1.0.0.yaml +38 -0
  558. raxe/packs/core/v1.0.0/rules/pii/pii-3026@1.0.0.yaml +42 -0
  559. raxe/packs/core/v1.0.0/rules/pii/pii-3027@1.0.0.yaml +38 -0
  560. raxe/packs/core/v1.0.0/rules/pii/pii-3028@1.0.0.yaml +42 -0
  561. raxe/packs/core/v1.0.0/rules/pii/pii-3029@1.0.0.yaml +36 -0
  562. raxe/packs/core/v1.0.0/rules/pii/pii-3030@1.0.0.yaml +42 -0
  563. raxe/packs/core/v1.0.0/rules/pii/pii-3031@1.0.0.yaml +37 -0
  564. raxe/packs/core/v1.0.0/rules/pii/pii-3032@1.0.0.yaml +42 -0
  565. raxe/packs/core/v1.0.0/rules/pii/pii-3033@1.0.0.yaml +39 -0
  566. raxe/packs/core/v1.0.0/rules/pii/pii-3034@1.0.0.yaml +40 -0
  567. raxe/packs/core/v1.0.0/rules/pii/pii-3035@1.0.0.yaml +43 -0
  568. raxe/packs/core/v1.0.0/rules/pii/pii-3036@1.0.0.yaml +41 -0
  569. raxe/packs/core/v1.0.0/rules/pii/pii-3037@1.0.0.yaml +35 -0
  570. raxe/packs/core/v1.0.0/rules/pii/pii-3038@1.0.0.yaml +35 -0
  571. raxe/packs/core/v1.0.0/rules/pii/pii-3039@1.0.0.yaml +35 -0
  572. raxe/packs/core/v1.0.0/rules/pii/pii-3040@1.0.0.yaml +41 -0
  573. raxe/packs/core/v1.0.0/rules/pii/pii-3041@1.0.0.yaml +39 -0
  574. raxe/packs/core/v1.0.0/rules/pii/pii-3042@1.0.0.yaml +36 -0
  575. raxe/packs/core/v1.0.0/rules/pii/pii-3043@1.0.0.yaml +35 -0
  576. raxe/packs/core/v1.0.0/rules/pii/pii-3044@1.0.0.yaml +43 -0
  577. raxe/packs/core/v1.0.0/rules/pii/pii-3045@1.0.0.yaml +36 -0
  578. raxe/packs/core/v1.0.0/rules/pii/pii-3046@1.0.0.yaml +37 -0
  579. raxe/packs/core/v1.0.0/rules/pii/pii-3047@1.0.0.yaml +36 -0
  580. raxe/packs/core/v1.0.0/rules/pii/pii-3048@1.0.0.yaml +36 -0
  581. raxe/packs/core/v1.0.0/rules/pii/pii-3049@1.0.0.yaml +38 -0
  582. raxe/packs/core/v1.0.0/rules/pii/pii-3050@1.0.0.yaml +44 -0
  583. raxe/packs/core/v1.0.0/rules/pii/pii-3051@1.0.0.yaml +35 -0
  584. raxe/packs/core/v1.0.0/rules/pii/pii-3052@1.0.0.yaml +36 -0
  585. raxe/packs/core/v1.0.0/rules/pii/pii-3053@1.0.0.yaml +35 -0
  586. raxe/packs/core/v1.0.0/rules/pii/pii-3054@1.0.0.yaml +35 -0
  587. raxe/packs/core/v1.0.0/rules/pii/pii-3055@1.0.0.yaml +40 -0
  588. raxe/packs/core/v1.0.0/rules/pii/pii-3056@1.0.0.yaml +38 -0
  589. raxe/packs/core/v1.0.0/rules/pii/pii-3057@1.0.0.yaml +40 -0
  590. raxe/packs/core/v1.0.0/rules/pii/pii-3058@1.0.0.yaml +43 -0
  591. raxe/packs/core/v1.0.0/rules/pii/pii-3059@1.0.0.yaml +42 -0
  592. raxe/packs/core/v1.0.0/rules/pii/pii-3060@1.0.0.yaml +42 -0
  593. raxe/packs/core/v1.0.0/rules/pii/pii-3061@1.0.0.yaml +50 -0
  594. raxe/packs/core/v1.0.0/rules/pii/pii-3062@1.0.0.yaml +50 -0
  595. raxe/packs/core/v1.0.0/rules/pii/pii-3063@1.0.0.yaml +54 -0
  596. raxe/packs/core/v1.0.0/rules/pii/pii-3064@1.0.0.yaml +78 -0
  597. raxe/packs/core/v1.0.0/rules/pii/pii-3065@1.0.0.yaml +84 -0
  598. raxe/packs/core/v1.0.0/rules/pii/pii-3066@1.0.0.yaml +84 -0
  599. raxe/packs/core/v1.0.0/rules/pii/pii-3067@1.0.0.yaml +88 -0
  600. raxe/packs/core/v1.0.0/rules/pii/pii-3068@1.0.0.yaml +94 -0
  601. raxe/packs/core/v1.0.0/rules/pii/pii-3069@1.0.0.yaml +90 -0
  602. raxe/packs/core/v1.0.0/rules/pii/pii-3070@1.0.0.yaml +99 -0
  603. raxe/packs/core/v1.0.0/rules/pii/pii-3071@1.0.0.yaml +91 -0
  604. raxe/packs/core/v1.0.0/rules/pii/pii-3072@1.0.0.yaml +38 -0
  605. raxe/packs/core/v1.0.0/rules/pii/pii-3073@1.0.0.yaml +38 -0
  606. raxe/packs/core/v1.0.0/rules/pii/pii-3074@1.0.0.yaml +38 -0
  607. raxe/packs/core/v1.0.0/rules/pii/pii-3075@1.0.0.yaml +38 -0
  608. raxe/packs/core/v1.0.0/rules/pii/pii-3076@1.0.0.yaml +38 -0
  609. raxe/packs/core/v1.0.0/rules/pii/pii-3077@1.0.0.yaml +38 -0
  610. raxe/packs/core/v1.0.0/rules/pii/pii-3078@1.0.0.yaml +38 -0
  611. raxe/packs/core/v1.0.0/rules/pii/pii-3079@1.0.0.yaml +38 -0
  612. raxe/packs/core/v1.0.0/rules/pii/pii-3080@1.0.0.yaml +38 -0
  613. raxe/packs/core/v1.0.0/rules/pii/pii-3081@1.0.0.yaml +38 -0
  614. raxe/packs/core/v1.0.0/rules/pii/pii-3082@1.0.0.yaml +38 -0
  615. raxe/packs/core/v1.0.0/rules/pii/pii-3083@1.0.0.yaml +38 -0
  616. raxe/packs/core/v1.0.0/rules/pii/pii-3084@1.0.0.yaml +38 -0
  617. raxe/packs/core/v1.0.0/rules/pii/pii-3085@1.0.0.yaml +38 -0
  618. raxe/packs/core/v1.0.0/rules/rag/rag-016@1.0.0.yaml +47 -0
  619. raxe/packs/core/v1.0.0/rules/rag/rag-028@1.0.0.yaml +47 -0
  620. raxe/packs/core/v1.0.0/rules/rag/rag-042@1.0.0.yaml +47 -0
  621. raxe/packs/core/v1.0.0/rules/rag/rag-044@1.0.0.yaml +47 -0
  622. raxe/packs/core/v1.0.0/rules/rag/rag-045@1.0.0.yaml +47 -0
  623. raxe/packs/core/v1.0.0/rules/rag/rag-050@1.0.0.yaml +47 -0
  624. raxe/packs/core/v1.0.0/rules/rag/rag-201@1.0.0.yaml +41 -0
  625. raxe/packs/core/v1.0.0/rules/rag/rag-202@1.0.0.yaml +41 -0
  626. raxe/packs/core/v1.0.0/rules/rag/rag-3001@1.0.0.yaml +41 -0
  627. raxe/packs/core/v1.0.0/rules/rag/rag-3006@1.0.0.yaml +41 -0
  628. raxe/packs/core/v1.0.0/rules/rag/rag-3009@1.0.0.yaml +41 -0
  629. raxe/packs/core/v1.0.0/rules/rag/rag-3012@1.0.0.yaml +41 -0
  630. raxe/plugins/__init__.py +98 -0
  631. raxe/plugins/custom_rules.py +380 -0
  632. raxe/plugins/loader.py +389 -0
  633. raxe/plugins/manager.py +538 -0
  634. raxe/plugins/protocol.py +428 -0
  635. raxe/py.typed +0 -0
  636. raxe/sdk/__init__.py +77 -0
  637. raxe/sdk/agent_scanner.py +1918 -0
  638. raxe/sdk/client.py +1603 -0
  639. raxe/sdk/decorator.py +175 -0
  640. raxe/sdk/exceptions.py +859 -0
  641. raxe/sdk/integrations/__init__.py +277 -0
  642. raxe/sdk/integrations/agent_scanner.py +71 -0
  643. raxe/sdk/integrations/autogen.py +872 -0
  644. raxe/sdk/integrations/crewai.py +1368 -0
  645. raxe/sdk/integrations/dspy.py +845 -0
  646. raxe/sdk/integrations/extractors.py +363 -0
  647. raxe/sdk/integrations/huggingface.py +395 -0
  648. raxe/sdk/integrations/langchain.py +948 -0
  649. raxe/sdk/integrations/litellm.py +484 -0
  650. raxe/sdk/integrations/llamaindex.py +1049 -0
  651. raxe/sdk/integrations/portkey.py +831 -0
  652. raxe/sdk/suppression_context.py +215 -0
  653. raxe/sdk/wrappers/__init__.py +163 -0
  654. raxe/sdk/wrappers/anthropic.py +310 -0
  655. raxe/sdk/wrappers/openai.py +221 -0
  656. raxe/sdk/wrappers/vertexai.py +484 -0
  657. raxe/utils/__init__.py +12 -0
  658. raxe/utils/error_sanitizer.py +135 -0
  659. raxe/utils/logging.py +241 -0
  660. raxe/utils/performance.py +414 -0
  661. raxe/utils/profiler.py +339 -0
  662. raxe/utils/validators.py +170 -0
  663. raxe-0.4.6.dist-info/METADATA +471 -0
  664. raxe-0.4.6.dist-info/RECORD +668 -0
  665. raxe-0.4.6.dist-info/WHEEL +5 -0
  666. raxe-0.4.6.dist-info/entry_points.txt +2 -0
  667. raxe-0.4.6.dist-info/licenses/LICENSE +56 -0
  668. raxe-0.4.6.dist-info/top_level.txt +1 -0
raxe/cli/auth.py ADDED
@@ -0,0 +1,1047 @@
1
+ """CLI commands for authentication and API key management.
2
+
3
+ Provides commands for:
4
+ - Device flow authentication (recommended): Opens browser for one-click setup
5
+ - Manual authentication: Opens RAXE Console for copy-paste key setup
6
+ - Validating API key configuration
7
+ - Checking remote API key status
8
+
9
+ Example usage:
10
+ raxe auth # Device flow (recommended)
11
+ raxe auth connect # Same as above
12
+ raxe auth login # Manual key setup
13
+ raxe auth status
14
+ raxe auth status --remote
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import os
20
+ import time
21
+ import webbrowser
22
+ from datetime import datetime, timezone
23
+ from typing import Optional
24
+
25
+ import click
26
+ import httpx
27
+ from rich.table import Table
28
+
29
+ from raxe.cli.error_handler import handle_cli_error
30
+ from raxe.cli.output import console, display_error, display_success
31
+
32
+
33
+ # Console URLs - resolved via centralized endpoints module
34
+ def _get_console_url() -> str:
35
+ """Get console URL from centralized endpoints."""
36
+ from raxe.infrastructure.config.endpoints import get_console_url
37
+ return get_console_url()
38
+
39
+
40
+ def _get_api_base_url() -> str:
41
+ """Get API base URL from centralized endpoints."""
42
+ from raxe.infrastructure.config.endpoints import get_api_base
43
+ return get_api_base()
44
+
45
+
46
+ def _get_cli_session_endpoint() -> str:
47
+ """Get CLI session endpoint from centralized endpoints."""
48
+ from raxe.infrastructure.config.endpoints import get_cli_session_endpoint
49
+ return get_cli_session_endpoint()
50
+
51
+
52
+ def _get_cli_link_endpoint() -> str:
53
+ """Get CLI link endpoint from centralized endpoints."""
54
+ from raxe.infrastructure.config.endpoints import Endpoint, get_endpoint
55
+ return get_endpoint(Endpoint.CLI_LINK)
56
+
57
+
58
+ def _get_console_keys_url() -> str:
59
+ """Get console keys URL."""
60
+ return f"{_get_console_url()}/keys"
61
+
62
+ # Polling configuration
63
+ POLL_INTERVAL_SECONDS = 2
64
+ POLL_TIMEOUT_SECONDS = 300 # 5 minutes
65
+
66
+
67
+ @click.group(invoke_without_command=True)
68
+ @click.option(
69
+ "--no-link-history",
70
+ is_flag=True,
71
+ default=False,
72
+ help="Do not link existing CLI history to the new account",
73
+ )
74
+ @click.pass_context
75
+ def auth(ctx, no_link_history: bool) -> None:
76
+ """Manage authentication and API keys.
77
+
78
+ Run without subcommand for interactive device flow authentication.
79
+ """
80
+ if ctx.invoked_subcommand is None:
81
+ # Default to connect flow when no subcommand
82
+ ctx.invoke(auth_connect, no_link_history=no_link_history)
83
+
84
+
85
+ def _get_current_key_id_from_telemetry() -> Optional[str]:
86
+ """Get the current api_key_id from telemetry state.
87
+
88
+ This ensures the temp_key_id sent during authentication matches
89
+ what telemetry events are using, enabling proper event linking
90
+ when upgrading from temporary to permanent keys.
91
+
92
+ Returns:
93
+ The api_key_id from telemetry state, or None if not available.
94
+ """
95
+ try:
96
+ from raxe.application.telemetry_orchestrator import get_orchestrator
97
+ orchestrator = get_orchestrator()
98
+ return orchestrator.get_current_api_key_id()
99
+ except Exception:
100
+ # Gracefully handle any initialization errors
101
+ return None
102
+
103
+
104
+ @auth.command("connect")
105
+ @click.option(
106
+ "--no-link-history",
107
+ is_flag=True,
108
+ default=False,
109
+ help="Do not link existing CLI history to the new account",
110
+ )
111
+ @handle_cli_error
112
+ def auth_connect(no_link_history: bool) -> None:
113
+ """Connect CLI to your RAXE account (recommended).
114
+
115
+ Opens your browser for one-click authentication.
116
+ Your CLI will be automatically configured.
117
+
118
+ By default, any existing CLI history from a temporary key will be
119
+ automatically linked to your account. Use --no-link-history to
120
+ skip this and start fresh.
121
+
122
+ Examples:
123
+ raxe auth
124
+ raxe auth connect
125
+ raxe auth --no-link-history
126
+ """
127
+ from rich.prompt import Confirm
128
+
129
+ from raxe.cli.branding import print_logo
130
+ from raxe.infrastructure.telemetry.credential_store import (
131
+ CredentialStore,
132
+ compute_key_id,
133
+ )
134
+
135
+ print_logo(console, compact=True)
136
+ console.print()
137
+ console.print("[bold cyan]RAXE CLI Authentication[/bold cyan]")
138
+ console.print()
139
+
140
+ # Get current credentials
141
+ store = CredentialStore()
142
+ credentials = store.load()
143
+ temp_key_id: Optional[str] = None
144
+ installation_id: Optional[str] = None
145
+
146
+ # Only detect temp_key_id if we want to link history (default behavior)
147
+ if not no_link_history:
148
+ # Priority 1: Get key_id from telemetry state (ensures consistency with events)
149
+ temp_key_id = _get_current_key_id_from_telemetry()
150
+
151
+ # Priority 2: Fall back to computing from credentials
152
+ if temp_key_id is None and credentials and credentials.api_key:
153
+ temp_key_id = compute_key_id(credentials.api_key)
154
+
155
+ if credentials:
156
+ installation_id = credentials.installation_id
157
+
158
+ # Check if already authenticated with a permanent key
159
+ if credentials.api_key and credentials.api_key.startswith("raxe_live_"):
160
+ masked_key = f"{credentials.api_key[:15]}...{credentials.api_key[-4:]}"
161
+ console.print(f"[green]Already authenticated![/green]")
162
+ console.print(f" API Key: [cyan]{masked_key}[/cyan]")
163
+ console.print()
164
+
165
+ if not Confirm.ask("Re-authenticate with a different account?", default=False):
166
+ console.print()
167
+ console.print("[dim]Run [cyan]raxe auth status[/cyan] to see details[/dim]")
168
+ return
169
+
170
+ console.print()
171
+
172
+ # Create CLI session
173
+ console.print("[dim]Creating authentication session...[/dim]")
174
+
175
+ try:
176
+ session_data = _create_cli_session(temp_key_id, installation_id)
177
+ except Exception as e:
178
+ display_error(
179
+ "Failed to create session",
180
+ details=str(e),
181
+ )
182
+ console.print()
183
+ console.print("[dim]Falling back to manual authentication:[/dim]")
184
+ console.print(f" Visit: [blue underline]{_get_console_keys_url()}[/blue underline]")
185
+ console.print(" Then run: [cyan]raxe config set api_key YOUR_KEY[/cyan]")
186
+ return
187
+
188
+ session_id = session_data["session_id"]
189
+ connect_url = session_data["connect_url"]
190
+ scan_count = session_data.get("scan_count", 0)
191
+
192
+ # Show scan preview if any (only when linking history)
193
+ # We show "scans" (not "events") for consistency with Portal metrics
194
+ if scan_count > 0 and not no_link_history:
195
+ console.print()
196
+ console.print(f"[green]Found {scan_count:,} scans from your CLI history![/green]")
197
+ console.print("[dim] These will be linked to your account.[/dim]")
198
+ elif no_link_history:
199
+ console.print()
200
+ console.print("[dim]History linking disabled (--no-link-history)[/dim]")
201
+
202
+ console.print()
203
+ console.print("[cyan]Opening browser...[/cyan]")
204
+ console.print()
205
+
206
+ # Open browser
207
+ try:
208
+ webbrowser.open(connect_url)
209
+ console.print("[dim]If browser doesn't open, visit:[/dim]")
210
+ console.print(f"[blue underline]{connect_url}[/blue underline]")
211
+ except Exception:
212
+ console.print("[yellow]Could not open browser. Please visit:[/yellow]")
213
+ console.print(f"[blue underline]{connect_url}[/blue underline]")
214
+
215
+ console.print()
216
+
217
+ # Poll for completion
218
+ with console.status("[cyan]Waiting for authentication...[/cyan]") as status:
219
+ start_time = time.time()
220
+
221
+ while time.time() - start_time < POLL_TIMEOUT_SECONDS:
222
+ try:
223
+ result = _poll_cli_session(session_id)
224
+
225
+ if result["status"] == "completed":
226
+ # Success! Save the new key
227
+ api_key = result["api_key"]
228
+ linked_scans = result.get("linked_scans", 0)
229
+ user_email = result.get("user_email", "")
230
+
231
+ # Save to credentials
232
+ _save_new_credentials(store, api_key, credentials)
233
+
234
+ # Show success
235
+ console.print()
236
+ console.print("[bold green]CLI Connected Successfully![/bold green]")
237
+ console.print()
238
+
239
+ # Display info table
240
+ table = Table(show_header=False, box=None, padding=(0, 2))
241
+ table.add_column("Label", style="dim")
242
+ table.add_column("Value")
243
+
244
+ masked_key = f"{api_key[:15]}...{api_key[-4:]}"
245
+ table.add_row("API Key:", f"[green]{masked_key}[/green]")
246
+ if user_email:
247
+ table.add_row("Account:", user_email)
248
+ if linked_scans > 0:
249
+ table.add_row("Scans Linked:", f"[green]{linked_scans:,}[/green]")
250
+
251
+ console.print(table)
252
+ console.print()
253
+ console.print(f"[dim]View your dashboard:[/dim] [blue underline]{_get_console_url()}/portal[/blue underline]")
254
+ console.print()
255
+ return
256
+
257
+ elif result["status"] == "expired":
258
+ display_error(
259
+ "Session expired",
260
+ details="Please run `raxe auth` again.",
261
+ )
262
+ return
263
+
264
+ # Still pending, continue polling
265
+ time.sleep(POLL_INTERVAL_SECONDS)
266
+
267
+ except httpx.HTTPError:
268
+ # Network error, retry
269
+ status.update("[yellow]Connection issue, retrying...[/yellow]")
270
+ time.sleep(POLL_INTERVAL_SECONDS)
271
+ except Exception as e:
272
+ # Processing error - don't retry, show actual error
273
+ console.print()
274
+ display_error(
275
+ "Authentication failed",
276
+ details=str(e),
277
+ )
278
+ return
279
+
280
+ # Timeout
281
+ console.print()
282
+ display_error(
283
+ "Authentication timed out",
284
+ details="Please complete the authentication in your browser within 5 minutes.",
285
+ )
286
+ console.print()
287
+ console.print("[dim]You can also set your API key manually:[/dim]")
288
+ console.print("[cyan] raxe config set api_key YOUR_API_KEY[/cyan]")
289
+
290
+
291
+ def _create_cli_session(
292
+ temp_key_id: Optional[str],
293
+ installation_id: Optional[str],
294
+ ) -> dict:
295
+ """Create a CLI auth session on the server.
296
+
297
+ Args:
298
+ temp_key_id: BigQuery-compatible ID of current temp key (if any).
299
+ installation_id: Installation ID for this CLI instance.
300
+
301
+ Returns:
302
+ Session data containing session_id, connect_url, and events_count.
303
+
304
+ Raises:
305
+ Exception: If session creation fails.
306
+ """
307
+ with httpx.Client(timeout=10) as client:
308
+ response = client.post(
309
+ _get_cli_session_endpoint(),
310
+ json={
311
+ "temp_key_id": temp_key_id,
312
+ "installation_id": installation_id,
313
+ },
314
+ )
315
+ response.raise_for_status()
316
+ data = response.json()
317
+
318
+ if not data.get("success"):
319
+ raise Exception(data.get("error", "Failed to create session"))
320
+
321
+ return data["data"]
322
+
323
+
324
+ def _poll_cli_session(session_id: str) -> dict:
325
+ """Poll for CLI session status.
326
+
327
+ Args:
328
+ session_id: Session ID to check.
329
+
330
+ Returns:
331
+ Session status data containing status and optionally api_key.
332
+
333
+ Raises:
334
+ Exception: If polling fails.
335
+ """
336
+ with httpx.Client(timeout=10) as client:
337
+ response = client.get(f"{_get_cli_session_endpoint()}/{session_id}")
338
+ response.raise_for_status()
339
+ data = response.json()
340
+
341
+ if not data.get("success"):
342
+ raise Exception(data.get("error", "Failed to check session"))
343
+
344
+ return data["data"]
345
+
346
+
347
+ def _save_new_credentials(
348
+ store, # CredentialStore
349
+ api_key: str,
350
+ old_credentials, # Credentials | None
351
+ ) -> None:
352
+ """Save new API key and send upgrade event.
353
+
354
+ Args:
355
+ store: CredentialStore instance.
356
+ api_key: New API key from authentication.
357
+ old_credentials: Previous credentials (may be None).
358
+ """
359
+ from raxe.domain.telemetry.events import create_key_upgrade_event
360
+ from raxe.infrastructure.telemetry.credential_store import compute_key_id
361
+
362
+ # Compute key IDs for upgrade event
363
+ old_key_id: Optional[str] = None
364
+ old_key_type = "temp"
365
+ days_on_previous: Optional[int] = None
366
+
367
+ if old_credentials and old_credentials.api_key:
368
+ old_key_id = compute_key_id(old_credentials.api_key)
369
+ if old_credentials.api_key.startswith("raxe_live_"):
370
+ old_key_type = "community"
371
+ elif old_credentials.api_key.startswith("raxe_test_"):
372
+ old_key_type = "test"
373
+ else:
374
+ old_key_type = "temp"
375
+ # Calculate days on previous key
376
+ try:
377
+ created = datetime.fromisoformat(
378
+ old_credentials.created_at.replace("Z", "+00:00")
379
+ )
380
+ now = datetime.now(timezone.utc)
381
+ days_on_previous = (now - created).days
382
+ except (ValueError, TypeError, AttributeError):
383
+ days_on_previous = None
384
+
385
+ new_key_id = compute_key_id(api_key)
386
+
387
+ # Determine new key type
388
+ if api_key.startswith("raxe_live_"):
389
+ new_key_type = "community"
390
+ elif api_key.startswith("raxe_test_"):
391
+ new_key_type = "test"
392
+ else:
393
+ new_key_type = "community" # Default for connected keys
394
+
395
+ # Update credentials file
396
+ store.upgrade_key(api_key, "live" if new_key_type == "community" else "test")
397
+
398
+ # Send upgrade event (fire and forget)
399
+ try:
400
+ from raxe.infrastructure.telemetry.sender import BatchSender
401
+
402
+ # Get config for endpoint
403
+ try:
404
+ from raxe.infrastructure.config.yaml_config import RaxeConfig
405
+ config = RaxeConfig.load()
406
+ endpoint = getattr(config.telemetry, "endpoint", None)
407
+ except Exception:
408
+ endpoint = None
409
+
410
+ if not endpoint:
411
+ endpoint = f"{_get_api_base_url()}/v1/telemetry"
412
+
413
+ # Create upgrade event
414
+ event = create_key_upgrade_event(
415
+ previous_key_type=old_key_type,
416
+ new_key_type=new_key_type,
417
+ previous_key_id=old_key_id,
418
+ new_key_id=new_key_id,
419
+ days_on_previous=days_on_previous,
420
+ conversion_trigger="cli_connect",
421
+ )
422
+
423
+ # Get installation_id for sender
424
+ installation_id = None
425
+ if old_credentials:
426
+ installation_id = old_credentials.installation_id
427
+
428
+ # Send via batch sender - use old_key_id for correlation (preserves temp key_id)
429
+ sender = BatchSender(
430
+ endpoint=endpoint,
431
+ api_key=api_key,
432
+ installation_id=installation_id or "inst_unknown",
433
+ api_key_id=old_key_id, # Correlate upgrade event with temp key_id
434
+ )
435
+
436
+ # Convert event to dict for sending
437
+ from raxe.domain.telemetry.events import event_to_dict
438
+ sender.send_batch([event_to_dict(event)])
439
+
440
+ except Exception:
441
+ pass # Don't fail auth on telemetry error
442
+
443
+
444
+ @auth.command("login")
445
+ @handle_cli_error
446
+ def auth_login() -> None:
447
+ """Open RAXE Console to manage API keys (manual).
448
+
449
+ For automatic CLI connection, use: raxe auth
450
+
451
+ Examples:
452
+ raxe auth login
453
+ """
454
+ console.print()
455
+ console.print("[cyan]Opening RAXE Console in your browser...[/cyan]")
456
+ console.print()
457
+
458
+ # Open the console URL in default browser
459
+ try:
460
+ webbrowser.open(_get_console_keys_url())
461
+ display_success(f"Opened {_get_console_keys_url()}")
462
+ except Exception as e:
463
+ console.print(f"[yellow]Could not open browser automatically: {e}[/yellow]")
464
+ console.print()
465
+ console.print(f"Please visit: [blue underline]{_get_console_keys_url()}[/blue underline]")
466
+
467
+ console.print()
468
+ console.print("[dim]After creating your API key, configure it with:[/dim]")
469
+ console.print("[cyan] raxe config set api_key YOUR_API_KEY[/cyan]")
470
+ console.print()
471
+ console.print("[dim]Or set the environment variable:[/dim]")
472
+ console.print("[cyan] export RAXE_API_KEY=YOUR_API_KEY[/cyan]")
473
+ console.print()
474
+
475
+
476
+ @auth.command("link")
477
+ @click.argument("code")
478
+ @handle_cli_error
479
+ def auth_link(code: str) -> None:
480
+ """Link CLI to an existing API key using a link code.
481
+
482
+ Get a link code from the RAXE Console by clicking "Link CLI" on any
483
+ API key card. Then run this command with the code.
484
+
485
+ This preserves your CLI's historical telemetry data and links it
486
+ to the selected API key.
487
+
488
+ NOTE: This command requires existing CLI history (from prior usage).
489
+ For first-time setup, use 'raxe auth' instead.
490
+
491
+ Examples:
492
+ raxe auth link ABC123
493
+ raxe link ABC123
494
+ """
495
+ from rich.prompt import Confirm
496
+
497
+ from raxe.cli.branding import print_logo
498
+ from raxe.infrastructure.telemetry.credential_store import (
499
+ CredentialStore,
500
+ compute_key_id,
501
+ )
502
+
503
+ print_logo(console, compact=True)
504
+ console.print()
505
+ console.print("[bold cyan]Link CLI to API Key[/bold cyan]")
506
+ console.print()
507
+
508
+ # Normalize link code
509
+ normalized_code = code.upper().strip()
510
+ if len(normalized_code) != 6:
511
+ display_error(
512
+ "Invalid link code format",
513
+ details="Link codes are 6 characters. Example: ABC123",
514
+ )
515
+ return
516
+
517
+ # Get current credentials
518
+ store = CredentialStore()
519
+ credentials = store.load()
520
+ temp_key_id: Optional[str] = None
521
+
522
+ # Priority 1: Get key_id from telemetry state (ensures consistency with events)
523
+ temp_key_id = _get_current_key_id_from_telemetry()
524
+
525
+ # Priority 2: Fall back to computing from credentials
526
+ if temp_key_id is None and credentials and credentials.api_key:
527
+ temp_key_id = compute_key_id(credentials.api_key)
528
+
529
+ if credentials and credentials.api_key:
530
+ # Check if already authenticated with a permanent key
531
+ if credentials.api_key.startswith("raxe_live_"):
532
+ masked_key = f"{credentials.api_key[:15]}...{credentials.api_key[-4:]}"
533
+ console.print(f"[green]Already authenticated![/green]")
534
+ console.print(f" API Key: [cyan]{masked_key}[/cyan]")
535
+ console.print()
536
+
537
+ if not Confirm.ask("Replace with a different key?", default=False):
538
+ console.print()
539
+ console.print("[dim]Run [cyan]raxe auth status[/cyan] to see details[/dim]")
540
+ return
541
+
542
+ console.print()
543
+ else:
544
+ console.print(f"[dim]Current key ID: {temp_key_id}[/dim]")
545
+ else:
546
+ # No credentials at all - link code requires existing CLI history
547
+ console.print("[yellow]No CLI history found.[/yellow]")
548
+ console.print()
549
+ console.print("The [cyan]raxe link[/cyan] command is used to link existing CLI history")
550
+ console.print("to an API key you've already created in the Console.")
551
+ console.print()
552
+ console.print("[bold]For first-time setup, use:[/bold]")
553
+ console.print(" [cyan]raxe auth[/cyan] - Connect your CLI to your RAXE account")
554
+ console.print()
555
+ return
556
+
557
+ console.print()
558
+
559
+ # Call the link API
560
+ try:
561
+ with console.status("[cyan]Linking CLI to API key...[/cyan]"):
562
+ result = _link_cli_to_key(normalized_code, temp_key_id)
563
+
564
+ if result.get("success"):
565
+ api_key = result["api_key"]
566
+ key_id = result["key_id"]
567
+ events_count = result.get("events_count", 0)
568
+ message = result.get("message", "")
569
+
570
+ # Save new credentials
571
+ _save_new_credentials(store, api_key, credentials)
572
+
573
+ # Show success
574
+ console.print("[bold green]CLI Linked Successfully![/bold green]")
575
+ console.print()
576
+
577
+ # Display info table
578
+ table = Table(show_header=False, box=None, padding=(0, 2))
579
+ table.add_column("Label", style="dim")
580
+ table.add_column("Value")
581
+
582
+ masked_key = f"{api_key[:15]}...{api_key[-4:]}"
583
+ table.add_row("API Key:", f"[green]{masked_key}[/green]")
584
+ table.add_row("Key ID:", key_id)
585
+ if events_count > 0:
586
+ table.add_row("Events Linked:", f"[green]{events_count:,}[/green]")
587
+
588
+ console.print(table)
589
+ console.print()
590
+ if message:
591
+ console.print(f"[dim]{message}[/dim]")
592
+ console.print()
593
+ console.print(f"[dim]View your dashboard:[/dim] [blue underline]{_get_console_url()}/portal[/blue underline]")
594
+ console.print()
595
+ else:
596
+ display_error(
597
+ "Link failed",
598
+ details=result.get("error", {}).get("message", "Unknown error"),
599
+ )
600
+
601
+ except Exception as e:
602
+ display_error(
603
+ "Failed to link CLI",
604
+ details=str(e),
605
+ )
606
+ console.print()
607
+ console.print("[dim]Make sure the link code is correct and hasn't expired.[/dim]")
608
+ console.print("[dim]Get a new code from the RAXE Console: [/dim]")
609
+ console.print(f"[blue underline]{_get_console_url()}/api-keys[/blue underline]")
610
+
611
+
612
+ def _link_cli_to_key(code: str, temp_key_id: Optional[str]) -> dict:
613
+ """Call the CLI link API to link temp key data to an existing key.
614
+
615
+ Args:
616
+ code: The 6-character link code from Console.
617
+ temp_key_id: The current temp key ID (if any).
618
+
619
+ Returns:
620
+ Response data containing success, api_key, key_id, events_count, message.
621
+
622
+ Raises:
623
+ Exception: If the link fails.
624
+ """
625
+ with httpx.Client(timeout=30) as client:
626
+ response = client.post(
627
+ _get_cli_link_endpoint(),
628
+ json={
629
+ "code": code,
630
+ "temp_key_id": temp_key_id or "",
631
+ },
632
+ )
633
+
634
+ data = response.json()
635
+
636
+ # Handle HTTP errors
637
+ if response.status_code != 200:
638
+ if not data.get("success"):
639
+ return {
640
+ "success": False,
641
+ "error": data.get("error", {"message": f"HTTP {response.status_code}"}),
642
+ }
643
+ response.raise_for_status()
644
+
645
+ if not data.get("success"):
646
+ return {
647
+ "success": False,
648
+ "error": data.get("error", {"message": "Unknown error"}),
649
+ }
650
+
651
+ return data.get("data", {})
652
+
653
+
654
+ @auth.command("status")
655
+ @click.option(
656
+ "--remote",
657
+ "-r",
658
+ is_flag=True,
659
+ default=False,
660
+ help="Check status with remote server (requires network)",
661
+ )
662
+ @handle_cli_error
663
+ def auth_status(remote: bool) -> None:
664
+ """Show current authentication status.
665
+
666
+ Displays information about the configured API key:
667
+ - Whether an API key is configured
668
+ - Key type (temporary, live, test)
669
+ - Key tier (if determinable)
670
+
671
+ Use --remote to fetch real-time information from the server including:
672
+ - Actual days remaining (server-calculated)
673
+ - Events sent today / remaining
674
+ - Rate limits
675
+ - Feature flags
676
+
677
+ Examples:
678
+ raxe auth status
679
+ raxe auth status --remote
680
+ raxe auth status -r
681
+ """
682
+ import os
683
+
684
+ from raxe.cli.branding import print_logo
685
+ from raxe.infrastructure.config.yaml_config import RaxeConfig
686
+ from raxe.infrastructure.telemetry.credential_store import CredentialStore
687
+
688
+ print_logo(console, compact=True)
689
+ console.print()
690
+
691
+ # Load API key with fallback chain:
692
+ # 1. RAXE_API_KEY environment variable (highest priority)
693
+ # 2. config.yaml (explicit user config)
694
+ # 3. credentials.json (auto-generated from raxe auth)
695
+ api_key = None
696
+ api_key_source = None
697
+
698
+ # Priority 1: Environment variable
699
+ env_api_key = os.environ.get("RAXE_API_KEY", "").strip()
700
+ if env_api_key:
701
+ api_key = env_api_key
702
+ api_key_source = "environment"
703
+
704
+ # Priority 2: config.yaml
705
+ if not api_key:
706
+ try:
707
+ config = RaxeConfig.load()
708
+ if config.core.api_key:
709
+ api_key = config.core.api_key
710
+ api_key_source = "config"
711
+ except Exception:
712
+ pass
713
+
714
+ # Priority 3: credentials.json
715
+ if not api_key:
716
+ try:
717
+ store = CredentialStore()
718
+ credentials = store.load()
719
+ if credentials:
720
+ api_key = credentials.api_key
721
+ api_key_source = "credentials"
722
+ except Exception:
723
+ pass
724
+
725
+ if not api_key:
726
+ console.print("[bold cyan]Authentication Status[/bold cyan]")
727
+ console.print()
728
+ console.print("[yellow]No API key configured[/yellow]")
729
+ console.print()
730
+ console.print("To get an API key:")
731
+ console.print(" 1. Run: [cyan]raxe auth[/cyan]")
732
+ console.print(" 2. Complete authentication in your browser")
733
+ console.print()
734
+ console.print("Or manually:")
735
+ console.print(" 1. Run: [cyan]raxe auth login[/cyan]")
736
+ console.print(" 2. Create a key in the RAXE Console")
737
+ console.print(" 3. Configure it: [cyan]raxe config set api_key YOUR_KEY[/cyan]")
738
+ console.print()
739
+ console.print(f"Or visit: [blue underline]{_get_console_keys_url()}[/blue underline]")
740
+ console.print()
741
+ return
742
+
743
+ if remote:
744
+ _display_remote_status(api_key, config)
745
+ else:
746
+ _display_local_status(api_key, api_key_source)
747
+
748
+
749
+ def _display_local_status(api_key: str, source: str | None = None) -> None:
750
+ """Display local-only authentication status.
751
+
752
+ Args:
753
+ api_key: The configured API key
754
+ source: Where the key was loaded from (environment, config, credentials)
755
+ """
756
+ console.print("[bold cyan]Authentication Status[/bold cyan]")
757
+ console.print()
758
+
759
+ # Determine key type from prefix
760
+ if api_key.startswith("raxe_live_"):
761
+ key_type = "Live (production)"
762
+ key_style = "green"
763
+ elif api_key.startswith("raxe_test_"):
764
+ key_type = "Test"
765
+ key_style = "yellow"
766
+ elif api_key.startswith("raxe_temp_"):
767
+ key_type = "Temporary (14-day expiry)"
768
+ key_style = "yellow"
769
+ else:
770
+ key_type = "Unknown format"
771
+ key_style = "red"
772
+
773
+ # Mask the key for display
774
+ if len(api_key) > 15:
775
+ masked_key = f"{api_key[:12]}...{api_key[-4:]}"
776
+ else:
777
+ masked_key = "***"
778
+
779
+ console.print(f" API Key: [{key_style}]{masked_key}[/{key_style}]")
780
+ console.print(f" Type: [{key_style}]{key_type}[/{key_style}]")
781
+
782
+ # Show source of the key
783
+ if source:
784
+ source_display = {
785
+ "environment": "RAXE_API_KEY env var",
786
+ "config": "~/.raxe/config.yaml",
787
+ "credentials": "~/.raxe/credentials.json",
788
+ }.get(source, source)
789
+ console.print(f" Source: [dim]{source_display}[/dim]")
790
+
791
+ # For temporary keys, show days remaining from credentials file
792
+ if api_key.startswith("raxe_temp_"):
793
+ _display_temp_key_expiry()
794
+ console.print()
795
+ console.print(f"Get a permanent key at: [blue underline]{_get_console_keys_url()}[/blue underline]")
796
+ console.print("Or run: [cyan]raxe auth[/cyan]")
797
+
798
+ console.print()
799
+ console.print("[dim]Use --remote flag for real-time server information[/dim]")
800
+ console.print()
801
+
802
+
803
+ def _display_temp_key_expiry() -> None:
804
+ """Display days remaining for temporary key from credentials file.
805
+
806
+ Reads the credentials file to get the expires_at field and
807
+ calculates the remaining days until expiry.
808
+ """
809
+ try:
810
+ from raxe.infrastructure.telemetry.credential_store import CredentialStore
811
+
812
+ store = CredentialStore()
813
+ credentials = store.load()
814
+
815
+ if credentials is None or not credentials.is_temporary():
816
+ console.print()
817
+ console.print("[yellow]Temporary keys expire after 14 days.[/yellow]")
818
+ return
819
+
820
+ days_remaining = credentials.days_until_expiry()
821
+
822
+ if days_remaining is None:
823
+ console.print()
824
+ console.print("[yellow]Temporary keys expire after 14 days.[/yellow]")
825
+ return
826
+
827
+ console.print()
828
+
829
+ if days_remaining <= 0:
830
+ console.print("[red bold] Expiry: EXPIRED[/red bold]")
831
+ elif days_remaining == 1:
832
+ console.print("[red bold] Expiry: Expires TODAY[/red bold]")
833
+ elif days_remaining <= 3:
834
+ console.print(f"[red] Expiry: {days_remaining} days remaining[/red]")
835
+ elif days_remaining <= 7:
836
+ console.print(f"[yellow] Expiry: {days_remaining} days remaining[/yellow]")
837
+ else:
838
+ console.print(f"[green] Expiry: {days_remaining} days remaining[/green]")
839
+
840
+ except Exception:
841
+ # Fallback to generic message if we can't read credentials
842
+ console.print()
843
+ console.print("[yellow]Temporary keys expire after 14 days.[/yellow]")
844
+
845
+
846
+ def _display_remote_status(api_key: str, config) -> None:
847
+ """Display authentication status from remote server.
848
+
849
+ Makes a request to the /v1/health endpoint to get real-time
850
+ information about the API key.
851
+
852
+ Args:
853
+ api_key: The configured API key
854
+ config: The RaxeConfig object
855
+ """
856
+ from raxe.infrastructure.telemetry.health_client import (
857
+ AuthenticationError,
858
+ HealthCheckError,
859
+ NetworkError,
860
+ TimeoutError,
861
+ check_health,
862
+ )
863
+
864
+ console.print("[bold cyan]Authentication Status (Remote)[/bold cyan]")
865
+ console.print()
866
+
867
+ # Mask the key for display
868
+ if len(api_key) > 15:
869
+ masked_key = f"{api_key[:12]}...{api_key[-4:]}"
870
+ else:
871
+ masked_key = "***"
872
+
873
+ # Get endpoint from config or use default
874
+ endpoint = getattr(config.telemetry, "endpoint", None)
875
+ if endpoint:
876
+ # Extract base URL from telemetry endpoint
877
+ # e.g., "https://api.raxe.ai/v1/telemetry" -> "https://api.raxe.ai"
878
+ if endpoint.endswith("/v1/telemetry"):
879
+ endpoint = endpoint.rsplit("/v1/telemetry", 1)[0]
880
+
881
+ try:
882
+ # Show spinner while fetching
883
+ with console.status("[cyan]Fetching status from server...[/cyan]"):
884
+ if endpoint:
885
+ response = check_health(api_key, endpoint=endpoint)
886
+ else:
887
+ response = check_health(api_key)
888
+
889
+ # Display key info
890
+ _display_key_info_table(masked_key, response)
891
+
892
+ except AuthenticationError as e:
893
+ display_error(
894
+ "Invalid or expired API key",
895
+ details=str(e),
896
+ )
897
+ console.print()
898
+ console.print(f"Get a new key at: [blue underline]{_get_console_keys_url()}[/blue underline]")
899
+ console.print("Or run: [cyan]raxe auth[/cyan]")
900
+ console.print()
901
+
902
+ except NetworkError:
903
+ display_error(
904
+ "Could not reach server",
905
+ details="Check your network connection and try again.",
906
+ )
907
+ console.print()
908
+ console.print("[dim]Showing local status instead:[/dim]")
909
+ console.print()
910
+ _display_local_status(api_key)
911
+
912
+ except TimeoutError:
913
+ display_error(
914
+ "Server timeout",
915
+ details="The server took too long to respond. Please try again.",
916
+ )
917
+ console.print()
918
+ console.print("[dim]Showing local status instead:[/dim]")
919
+ console.print()
920
+ _display_local_status(api_key)
921
+
922
+ except HealthCheckError as e:
923
+ display_error(
924
+ "Health check failed",
925
+ details=str(e),
926
+ )
927
+ console.print()
928
+ console.print("[dim]Showing local status instead:[/dim]")
929
+ console.print()
930
+ _display_local_status(api_key)
931
+
932
+
933
+ def _display_key_info_table(masked_key: str, response) -> None:
934
+ """Display formatted key information table.
935
+
936
+ Args:
937
+ masked_key: Masked API key for display
938
+ response: HealthResponse from server
939
+ """
940
+ # Determine key type display
941
+ key_type_display = response.key_type.capitalize()
942
+ if response.key_type == "temp":
943
+ key_type_display = "Temporary"
944
+ elif response.key_type == "live":
945
+ key_type_display = "Live (production)"
946
+
947
+ # Key type style
948
+ if response.key_type == "live":
949
+ key_style = "green"
950
+ elif response.key_type in ("test", "temp"):
951
+ key_style = "yellow"
952
+ else:
953
+ key_style = "white"
954
+
955
+ # Create main info table
956
+ table = Table(show_header=False, box=None, padding=(0, 2))
957
+ table.add_column("Label", style="dim")
958
+ table.add_column("Value")
959
+
960
+ table.add_row("API Key:", f"[{key_style}]{masked_key}[/{key_style}]")
961
+ table.add_row("Type:", f"[{key_style}]{key_type_display}[/{key_style}]")
962
+ table.add_row("Tier:", response.tier.capitalize())
963
+
964
+ console.print(table)
965
+ console.print()
966
+
967
+ # Trial status section (for temp keys)
968
+ if response.trial_status and response.trial_status.is_trial:
969
+ console.print("[bold]Trial Status:[/bold]")
970
+ trial_table = Table(show_header=False, box=None, padding=(0, 2))
971
+ trial_table.add_column("Label", style="dim")
972
+ trial_table.add_column("Value")
973
+
974
+ days = response.days_remaining
975
+ if days is not None:
976
+ if days <= 3:
977
+ days_style = "red bold"
978
+ elif days <= 7:
979
+ days_style = "yellow"
980
+ else:
981
+ days_style = "green"
982
+ trial_table.add_row("Days Remaining:", f"[{days_style}]{days}[/{days_style}]")
983
+
984
+ if response.trial_status.scans_during_trial > 0:
985
+ trial_table.add_row(
986
+ "Scans During Trial:",
987
+ f"{response.trial_status.scans_during_trial:,}",
988
+ )
989
+ if response.trial_status.threats_detected_during_trial > 0:
990
+ trial_table.add_row(
991
+ "Threats Detected:",
992
+ f"{response.trial_status.threats_detected_during_trial:,}",
993
+ )
994
+
995
+ console.print(trial_table)
996
+ console.print()
997
+
998
+ # Usage section
999
+ console.print("[bold]Usage Today:[/bold]")
1000
+ usage_table = Table(show_header=False, box=None, padding=(0, 2))
1001
+ usage_table.add_column("Label", style="dim")
1002
+ usage_table.add_column("Value")
1003
+
1004
+ usage_table.add_row("Events Sent:", f"{response.events_today:,}")
1005
+ usage_table.add_row("Events Remaining:", f"{response.events_remaining:,}")
1006
+
1007
+ console.print(usage_table)
1008
+ console.print()
1009
+
1010
+ # Rate limits section
1011
+ console.print("[bold]Rate Limits:[/bold]")
1012
+ rate_table = Table(show_header=False, box=None, padding=(0, 2))
1013
+ rate_table.add_column("Label", style="dim")
1014
+ rate_table.add_column("Value")
1015
+
1016
+ rate_table.add_row("Requests/min:", f"{response.rate_limit_rpm:,}")
1017
+ rate_table.add_row("Events/day:", f"{response.rate_limit_daily:,}")
1018
+
1019
+ console.print(rate_table)
1020
+ console.print()
1021
+
1022
+ # Features section
1023
+ console.print("[bold]Features:[/bold]")
1024
+ features_table = Table(show_header=False, box=None, padding=(0, 2))
1025
+ features_table.add_column("Label", style="dim")
1026
+ features_table.add_column("Value")
1027
+
1028
+ telemetry_status = "[green]Yes[/green]" if response.can_disable_telemetry else "[yellow]No[/yellow]"
1029
+ offline_status = "[green]Yes[/green]" if response.offline_mode else "[yellow]No[/yellow]"
1030
+
1031
+ features_table.add_row("Can Disable Telemetry:", telemetry_status)
1032
+ features_table.add_row("Offline Mode:", offline_status)
1033
+
1034
+ console.print(features_table)
1035
+ console.print()
1036
+
1037
+ # Upgrade prompt for temp/community keys
1038
+ if response.key_type == "temp" or response.tier in ("temporary", "community"):
1039
+ console.print("[dim]" + "-" * 50 + "[/dim]")
1040
+ console.print()
1041
+ if response.key_type == "temp":
1042
+ console.print("[yellow]Upgrade to a permanent key for uninterrupted service.[/yellow]")
1043
+ else:
1044
+ console.print("[cyan]Upgrade to Pro for higher limits and more features.[/cyan]")
1045
+ console.print(f"Visit: [blue underline]{_get_console_keys_url()}[/blue underline]")
1046
+ console.print("Or run: [cyan]raxe auth[/cyan]")
1047
+ console.print()