openhack 0.1.0__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 (113) hide show
  1. openhack/__init__.py +2 -0
  2. openhack/__main__.py +225 -0
  3. openhack/agents/__init__.py +30 -0
  4. openhack/agents/base.py +230 -0
  5. openhack/agents/browser_verifier.py +679 -0
  6. openhack/agents/browser_verifier_swarm.py +256 -0
  7. openhack/agents/checkpoint.py +89 -0
  8. openhack/agents/context_manager.py +356 -0
  9. openhack/agents/coordinator.py +1105 -0
  10. openhack/agents/endpoint_analyst.py +307 -0
  11. openhack/agents/feature_hunter.py +93 -0
  12. openhack/agents/hunter.py +481 -0
  13. openhack/agents/hunter_swarm.py +385 -0
  14. openhack/agents/llm.py +334 -0
  15. openhack/agents/recon.py +19 -0
  16. openhack/agents/sandbox_verifier.py +396 -0
  17. openhack/agents/sandbox_verifier_swarm.py +250 -0
  18. openhack/agents/session.py +286 -0
  19. openhack/agents/validator.py +217 -0
  20. openhack/agents/validator_swarm.py +106 -0
  21. openhack/auth.py +175 -0
  22. openhack/browser/__init__.py +12 -0
  23. openhack/browser/runner.py +385 -0
  24. openhack/categories.py +130 -0
  25. openhack/config.py +201 -0
  26. openhack/deterministic_recon.py +464 -0
  27. openhack/entry_points.py +745 -0
  28. openhack/framework_classifier.py +515 -0
  29. openhack/framework_detection.py +269 -0
  30. openhack/headless_scan.py +179 -0
  31. openhack/prompts/__init__.py +108 -0
  32. openhack/prompts/browser_verifier.py +171 -0
  33. openhack/prompts/coordinator.py +31 -0
  34. openhack/prompts/django/__init__.py +32 -0
  35. openhack/prompts/django/auth_bypass.py +76 -0
  36. openhack/prompts/django/csrf.py +62 -0
  37. openhack/prompts/django/data_exposure.py +67 -0
  38. openhack/prompts/django/idor.py +74 -0
  39. openhack/prompts/django/injection.py +67 -0
  40. openhack/prompts/django/misconfiguration.py +70 -0
  41. openhack/prompts/django/ssrf.py +64 -0
  42. openhack/prompts/endpoint_analyst.py +122 -0
  43. openhack/prompts/express/__init__.py +29 -0
  44. openhack/prompts/express/auth_bypass.py +71 -0
  45. openhack/prompts/express/data_exposure.py +77 -0
  46. openhack/prompts/express/idor.py +69 -0
  47. openhack/prompts/express/injection.py +75 -0
  48. openhack/prompts/express/misconfiguration.py +72 -0
  49. openhack/prompts/express/ssrf.py +63 -0
  50. openhack/prompts/feature_hunter.py +140 -0
  51. openhack/prompts/flask/__init__.py +29 -0
  52. openhack/prompts/flask/auth_bypass.py +86 -0
  53. openhack/prompts/flask/data_exposure.py +78 -0
  54. openhack/prompts/flask/idor.py +83 -0
  55. openhack/prompts/flask/injection.py +77 -0
  56. openhack/prompts/flask/misconfiguration.py +73 -0
  57. openhack/prompts/flask/ssrf.py +65 -0
  58. openhack/prompts/hunter.py +362 -0
  59. openhack/prompts/hunter_continuation_loop.py +12 -0
  60. openhack/prompts/hunter_continuation_no_findings.py +19 -0
  61. openhack/prompts/hunter_continuation_no_progress.py +22 -0
  62. openhack/prompts/hunter_tool_instructions.py +55 -0
  63. openhack/prompts/nextjs/__init__.py +42 -0
  64. openhack/prompts/nextjs/auth_bypass.py +80 -0
  65. openhack/prompts/nextjs/csrf.py +71 -0
  66. openhack/prompts/nextjs/data_exposure.py +88 -0
  67. openhack/prompts/nextjs/idor.py +64 -0
  68. openhack/prompts/nextjs/injection.py +65 -0
  69. openhack/prompts/nextjs/middleware_bypass.py +75 -0
  70. openhack/prompts/nextjs/misconfiguration.py +92 -0
  71. openhack/prompts/nextjs/server_actions.py +97 -0
  72. openhack/prompts/nextjs/ssrf.py +66 -0
  73. openhack/prompts/nextjs/xss.py +69 -0
  74. openhack/prompts/pr_analysis_system.py +80 -0
  75. openhack/prompts/pr_analysis_user.py +11 -0
  76. openhack/prompts/project_context.py +89 -0
  77. openhack/prompts/recon.py +199 -0
  78. openhack/prompts/reporter.py +88 -0
  79. openhack/prompts/researchers.py +434 -0
  80. openhack/prompts/sandbox_verifier.py +128 -0
  81. openhack/prompts/supabase/__init__.py +39 -0
  82. openhack/prompts/supabase/auth_tokens.py +131 -0
  83. openhack/prompts/supabase/edge_functions.py +150 -0
  84. openhack/prompts/supabase/graphql.py +102 -0
  85. openhack/prompts/supabase/postgrest.py +99 -0
  86. openhack/prompts/supabase/realtime.py +93 -0
  87. openhack/prompts/supabase/rls.py +110 -0
  88. openhack/prompts/supabase/rpc_functions.py +127 -0
  89. openhack/prompts/supabase/storage.py +110 -0
  90. openhack/prompts/supabase/tenant_isolation.py +118 -0
  91. openhack/prompts/validator.py +319 -0
  92. openhack/prompts/validator_continuation_incomplete.py +12 -0
  93. openhack/prompts/validator_tool_instructions.py +29 -0
  94. openhack/quality.py +231 -0
  95. openhack/sandbox/__init__.py +12 -0
  96. openhack/sandbox/orchestrator.py +517 -0
  97. openhack/sandbox/runner.py +177 -0
  98. openhack/scan_session.py +245 -0
  99. openhack/setup.py +452 -0
  100. openhack/static_validator.py +612 -0
  101. openhack/tools/__init__.py +1 -0
  102. openhack/tools/ast_tools.py +307 -0
  103. openhack/tools/coverage.py +1078 -0
  104. openhack/tools/filesystem.py +404 -0
  105. openhack/tools/nextjs.py +258 -0
  106. openhack/tools/registry.py +52 -0
  107. openhack/tui.py +3450 -0
  108. openhack/updates.py +170 -0
  109. openhack-0.1.0.dist-info/METADATA +189 -0
  110. openhack-0.1.0.dist-info/RECORD +113 -0
  111. openhack-0.1.0.dist-info/WHEEL +4 -0
  112. openhack-0.1.0.dist-info/entry_points.txt +2 -0
  113. openhack-0.1.0.dist-info/licenses/LICENSE +661 -0
openhack/updates.py ADDED
@@ -0,0 +1,170 @@
1
+ """
2
+ Startup update check + announcements fetcher.
3
+
4
+ Calls GET /updates on the inference worker. Never blocks the TUI or
5
+ raises to the user on failure — network errors are silently swallowed.
6
+ """
7
+
8
+ import json
9
+ import logging
10
+ import os
11
+ import time
12
+ from dataclasses import dataclass, field
13
+ from datetime import datetime, timezone
14
+ from pathlib import Path
15
+ from typing import Optional
16
+
17
+ import httpx
18
+
19
+ from openhack import __version__
20
+ from openhack.config import CONFIG_DIR
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+ _DISMISSED_FILE = CONFIG_DIR / "dismissed_announcements.json"
25
+ _LAST_CHECK_FILE = CONFIG_DIR / ".last_update_check"
26
+ _RECHECK_INTERVAL = 3600 # 1 hour
27
+
28
+
29
+ @dataclass
30
+ class LatestRelease:
31
+ version: str
32
+ published_at: str = ""
33
+ download_url: str = ""
34
+ release_notes: str = ""
35
+
36
+
37
+ @dataclass
38
+ class Announcement:
39
+ id: str
40
+ level: str # "info" | "warning" | "critical"
41
+ title: str
42
+ body: str = ""
43
+ placement: list[str] = field(default_factory=list)
44
+ published_at: str = ""
45
+ expires_at: Optional[str] = None
46
+
47
+
48
+ @dataclass
49
+ class UpdateInfo:
50
+ latest: Optional[LatestRelease] = None
51
+ announcements: list[Announcement] = field(default_factory=list)
52
+ has_update: bool = False
53
+
54
+
55
+ def _get_updates_url() -> str:
56
+ if os.environ.get("OPENHACK_DEV", "0") == "1":
57
+ return "http://localhost:8787/updates"
58
+ return "https://api.openhack.com/updates"
59
+
60
+
61
+ def _semver_gt(a: str, b: str) -> bool:
62
+ """Return True if version `a` is strictly greater than `b` (semver major.minor.patch)."""
63
+ def _parse(v: str) -> tuple[int, ...]:
64
+ v = v.lstrip("v")
65
+ parts = v.split("-")[0].split("+")[0] # strip pre-release/build
66
+ return tuple(int(x) for x in parts.split(".") if x.isdigit())
67
+ try:
68
+ return _parse(a) > _parse(b)
69
+ except (ValueError, TypeError):
70
+ return False
71
+
72
+
73
+ def _is_expired(expires_at: Optional[str]) -> bool:
74
+ if not expires_at:
75
+ return False
76
+ try:
77
+ exp = datetime.fromisoformat(expires_at.replace("Z", "+00:00"))
78
+ return datetime.now(timezone.utc) > exp
79
+ except (ValueError, TypeError):
80
+ return False
81
+
82
+
83
+ def _load_dismissed() -> set[str]:
84
+ try:
85
+ data = json.loads(_DISMISSED_FILE.read_text())
86
+ return set(data) if isinstance(data, list) else set()
87
+ except Exception:
88
+ return set()
89
+
90
+
91
+ def save_dismissed(ann_id: str) -> None:
92
+ """Persist an announcement ID as dismissed so it won't re-appear."""
93
+ dismissed = _load_dismissed()
94
+ dismissed.add(ann_id)
95
+ try:
96
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True)
97
+ _DISMISSED_FILE.write_text(json.dumps(sorted(dismissed)))
98
+ except Exception:
99
+ pass
100
+
101
+
102
+ def _should_check() -> bool:
103
+ """Don't re-check if we already checked within this hour."""
104
+ try:
105
+ ts = float(_LAST_CHECK_FILE.read_text().strip())
106
+ return (time.time() - ts) > _RECHECK_INTERVAL
107
+ except Exception:
108
+ return True
109
+
110
+
111
+ def _mark_checked() -> None:
112
+ try:
113
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True)
114
+ _LAST_CHECK_FILE.write_text(str(time.time()))
115
+ except Exception:
116
+ pass
117
+
118
+
119
+ async def fetch_updates(force: bool = False) -> Optional[UpdateInfo]:
120
+ """Fetch update info from /updates. Returns None on any failure."""
121
+ if not force and not _should_check():
122
+ return None
123
+
124
+ url = _get_updates_url()
125
+ try:
126
+ async with httpx.AsyncClient(timeout=5.0) as client:
127
+ resp = await client.get(url, params={"current": __version__})
128
+ if resp.status_code != 200:
129
+ return None
130
+ data = resp.json()
131
+ except Exception:
132
+ return None
133
+
134
+ _mark_checked()
135
+
136
+ info = UpdateInfo()
137
+
138
+ # Parse latest release
139
+ latest_raw = data.get("latest")
140
+ if latest_raw and isinstance(latest_raw, dict):
141
+ info.latest = LatestRelease(
142
+ version=latest_raw.get("version", ""),
143
+ published_at=latest_raw.get("publishedAt", ""),
144
+ download_url=latest_raw.get("downloadUrl", ""),
145
+ release_notes=latest_raw.get("releaseNotes", ""),
146
+ )
147
+ if info.latest.version and _semver_gt(info.latest.version, __version__):
148
+ info.has_update = True
149
+
150
+ # Parse announcements
151
+ dismissed = _load_dismissed()
152
+ for ann_raw in data.get("announcements") or []:
153
+ if not isinstance(ann_raw, dict):
154
+ continue
155
+ ann_id = ann_raw.get("id", "")
156
+ if ann_id in dismissed:
157
+ continue
158
+ if _is_expired(ann_raw.get("expiresAt")):
159
+ continue
160
+ info.announcements.append(Announcement(
161
+ id=ann_id,
162
+ level=ann_raw.get("level", "info"),
163
+ title=ann_raw.get("title", ""),
164
+ body=ann_raw.get("body", ""),
165
+ placement=ann_raw.get("placement") or [],
166
+ published_at=ann_raw.get("publishedAt", ""),
167
+ expires_at=ann_raw.get("expiresAt"),
168
+ ))
169
+
170
+ return info
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: openhack
3
+ Version: 0.1.0
4
+ Summary: AI-powered security scanner for your codebase. Find SQL injection, XSS, IDOR, auth bypass, and more — straight from your terminal.
5
+ Project-URL: Homepage, https://openhack.com
6
+ Project-URL: Documentation, https://github.com/openhackai/openhack
7
+ Project-URL: Repository, https://github.com/openhackai/openhack
8
+ Project-URL: Issues, https://github.com/openhackai/openhack/issues
9
+ Author: OpenHack
10
+ License-Expression: AGPL-3.0-only
11
+ License-File: LICENSE
12
+ Keywords: ai-security,appsec,code-review,llm,sast,security,static-analysis,vulnerability-scanner
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Information Technology
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Security
23
+ Classifier: Topic :: Software Development :: Bug Tracking
24
+ Classifier: Topic :: Software Development :: Quality Assurance
25
+ Requires-Python: >=3.11
26
+ Requires-Dist: aiohttp>=3.9.0
27
+ Requires-Dist: httpx>=0.25.0
28
+ Requires-Dist: openai>=1.0.0
29
+ Requires-Dist: prompt-toolkit>=3.0.0
30
+ Requires-Dist: pydantic-settings>=2.6.0
31
+ Requires-Dist: pydantic>=2.10.0
32
+ Requires-Dist: pygments>=2.19.0
33
+ Requires-Dist: rich>=13.0.0
34
+ Requires-Dist: tree-sitter-javascript>=0.25.0
35
+ Requires-Dist: tree-sitter-python>=0.25.0
36
+ Requires-Dist: tree-sitter-typescript>=0.23.2
37
+ Requires-Dist: tree-sitter>=0.25.2
38
+ Provides-Extra: browser
39
+ Requires-Dist: playwright>=1.40.0; extra == 'browser'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # ⏚ [OpenHack](https://openhack.com)
43
+
44
+ **Open Source Agentic Security Scanner for your codebase.**
45
+
46
+ Like Claude Code Security / Codex Security but open source. OpenHack does recon -> hunting -> validation -> verification all in one pipeline to find high quality verified vulnerabilities. OpenHack exclusively uses open source models and specializes in web app vulnerabilities.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pipx install openhack
52
+ ```
53
+
54
+ Or with pip:
55
+
56
+ ```bash
57
+ pip install openhack
58
+ ```
59
+
60
+ ## Quick start
61
+
62
+ ```bash
63
+ openhack
64
+ ```
65
+
66
+ On first run you'll go through a one-time setup:
67
+
68
+ 1. Pick **Login with OpenHack account** (recommended) — opens a browser, you log in, get **$20 in free credits**, and the CLI gets a token automatically.
69
+ 2. Type `/scan .` to scan the current directory, or `/scan path/to/repo` for somewhere else.
70
+ 3. While scanning, the **Trace tab** shows live agent activity (recon → hunters → validators). When the scan finishes, the **Findings tab** shows everything that was found.
71
+
72
+ ## What it does
73
+
74
+ OpenHack runs a multi-agent pipeline against your codebase:
75
+
76
+ - **Recon** — reads the code, builds a project model
77
+ - **Hunters** — multiple specialized agents look for different vulnerability classes (input validation, access control, data handling, …)
78
+ - **Feature hunters** — deeper passes on specific risk categories (XSS rendering, raw SQL, command exec, etc.)
79
+ - **Validators** — re-read the suspect code to confirm or reject each candidate finding
80
+ - **Sandbox verification** (`/verify sandbox`) *(Beta — requires Docker)* — spins up your app in a Docker container and attempts to exploit each finding with live HTTP requests. Findings that are successfully exploited get a ✓ mark.
81
+ - **Browser verification** (`/verify browser`) *(Beta — requires Docker when combined with sandbox)* — launches a headless browser against the sandboxed app to verify client-side vulnerabilities (XSS, CSRF, DOM-based issues) with real browser execution.
82
+
83
+ > **Docker prerequisite.** Sandbox verification requires Docker Desktop (or any working Docker daemon) installed and running on the machine where the scan runs. Browser verification inherits this when used with sandbox. If Docker isn't running, `/verify sandbox` will fail with a clear error before the scan starts.
84
+
85
+ For every confirmed finding you get: severity, CVSS score, file location, full description, the vulnerable code snippet, and a recommended fix — all rendered with syntax highlighting in the TUI.
86
+
87
+ ## Slash commands
88
+
89
+
90
+ | Command | Description |
91
+ | -------------------------- | -------------------------------------------------------------------------------------------------- |
92
+ | `/scan <path>` | Full scan on a directory (defaults to current dir) |
93
+ | `/pause` · `/resume` | Pause and resume a running scan (Ctrl+C also pauses) |
94
+ | `/cancel` | Permanently cancel a running scan |
95
+ | `/sessions` | Browse and re-load past scans (also supports re-running an aborted scan with `r`) |
96
+ | `/findings` | Re-display findings from last scan |
97
+ | `/copy` | Copy the selected finding (description + vulnerable code + fix) for Codex / Claude Code / OpenCode |
98
+ | `/verify sandbox` *(Beta)* | Spin up a Docker sandbox and exploit-test each finding with live requests |
99
+ | `/verify browser` *(Beta)* | Launch a headless browser to verify client-side vulns (XSS, CSRF, etc.) |
100
+ | `/login` | Re-login to your OpenHack account |
101
+ | `/setup` | Run the setup wizard again |
102
+ | `/config` | Show current config; `/config <key> <value>` to set |
103
+ | `/sidebar` | Show/hide the Findings list sidebar (`Ctrl+B`) |
104
+ | `/cost` | Cost breakdown for the last scan |
105
+ | `/clear` | Clear scan state and return to landing |
106
+ | `/discord` | Open the OpenHack Discord |
107
+ | `/mouse` | Toggle mouse capture (off = native text selection) |
108
+ | `/help` | List commands |
109
+ | `/quit` | Exit |
110
+
111
+
112
+ ## Keyboard shortcuts (Findings tab)
113
+
114
+ - `↑` / `↓` — switch finding
115
+ - `[` · `]` — alternate prev / next
116
+ - Mouse wheel or `PgUp` / `PgDn` — scroll the details pane
117
+ - `y` — yank (copy) selected finding for an AI agent
118
+ - `<` · `>` — resize the sidebar
119
+ - `Ctrl+B` — toggle sidebar
120
+
121
+ ## Keyboard shortcuts (Trace tab)
122
+
123
+ - `↑` / `↓` — switch agent in the sidebar tree
124
+ - `[` · `]` — alternate prev / next agent
125
+ - Mouse wheel or `PgUp` / `PgDn` — scroll the trace
126
+ - `Home` — jump to "All" (full trace)
127
+ - `End` — resume auto-follow-to-bottom
128
+
129
+ ## Selecting text
130
+
131
+ The TUI captures mouse events by default (for scrolling and clicking). To select and copy text natively:
132
+
133
+ - **macOS**: Hold `Option` (⌥) and drag to select, then `Cmd+C` to copy.
134
+ - **Linux / Windows**: Hold `Shift` and drag to select.
135
+ - **Or**: Run `/mouse` to disable mouse capture entirely — the terminal's native selection works normally until you toggle it back on.
136
+
137
+ ## CLI commands (headless)
138
+
139
+ For CI, scripts, or one-off scans where you don't want the TUI:
140
+
141
+ ```bash
142
+ openhack scan /path/to/repo
143
+ ```
144
+
145
+ OpenHack runs the same pipeline as the TUI, prints progress to stdout, writes a JSON report to `~/.openhack/scans/<session-id>.json`, and exits.
146
+
147
+
148
+ | Command | Description |
149
+ | -------------------------- | -------------------------------------------------------- |
150
+ | `openhack` | Launch interactive TUI |
151
+ | `openhack scan [path]` | Full scan, headless (defaults to `.`) |
152
+ | `openhack sessions` | List all saved scans |
153
+ | `openhack resume <id>` | Resume a scan from its last checkpoint |
154
+ | `openhack classify [path]` | Classify frameworks + detect entry points (no LLM calls) |
155
+ | `openhack login` | Log in to your OpenHack account |
156
+ | `openhack setup` | Run the setup wizard |
157
+ | `openhack --help` | Show usage |
158
+
159
+
160
+ Scans are checkpointed after each pipeline stage. If a scan is interrupted or fails, resume it:
161
+
162
+ ```bash
163
+ openhack resume <session-id>
164
+ ```
165
+
166
+ ## Configuration
167
+
168
+ Configuration is stored in `~/.openhack/config` (mode `0600` since it contains a bearer token) and persists across sessions.
169
+
170
+ You can override at runtime via environment variables:
171
+
172
+
173
+ | Variable | Effect |
174
+ | ------------------ | ------------------------------------------------------------------------------------------------ |
175
+ | `OPENHACK_API_KEY` | Bearer token for the OpenHack inference API |
176
+ | `OPENHACK_DEV=1` | Point the CLI at local dev servers (app on `:9080`, inference on `:8787`) for self-hosted setups |
177
+
178
+
179
+ ## Privacy
180
+
181
+ OpenHack reads and processes your source code **locally** — prompts are built on your machine. Only LLM tokens (not raw source files) are forwarded to the OpenHack inference API. No source code is uploaded or retained.
182
+
183
+ ## Contributing
184
+
185
+ OpenHack is open source. Issues and PRs welcome on [GitHub](https://github.com/openhackai/openhack).
186
+
187
+ ## License
188
+
189
+ AGPL-3.0 — see [LICENSE](LICENSE). Free for personal, educational, and open-source use. For commercial licensing without AGPL obligations, contact [team@openhack.com](mailto:team@openhack.com).
@@ -0,0 +1,113 @@
1
+ openhack/__init__.py,sha256=9XWDrE_f_hDez7_120gBGOmVxjQTnJ8iuhmhpkzYJqY,89
2
+ openhack/__main__.py,sha256=9TnnjjxU3hi3COw4qe37d-VugxNCyJj2IYZgpeexsGo,6758
3
+ openhack/auth.py,sha256=BHC-21Fi45NKXtb2wpZEcKbcvR8NKncjYoVWLhVyqDI,5941
4
+ openhack/categories.py,sha256=8j9aXdTY0ekByZZ0_QpR5gbzZOc-6zMqV6w7zRTbp4k,5291
5
+ openhack/config.py,sha256=xLejsgw6B5wM_lZvoMAhkpC4wyWILZbscD2mrpoZriw,6539
6
+ openhack/deterministic_recon.py,sha256=gtZUFnJikpO8T_PpuDe_5ZowttvYZQgJ4X-J3x4rl8A,18867
7
+ openhack/entry_points.py,sha256=j8pyEbRnoYr9uhiq10Tl0Lsipis6lh51FRH_kssJGyw,29625
8
+ openhack/framework_classifier.py,sha256=TB7ogAh3HYf3-YiIAZcTgN0Tke8kgQshi-BYDkWcyQ0,16829
9
+ openhack/framework_detection.py,sha256=_Q_sS-7WYrTSUIzItm61JXbrgBlHR0waRoyVpT9hdKo,9110
10
+ openhack/headless_scan.py,sha256=3HI7agE-E9DzvVZ78HWDGX3EXQdtgqO2w8-_-jyiiWg,5955
11
+ openhack/quality.py,sha256=NF0qSqAb41-Npq9lf0kVYs8GXW8tQDvuuySATMId5y0,7512
12
+ openhack/scan_session.py,sha256=DhST3BBB7ombHqcxguOWq7_5aOoKmuI0frNq_-FrUSw,9759
13
+ openhack/setup.py,sha256=EaKEodlfQViuz6cw5K_JpWKtwTrw269b1ffWLSb6SIM,15844
14
+ openhack/static_validator.py,sha256=ZiICE4CoTj1beRTheMcavF9UAT8fcRC0iYksuEqp8zU,24723
15
+ openhack/tui.py,sha256=kWcXByLdrBkUSwpOhgVzwMPt6iJkGnFd5fa9xmynV2w,144968
16
+ openhack/updates.py,sha256=m6xIyGSeYUtalxr4oVOdjpvTc0szXKsr560Gv-i_Uoo,4918
17
+ openhack/agents/__init__.py,sha256=nxt3eCGM4Pw-DZy7_2dbOh7AUc0xJXh15X-iT98pmGY,742
18
+ openhack/agents/base.py,sha256=uNlJmV8PxPYP0l3xOz2wJID-u_d9XY1hQkyq3YNRsHI,9600
19
+ openhack/agents/browser_verifier.py,sha256=NU9AFFNRLViSAvfpiO_6LR59oLdppQhTQ6w8GUSjE78,27355
20
+ openhack/agents/browser_verifier_swarm.py,sha256=LSzuSaF1WW-s072mFU8otbmBzjEnYwajWR_efdqqlRA,11247
21
+ openhack/agents/checkpoint.py,sha256=tpcfDK2WuD54eAX-yOXLkEG4KkDjlxXeX2_Liv9hwCU,3466
22
+ openhack/agents/context_manager.py,sha256=UsC2dfqj8Urj_o3BThBPRUXdplsoEHYqbUaWpY-whO4,14669
23
+ openhack/agents/coordinator.py,sha256=IZEpmHU0VSWAmLhQ1A3-YBUPBNPqxlV-sFq4ffCUzrc,55761
24
+ openhack/agents/endpoint_analyst.py,sha256=QniEiy92IpRUpwGY7bThOnWcOXa7jlvrAhXnS3siHY0,10745
25
+ openhack/agents/feature_hunter.py,sha256=etp7_LN6Dp8qgX0TRoMY_vIp5w3pe9HxcqsNTjf2XMM,3399
26
+ openhack/agents/hunter.py,sha256=9uOwqhK5UTnEPTW6eDzs9ZebIfqqIKAAPV5JgFpmGFY,21545
27
+ openhack/agents/hunter_swarm.py,sha256=g0hSu5dJouM5iutHbA7JLrvONFlSJ5TnuCCscgxoXGg,17088
28
+ openhack/agents/llm.py,sha256=vyObGgbEwZF6mljV9h4RzyVVjtIm9uBWEagvInv8oBI,12424
29
+ openhack/agents/recon.py,sha256=KvZZhSq3XNmzeM0nwxTDA8HlC7XbuCYnCPZcj8MrTC8,657
30
+ openhack/agents/sandbox_verifier.py,sha256=llPTD8YyJWXszgcd9ucd9-IpRBzmKlyZZxj8D2IDPQ4,15054
31
+ openhack/agents/sandbox_verifier_swarm.py,sha256=2kFlUxPV3wk5DMB8TUYekKQFdh8h11ThY40fJ6HSLg8,10994
32
+ openhack/agents/session.py,sha256=Oawl3ZVm9ZpVZfrGuJmqGef9fNiqjFjzlX8tclxruHM,10552
33
+ openhack/agents/validator.py,sha256=PwWLGe4dJYtx8dfbPQwL3DDZI4C0a6slRSBjZLqnMB8,8487
34
+ openhack/agents/validator_swarm.py,sha256=3hyFqftXDPRplF0P6aRYpDx8OwR0_M9fKaPe2Mi6sxk,4485
35
+ openhack/browser/__init__.py,sha256=X7B_4QGBCatIykwfRJnoETatfvDNrCZ1vVOYnN7bTQM,391
36
+ openhack/browser/runner.py,sha256=opspL8qBpsl_drNdkVmXVH-YiG9iOa6od-6VEb_ynT4,13820
37
+ openhack/prompts/__init__.py,sha256=5zILgAcRLau2sOdfiQQ6LFkGxNPxUL257B6y-XxidF4,3726
38
+ openhack/prompts/browser_verifier.py,sha256=vv_zxzJJpLJ4vzYeu-IjDYBuqhPUjJYYQNaSfxI0siQ,8366
39
+ openhack/prompts/coordinator.py,sha256=2tXBXoYXi8GoOOScD8LR4H-jyBz2Q7BBKgQgEMnJ9gs,1067
40
+ openhack/prompts/endpoint_analyst.py,sha256=4EKFDckaw3l8RxvLMBo0WFnE0Y2E7JaXFTM8u4Ki3Ig,6141
41
+ openhack/prompts/feature_hunter.py,sha256=WiBOfdKmdBIJd-qqm06dSUIYpVAYx09Bu8bWML9yGzs,7852
42
+ openhack/prompts/hunter.py,sha256=JgzahwK1Yb3D0zfENKAilnOh9RgQH1RS-PF-nWl-1u0,26015
43
+ openhack/prompts/hunter_continuation_loop.py,sha256=f8zXIYd_F0-NYxKDIXwxoVDl8E0N-hSxfm5wMxsCCoc,502
44
+ openhack/prompts/hunter_continuation_no_findings.py,sha256=NE_zYkcEF7z9MKYPP4t5HBgYjvuGCpfzJAk9TDjr8L0,1126
45
+ openhack/prompts/hunter_continuation_no_progress.py,sha256=5OFKMgE_XnnDoxWShZAWJTAL4DpJdW1FplxtBKgIrhk,1325
46
+ openhack/prompts/hunter_tool_instructions.py,sha256=2iRhwLIUymmeZIPNNI-F0EsYBf41y_2rv-ya9i0sO9g,1791
47
+ openhack/prompts/pr_analysis_system.py,sha256=4xEc_okSgK8pw5O_w0rWLGVVcLp17jMUaTB9dy_Lzcc,4851
48
+ openhack/prompts/pr_analysis_user.py,sha256=VbCYO1aLLS9y2FL8N45LFCM432mMV3-kf9VCa0lnyDo,241
49
+ openhack/prompts/project_context.py,sha256=1N_-_0pwnrdvkLAyPOnARsUB10D54nosewM1Gh1IxPc,3203
50
+ openhack/prompts/recon.py,sha256=W4iqgBefhwJuCIfAWY_THWVs0UVbd1MO-pRmiFQbfkE,9605
51
+ openhack/prompts/reporter.py,sha256=3ZgYPq509f4beXBHV-Q_KkgWWZAGWuK_Nm3wK9GkPk4,1527
52
+ openhack/prompts/researchers.py,sha256=vjwX7txBjNu6BlGXKRiGsPauoVpVBKeVLBRwsFXo6fQ,28137
53
+ openhack/prompts/sandbox_verifier.py,sha256=LBQ18zGXSYztCUezbZUmHkskhPhmDwW-zavglCijTkc,5566
54
+ openhack/prompts/validator.py,sha256=zOfGza8uPAztHrRxduwHM_14x7diFmxZiW8aAH2MXKM,20227
55
+ openhack/prompts/validator_continuation_incomplete.py,sha256=HdWEHtZSg25ZLWrTPm_DR1JY3mTNTRl46p4PJkmLvW4,545
56
+ openhack/prompts/validator_tool_instructions.py,sha256=wS2JOf7_3Ii9EWJ-5Qu33ao3H3Se6I9ZRVLaYNHiw2g,1059
57
+ openhack/prompts/django/__init__.py,sha256=raxFuUWLb5i_v0acAkWVWVnOz5wU0cJ_yOcEImctzDU,964
58
+ openhack/prompts/django/auth_bypass.py,sha256=jNk_TCuWNT63f11VF_7OyDQ82BaDJScrmJZrNvQZ42Y,2382
59
+ openhack/prompts/django/csrf.py,sha256=tc2zefCijE-UVAS9UZiGPN4ewcVnesV10Vvg_Qn-HUc,1866
60
+ openhack/prompts/django/data_exposure.py,sha256=wKw2sQDxoqcRuEZD319aw1_VvIvL8ja57hcxSlOhXYU,2101
61
+ openhack/prompts/django/idor.py,sha256=Sa8aW4asrIPHyEOpJHW_nlkTMbTR1lfm77R-dZ2WqzQ,2393
62
+ openhack/prompts/django/injection.py,sha256=5Pz1_rU0Vz4OtQuS7KMOoxQ3Kw-O5Btn6aOwtxAUCKQ,2007
63
+ openhack/prompts/django/misconfiguration.py,sha256=wpfsD05DlSdwPnbInznFNxgfbvEQw7-XKGe9Khbu5q8,1965
64
+ openhack/prompts/django/ssrf.py,sha256=kQkmQk5jJsH5bKazp5opqG_jZNYHMRrpzxB_IIxIr2g,1914
65
+ openhack/prompts/express/__init__.py,sha256=O5OoyjBo02tmpJtMFTNqfq-RqjVCQW4_liiA7AQ7PSk,893
66
+ openhack/prompts/express/auth_bypass.py,sha256=KEVvvXhUbwjM6BBzV8BBePgYIswitHX9gEOHkRVquzY,2120
67
+ openhack/prompts/express/data_exposure.py,sha256=Yy0hc0LUcQGCl3p-GgUwlTS75hA4tqVdBlMdWdmGpj4,2321
68
+ openhack/prompts/express/idor.py,sha256=fcokHAcVEUhs1eu4X92PfRkMUBG2D_80CgRQax0s7mA,2106
69
+ openhack/prompts/express/injection.py,sha256=FKrWVMQUb-StswRoZoXMnqatIS1izuDSLc-jFcerytg,2299
70
+ openhack/prompts/express/misconfiguration.py,sha256=eYMDaWY5cUDNYbpFk7BTDo7-m3ok_Dr8HVnMbJ9jkeI,2155
71
+ openhack/prompts/express/ssrf.py,sha256=OBlbDGWtRfCvm5hkpMN6PcMir_cGPZUCTHXsY7tNNAc,1992
72
+ openhack/prompts/flask/__init__.py,sha256=h7pWUZ1HUKDpdpAEmfSbgQ1ZJlfWBET8GJG-j6bWAC0,848
73
+ openhack/prompts/flask/auth_bypass.py,sha256=Xgg6db8sN-Z0tUNFyeWKTPHjybmAKngtLrCLMxcnCog,2390
74
+ openhack/prompts/flask/data_exposure.py,sha256=EbVbRO2Ye1w1HNGGoThoEkn71RqvRQtqiFFTX8xaekU,2325
75
+ openhack/prompts/flask/idor.py,sha256=Xgs2FKs3eNxCVHO8xN-dDJDsAnjxjfCpduYcrXmNKMg,2574
76
+ openhack/prompts/flask/injection.py,sha256=c2VsWiiDT963u9s-WvZOpigEPQq5JJGJ5LbGPw8e4XA,2323
77
+ openhack/prompts/flask/misconfiguration.py,sha256=CWMglLuilfg4PErr34WqNOMi9l7cC7XI5b7zSA1ZWyA,2207
78
+ openhack/prompts/flask/ssrf.py,sha256=h8f_nsJN6hDKTXA7TVqPkvOWfBKMEAgmLeCc_2czHKM,1894
79
+ openhack/prompts/nextjs/__init__.py,sha256=8avE5rNmLpnl4kOJ78AVwlezQvFMDBM0bUrWbxXDyGI,1430
80
+ openhack/prompts/nextjs/auth_bypass.py,sha256=xkdoBqgeEjmXWG6kT7srTFxI6jwP12U8o4sFJCQBdig,1997
81
+ openhack/prompts/nextjs/csrf.py,sha256=y-66G7_tk3hdlBi0_jEx8ptkD60mtVR3kkq1Vdh-9Cw,2110
82
+ openhack/prompts/nextjs/data_exposure.py,sha256=Fe6tsDxq_VCYsxxaOg0k7BLkoUdkp73UxciS36lSWIE,2125
83
+ openhack/prompts/nextjs/idor.py,sha256=p724eOB8An8LMqcs-GjAtAYkQkUG_zH2V82PqD7wcEA,1938
84
+ openhack/prompts/nextjs/injection.py,sha256=4tEruIYwewewjOgxMuX0LHhREzV3zldXSvXgZd1FgjM,1888
85
+ openhack/prompts/nextjs/middleware_bypass.py,sha256=eBNpBOucP7BZ1nWyF0zsf1u_ojOhKlxMB4tUzn_tvsQ,1808
86
+ openhack/prompts/nextjs/misconfiguration.py,sha256=pN8HxYzk5Tzs272x_-rS34TIZpy9KBFDzXPhuanu824,2132
87
+ openhack/prompts/nextjs/server_actions.py,sha256=tnXxv6CFdPdpfJXyAlrDFluhE0hFMlYOj3FoTakwezo,2317
88
+ openhack/prompts/nextjs/ssrf.py,sha256=k74-EiJCS41cIUpgiLerpFBsmzxKR5us5-qCRon5Vek,1839
89
+ openhack/prompts/nextjs/xss.py,sha256=CpufRzgN2O-06pFndgRY7bDSo4Rtje60_iF9xqZc6ZU,1953
90
+ openhack/prompts/supabase/__init__.py,sha256=zB4GN5VxH93_sd3AT-tgb8LsvShnBLmXSQW42pAbcCI,1404
91
+ openhack/prompts/supabase/auth_tokens.py,sha256=Ki70mhantnTd21ceZ2Xca658GKc6XYRESdeMi-oVt2I,5720
92
+ openhack/prompts/supabase/edge_functions.py,sha256=suLWadQeXRyL-1BBI9cwGL8NUYFU6r_UHzwVPPnPVwg,5526
93
+ openhack/prompts/supabase/graphql.py,sha256=gEKauXouuNo7pz4rlxu5mXWA_1VZE9qgE4pZ_jdcD-g,3473
94
+ openhack/prompts/supabase/postgrest.py,sha256=ngob-RKt_voSiBa3b-BObC9ri-iQgP5cuncmSbfqlIk,4164
95
+ openhack/prompts/supabase/realtime.py,sha256=4raTILryluvvRuLLfVJrkm4rxbbEImLQ5lmGQkyVHoM,3634
96
+ openhack/prompts/supabase/rls.py,sha256=xTYqcjqKTCV4WpOTO8QyGcdv-Jtg258i61XEpsRAdas,4754
97
+ openhack/prompts/supabase/rpc_functions.py,sha256=A9UMBd8fw9tZlo4n6TRrb9cea4Ji3DV0vFqGyyZO9NM,4262
98
+ openhack/prompts/supabase/storage.py,sha256=wwjhTdbgR-KS6wqC3hydzuA91VBS6hdcVTE2rCj4HmU,4586
99
+ openhack/prompts/supabase/tenant_isolation.py,sha256=UAwdw-9jWU48IDQ2pwrniNL6p9Y-8gEChz4VhvUp-0Y,4561
100
+ openhack/sandbox/__init__.py,sha256=9zG2LlE-B16NcSD8aDeOqmwANKfpm8ILqg4ZMDQT7fk,325
101
+ openhack/sandbox/orchestrator.py,sha256=khHYkOfRUo1ZpXeuBCjIsBkY86Ikxnp6Q7VaFg8RKKQ,19297
102
+ openhack/sandbox/runner.py,sha256=-gkBi9qNW8HgU4aNOBBJYFgtMW_6Pf7yPztCikv52OA,5921
103
+ openhack/tools/__init__.py,sha256=jRUmIPA2pVJjI0ZlPFOotF9Jb6qzdbxIfokmHMxoEBM,22
104
+ openhack/tools/ast_tools.py,sha256=zEXZpA0VFJw_5QNTpEMstkjR6s1PHOu6A-vLBJXAcZw,12655
105
+ openhack/tools/coverage.py,sha256=97AC7Oo3GV1YMQ3Cm9-4g0nHuV-mI_fECMp4M648qHs,43419
106
+ openhack/tools/filesystem.py,sha256=Yj8Tc_90yiGm4I217Ck5klv7kAzzhJ-RlhtbXXBkODA,16410
107
+ openhack/tools/nextjs.py,sha256=_bYfLbAatuQe2Ae3K_CJN3Dk-h8WDYWReexBpvPsI4A,10368
108
+ openhack/tools/registry.py,sha256=48lIpGeKf-W1C81UwrcY7Pb9RFJi6HBu7vS0753t51c,1790
109
+ openhack-0.1.0.dist-info/METADATA,sha256=pqK5ASkNCHXl1bTxaaZ2viskf86eBmvC08EmKZHZrYY,10413
110
+ openhack-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
111
+ openhack-0.1.0.dist-info/entry_points.txt,sha256=89qyBLVygik6q5v0jcYfaUty36c8Ne1Ici9n48yvpcM,52
112
+ openhack-0.1.0.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
113
+ openhack-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ openhack = openhack.__main__:main