| 62 | |
| 63 | |
| 64 | def _build_parser() -> argparse.ArgumentParser: |
| 65 | parser = argparse.ArgumentParser( |
| 66 | prog="openosint", |
| 67 | description=( |
| 68 | "OpenOSINT — AI-powered OSINT framework.\n" |
| 69 | "Run without arguments to start the interactive REPL." |
| 70 | ), |
| 71 | formatter_class=argparse.RawDescriptionHelpFormatter, |
| 72 | epilog=( |
| 73 | "Examples:\n" |
| 74 | " openosint # interactive AI session\n" |
| 75 | " openosint email target@example.com # direct email scan\n" |
| 76 | " openosint username johndoe99 # direct username scan\n" |
| 77 | " openosint shodan 8.8.8.8 # Shodan host lookup\n" |
| 78 | " openosint censys 8.8.8.8 # Censys host lookup\n" |
| 79 | " openosint censys example.com # Censys certificate search\n" |
| 80 | " openosint ip2location 8.8.8.8 # IP2Location lookup\n" |
| 81 | " openosint multi targets.txt # multi-target from file\n" |
| 82 | " openosint multi a@x.com,b@y.com # multi-target inline\n" |
| 83 | " openosint --parallel email target@example.com\n" |
| 84 | " openosint --json email target@example.com\n" |
| 85 | " openosint --provider ollama # use local Ollama\n" |
| 86 | " openosint --provider ollama --ollama-model mistral\n" |
| 87 | ), |
| 88 | ) |
| 89 | parser.add_argument( |
| 90 | "-v", |
| 91 | "--verbose", |
| 92 | action="store_true", |
| 93 | help="Enable debug-level logging.", |
| 94 | ) |
| 95 | parser.add_argument( |
| 96 | "--api-key", |
| 97 | type=str, |
| 98 | default=None, |
| 99 | metavar="KEY", |
| 100 | help="Anthropic API key (overrides ANTHROPIC_API_KEY env var).", |
| 101 | ) |
| 102 | parser.add_argument( |
| 103 | "--parallel", |
| 104 | action="store_true", |
| 105 | dest="is_parallel", |
| 106 | help=( |
| 107 | "Run independent complementary tools concurrently using asyncio.gather(). " |
| 108 | "For 'email': runs search_email + search_breach in parallel. " |
| 109 | "For 'username': runs search_username + search_paste in parallel." |
| 110 | ), |
| 111 | ) |
| 112 | parser.add_argument( |
| 113 | "--json", |
| 114 | action="store_true", |
| 115 | dest="json_output", |
| 116 | help="Output results as structured JSON instead of formatted text.", |
| 117 | ) |
| 118 | parser.add_argument( |
| 119 | "--provider", |
| 120 | type=str, |
| 121 | default="anthropic", |