Skip to content

Commit 58b94f6

Browse files
Phase 1 foundation: linting, CI/CD, Docker, tests, pre-commit
- Fix all ruff lint issues (51 errors → 0) - Add GitHub Actions CI pipeline (lint + typecheck + test + build) - Add pre-commit hooks (ruff, mypy, trailing whitespace, secrets) - Add Dockerfile for containerized deployment - Add Makefile with common dev commands - Write initial test suite (17 tests for target detection) - Add .pre-commit-config.yaml - Enhance README with full CLI reference and contribution guide - Improve type annotations and fix import ordering - Migrate string enums to StrEnum
1 parent 0668097 commit 58b94f6

27 files changed

Lines changed: 464 additions & 106 deletions

File tree

.github/workflows/ci.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
env:
10+
PYTHON_VERSION: "3.13"
11+
12+
jobs:
13+
lint:
14+
name: Lint
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- name: Install uv
19+
uses: astral-sh/setup-uv@v5
20+
with:
21+
python-version: ${{ env.PYTHON_VERSION }}
22+
- name: Install dependencies
23+
run: uv sync --all-extras
24+
- name: Run ruff check
25+
run: uv run ruff check bugfinder/ tests/
26+
- name: Run ruff format check
27+
run: uv run ruff format --check bugfinder/ tests/
28+
29+
typecheck:
30+
name: Type Check
31+
runs-on: ubuntu-latest
32+
steps:
33+
- uses: actions/checkout@v4
34+
- name: Install uv
35+
uses: astral-sh/setup-uv@v5
36+
with:
37+
python-version: ${{ env.PYTHON_VERSION }}
38+
- name: Install dependencies
39+
run: uv sync --all-extras
40+
- name: Run mypy
41+
run: uv run mypy bugfinder/ --ignore-missing-imports
42+
continue-on-error: true
43+
44+
test:
45+
name: Test
46+
runs-on: ubuntu-latest
47+
strategy:
48+
matrix:
49+
python-version: ["3.12", "3.13"]
50+
steps:
51+
- uses: actions/checkout@v4
52+
- name: Install uv
53+
uses: astral-sh/setup-uv@v5
54+
with:
55+
python-version: ${{ matrix.python-version }}
56+
- name: Install dependencies
57+
run: uv sync --all-extras
58+
- name: Run tests
59+
run: uv run python -m pytest tests/ -v --cov=bugfinder --cov-report=xml --cov-report=term
60+
- name: Upload coverage
61+
uses: codecov/codecov-action@v5
62+
with:
63+
token: ${{ secrets.CODECOV_TOKEN }}
64+
continue-on-error: true
65+
66+
build:
67+
name: Build
68+
runs-on: ubuntu-latest
69+
steps:
70+
- uses: actions/checkout@v4
71+
- name: Install uv
72+
uses: astral-sh/setup-uv@v5
73+
with:
74+
python-version: ${{ env.PYTHON_VERSION }}
75+
- name: Build package
76+
run: uv build
77+
- name: Upload wheel
78+
uses: actions/upload-artifact@v4
79+
with:
80+
name: dist
81+
path: dist/

.pre-commit-config.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.8.0
4+
hooks:
5+
- id: ruff
6+
args: [--fix]
7+
- id: ruff-format
8+
9+
- repo: https://github.com/pre-commit/mirrors-mypy
10+
rev: v1.14.0
11+
hooks:
12+
- id: mypy
13+
args: [--ignore-missing-imports, --python-version=3.12]
14+
additional_dependencies: [types-PyYAML]
15+
pass_filenames: false
16+
17+
- repo: https://github.com/pre-commit/pre-commit-hooks
18+
rev: v5.0.0
19+
hooks:
20+
- id: trailing-whitespace
21+
- id: end-of-file-fixer
22+
- id: check-yaml
23+
- id: check-toml
24+
- id: check-json
25+
- id: check-added-large-files
26+
- id: detect-private-key

Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
FROM python:3.13-slim AS builder
2+
3+
WORKDIR /app
4+
5+
RUN pip install uv
6+
COPY pyproject.toml README.md ./
7+
RUN uv sync --all-extras --no-dev
8+
9+
COPY bugfinder/ bugfinder/
10+
RUN uv build && uv pip install dist/*.whl
11+
12+
13+
FROM python:3.13-slim
14+
15+
RUN apt-get update && apt-get install -y --no-install-recommends \
16+
ca-certificates \
17+
&& rm -rf /var/lib/apt/lists/*
18+
19+
WORKDIR /app
20+
21+
COPY --from=builder /app/.venv /app/.venv
22+
COPY --from=builder /app/bugfinder /app/bugfinder
23+
COPY pyproject.toml README.md ./
24+
25+
ENV PATH="/app/.venv/bin:$PATH"
26+
ENV BF_DATABASE_URL="sqlite+aiosqlite:////data/bugfinder.db"
27+
28+
VOLUME ["/data"]
29+
ENTRYPOINT ["bf"]
30+
CMD ["--help"]

Makefile

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
.PHONY: install test lint format typecheck clean build docker dev
2+
3+
install:
4+
uv sync --all-extras
5+
6+
test:
7+
uv run python -m pytest tests/ -v --cov=bugfinder
8+
9+
lint:
10+
uv run ruff check bugfinder/ tests/
11+
12+
format:
13+
uv run ruff format bugfinder/ tests/
14+
15+
typecheck:
16+
uv run mypy bugfinder/ --ignore-missing-imports
17+
18+
clean:
19+
rm -rf .venv/ dist/ *.egg-info/ .pytest_cache/ __pycache__/
20+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
21+
find . -type f -name '*.pyc' -delete
22+
23+
build:
24+
uv build
25+
26+
docker:
27+
docker build -t bugfinder:latest .
28+
29+
dev:
30+
uv run python -m bugfinder tui
31+
32+
precommit:
33+
uv run pre-commit run --all-files

README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,133 @@
22

33
AI-powered autonomous bug bounty assistant and security assessment platform.
44

5+
BugFinder automatically determines the target type, selects appropriate assessment modules, executes safe scans, correlates findings, and generates professional reports — all while explaining each finding in plain language.
6+
7+
```bash
8+
bf scan https://example.com
9+
bf scan app.apk
10+
bf scan 10.0.0.0/24
11+
bf tui # Launch the terminal dashboard
12+
```
13+
14+
## Quick Start
15+
516
```bash
17+
# Install
618
pip install bugfinder
19+
20+
# Set your NVIDIA API key (required for AI features)
21+
export BF_NVIDIA_API_KEY="your-key-here"
22+
23+
# Run your first scan
724
bf scan https://example.com
25+
26+
# Launch the TUI dashboard
27+
bf tui
828
```
29+
30+
## Features
31+
32+
- **Auto-detect**: Automatically identifies target type (website, API, APK, IP, Docker, etc.)
33+
- **AI-Powered**: NVIDIA API integration for intelligent planning, explanation, and reporting
34+
- **Zero Config**: Works out of the box — no manual configuration required for standard scans
35+
- **Dual Mode**: Beginner mode (guided, educational) and Expert mode (full control)
36+
- **Knowledge Graph**: Maintains relationships between discovered assets for smarter analysis
37+
- **Plugin System**: Extensible via plugins for custom technologies and workflows
38+
- **Rich TUI**: Terminal-based dashboard with real-time progress, findings explorer, and report preview
39+
- **Multi-Format Reports**: Markdown, HTML, PDF, JSON, CSV export
40+
- **Scope-Aware**: Built-in scope enforcement and rate limiting for safe testing
41+
42+
## CLI Reference
43+
44+
| Command | Description |
45+
|---|---|
46+
| `bf scan <target>` | Auto-detect and scan |
47+
| `bf scan <target> --quick` | Lightweight scan |
48+
| `bf scan <target> --deep` | Maximum coverage |
49+
| `bf scan <target> --expert` | Full configuration control |
50+
| `bf tui` | Launch Textual terminal UI |
51+
| `bf report <scan_id>` | Generate report |
52+
| `bf config <key> <value>` | Set configuration |
53+
| `bf list-agents` | Show available agents |
54+
| `bf plugin install <name>` | Install plugin |
55+
56+
## Configuration
57+
58+
Configuration via environment variables (prefixed with `BF_`), `.env` file, or `bf config`:
59+
60+
```bash
61+
# Required for AI features
62+
BF_NVIDIA_API_KEY=your_key_here
63+
BF_NVIDIA_MODEL=minimax-m3
64+
65+
# Scope enforcement (comma-separated)
66+
BF_ALLOWED_DOMAINS=example.com,api.example.com
67+
68+
# Scan settings
69+
BF_MAX_CONCURRENT_TASKS=10
70+
BF_RATE_LIMIT_PER_SECOND=50
71+
72+
# Mode
73+
BF_BEGINNER_MODE=true
74+
BF_EDUCATIONAL_MODE=true
75+
```
76+
77+
## Development
78+
79+
```bash
80+
# Clone and setup
81+
git clone https://github.com/highoncomputers/BugFinder.git
82+
cd BugFinder
83+
make install
84+
85+
# Run tests
86+
make test
87+
88+
# Lint and format
89+
make lint
90+
make format
91+
92+
# Type check
93+
make typecheck
94+
95+
# Run TUI
96+
make dev
97+
```
98+
99+
## Project Structure
100+
101+
```
102+
bugfinder/
103+
├── cli/ # CLI commands + Textual TUI
104+
├── core/ # Config, types, exceptions
105+
├── target/ # Target auto-detection
106+
├── planner/ # AI + rule-based planner
107+
├── agents/ # Assessment agents
108+
│ ├── web/ # Web app scanners
109+
│ ├── api/ # API testing
110+
│ ├── android/ # APK analysis
111+
│ ├── cloud/ # Cloud config review
112+
│ ├── infra/ # Network/infrastructure
113+
│ ├── secrets/ # Secret detection
114+
│ └── recon/ # Reconnaissance
115+
├── engine/ # Scheduler + executor
116+
├── knowledge_graph/ # Asset relationship graph
117+
├── database/ # SQLAlchemy models
118+
├── ai/ # NVIDIA API client
119+
├── reporting/ # Report generators
120+
├── plugins/ # Plugin system
121+
├── security/ # Scope + rate limiting
122+
└── learning/ # Educational resources
123+
```
124+
125+
## Contributing
126+
127+
1. Fork the repository
128+
2. Create a feature branch (`git checkout -b feature/amazing`)
129+
3. Run `make precommit` before committing
130+
4. Open a Pull Request
131+
132+
## License
133+
134+
MIT

bugfinder/agents/base.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
from dataclasses import dataclass, field
55
from typing import Any
66

7-
from bugfinder.knowledge_graph.graph import KnowledgeGraph
87
from bugfinder.ai.client import NVIDIAClient
98
from bugfinder.database.repository import Repository
9+
from bugfinder.knowledge_graph.graph import KnowledgeGraph
1010

1111

1212
@dataclass
@@ -39,8 +39,7 @@ def __init__(self, context: AgentContext) -> None:
3939
self.context = context
4040

4141
@abstractmethod
42-
async def execute(self) -> AgentResult:
43-
...
42+
async def execute(self) -> AgentResult: ...
4443

4544
async def initialize(self) -> None:
4645
pass

bugfinder/ai/client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def __init__(
2525
self.base_url = base_url or settings.nvidia_base_url
2626
self._client: httpx.AsyncClient | None = None
2727

28-
async def __aenter__(self) -> "NVIDIAClient":
28+
async def __aenter__(self) -> NVIDIAClient:
2929
self._client = httpx.AsyncClient(
3030
base_url=self.base_url,
3131
timeout=httpx.Timeout(settings.request_timeout),
@@ -51,7 +51,11 @@ async def chat(
5151
response_format: dict | None = None,
5252
) -> dict[str, Any]:
5353
if not self.api_key:
54-
raise AIClientError("NVIDIA API key not configured. Set BF_NVIDIA_API_KEY or run `bf config nvidia.api_key YOUR_KEY`.")
54+
msg = (
55+
"NVIDIA API key not configured. "
56+
"Set BF_NVIDIA_API_KEY or run `bf config nvidia.api_key YOUR_KEY`."
57+
)
58+
raise AIClientError(msg)
5559

5660
payload: dict[str, Any] = {
5761
"model": self.model,

bugfinder/ai/prompts.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
SYSTEM_PLANNER = """You are BugFinder's AI security assessment planner.
1111
Your role is to analyze the target, review current findings, and decide the next best step.
1212
Only recommend steps that are legal and within scope.
13-
Be concise and specific. Output JSON with: {{"next_step": "...", "rationale": "...", "agents": ["..."]}}"""
13+
Be concise and specific. Output JSON with:
14+
{{"next_step": "...", "rationale": "...", "agents": ["..."]}}"""
1415

1516
SYSTEM_EXPLAINER = """You are BugFinder's AI security mentor.
1617
You explain security findings in clear, simple language.
@@ -52,9 +53,7 @@ def explainer_prompt(finding_title: str, description: str, evidence: str) -> tup
5253
return system, user
5354

5455

55-
def report_prompt(
56-
target: str, findings_summary: str, graph_summary: str
57-
) -> tuple[str, str]:
56+
def report_prompt(target: str, findings_summary: str, graph_summary: str) -> tuple[str, str]:
5857
system = SYSTEM_REPORT
5958
user = f"""Target: {target}
6059
Findings: {findings_summary}

bugfinder/cli/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from __future__ import annotations
22

33
from textual.app import App, ComposeResult
4-
from textual.screen import Screen
5-
from textual.widgets import Header, Footer, Static, Button, Input, ListView, ListItem
64
from textual.containers import Horizontal, Vertical
5+
from textual.screen import Screen
6+
from textual.widgets import Button, Footer, Header, Input, ListView, Static
77

88

99
class WelcomeScreen(Screen):

0 commit comments

Comments
 (0)