bmad-plus 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/LICENSE +21 -21
  3. package/README.md +106 -86
  4. package/osint-agent-package/README.md +88 -88
  5. package/osint-agent-package/SETUP_KEYS.md +108 -108
  6. package/osint-agent-package/agents/osint-investigator.md +80 -80
  7. package/osint-agent-package/install.ps1 +87 -87
  8. package/osint-agent-package/install.sh +76 -76
  9. package/osint-agent-package/skills/bmad-osint-investigate/SKILL.md +147 -147
  10. package/osint-agent-package/skills/bmad-osint-investigate/osint/references/enrichment-databases-fr.md +148 -148
  11. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/_http.py +101 -101
  12. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/apify.py +266 -266
  13. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/brightdata.py +101 -101
  14. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/diagnose.py +141 -141
  15. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/exa.py +79 -79
  16. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/jina.py +71 -71
  17. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/parallel.py +85 -85
  18. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/perplexity.py +102 -102
  19. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/tavily.py +72 -72
  20. package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/volley.py +208 -208
  21. package/osint-agent-package/skills/bmad-osint-investigator/SKILL.md +15 -15
  22. package/package.json +30 -3
  23. package/readme-international/README.de.md +8 -3
  24. package/readme-international/README.es.md +8 -3
  25. package/readme-international/README.fr.md +8 -3
  26. package/src/bmad-plus/agents/agent-architect-dev/SKILL.md +96 -96
  27. package/src/bmad-plus/agents/agent-architect-dev/bmad-skill-manifest.yaml +13 -13
  28. package/src/bmad-plus/agents/agent-maker/SKILL.md +201 -201
  29. package/src/bmad-plus/agents/agent-maker/bmad-skill-manifest.yaml +13 -13
  30. package/src/bmad-plus/agents/agent-orchestrator/SKILL.md +137 -137
  31. package/src/bmad-plus/agents/agent-orchestrator/bmad-skill-manifest.yaml +13 -13
  32. package/src/bmad-plus/agents/agent-quality/SKILL.md +83 -83
  33. package/src/bmad-plus/agents/agent-quality/bmad-skill-manifest.yaml +13 -13
  34. package/src/bmad-plus/agents/agent-shadow/SKILL.md +71 -71
  35. package/src/bmad-plus/agents/agent-shadow/bmad-skill-manifest.yaml +13 -13
  36. package/src/bmad-plus/agents/agent-strategist/SKILL.md +80 -80
  37. package/src/bmad-plus/agents/agent-strategist/bmad-skill-manifest.yaml +13 -13
  38. package/src/bmad-plus/data/role-triggers.yaml +209 -209
  39. package/src/bmad-plus/module-help.csv +10 -10
  40. package/src/bmad-plus/packs/pack-memory/README.md +106 -106
  41. package/src/bmad-plus/packs/pack-memory/memory-orchestrator.md +79 -79
  42. package/src/bmad-plus/packs/pack-memory/shared/karpathy-guardrails.md +86 -86
  43. package/src/bmad-plus/packs/pack-memory/shared/memory-protocol.md +143 -143
  44. package/src/bmad-plus/packs/pack-memory/templates/context.md +39 -39
  45. package/src/bmad-plus/packs/pack-memory/templates/decisions.md +25 -25
  46. package/src/bmad-plus/packs/pack-memory/templates/identity.yaml +39 -39
  47. package/src/bmad-plus/packs/pack-memory/templates/lessons.md +31 -31
  48. package/src/bmad-plus/packs/pack-memory/templates/patterns.md +24 -24
  49. package/src/bmad-plus/packs/pack-memory/templates/session-handoff.md +25 -25
  50. package/src/bmad-plus/packs/pack-memory/zecher-agent.md +157 -157
  51. package/src/bmad-plus/packs/pack-seo/bmad-skill-manifest.yaml +13 -13
  52. package/src/bmad-plus/packs/pack-shield/README.md +110 -110
  53. package/src/bmad-plus/packs/pack-shield/SKILL.md +82 -82
  54. package/src/bmad-plus/packs/pack-shield/categories/accessibility-esg/csrd-agent.md +251 -251
  55. package/src/bmad-plus/packs/pack-shield/categories/accessibility-esg/section508-agent.md +168 -168
  56. package/src/bmad-plus/packs/pack-shield/categories/accessibility-esg/wcag-agent.md +190 -190
  57. package/src/bmad-plus/packs/pack-shield/categories/ai-governance/eu-ai-act-agent.md +86 -86
  58. package/src/bmad-plus/packs/pack-shield/categories/ai-governance/iso42001-agent.md +240 -240
  59. package/src/bmad-plus/packs/pack-shield/categories/ai-governance/nist-ai-rmf-agent.md +122 -122
  60. package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/cis-controls-agent.md +210 -210
  61. package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/ism-agent.md +139 -139
  62. package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/iso27001-agent.md +156 -156
  63. package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/nis2-agent.md +72 -72
  64. package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/nist-800-53-agent.md +239 -239
  65. package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/nist-csf-agent.md +207 -207
  66. package/src/bmad-plus/packs/pack-shield/categories/data-privacy/ccpa-agent.md +94 -94
  67. package/src/bmad-plus/packs/pack-shield/categories/data-privacy/dpdpa-agent.md +136 -136
  68. package/src/bmad-plus/packs/pack-shield/categories/data-privacy/gdpr-agent.md +296 -296
  69. package/src/bmad-plus/packs/pack-shield/categories/data-privacy/iso27701-agent.md +134 -134
  70. package/src/bmad-plus/packs/pack-shield/categories/data-privacy/lgpd-agent.md +129 -129
  71. package/src/bmad-plus/packs/pack-shield/categories/defense-export/cmmc-agent.md +116 -116
  72. package/src/bmad-plus/packs/pack-shield/categories/defense-export/ear-agent.md +261 -261
  73. package/src/bmad-plus/packs/pack-shield/categories/defense-export/itar-agent.md +191 -191
  74. package/src/bmad-plus/packs/pack-shield/categories/defense-export/tsa-agent.md +356 -356
  75. package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/dora-agent.md +499 -499
  76. package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/fedramp-agent.md +236 -236
  77. package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/hipaa-agent.md +162 -162
  78. package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/pci-dss-agent.md +228 -228
  79. package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/soc2-agent.md +255 -255
  80. package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/swift-csp-agent.md +153 -153
  81. package/src/bmad-plus/packs/pack-shield/categories/workflows/ai-act-classifier.md +131 -131
  82. package/src/bmad-plus/packs/pack-shield/categories/workflows/ai-act-fria.md +155 -155
  83. package/src/bmad-plus/packs/pack-shield/categories/workflows/ai-act-incidents.md +187 -187
  84. package/src/bmad-plus/packs/pack-shield/categories/workflows/ai-act-roles.md +113 -113
  85. package/src/bmad-plus/packs/pack-shield/categories/workflows/breach-sentinel.md +197 -197
  86. package/src/bmad-plus/packs/pack-shield/categories/workflows/cookie-policy-gen.md +180 -180
  87. package/src/bmad-plus/packs/pack-shield/categories/workflows/dpia-sentinel.md +235 -235
  88. package/src/bmad-plus/packs/pack-shield/categories/workflows/legitimate-interest.md +159 -159
  89. package/src/bmad-plus/packs/pack-shield/categories/workflows/privacy-advisor.md +133 -133
  90. package/src/bmad-plus/packs/pack-shield/categories/workflows/privacy-notice-gen.md +160 -160
  91. package/src/bmad-plus/packs/pack-shield/categories/workflows/privacy-policy-gen.md +135 -135
  92. package/src/bmad-plus/packs/pack-shield/references/ccpa/ccpa-gdpr-comparison.md +117 -117
  93. package/src/bmad-plus/packs/pack-shield/references/ccpa/consumer-rights-workflows.md +177 -177
  94. package/src/bmad-plus/packs/pack-shield/references/cis-controls/framework-mappings.md +162 -162
  95. package/src/bmad-plus/packs/pack-shield/references/cis-controls/implementation-guidance.md +235 -235
  96. package/src/bmad-plus/packs/pack-shield/references/cis-controls/safeguards-detail.md +252 -252
  97. package/src/bmad-plus/packs/pack-shield/references/cmmc/cmmc-assessment.md +170 -170
  98. package/src/bmad-plus/packs/pack-shield/references/cmmc/cmmc-levels.md +113 -113
  99. package/src/bmad-plus/packs/pack-shield/references/cmmc/cmmc-practices.md +211 -211
  100. package/src/bmad-plus/packs/pack-shield/references/csrd/compliance-program.md +281 -281
  101. package/src/bmad-plus/packs/pack-shield/references/csrd/double-materiality.md +253 -253
  102. package/src/bmad-plus/packs/pack-shield/references/csrd/esrs-standards.md +401 -401
  103. package/src/bmad-plus/packs/pack-shield/references/dora/article-reference.md +441 -441
  104. package/src/bmad-plus/packs/pack-shield/references/dora/incident-classification.md +297 -297
  105. package/src/bmad-plus/packs/pack-shield/references/dora/rts-its-guide.md +306 -306
  106. package/src/bmad-plus/packs/pack-shield/references/dora/third-party-risk.md +349 -349
  107. package/src/bmad-plus/packs/pack-shield/references/dpdpa/gdpr-comparison.md +173 -173
  108. package/src/bmad-plus/packs/pack-shield/references/dpdpa/rights-and-obligations.md +426 -426
  109. package/src/bmad-plus/packs/pack-shield/references/dpdpa/rules-2025.md +599 -599
  110. package/src/bmad-plus/packs/pack-shield/references/dpdpa/sections-reference.md +319 -319
  111. package/src/bmad-plus/packs/pack-shield/references/ear/ccl-eccn-guide.md +250 -250
  112. package/src/bmad-plus/packs/pack-shield/references/ear/compliance-program.md +280 -280
  113. package/src/bmad-plus/packs/pack-shield/references/ear/license-exceptions.md +207 -207
  114. package/src/bmad-plus/packs/pack-shield/references/eu-ai-act/gpai-governance.md +267 -267
  115. package/src/bmad-plus/packs/pack-shield/references/eu-ai-act/obligations-high-risk.md +287 -287
  116. package/src/bmad-plus/packs/pack-shield/references/eu-ai-act/risk-classification.md +182 -182
  117. package/src/bmad-plus/packs/pack-shield/references/fedramp/appendices-guide.md +209 -209
  118. package/src/bmad-plus/packs/pack-shield/references/fedramp/control-families.md +281 -281
  119. package/src/bmad-plus/packs/pack-shield/references/fedramp/poam-guide.md +93 -93
  120. package/src/bmad-plus/packs/pack-shield/references/fedramp/readiness-checklist.md +134 -134
  121. package/src/bmad-plus/packs/pack-shield/references/fedramp/sap-sar-guide.md +86 -86
  122. package/src/bmad-plus/packs/pack-shield/references/fedramp/ssp-guide.md +129 -129
  123. package/src/bmad-plus/packs/pack-shield/references/gdpr-compliance/documents.md +192 -192
  124. package/src/bmad-plus/packs/pack-shield/references/gdpr-compliance/dpa-template.md +121 -121
  125. package/src/bmad-plus/packs/pack-shield/references/gdpr-compliance/privacy-notice.md +87 -87
  126. package/src/bmad-plus/packs/pack-shield/references/hipaa-compliance/breach-notification.md +293 -293
  127. package/src/bmad-plus/packs/pack-shield/references/hipaa-compliance/privacy-rule.md +276 -276
  128. package/src/bmad-plus/packs/pack-shield/references/hipaa-compliance/security-rule.md +299 -299
  129. package/src/bmad-plus/packs/pack-shield/references/hipaa-compliance/templates.md +568 -568
  130. package/src/bmad-plus/packs/pack-shield/references/ism/control-applicability.md +181 -181
  131. package/src/bmad-plus/packs/pack-shield/references/ism/guidelines-overview.md +183 -183
  132. package/src/bmad-plus/packs/pack-shield/references/iso27001/annex-a-2013.md +203 -203
  133. package/src/bmad-plus/packs/pack-shield/references/iso27001/annex-a-2022.md +132 -132
  134. package/src/bmad-plus/packs/pack-shield/references/iso27001/control-mapping.md +153 -153
  135. package/src/bmad-plus/packs/pack-shield/references/iso27701/annex-a-controls.md +195 -195
  136. package/src/bmad-plus/packs/pack-shield/references/iso27701/regulatory-mapping.md +229 -229
  137. package/src/bmad-plus/packs/pack-shield/references/iso27701/transition-guide.md +219 -219
  138. package/src/bmad-plus/packs/pack-shield/references/iso42001/iso42001-ai-risk-assessment.md +258 -258
  139. package/src/bmad-plus/packs/pack-shield/references/iso42001/iso42001-clauses-requirements.md +279 -279
  140. package/src/bmad-plus/packs/pack-shield/references/iso42001/iso42001-controls-annex-a.md +155 -155
  141. package/src/bmad-plus/packs/pack-shield/references/itar/compliance-program.md +174 -174
  142. package/src/bmad-plus/packs/pack-shield/references/itar/licensing-guide.md +146 -146
  143. package/src/bmad-plus/packs/pack-shield/references/itar/usml-categories.md +93 -93
  144. package/src/bmad-plus/packs/pack-shield/references/lgpd/anpd-enforcement.md +147 -147
  145. package/src/bmad-plus/packs/pack-shield/references/lgpd/compliance-program.md +272 -272
  146. package/src/bmad-plus/packs/pack-shield/references/lgpd/lgpd-articles.md +271 -271
  147. package/src/bmad-plus/packs/pack-shield/references/nis2/article-21-measures.md +153 -153
  148. package/src/bmad-plus/packs/pack-shield/references/nis2/iso27001-nis2-mapping.md +68 -68
  149. package/src/bmad-plus/packs/pack-shield/references/nist-800-53/assessment-rmf.md +349 -349
  150. package/src/bmad-plus/packs/pack-shield/references/nist-800-53/baselines-tailoring.md +277 -277
  151. package/src/bmad-plus/packs/pack-shield/references/nist-800-53/control-families.md +450 -450
  152. package/src/bmad-plus/packs/pack-shield/references/nist-ai-rmf/rmf-core.md +361 -361
  153. package/src/bmad-plus/packs/pack-shield/references/nist-ai-rmf/rmf-profiles.md +192 -192
  154. package/src/bmad-plus/packs/pack-shield/references/nist-csf/csf-10-to-20-mapping.md +143 -143
  155. package/src/bmad-plus/packs/pack-shield/references/nist-csf/csf-20-functions-categories.md +278 -278
  156. package/src/bmad-plus/packs/pack-shield/references/nist-csf/csf-implementation-tiers.md +135 -135
  157. package/src/bmad-plus/packs/pack-shield/references/pci-compliance/pci-dss-requirements.md +366 -366
  158. package/src/bmad-plus/packs/pack-shield/references/pci-compliance/pci-dss-saq-guide.md +217 -217
  159. package/src/bmad-plus/packs/pack-shield/references/pci-compliance/pci-dss-v4-changes.md +190 -190
  160. package/src/bmad-plus/packs/pack-shield/references/section-508/wcag-mapping.md +160 -160
  161. package/src/bmad-plus/packs/pack-shield/references/soc2/controls.md +241 -241
  162. package/src/bmad-plus/packs/pack-shield/references/soc2/evidence.md +236 -236
  163. package/src/bmad-plus/packs/pack-shield/references/soc2/policies.md +254 -254
  164. package/src/bmad-plus/packs/pack-shield/references/soc2/vendor.md +276 -276
  165. package/src/bmad-plus/packs/pack-shield/references/swift-csp/swift-assessment.md +202 -202
  166. package/src/bmad-plus/packs/pack-shield/references/swift-csp/swift-controls.md +545 -545
  167. package/src/bmad-plus/packs/pack-shield/references/tsa-compliance/tsa-crmp-requirements.md +359 -359
  168. package/src/bmad-plus/packs/pack-shield/references/tsa-compliance/tsa-directives-overview.md +187 -187
  169. package/src/bmad-plus/packs/pack-shield/references/tsa-compliance/tsa-incident-reporting.md +187 -187
  170. package/src/bmad-plus/packs/pack-shield/references/wcag/criteria-detail.md +510 -510
  171. package/src/bmad-plus/packs/pack-shield/shared/audit-report-template.md +103 -103
  172. package/src/bmad-plus/packs/pack-shield/shared/cross-framework-mapper.md +103 -103
  173. package/src/bmad-plus/packs/pack-shield/shared/gap-analysis-template.md +83 -83
  174. package/src/bmad-plus/packs/pack-shield/shield-orchestrator.md +229 -229
  175. package/src/bmad-plus/packs/pack-shield/upstream-sync.yaml +68 -68
  176. package/src/bmad-plus/skills/bmad-plus-autopilot/SKILL.md +99 -99
  177. package/src/bmad-plus/skills/bmad-plus-parallel/SKILL.md +93 -93
  178. package/src/bmad-plus/skills/bmad-plus-sync/SKILL.md +69 -69
  179. package/tools/cli/bmad-plus-cli.js +5 -3
  180. package/tools/cli/commands/autoconfig.js +23 -59
  181. package/tools/cli/commands/doctor.js +14 -0
  182. package/tools/cli/commands/install.js +29 -128
  183. package/tools/cli/commands/memory.js +1 -0
  184. package/tools/cli/commands/scan.js +44 -42
  185. package/tools/cli/commands/uninstall.js +10 -5
  186. package/tools/cli/commands/update.js +21 -3
  187. package/tools/cli/lib/ide-config.js +259 -0
  188. package/tools/cli/lib/memory-init.js +0 -1
  189. package/tools/cli/lib/pack-copy.js +84 -84
  190. package/tools/cli/lib/packs.js +16 -8
  191. package/tools/cli/lib/stack-detect.js +102 -0
  192. package/tools/cli/lib/validate.js +50 -0
@@ -1,101 +1,101 @@
1
- #!/usr/bin/env python3
2
- """Bright Data MCP wrapper — scrape, search, search-geo, search-yandex. Stdlib only.
3
-
4
- Uses mcp-client.py for MCP JSON-RPC calls.
5
- """
6
-
7
- import json
8
- import os
9
- import subprocess
10
- import sys
11
-
12
- sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
13
- from _http import get_key, get_workspace
14
-
15
-
16
- def init():
17
- workspace, _, _ = get_workspace()
18
- return get_key("BRIGHTDATA_MCP_URL",
19
- file_fallback=os.path.join(workspace, "scripts", "brightdata-mcp-url.txt"),
20
- help_url="https://brightdata.com/products/web-scraper/mcp")
21
-
22
-
23
- def mcp_call(mcp_url, tool_name, arguments):
24
- """Call MCP tool via mcp-client.py."""
25
- scripts_dir = os.path.dirname(os.path.abspath(__file__))
26
- mcp_client = os.path.join(scripts_dir, "mcp-client.py")
27
- args_json = json.dumps(arguments)
28
- result = subprocess.run(
29
- [sys.executable, mcp_client, mcp_url, tool_name, args_json],
30
- capture_output=True, text=True, timeout=120
31
- )
32
- if result.stdout:
33
- print(result.stdout)
34
- if result.stderr:
35
- print(result.stderr, file=sys.stderr)
36
- return result.returncode
37
-
38
-
39
- def list_tools(mcp_url):
40
- """List available MCP tools."""
41
- scripts_dir = os.path.dirname(os.path.abspath(__file__))
42
- mcp_client = os.path.join(scripts_dir, "mcp-client.py")
43
- result = subprocess.run(
44
- [sys.executable, mcp_client, mcp_url, "--list-tools"],
45
- capture_output=True, text=True, timeout=30
46
- )
47
- if result.stdout:
48
- print(result.stdout)
49
- if result.stderr:
50
- print(result.stderr, file=sys.stderr)
51
-
52
-
53
- def main():
54
- if len(sys.argv) < 2:
55
- print("Usage: brightdata.py {tools|scrape|scrape-batch|search|search-geo|search-yandex} <args>")
56
- print()
57
- print(" tools - list available MCP tools")
58
- print(" scrape <url> - any URL → markdown (bypasses CAPTCHA)")
59
- print(" scrape-batch <url1> <url2> - batch scrape up to 10 URLs")
60
- print(" search <query> - Google search via Bright Data")
61
- print(" search-geo <cc> <query> - geo-targeted search")
62
- print(" search-yandex <query> - Yandex search")
63
- sys.exit(1)
64
-
65
- mcp_url = init()
66
- cmd = sys.argv[1]
67
-
68
- if cmd == "tools":
69
- list_tools(mcp_url)
70
- elif cmd == "scrape":
71
- url = sys.argv[2] if len(sys.argv) > 2 else ""
72
- if not url:
73
- print("Usage: brightdata.py scrape <url>", file=sys.stderr)
74
- sys.exit(1)
75
- mcp_call(mcp_url, "scrape_as_markdown", {"url": url})
76
- elif cmd == "scrape-batch":
77
- urls = sys.argv[2:]
78
- if not urls:
79
- print("Usage: brightdata.py scrape-batch <url1> <url2>...", file=sys.stderr)
80
- sys.exit(1)
81
- mcp_call(mcp_url, "scrape_as_markdown_batch", {"urls": urls})
82
- elif cmd == "search":
83
- query = " ".join(sys.argv[2:])
84
- mcp_call(mcp_url, "web_data_search_engine", {"query": query})
85
- elif cmd == "search-geo":
86
- if len(sys.argv) < 4:
87
- print("Usage: brightdata.py search-geo <country_code> <query>", file=sys.stderr)
88
- sys.exit(1)
89
- geo = sys.argv[2]
90
- query = " ".join(sys.argv[3:])
91
- mcp_call(mcp_url, "web_data_search_engine", {"query": query, "country": geo})
92
- elif cmd == "search-yandex":
93
- query = " ".join(sys.argv[2:])
94
- mcp_call(mcp_url, "web_data_search_engine", {"query": query, "engine": "yandex"})
95
- else:
96
- print(f"Unknown: {cmd}", file=sys.stderr)
97
- sys.exit(1)
98
-
99
-
100
- if __name__ == "__main__":
101
- main()
1
+ #!/usr/bin/env python3
2
+ """Bright Data MCP wrapper — scrape, search, search-geo, search-yandex. Stdlib only.
3
+
4
+ Uses mcp-client.py for MCP JSON-RPC calls.
5
+ """
6
+
7
+ import json
8
+ import os
9
+ import subprocess
10
+ import sys
11
+
12
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
13
+ from _http import get_key, get_workspace
14
+
15
+
16
+ def init():
17
+ workspace, _, _ = get_workspace()
18
+ return get_key("BRIGHTDATA_MCP_URL",
19
+ file_fallback=os.path.join(workspace, "scripts", "brightdata-mcp-url.txt"),
20
+ help_url="https://brightdata.com/products/web-scraper/mcp")
21
+
22
+
23
+ def mcp_call(mcp_url, tool_name, arguments):
24
+ """Call MCP tool via mcp-client.py."""
25
+ scripts_dir = os.path.dirname(os.path.abspath(__file__))
26
+ mcp_client = os.path.join(scripts_dir, "mcp-client.py")
27
+ args_json = json.dumps(arguments)
28
+ result = subprocess.run(
29
+ [sys.executable, mcp_client, mcp_url, tool_name, args_json],
30
+ capture_output=True, text=True, timeout=120
31
+ )
32
+ if result.stdout:
33
+ print(result.stdout)
34
+ if result.stderr:
35
+ print(result.stderr, file=sys.stderr)
36
+ return result.returncode
37
+
38
+
39
+ def list_tools(mcp_url):
40
+ """List available MCP tools."""
41
+ scripts_dir = os.path.dirname(os.path.abspath(__file__))
42
+ mcp_client = os.path.join(scripts_dir, "mcp-client.py")
43
+ result = subprocess.run(
44
+ [sys.executable, mcp_client, mcp_url, "--list-tools"],
45
+ capture_output=True, text=True, timeout=30
46
+ )
47
+ if result.stdout:
48
+ print(result.stdout)
49
+ if result.stderr:
50
+ print(result.stderr, file=sys.stderr)
51
+
52
+
53
+ def main():
54
+ if len(sys.argv) < 2:
55
+ print("Usage: brightdata.py {tools|scrape|scrape-batch|search|search-geo|search-yandex} <args>")
56
+ print()
57
+ print(" tools - list available MCP tools")
58
+ print(" scrape <url> - any URL → markdown (bypasses CAPTCHA)")
59
+ print(" scrape-batch <url1> <url2> - batch scrape up to 10 URLs")
60
+ print(" search <query> - Google search via Bright Data")
61
+ print(" search-geo <cc> <query> - geo-targeted search")
62
+ print(" search-yandex <query> - Yandex search")
63
+ sys.exit(1)
64
+
65
+ mcp_url = init()
66
+ cmd = sys.argv[1]
67
+
68
+ if cmd == "tools":
69
+ list_tools(mcp_url)
70
+ elif cmd == "scrape":
71
+ url = sys.argv[2] if len(sys.argv) > 2 else ""
72
+ if not url:
73
+ print("Usage: brightdata.py scrape <url>", file=sys.stderr)
74
+ sys.exit(1)
75
+ mcp_call(mcp_url, "scrape_as_markdown", {"url": url})
76
+ elif cmd == "scrape-batch":
77
+ urls = sys.argv[2:]
78
+ if not urls:
79
+ print("Usage: brightdata.py scrape-batch <url1> <url2>...", file=sys.stderr)
80
+ sys.exit(1)
81
+ mcp_call(mcp_url, "scrape_as_markdown_batch", {"urls": urls})
82
+ elif cmd == "search":
83
+ query = " ".join(sys.argv[2:])
84
+ mcp_call(mcp_url, "web_data_search_engine", {"query": query})
85
+ elif cmd == "search-geo":
86
+ if len(sys.argv) < 4:
87
+ print("Usage: brightdata.py search-geo <country_code> <query>", file=sys.stderr)
88
+ sys.exit(1)
89
+ geo = sys.argv[2]
90
+ query = " ".join(sys.argv[3:])
91
+ mcp_call(mcp_url, "web_data_search_engine", {"query": query, "country": geo})
92
+ elif cmd == "search-yandex":
93
+ query = " ".join(sys.argv[2:])
94
+ mcp_call(mcp_url, "web_data_search_engine", {"query": query, "engine": "yandex"})
95
+ else:
96
+ print(f"Unknown: {cmd}", file=sys.stderr)
97
+ sys.exit(1)
98
+
99
+
100
+ if __name__ == "__main__":
101
+ main()
@@ -1,141 +1,141 @@
1
- #!/usr/bin/env python3
2
- """OSINT Toolkit Diagnostic — checks available API keys, CLI tools, and capabilities."""
3
-
4
- import os
5
- import shutil
6
- import sys
7
-
8
- sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
9
- from _http import get_workspace
10
-
11
-
12
- def check_key(env_var, file_path=None):
13
- """Check if API key is available via env or file."""
14
- if os.environ.get(env_var):
15
- return True, f"(env)"
16
- if file_path and os.path.isfile(file_path):
17
- return True, f"(file: {os.path.basename(file_path)})"
18
- return False, ""
19
-
20
-
21
- def main():
22
- workspace, skill_dir, scripts_dir = get_workspace()
23
-
24
- print("=== OSINT TOOLKIT DIAGNOSTIC ===")
25
- print()
26
-
27
- # 1. API Tokens
28
- print("📡 API Tokens:")
29
- keys = [
30
- ("APIFY_API_TOKEN", os.path.join(workspace, "scripts", "apify-api-token.txt"),
31
- "https://console.apify.com/account/integrations"),
32
- ("JINA_API_KEY", os.path.join(workspace, "scripts", "jina-api-key.txt"),
33
- "https://jina.ai/api-key"),
34
- ("PERPLEXITY_API_KEY", None, "https://perplexity.ai/settings/api"),
35
- ("PARALLEL_API_KEY", os.path.join(workspace, "scripts", "parallel-api-key.txt"),
36
- "https://platform.parallel.ai"),
37
- ("EXA_API_KEY", None, "https://dashboard.exa.ai"),
38
- ("TAVILY_API_KEY", None, "https://app.tavily.com/home"),
39
- ("BRIGHTDATA_MCP_URL", os.path.join(workspace, "scripts", "brightdata-mcp-url.txt"),
40
- "https://brightdata.com/products/web-scraper/mcp"),
41
- ]
42
- for env_var, file_path, url in keys:
43
- found, source = check_key(env_var, file_path)
44
- if found:
45
- print(f" ✅ {env_var} {source}")
46
- else:
47
- print(f" ❌ {env_var} — get one at {url}")
48
- print()
49
-
50
- # 2. CLI Tools
51
- print("🔧 CLI Tools:")
52
- tools = [
53
- ("python3", "python"),
54
- ("node", None),
55
- ("jq", None),
56
- ("curl", None),
57
- ("git", None),
58
- ]
59
- for tool_name, alt_name in tools:
60
- path = shutil.which(tool_name) or (shutil.which(alt_name) if alt_name else None)
61
- if path:
62
- print(f" ✅ {tool_name}")
63
- else:
64
- print(f" ❌ {tool_name}")
65
-
66
- # Check run_actor.js
67
- run_actor_js = os.path.join(scripts_dir, "run_actor.js")
68
- if os.path.isfile(run_actor_js):
69
- print(f" ✅ run_actor.js (embedded, 55+ actors)")
70
- else:
71
- print(f" ❌ run_actor.js (missing)")
72
-
73
- # Check Python scripts
74
- py_scripts = ["perplexity.py", "tavily.py", "exa.py", "jina.py",
75
- "parallel.py", "apify.py", "brightdata.py", "volley.py"]
76
- for script in py_scripts:
77
- path = os.path.join(scripts_dir, script)
78
- if os.path.isfile(path):
79
- print(f" ✅ {script}")
80
- else:
81
- print(f" ⚠️ {script} (not found)")
82
- print()
83
-
84
- # 3. Internal Intelligence
85
- print("📱 Internal Intelligence:")
86
- tg_path = os.path.join(workspace, "skills", "telegram", "scripts", "tg.py")
87
- if os.path.isfile(tg_path):
88
- print(" ✅ tg.py (Telegram history/search)")
89
- else:
90
- print(" ❌ tg.py (no Telegram access)")
91
-
92
- himalaya = shutil.which("himalaya")
93
- himalaya_local = os.path.expanduser("~/.local/bin/himalaya")
94
- if himalaya or os.path.isfile(himalaya_local):
95
- print(" ✅ himalaya (email search)")
96
- else:
97
- print(" ❌ himalaya (no email access)")
98
-
99
- vault_crm = os.path.join(workspace, "vault", "crm")
100
- if os.path.isdir(vault_crm):
101
- count = sum(1 for f in os.listdir(vault_crm) if f.endswith(".md"))
102
- print(f" ✅ vault/crm ({count} cards)")
103
- else:
104
- print(" ❌ vault/crm (no CRM vault)")
105
- print()
106
-
107
- # 4. Capability Summary
108
- print("📊 Capabilities:")
109
- apify_ok = check_key("APIFY_API_TOKEN", os.path.join(workspace, "scripts", "apify-api-token.txt"))[0]
110
- bright_ok = check_key("BRIGHTDATA_MCP_URL", os.path.join(workspace, "scripts", "brightdata-mcp-url.txt"))[0]
111
- jina_ok = check_key("JINA_API_KEY", os.path.join(workspace, "scripts", "jina-api-key.txt"))[0]
112
- perp_ok = check_key("PERPLEXITY_API_KEY")[0]
113
- tavily_ok = check_key("TAVILY_API_KEY")[0]
114
- exa_ok = check_key("EXA_API_KEY")[0]
115
- parallel_ok = check_key("PARALLEL_API_KEY", os.path.join(workspace, "scripts", "parallel-api-key.txt"))[0]
116
-
117
- caps = [
118
- (apify_ok, "LinkedIn scraping (Apify)"),
119
- (apify_ok, "Instagram scraping (Apify)"),
120
- (apify_ok, "TikTok scraping (Apify)"),
121
- (apify_ok, "YouTube scraping (Apify)"),
122
- (apify_ok, "Contact enrichment (Apify)"),
123
- (apify_ok, "Google Maps (Apify)"),
124
- (bright_ok, "Facebook scraping (Bright Data)"),
125
- (bright_ok, "CAPTCHA bypass (Bright Data)"),
126
- (jina_ok, "Deep search (Jina)"),
127
- (perp_ok, "Quick answers (Perplexity Sonar)"),
128
- (perp_ok, "Deep research (Perplexity Deep)"),
129
- (tavily_ok, "Agent search (Tavily)"),
130
- (exa_ok, "Semantic search (Exa)"),
131
- (exa_ok, "People/Company search (Exa)"),
132
- (parallel_ok, "AI search (Parallel)"),
133
- ]
134
- for available, name in caps:
135
- print(f" {'✅' if available else '❌'} {name}")
136
- print()
137
- print("=== END DIAGNOSTIC ===")
138
-
139
-
140
- if __name__ == "__main__":
141
- main()
1
+ #!/usr/bin/env python3
2
+ """OSINT Toolkit Diagnostic — checks available API keys, CLI tools, and capabilities."""
3
+
4
+ import os
5
+ import shutil
6
+ import sys
7
+
8
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
9
+ from _http import get_workspace
10
+
11
+
12
+ def check_key(env_var, file_path=None):
13
+ """Check if API key is available via env or file."""
14
+ if os.environ.get(env_var):
15
+ return True, f"(env)"
16
+ if file_path and os.path.isfile(file_path):
17
+ return True, f"(file: {os.path.basename(file_path)})"
18
+ return False, ""
19
+
20
+
21
+ def main():
22
+ workspace, skill_dir, scripts_dir = get_workspace()
23
+
24
+ print("=== OSINT TOOLKIT DIAGNOSTIC ===")
25
+ print()
26
+
27
+ # 1. API Tokens
28
+ print("📡 API Tokens:")
29
+ keys = [
30
+ ("APIFY_API_TOKEN", os.path.join(workspace, "scripts", "apify-api-token.txt"),
31
+ "https://console.apify.com/account/integrations"),
32
+ ("JINA_API_KEY", os.path.join(workspace, "scripts", "jina-api-key.txt"),
33
+ "https://jina.ai/api-key"),
34
+ ("PERPLEXITY_API_KEY", None, "https://perplexity.ai/settings/api"),
35
+ ("PARALLEL_API_KEY", os.path.join(workspace, "scripts", "parallel-api-key.txt"),
36
+ "https://platform.parallel.ai"),
37
+ ("EXA_API_KEY", None, "https://dashboard.exa.ai"),
38
+ ("TAVILY_API_KEY", None, "https://app.tavily.com/home"),
39
+ ("BRIGHTDATA_MCP_URL", os.path.join(workspace, "scripts", "brightdata-mcp-url.txt"),
40
+ "https://brightdata.com/products/web-scraper/mcp"),
41
+ ]
42
+ for env_var, file_path, url in keys:
43
+ found, source = check_key(env_var, file_path)
44
+ if found:
45
+ print(f" ✅ {env_var} {source}")
46
+ else:
47
+ print(f" ❌ {env_var} — get one at {url}")
48
+ print()
49
+
50
+ # 2. CLI Tools
51
+ print("🔧 CLI Tools:")
52
+ tools = [
53
+ ("python3", "python"),
54
+ ("node", None),
55
+ ("jq", None),
56
+ ("curl", None),
57
+ ("git", None),
58
+ ]
59
+ for tool_name, alt_name in tools:
60
+ path = shutil.which(tool_name) or (shutil.which(alt_name) if alt_name else None)
61
+ if path:
62
+ print(f" ✅ {tool_name}")
63
+ else:
64
+ print(f" ❌ {tool_name}")
65
+
66
+ # Check run_actor.js
67
+ run_actor_js = os.path.join(scripts_dir, "run_actor.js")
68
+ if os.path.isfile(run_actor_js):
69
+ print(f" ✅ run_actor.js (embedded, 55+ actors)")
70
+ else:
71
+ print(f" ❌ run_actor.js (missing)")
72
+
73
+ # Check Python scripts
74
+ py_scripts = ["perplexity.py", "tavily.py", "exa.py", "jina.py",
75
+ "parallel.py", "apify.py", "brightdata.py", "volley.py"]
76
+ for script in py_scripts:
77
+ path = os.path.join(scripts_dir, script)
78
+ if os.path.isfile(path):
79
+ print(f" ✅ {script}")
80
+ else:
81
+ print(f" ⚠️ {script} (not found)")
82
+ print()
83
+
84
+ # 3. Internal Intelligence
85
+ print("📱 Internal Intelligence:")
86
+ tg_path = os.path.join(workspace, "skills", "telegram", "scripts", "tg.py")
87
+ if os.path.isfile(tg_path):
88
+ print(" ✅ tg.py (Telegram history/search)")
89
+ else:
90
+ print(" ❌ tg.py (no Telegram access)")
91
+
92
+ himalaya = shutil.which("himalaya")
93
+ himalaya_local = os.path.expanduser("~/.local/bin/himalaya")
94
+ if himalaya or os.path.isfile(himalaya_local):
95
+ print(" ✅ himalaya (email search)")
96
+ else:
97
+ print(" ❌ himalaya (no email access)")
98
+
99
+ vault_crm = os.path.join(workspace, "vault", "crm")
100
+ if os.path.isdir(vault_crm):
101
+ count = sum(1 for f in os.listdir(vault_crm) if f.endswith(".md"))
102
+ print(f" ✅ vault/crm ({count} cards)")
103
+ else:
104
+ print(" ❌ vault/crm (no CRM vault)")
105
+ print()
106
+
107
+ # 4. Capability Summary
108
+ print("📊 Capabilities:")
109
+ apify_ok = check_key("APIFY_API_TOKEN", os.path.join(workspace, "scripts", "apify-api-token.txt"))[0]
110
+ bright_ok = check_key("BRIGHTDATA_MCP_URL", os.path.join(workspace, "scripts", "brightdata-mcp-url.txt"))[0]
111
+ jina_ok = check_key("JINA_API_KEY", os.path.join(workspace, "scripts", "jina-api-key.txt"))[0]
112
+ perp_ok = check_key("PERPLEXITY_API_KEY")[0]
113
+ tavily_ok = check_key("TAVILY_API_KEY")[0]
114
+ exa_ok = check_key("EXA_API_KEY")[0]
115
+ parallel_ok = check_key("PARALLEL_API_KEY", os.path.join(workspace, "scripts", "parallel-api-key.txt"))[0]
116
+
117
+ caps = [
118
+ (apify_ok, "LinkedIn scraping (Apify)"),
119
+ (apify_ok, "Instagram scraping (Apify)"),
120
+ (apify_ok, "TikTok scraping (Apify)"),
121
+ (apify_ok, "YouTube scraping (Apify)"),
122
+ (apify_ok, "Contact enrichment (Apify)"),
123
+ (apify_ok, "Google Maps (Apify)"),
124
+ (bright_ok, "Facebook scraping (Bright Data)"),
125
+ (bright_ok, "CAPTCHA bypass (Bright Data)"),
126
+ (jina_ok, "Deep search (Jina)"),
127
+ (perp_ok, "Quick answers (Perplexity Sonar)"),
128
+ (perp_ok, "Deep research (Perplexity Deep)"),
129
+ (tavily_ok, "Agent search (Tavily)"),
130
+ (exa_ok, "Semantic search (Exa)"),
131
+ (exa_ok, "People/Company search (Exa)"),
132
+ (parallel_ok, "AI search (Parallel)"),
133
+ ]
134
+ for available, name in caps:
135
+ print(f" {'✅' if available else '❌'} {name}")
136
+ print()
137
+ print("=== END DIAGNOSTIC ===")
138
+
139
+
140
+ if __name__ == "__main__":
141
+ main()
@@ -1,79 +1,79 @@
1
- #!/usr/bin/env python3
2
- """Exa AI — semantic search, company research, people search, crawl. Stdlib only."""
3
-
4
- import json
5
- import os
6
- import sys
7
-
8
- sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
9
- from _http import api_post, get_key, truncate
10
-
11
- BASE = "https://api.exa.ai"
12
-
13
-
14
- def init():
15
- return get_key("EXA_API_KEY", help_url="https://dashboard.exa.ai")
16
-
17
-
18
- def search(api_key, query, category=None, max_chars=500, icon="🔗"):
19
- """Exa semantic search."""
20
- payload = {
21
- "query": query,
22
- "type": "auto",
23
- "numResults": 10,
24
- "contents": {"text": {"maxCharacters": max_chars}},
25
- }
26
- if category:
27
- payload["category"] = category
28
- data = api_post(f"{BASE}/search", payload,
29
- headers={"x-api-key": api_key})
30
- if not data:
31
- return
32
- for r in data.get("results", [])[:10]:
33
- print(f'{icon} {r.get("title", "")}')
34
- print(f' {r.get("url", "")}')
35
- txt = truncate(r.get("text", ""), max_chars)
36
- if txt:
37
- print(f" {txt}")
38
- print()
39
-
40
-
41
- def crawl(api_key, url):
42
- """Crawl a URL and extract content."""
43
- data = api_post(f"{BASE}/contents",
44
- {"urls": [url], "text": {"maxCharacters": 5000}},
45
- headers={"x-api-key": api_key})
46
- if not data:
47
- return
48
- for r in data.get("results", []):
49
- print(f'📄 {r.get("title", "")}')
50
- print(f' {r.get("url", "")}')
51
- print(r.get("text", "")[:3000])
52
-
53
-
54
- def main():
55
- if len(sys.argv) < 3:
56
- print("Usage: exa.py search|company|people|crawl|deep <query>")
57
- sys.exit(1)
58
- api_key = init()
59
- cmd = sys.argv[1]
60
- query = " ".join(sys.argv[2:])
61
- if cmd == "search":
62
- search(api_key, query)
63
- elif cmd == "company":
64
- search(api_key, f"{query} company information about",
65
- category="company", max_chars=1000, icon="🏢")
66
- elif cmd == "people":
67
- search(api_key, query, category="personal site", icon="👤")
68
- elif cmd == "crawl":
69
- crawl(api_key, query)
70
- elif cmd == "deep":
71
- print("🔬 Exa Deep Research — use MCP or dashboard")
72
- print(" MCP: https://mcp.exa.ai/mcp?tools=deep_researcher_start,deep_researcher_check")
73
- else:
74
- print(f"Unknown: {cmd} (use search|company|people|crawl|deep)", file=sys.stderr)
75
- sys.exit(1)
76
-
77
-
78
- if __name__ == "__main__":
79
- main()
1
+ #!/usr/bin/env python3
2
+ """Exa AI — semantic search, company research, people search, crawl. Stdlib only."""
3
+
4
+ import json
5
+ import os
6
+ import sys
7
+
8
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
9
+ from _http import api_post, get_key, truncate
10
+
11
+ BASE = "https://api.exa.ai"
12
+
13
+
14
+ def init():
15
+ return get_key("EXA_API_KEY", help_url="https://dashboard.exa.ai")
16
+
17
+
18
+ def search(api_key, query, category=None, max_chars=500, icon="🔗"):
19
+ """Exa semantic search."""
20
+ payload = {
21
+ "query": query,
22
+ "type": "auto",
23
+ "numResults": 10,
24
+ "contents": {"text": {"maxCharacters": max_chars}},
25
+ }
26
+ if category:
27
+ payload["category"] = category
28
+ data = api_post(f"{BASE}/search", payload,
29
+ headers={"x-api-key": api_key})
30
+ if not data:
31
+ return
32
+ for r in data.get("results", [])[:10]:
33
+ print(f'{icon} {r.get("title", "")}')
34
+ print(f' {r.get("url", "")}')
35
+ txt = truncate(r.get("text", ""), max_chars)
36
+ if txt:
37
+ print(f" {txt}")
38
+ print()
39
+
40
+
41
+ def crawl(api_key, url):
42
+ """Crawl a URL and extract content."""
43
+ data = api_post(f"{BASE}/contents",
44
+ {"urls": [url], "text": {"maxCharacters": 5000}},
45
+ headers={"x-api-key": api_key})
46
+ if not data:
47
+ return
48
+ for r in data.get("results", []):
49
+ print(f'📄 {r.get("title", "")}')
50
+ print(f' {r.get("url", "")}')
51
+ print(r.get("text", "")[:3000])
52
+
53
+
54
+ def main():
55
+ if len(sys.argv) < 3:
56
+ print("Usage: exa.py search|company|people|crawl|deep <query>")
57
+ sys.exit(1)
58
+ api_key = init()
59
+ cmd = sys.argv[1]
60
+ query = " ".join(sys.argv[2:])
61
+ if cmd == "search":
62
+ search(api_key, query)
63
+ elif cmd == "company":
64
+ search(api_key, f"{query} company information about",
65
+ category="company", max_chars=1000, icon="🏢")
66
+ elif cmd == "people":
67
+ search(api_key, query, category="personal site", icon="👤")
68
+ elif cmd == "crawl":
69
+ crawl(api_key, query)
70
+ elif cmd == "deep":
71
+ print("🔬 Exa Deep Research — use MCP or dashboard")
72
+ print(" MCP: https://mcp.exa.ai/mcp?tools=deep_researcher_start,deep_researcher_check")
73
+ else:
74
+ print(f"Unknown: {cmd} (use search|company|people|crawl|deep)", file=sys.stderr)
75
+ sys.exit(1)
76
+
77
+
78
+ if __name__ == "__main__":
79
+ main()