Commit 85f2ba0a authored by Hardik Zinzuvadiya's avatar Hardik Zinzuvadiya
Browse files

Feature: Tool recommendations — "I want to do X" (r command)

- Add _RECOMMENDATIONS dict — maps 22 common tasks to tag names:
  "scan a network" → scanner, "crack passwords" → bruteforce/credentials,
  "pentest active directory" → active-directory, "pivot through network"
  → network, etc.
- Add recommend_tools() — shows numbered task list, user picks one,
  shows all matching tools with installed status, select to jump in
- Wire r/rec/recommend into interact_menu()
- Updated hint bar and help overlay
parent fd8d7574
Loading
Loading
Loading
Loading
+104 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ def show_help():
            ("  21     ", "bold cyan"), ("Update / Uninstall hackingtool\n", "white"),
            ("  / or s ", "bold cyan"), ("search tools by name or keyword\n", "white"),
            ("  t      ", "bold cyan"), ("filter tools by tag (osint, web, c2, ...)\n", "white"),
            ("  r      ", "bold cyan"), ("recommend tools for a task\n", "white"),
            ("  ?      ", "bold cyan"), ("show this help\n", "white"),
            ("  q      ", "bold cyan"), ("quit hackingtool\n\n", "white"),
            ("  Inside a category\n", "bold white"),
@@ -319,6 +320,7 @@ def build_menu():
        "  [dim]Enter number  ·  "
        "[bold cyan]/[/bold cyan] search  ·  "
        "[bold cyan]t[/bold cyan] tags  ·  "
        "[bold cyan]r[/bold cyan] recommend  ·  "
        "[bold cyan]?[/bold cyan] help  ·  "
        "[bold cyan]q[/bold cyan] quit[/dim]\n"
    )
@@ -428,6 +430,104 @@ def filter_by_tag():
        tool.show_options()


_RECOMMENDATIONS = {
    "scan a network":           ["scanner", "port-scanner"],
    "find subdomains":          ["recon"],
    "scan for vulnerabilities": ["scanner", "web"],
    "crack passwords":          ["bruteforce", "credentials"],
    "find leaked secrets":      ["credentials"],
    "phishing campaign":        ["social-engineering"],
    "post exploitation":        ["c2", "privesc"],
    "pivot through network":    ["network"],
    "pentest active directory": ["active-directory"],
    "pentest web application":  ["web", "scanner"],
    "pentest cloud":            ["cloud"],
    "pentest mobile app":       ["mobile"],
    "reverse engineer binary":  ["reversing"],
    "capture wifi handshake":   ["wireless"],
    "intercept http traffic":   ["web", "network"],
    "forensic analysis":        ["forensics"],
    "ddos testing":             ["ddos"],
    "create payloads":          ["payload"],
    "find xss vulnerabilities": ["web"],
    "brute force directories":  ["bruteforce", "web"],
    "osint / recon a target":   ["osint", "recon"],
    "hide my identity":         ["network"],
}


def recommend_tools():
    """Show common tasks, user picks one, show matching tools."""
    table = Table(
        title="What do you want to do?",
        box=box.SIMPLE_HEAD,
    )
    table.add_column("No.", justify="center", style="bold cyan", width=5)
    table.add_column("Task", style="bold yellow")

    tasks = list(_RECOMMENDATIONS.keys())
    for i, task in enumerate(tasks, start=1):
        table.add_row(str(i), task.title())

    table.add_row("99", "Back to main menu")
    console.print(table)

    raw = Prompt.ask("[bold cyan]>[/bold cyan]", default="").strip()
    if not raw or raw == "99":
        return

    try:
        idx = int(raw)
    except ValueError:
        return

    if 1 <= idx <= len(tasks):
        task = tasks[idx - 1]
        tag_names = _RECOMMENDATIONS[task]
        tag_index = _get_all_tags()

        # Collect unique tools across all matching tags
        seen = set()
        matches = []
        for tag in tag_names:
            for tool, cat in tag_index.get(tag, []):
                if id(tool) not in seen:
                    seen.add(id(tool))
                    matches.append((tool, cat))

        if not matches:
            console.print("[dim]No tools found for this task.[/dim]")
            Prompt.ask("[dim]Press Enter to return[/dim]", default="")
            return

        console.print(Panel(
            f"[bold]Recommended tools for: {task.title()}[/bold]",
            border_style="green", box=box.ROUNDED,
        ))

        rtable = Table(box=box.SIMPLE_HEAD, show_lines=True)
        rtable.add_column("No.", justify="center", style="bold cyan", width=5)
        rtable.add_column("", width=2)
        rtable.add_column("Tool", style="bold yellow", min_width=20)
        rtable.add_column("Category", style="magenta")

        for i, (tool, cat) in enumerate(matches, start=1):
            status = "[green]✔[/green]" if tool.is_installed else "[dim]✘[/dim]"
            rtable.add_row(str(i), status, tool.TITLE, cat)

        rtable.add_row("99", "", "Back", "")
        console.print(rtable)

        raw2 = Prompt.ask("[bold cyan]>[/bold cyan]", default="").strip()
        if raw2 and raw2 != "99":
            try:
                ridx = int(raw2)
                if 1 <= ridx <= len(matches):
                    matches[ridx - 1][0].show_options()
            except ValueError:
                pass


def search_tools():
    """Interactive search — user types query, results update, select to jump."""
    query = Prompt.ask("[bold cyan]/ Search[/bold cyan]", default="").strip().lower()
@@ -508,6 +608,10 @@ def interact_menu():
                filter_by_tag()
                continue

            if raw in ("r", "rec", "recommend"):
                recommend_tools()
                continue

            if raw in ("q", "quit", "exit"):
                console.print(Panel(
                    "[bold white on magenta]  Goodbye — Come Back Safely  [/bold white on magenta]",