voidaccess 1.3.0__tar.gz → 1.4.2__tar.gz

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 (179) hide show
  1. {voidaccess-1.3.0 → voidaccess-1.4.2}/PKG-INFO +2 -3
  2. {voidaccess-1.3.0 → voidaccess-1.4.2}/pyproject.toml +4 -5
  3. {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/PKG-INFO +2 -3
  4. {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/SOURCES.txt +15 -15
  5. voidaccess-1.4.2/voidaccess.egg-info/entry_points.txt +2 -0
  6. {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/top_level.txt +1 -1
  7. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/__init__.py +1 -1
  8. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/configure.py +1 -1
  9. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/enrich.py +3 -3
  10. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/export.py +11 -7
  11. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/investigate.py +26 -6
  12. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/show.py +26 -4
  13. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/config.py +6 -0
  14. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/main.py +46 -9
  15. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/tor_detect.py +1 -1
  16. voidaccess-1.3.0/voidaccess.egg-info/entry_points.txt +0 -2
  17. {voidaccess-1.3.0 → voidaccess-1.4.2}/LICENSE +0 -0
  18. {voidaccess-1.3.0 → voidaccess-1.4.2}/README.md +0 -0
  19. {voidaccess-1.3.0 → voidaccess-1.4.2}/analysis/__init__.py +0 -0
  20. {voidaccess-1.3.0 → voidaccess-1.4.2}/analysis/opsec.py +0 -0
  21. {voidaccess-1.3.0 → voidaccess-1.4.2}/analysis/patterns.py +0 -0
  22. {voidaccess-1.3.0 → voidaccess-1.4.2}/analysis/temporal.py +0 -0
  23. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/__init__.py +0 -0
  24. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/auth.py +0 -0
  25. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/main.py +0 -0
  26. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/__init__.py +0 -0
  27. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/admin.py +0 -0
  28. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/auth.py +0 -0
  29. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/entities.py +0 -0
  30. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/export.py +0 -0
  31. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/investigations.py +0 -0
  32. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/monitors.py +0 -0
  33. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/search.py +0 -0
  34. {voidaccess-1.3.0 → voidaccess-1.4.2}/api/routes/settings.py +0 -0
  35. {voidaccess-1.3.0 → voidaccess-1.4.2}/auth/__init__.py +0 -0
  36. {voidaccess-1.3.0 → voidaccess-1.4.2}/auth/token_blacklist.py +0 -0
  37. {voidaccess-1.3.0 → voidaccess-1.4.2}/config.py +0 -0
  38. {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/__init__.py +0 -0
  39. {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/dedup.py +0 -0
  40. {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/frontier.py +0 -0
  41. {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/spider.py +0 -0
  42. {voidaccess-1.3.0 → voidaccess-1.4.2}/crawler/utils.py +0 -0
  43. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/__init__.py +0 -0
  44. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/__init__.py +0 -0
  45. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/env.py +0 -0
  46. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0001_initial_schema.py +0 -0
  47. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0002_add_investigation_status_column.py +0 -0
  48. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0002_add_missing_tables.py +0 -0
  49. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0003_add_canonical_value_and_entity_links.py +0 -0
  50. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0004_add_page_posted_at.py +0 -0
  51. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0005_add_extraction_method.py +0 -0
  52. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0006_add_monitor_alerts.py +0 -0
  53. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0007_add_actor_style_profiles.py +0 -0
  54. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0008_add_users_table.py +0 -0
  55. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0009_add_investigation_id_to_relationships.py +0 -0
  56. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0010_add_composite_index_entity_relationships.py +0 -0
  57. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0011_add_page_extraction_cache.py +0 -0
  58. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0013_add_graph_status.py +0 -0
  59. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0015_add_progress_fields.py +0 -0
  60. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0016_backfill_graph_status.py +0 -0
  61. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0017_add_user_api_keys.py +0 -0
  62. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0018_add_user_id_to_investigations.py +0 -0
  63. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0019_add_content_safety_log.py +0 -0
  64. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/migrations/versions/0020_add_entity_source_tracking.py +0 -0
  65. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/models.py +0 -0
  66. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/queries.py +0 -0
  67. {voidaccess-1.3.0 → voidaccess-1.4.2}/db/session.py +0 -0
  68. {voidaccess-1.3.0 → voidaccess-1.4.2}/export/__init__.py +0 -0
  69. {voidaccess-1.3.0 → voidaccess-1.4.2}/export/misp.py +0 -0
  70. {voidaccess-1.3.0 → voidaccess-1.4.2}/export/sigma.py +0 -0
  71. {voidaccess-1.3.0 → voidaccess-1.4.2}/export/stix.py +0 -0
  72. {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/__init__.py +0 -0
  73. {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/llm_extract.py +0 -0
  74. {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/ner.py +0 -0
  75. {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/normalizer.py +0 -0
  76. {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/pipeline.py +0 -0
  77. {voidaccess-1.3.0 → voidaccess-1.4.2}/extractor/regex_patterns.py +0 -0
  78. {voidaccess-1.3.0 → voidaccess-1.4.2}/fingerprint/__init__.py +0 -0
  79. {voidaccess-1.3.0 → voidaccess-1.4.2}/fingerprint/profiler.py +0 -0
  80. {voidaccess-1.3.0 → voidaccess-1.4.2}/fingerprint/stylometry.py +0 -0
  81. {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/__init__.py +0 -0
  82. {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/builder.py +0 -0
  83. {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/export.py +0 -0
  84. {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/model.py +0 -0
  85. {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/queries.py +0 -0
  86. {voidaccess-1.3.0 → voidaccess-1.4.2}/graph/visualize.py +0 -0
  87. {voidaccess-1.3.0 → voidaccess-1.4.2}/i18n/__init__.py +0 -0
  88. {voidaccess-1.3.0 → voidaccess-1.4.2}/i18n/detect.py +0 -0
  89. {voidaccess-1.3.0 → voidaccess-1.4.2}/i18n/query_expand.py +0 -0
  90. {voidaccess-1.3.0 → voidaccess-1.4.2}/i18n/translate.py +0 -0
  91. {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/__init__.py +0 -0
  92. {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/_db.py +0 -0
  93. {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/alerts.py +0 -0
  94. {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/config.py +0 -0
  95. {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/diff.py +0 -0
  96. {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/jobs.py +0 -0
  97. {voidaccess-1.3.0 → voidaccess-1.4.2}/monitor/scheduler.py +0 -0
  98. {voidaccess-1.3.0 → voidaccess-1.4.2}/scraper/__init__.py +0 -0
  99. {voidaccess-1.3.0 → voidaccess-1.4.2}/scraper/scrape.py +0 -0
  100. {voidaccess-1.3.0 → voidaccess-1.4.2}/scraper/scrape_js.py +0 -0
  101. {voidaccess-1.3.0 → voidaccess-1.4.2}/search/__init__.py +0 -0
  102. {voidaccess-1.3.0 → voidaccess-1.4.2}/search/circuit_breaker.py +0 -0
  103. {voidaccess-1.3.0 → voidaccess-1.4.2}/search/search.py +0 -0
  104. {voidaccess-1.3.0 → voidaccess-1.4.2}/setup.cfg +0 -0
  105. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/__init__.py +0 -0
  106. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/blockchain.py +0 -0
  107. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/cache.py +0 -0
  108. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/cisa.py +0 -0
  109. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/dns_enrichment.py +0 -0
  110. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/domain_reputation.py +0 -0
  111. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/email_reputation.py +0 -0
  112. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/engines.py +0 -0
  113. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/enrichment.py +0 -0
  114. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/github_scraper.py +0 -0
  115. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/gitlab_scraper.py +0 -0
  116. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/hash_reputation.py +0 -0
  117. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/historical_intel.py +0 -0
  118. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/ip_reputation.py +0 -0
  119. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/paste_scraper.py +0 -0
  120. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/pastes.py +0 -0
  121. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/rss_scraper.py +0 -0
  122. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/seed_manager.py +0 -0
  123. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/seeds.py +0 -0
  124. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/shodan.py +0 -0
  125. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/telegram.py +0 -0
  126. {voidaccess-1.3.0 → voidaccess-1.4.2}/sources/virustotal.py +0 -0
  127. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_analysis_opsec.py +0 -0
  128. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_analysis_stylometry.py +0 -0
  129. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_analysis_temporal.py +0 -0
  130. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_api.py +0 -0
  131. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_api_monitors.py +0 -0
  132. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_blockchain.py +0 -0
  133. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_config.py +0 -0
  134. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_crawler.py +0 -0
  135. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_db.py +0 -0
  136. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_dns_enrichment.py +0 -0
  137. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_domain_reputation.py +0 -0
  138. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_email_reputation.py +0 -0
  139. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_fingerprint.py +0 -0
  140. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_github_scraper.py +0 -0
  141. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_gitlab_scraper.py +0 -0
  142. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_graph.py +0 -0
  143. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_hash_reputation.py +0 -0
  144. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_i18n.py +0 -0
  145. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_ip_reputation.py +0 -0
  146. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_llm.py +0 -0
  147. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_llm_utils.py +0 -0
  148. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_model_singleton.py +0 -0
  149. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_monitor.py +0 -0
  150. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_pagination.py +0 -0
  151. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_paste_scraper.py +0 -0
  152. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_rss_scraper.py +0 -0
  153. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_scrape_js.py +0 -0
  154. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_settings.py +0 -0
  155. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_sources.py +0 -0
  156. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_sources_enrichment_new.py +0 -0
  157. {voidaccess-1.3.0 → voidaccess-1.4.2}/tests/test_vector.py +0 -0
  158. {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/__init__.py +0 -0
  159. {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/async_utils.py +0 -0
  160. {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/content_safety.py +0 -0
  161. {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/defang.py +0 -0
  162. {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/encryption.py +0 -0
  163. {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/ioc_freshness.py +0 -0
  164. {voidaccess-1.3.0 → voidaccess-1.4.2}/utils/user_keys.py +0 -0
  165. {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/__init__.py +0 -0
  166. {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/embedder.py +0 -0
  167. {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/model_singleton.py +0 -0
  168. {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/search.py +0 -0
  169. {voidaccess-1.3.0 → voidaccess-1.4.2}/vector/store.py +0 -0
  170. {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess/__init__.py +0 -0
  171. {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess/llm.py +0 -0
  172. {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess/llm_utils.py +0 -0
  173. {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/dependency_links.txt +0 -0
  174. {voidaccess-1.3.0 → voidaccess-1.4.2}/voidaccess.egg-info/requires.txt +0 -0
  175. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/adapters/__init__.py +0 -0
  176. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/adapters/sqlite.py +0 -0
  177. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/browser.py +0 -0
  178. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/commands/__init__.py +0 -0
  179. {voidaccess-1.3.0/cli → voidaccess-1.4.2/voidaccess_cli}/display.py +0 -0
@@ -1,14 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voidaccess
3
- Version: 1.3.0
3
+ Version: 1.4.2
4
4
  Summary: Dark web OSINT CLI — automated threat intelligence from query to report
5
5
  Author: VoidAccess
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Keywords: osint,darkweb,threat-intelligence,tor,cli
8
8
  Classifier: Development Status :: 4 - Beta
9
9
  Classifier: Environment :: Console
10
10
  Classifier: Intended Audience :: Information Technology
11
- Classifier: License :: OSI Approved :: MIT License
12
11
  Classifier: Operating System :: OS Independent
13
12
  Classifier: Programming Language :: Python :: 3
14
13
  Classifier: Programming Language :: Python :: 3.11
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "voidaccess"
7
- version = "1.3.0"
7
+ version = "1.4.2"
8
8
  description = "Dark web OSINT CLI — automated threat intelligence from query to report"
9
9
  readme = "README.md"
10
- license = { text = "MIT" }
10
+ license = "MIT"
11
11
  requires-python = ">=3.10"
12
12
  authors = [{ name = "VoidAccess" }]
13
13
  keywords = ["osint", "darkweb", "threat-intelligence", "tor", "cli"]
@@ -15,7 +15,6 @@ classifiers = [
15
15
  "Development Status :: 4 - Beta",
16
16
  "Environment :: Console",
17
17
  "Intended Audience :: Information Technology",
18
- "License :: OSI Approved :: MIT License",
19
18
  "Operating System :: OS Independent",
20
19
  "Programming Language :: Python :: 3",
21
20
  "Programming Language :: Python :: 3.11",
@@ -51,7 +50,7 @@ dependencies = [
51
50
  dev = ["pytest", "pytest-asyncio"]
52
51
 
53
52
  [project.scripts]
54
- voidaccess = "cli.main:app"
53
+ voidaccess = "voidaccess_cli.main:app"
55
54
 
56
55
  [tool.setuptools]
57
56
  py-modules = ["config"]
@@ -59,7 +58,7 @@ py-modules = ["config"]
59
58
  [tool.setuptools.packages.find]
60
59
  where = ["."]
61
60
  include = [
62
- "cli*",
61
+ "voidaccess_cli*",
63
62
  "db*",
64
63
  "sources*",
65
64
  "extractor*",
@@ -1,14 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voidaccess
3
- Version: 1.3.0
3
+ Version: 1.4.2
4
4
  Summary: Dark web OSINT CLI — automated threat intelligence from query to report
5
5
  Author: VoidAccess
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Keywords: osint,darkweb,threat-intelligence,tor,cli
8
8
  Classifier: Development Status :: 4 - Beta
9
9
  Classifier: Environment :: Console
10
10
  Classifier: Intended Audience :: Information Technology
11
- Classifier: License :: OSI Approved :: MIT License
12
11
  Classifier: Operating System :: OS Independent
13
12
  Classifier: Programming Language :: Python :: 3
14
13
  Classifier: Programming Language :: Python :: 3.11
@@ -20,20 +20,6 @@ api/routes/search.py
20
20
  api/routes/settings.py
21
21
  auth/__init__.py
22
22
  auth/token_blacklist.py
23
- cli/__init__.py
24
- cli/browser.py
25
- cli/config.py
26
- cli/display.py
27
- cli/main.py
28
- cli/tor_detect.py
29
- cli/adapters/__init__.py
30
- cli/adapters/sqlite.py
31
- cli/commands/__init__.py
32
- cli/commands/configure.py
33
- cli/commands/enrich.py
34
- cli/commands/export.py
35
- cli/commands/investigate.py
36
- cli/commands/show.py
37
23
  crawler/__init__.py
38
24
  crawler/dedup.py
39
25
  crawler/frontier.py
@@ -173,4 +159,18 @@ voidaccess.egg-info/SOURCES.txt
173
159
  voidaccess.egg-info/dependency_links.txt
174
160
  voidaccess.egg-info/entry_points.txt
175
161
  voidaccess.egg-info/requires.txt
176
- voidaccess.egg-info/top_level.txt
162
+ voidaccess.egg-info/top_level.txt
163
+ voidaccess_cli/__init__.py
164
+ voidaccess_cli/browser.py
165
+ voidaccess_cli/config.py
166
+ voidaccess_cli/display.py
167
+ voidaccess_cli/main.py
168
+ voidaccess_cli/tor_detect.py
169
+ voidaccess_cli/adapters/__init__.py
170
+ voidaccess_cli/adapters/sqlite.py
171
+ voidaccess_cli/commands/__init__.py
172
+ voidaccess_cli/commands/configure.py
173
+ voidaccess_cli/commands/enrich.py
174
+ voidaccess_cli/commands/export.py
175
+ voidaccess_cli/commands/investigate.py
176
+ voidaccess_cli/commands/show.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ voidaccess = voidaccess_cli.main:app
@@ -1,7 +1,6 @@
1
1
  analysis
2
2
  api
3
3
  auth
4
- cli
5
4
  config
6
5
  crawler
7
6
  db
@@ -17,3 +16,4 @@ sources
17
16
  utils
18
17
  vector
19
18
  voidaccess
19
+ voidaccess_cli
@@ -1,3 +1,3 @@
1
1
  """voidaccess CLI — dark-web OSINT command-line interface."""
2
2
 
3
- __version__ = "1.3.0"
3
+ __version__ = "1.4.1"
@@ -15,7 +15,7 @@ from rich.console import Console
15
15
  from rich.prompt import Prompt, Confirm
16
16
  from rich.table import Table
17
17
 
18
- from cli import config as cli_config
18
+ from voidaccess_cli import config as cli_config
19
19
 
20
20
  app = typer.Typer(help="Configure the voidaccess CLI.", no_args_is_help=False, invoke_without_command=True)
21
21
  console = Console()
@@ -30,7 +30,7 @@ def run(
30
30
  skip_emails: bool = typer.Option(False, "--skip-emails"),
31
31
  ) -> None:
32
32
  """Re-enrich entities for an existing investigation."""
33
- from cli import config as cli_config
33
+ from voidaccess_cli import config as cli_config
34
34
  cli_config.apply_env()
35
35
 
36
36
  inv_id = _resolve_investigation_id(target)
@@ -50,7 +50,7 @@ def _resolve_investigation_id(target: str) -> Optional[str]:
50
50
  except Exception:
51
51
  return None
52
52
  return data.get("investigation", {}).get("id") or data.get("id")
53
- from cli.adapters import sqlite as sqlite_adapter
53
+ from voidaccess_cli.adapters import sqlite as sqlite_adapter
54
54
  sqlite_adapter.init_db()
55
55
  resolved = sqlite_adapter.resolve_investigation_id(target) or target
56
56
  row = sqlite_adapter.get_investigation(resolved)
@@ -89,7 +89,7 @@ _TYPE_MAP = {
89
89
 
90
90
  def _load_extraction_results(investigation_id: str) -> list:
91
91
  """Reconstruct ExtractionResult-shaped objects from the DB."""
92
- from cli.adapters import sqlite as sqlite_adapter
92
+ from voidaccess_cli.adapters import sqlite as sqlite_adapter
93
93
  rows = sqlite_adapter.get_entities(investigation_id)
94
94
  fakes = []
95
95
  for r in rows:
@@ -25,7 +25,7 @@ def run(
25
25
  output: Optional[Path] = typer.Option(None, "--output", help="Output file"),
26
26
  ) -> None:
27
27
  """Export an investigation."""
28
- from cli import config as cli_config
28
+ from voidaccess_cli import config as cli_config
29
29
  cli_config.apply_env()
30
30
 
31
31
  fmt = fmt.lower()
@@ -39,7 +39,7 @@ def run(
39
39
  raise typer.Exit(code=1)
40
40
 
41
41
  payload, suffix = _render(fmt, inv_id, data)
42
- out_path = output or _default_out_path(target, suffix)
42
+ out_path = output or _default_out_path(target, suffix, fmt=fmt)
43
43
  out_path = Path(out_path).expanduser()
44
44
  out_path.parent.mkdir(parents=True, exist_ok=True)
45
45
  if isinstance(payload, bytes):
@@ -58,7 +58,7 @@ def _load_target(target: str) -> tuple[Optional[str], Optional[dict]]:
58
58
  return None, None
59
59
  inv_id = data.get("investigation", {}).get("id") or data.get("id")
60
60
  return inv_id, data
61
- from cli.adapters import sqlite as sqlite_adapter
61
+ from voidaccess_cli.adapters import sqlite as sqlite_adapter
62
62
  sqlite_adapter.init_db()
63
63
  resolved = sqlite_adapter.resolve_investigation_id(target) or target
64
64
  data = sqlite_adapter.investigation_to_export_dict(resolved)
@@ -75,7 +75,7 @@ def _render(fmt: str, inv_id: Optional[str], data: dict) -> tuple[str | bytes, s
75
75
  return _csv_from_data(data), ".csv"
76
76
 
77
77
  if fmt == "md":
78
- from cli.commands.investigate import _render_markdown # reuse renderer
78
+ from voidaccess_cli.commands.investigate import _render_markdown # reuse renderer
79
79
  # Adapt shape: _render_markdown expects flat payload
80
80
  flat = _flatten_for_md(data)
81
81
  return _render_markdown(flat), ".md"
@@ -150,9 +150,13 @@ def _flatten_for_md(data: dict) -> dict:
150
150
  return data
151
151
 
152
152
 
153
- def _default_out_path(target: str, suffix: str) -> Path:
153
+ def _default_out_path(target: str, suffix: str, fmt: str = "") -> Path:
154
154
  p = Path(target).expanduser()
155
155
  if p.exists():
156
- return p.with_suffix(suffix)
157
- from cli import config as cli_config
156
+ candidate = p.with_suffix(suffix)
157
+ # Avoid overwriting input when suffix is the same (e.g. stix/misp .json)
158
+ if candidate == p and fmt and fmt not in ("json",):
159
+ return p.parent / f"{p.stem}-{fmt}{suffix}"
160
+ return candidate
161
+ from voidaccess_cli import config as cli_config
158
162
  return cli_config.get_output_dir() / f"{target}{suffix}"
@@ -46,12 +46,31 @@ def run(
46
46
  quiet: bool = typer.Option(False, "--quiet", help="No live display; print final summary only"),
47
47
  ) -> None:
48
48
  """Run an investigation: query → search → scrape → extract → enrich → report."""
49
- from cli import config as cli_config
49
+ from voidaccess_cli import config as cli_config
50
50
 
51
51
  cli_config.apply_env()
52
+
53
+ try:
54
+ import spacy
55
+ spacy.load("en_core_web_sm")
56
+ except Exception:
57
+ import subprocess, sys
58
+ from rich.console import Console
59
+ Console().print(" [dim]→[/dim] Installing spaCy NER model (one-time)...")
60
+ subprocess.run(
61
+ [sys.executable, "-m", "spacy", "download", "en_core_web_sm"],
62
+ capture_output=True,
63
+ )
64
+
52
65
  if quiet:
53
66
  logging.getLogger().setLevel(logging.ERROR)
54
67
 
68
+ from utils.content_safety import is_blocked_query
69
+ blocked, reason = is_blocked_query(query)
70
+ if blocked:
71
+ console.print(f"[red]Query blocked:[/red] {reason}")
72
+ raise typer.Exit(code=1)
73
+
55
74
  if not cli_config.is_configured() and not no_llm:
56
75
  console.print("[yellow]No LLM configured.[/yellow] Run [bold]voidaccess configure[/bold] first, or pass --no-llm.")
57
76
  raise typer.Exit(code=2)
@@ -106,10 +125,10 @@ async def _run_investigation(
106
125
  fmt: str,
107
126
  quiet: bool,
108
127
  ) -> None:
109
- from cli import config as cli_config
110
- from cli.adapters import sqlite as sqlite_adapter
111
- from cli.display import InvestigationDisplay
112
- from cli.tor_detect import detect_tor, tor_unavailable_message
128
+ from voidaccess_cli import config as cli_config
129
+ from voidaccess_cli.adapters import sqlite as sqlite_adapter
130
+ from voidaccess_cli.display import InvestigationDisplay
131
+ from voidaccess_cli.tor_detect import detect_tor, tor_unavailable_message
113
132
 
114
133
  cfg = cli_config.load_config()
115
134
  preset = DEPTH_PRESETS[depth]
@@ -382,6 +401,7 @@ async def _run_investigation(
382
401
  "query": query,
383
402
  "refined_query": refined,
384
403
  "model_used": chosen_model if llm is not None else None,
404
+ "status": "completed" if final_entities or scraped_pages else "completed_no_results",
385
405
  "created_at": datetime.now(timezone.utc).isoformat(),
386
406
  "summary": summary_text,
387
407
  "sources_used": sources_used,
@@ -500,7 +520,7 @@ def _build_cooccurrence_edges(investigation_id: str) -> int:
500
520
  from db.session import get_session
501
521
  except Exception:
502
522
  return 0
503
- from cli.adapters.sqlite import save_relationships
523
+ from voidaccess_cli.adapters.sqlite import save_relationships
504
524
 
505
525
  edges: list[dict] = []
506
526
  inv_uuid = uuid.UUID(investigation_id)
@@ -24,14 +24,18 @@ def run(
24
24
  target: Optional[str] = typer.Argument(
25
25
  None, help="Investigation id or path to a .json export"
26
26
  ),
27
+ no_tui: bool = typer.Option(False, "--no-tui", help="Print summary table without launching TUI (for scripted use)."),
27
28
  ) -> None:
28
29
  """Open the entity browser TUI."""
29
- from cli import config as cli_config
30
+ from voidaccess_cli import config as cli_config
30
31
  cli_config.apply_env()
31
32
 
32
33
  data: Optional[dict] = None
33
34
 
34
35
  if target is None:
36
+ if no_tui:
37
+ console.print("[yellow]No target specified.[/yellow]")
38
+ raise typer.Exit(code=1)
35
39
  target = _pick_recent()
36
40
  if target is None:
37
41
  console.print("[yellow]No investigations found. Run `voidaccess investigate` first.[/yellow]")
@@ -41,7 +45,7 @@ def run(
41
45
  if candidate_path.exists() and candidate_path.suffix == ".json":
42
46
  data = json.loads(candidate_path.read_text(encoding="utf-8"))
43
47
  else:
44
- from cli.adapters import sqlite as sqlite_adapter
48
+ from voidaccess_cli.adapters import sqlite as sqlite_adapter
45
49
  sqlite_adapter.init_db()
46
50
  resolved = sqlite_adapter.resolve_investigation_id(target) or target
47
51
  data = sqlite_adapter.investigation_to_export_dict(resolved)
@@ -49,13 +53,31 @@ def run(
49
53
  console.print(f"[red]Unknown investigation:[/red] {target}")
50
54
  raise typer.Exit(code=1)
51
55
 
52
- from cli.browser import EntityBrowserApp
56
+ if no_tui:
57
+ _print_summary(data)
58
+ return
59
+
60
+ from voidaccess_cli.browser import EntityBrowserApp
53
61
  app = EntityBrowserApp(data=data)
54
62
  app.run()
55
63
 
56
64
 
65
+ def _print_summary(data: dict) -> None:
66
+ inv = data.get("investigation") or data
67
+ entities = data.get("entities", [])
68
+ table = Table(title="Investigation summary")
69
+ table.add_column("Field", style="bold")
70
+ table.add_column("Value")
71
+ table.add_row("Query", str(inv.get("query") or ""))
72
+ table.add_row("Status", str(inv.get("status") or ""))
73
+ table.add_row("Entities", str(len(entities)))
74
+ table.add_row("Created", str(inv.get("created_at") or "")[:19])
75
+ table.add_row("Summary", (str(inv.get("summary") or "—"))[:120])
76
+ console.print(table)
77
+
78
+
57
79
  def _pick_recent() -> Optional[str]:
58
- from cli.adapters import sqlite as sqlite_adapter
80
+ from voidaccess_cli.adapters import sqlite as sqlite_adapter
59
81
  sqlite_adapter.init_db()
60
82
  rows = sqlite_adapter.list_investigations(limit=20)
61
83
  if not rows:
@@ -178,3 +178,9 @@ def apply_env(config: Optional[dict[str, Any]] = None) -> None:
178
178
  # Enrichment keys
179
179
  for k, v in (cfg.get("enrichment_keys") or {}).items():
180
180
  _set_env_if_present(k, v, clear_if_empty=True)
181
+
182
+ # Keyless APIs (ThreatFox/URLhaus/MalwareBazaar/abuse.ch) must never
183
+ # receive an empty auth header — clear any empty env remnant.
184
+ for key in ("ABUSECH_API_KEY", "VT_API_KEY", "OTX_API_KEY"):
185
+ if not os.environ.get(key):
186
+ os.environ.pop(key, None)
@@ -2,7 +2,7 @@
2
2
  cli/main.py — typer entry point exposed as the `voidaccess` script.
3
3
 
4
4
  Defined as the [project.scripts] target in pyproject.toml:
5
- voidaccess = "cli.main:app"
5
+ voidaccess = "voidaccess_cli.main:app"
6
6
  """
7
7
 
8
8
  from __future__ import annotations
@@ -14,6 +14,7 @@ import sys
14
14
  # Force UTF-8 on Windows consoles so rich glyphs render reliably
15
15
  if sys.platform == "win32":
16
16
  os.environ.setdefault("PYTHONIOENCODING", "utf-8")
17
+ os.environ.setdefault("PYTHONUTF8", "1")
17
18
  try:
18
19
  sys.stdout.reconfigure(encoding="utf-8") # type: ignore[attr-defined]
19
20
  sys.stderr.reconfigure(encoding="utf-8") # type: ignore[attr-defined]
@@ -21,14 +22,28 @@ if sys.platform == "win32":
21
22
  pass
22
23
 
23
24
  import typer
25
+ from rich.align import Align
24
26
  from rich.console import Console
25
27
  from rich.table import Table
26
28
 
27
- from cli import __version__
28
- from cli import config as cli_config
29
- from cli.commands import configure, enrich, export, investigate, show
29
+ from voidaccess_cli import __version__
30
+ from voidaccess_cli import config as cli_config
31
+ from voidaccess_cli.commands import configure, enrich, export, investigate, show
30
32
 
31
33
  console = Console()
34
+ BANNER = """\
35
+ [color(183)] ░░░░░[color(141)]█[color(183)]░░░░░[/]
36
+ [color(183)] ░░[color(141)]█████████████[color(183)]░░[/]
37
+ [color(183)] ░[color(141)]█████████████████[color(183)]░[/]
38
+ [color(183)]░[color(141)]███████████████████[color(183)]░[/]
39
+ [color(183)]░[color(141)]███████████████████[color(183)]░[/]
40
+ [color(141)]██████[/] [bright_white]void[/] [color(141)]███████[/]
41
+ [color(183)]░[color(141)]███████████████████[color(183)]░[/]
42
+ [color(183)]░[color(141)]███████████████████[color(183)]░[/]
43
+ [color(183)] ░[color(141)]█████████████████[color(183)]░[/]
44
+ [color(183)] ░░[color(141)]█████████████[color(183)]░░[/]
45
+ [color(183)] ░░░░░[color(141)]█[color(183)]░░░░░[/]
46
+ [dim white] dark web osint intelligence[/dim white]"""
32
47
 
33
48
  app = typer.Typer(
34
49
  name="voidaccess",
@@ -63,7 +78,7 @@ def _ensure_first_run() -> None:
63
78
  @app.command("status")
64
79
  def status() -> None:
65
80
  """Show current config, Tor status, and detected API keys."""
66
- from cli.tor_detect import detect_tor
81
+ from voidaccess_cli.tor_detect import detect_tor
67
82
  cli_config.apply_env()
68
83
  cfg = cli_config.load_config()
69
84
 
@@ -112,7 +127,7 @@ def list_investigations(
112
127
  ) -> None:
113
128
  """List saved investigations."""
114
129
  cli_config.apply_env()
115
- from cli.adapters import sqlite as sqlite_adapter
130
+ from voidaccess_cli.adapters import sqlite as sqlite_adapter
116
131
  sqlite_adapter.init_db()
117
132
  rows = sqlite_adapter.list_investigations(limit=limit)
118
133
  if as_json:
@@ -144,10 +159,32 @@ def version() -> None:
144
159
  console.print(f"voidaccess {__version__}")
145
160
 
146
161
 
147
- @app.callback()
148
- def _global(ctx: typer.Context) -> None:
149
- """Set env vars before sub-commands import voidaccess modules."""
162
+ def show_banner(console: Console) -> None:
163
+ import shutil
164
+ if os.environ.get("TERM") == "dumb":
165
+ return
166
+ if not sys.stdout.isatty() and "PS1" not in os.environ and os.name != "nt":
167
+ return
168
+ console.print()
169
+ raw_line = " oooooXooooo " # widest line, 21 chars
170
+ pad = max(0, (console.width - len(raw_line)) // 2)
171
+ for line in BANNER.split("\n"):
172
+ console.print(" " * pad + line)
173
+ console.print()
174
+
175
+
176
+ @app.callback(invoke_without_command=True)
177
+ def main(
178
+ ctx: typer.Context,
179
+ no_banner: bool = typer.Option(
180
+ False, "--no-banner",
181
+ help="Skip banner"
182
+ ),
183
+ ) -> None:
184
+ """Set env vars and render banner before command execution."""
150
185
  cli_config.apply_env()
186
+ if not no_banner and ctx.invoked_subcommand:
187
+ show_banner(console)
151
188
 
152
189
 
153
190
  if __name__ == "__main__":
@@ -17,7 +17,7 @@ import struct
17
17
  from dataclasses import dataclass
18
18
  from typing import Optional
19
19
 
20
- from cli.config import load_config
20
+ from voidaccess_cli.config import load_config
21
21
 
22
22
 
23
23
  @dataclass
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- voidaccess = cli.main:app
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes