From 395013fdeb808fc2e946f5ab063854a9562fa22d Mon Sep 17 00:00:00 2001 From: Ahmed Allam Date: Fri, 31 Oct 2025 20:53:28 +0200 Subject: [PATCH] feat(docs): Enhance README with headless mode and CI/CD integration examples --- README.md | 34 ++++++++++++++++++++++++++++++++++ strix/interface/cli.py | 16 ++++++++++++++-- strix/interface/main.py | 5 +++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b339900..31b3e95 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,40 @@ strix --target api.your-app.com --instruction "Prioritize authentication and aut strix --target https://your-app.com --instruction "Test with credentials: testuser/testpass. Focus on privilege escalation and access control bypasses." ``` +### 🤖 Headless Mode + +Run Strix programmatically without interactive UI using the `-n/--non-interactive` flag—perfect for servers and automated jobs. The CLI prints real-time vulnerability findings, and the final penetration test report before exiting. Exits with non-zero code when vulnerabilities are found. + +```bash +strix --target https://your-app.com -n --instruction "Focus on authentication bypass and session management" +``` + +### 🔄 CI/CD (GitHub Actions) + +Strix can be added to your pipeline to run a security test on pull requests with a lightweight GitHub Actions workflow: + +```yaml +name: strix-penetration-test + +on: + pull_request: + +jobs: + security-scan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Strix + run: pipx install strix-agent + + - name: Run Strix + env: + STRIX_LLM: ${{ secrets.STRIX_LLM }} + LLM_API_KEY: ${{ secrets.LLM_API_KEY }} + run: strix -n --target ./ +``` + ### ⚙️ Configuration ```bash diff --git a/strix/interface/cli.py b/strix/interface/cli.py index 3f4a769..4824be7 100644 --- a/strix/interface/cli.py +++ b/strix/interface/cli.py @@ -29,6 +29,16 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 instructions_text.append("📋 Instructions: ", style="bold cyan") instructions_text.append(args.instruction, style="white") + results_text = Text() + results_text.append("📊 Results will be saved to: ", style="bold cyan") + results_text.append(f"agent_runs/{args.run_name}", style="bold white") + + note_text = Text() + note_text.append("\n\n", style="dim") + note_text.append("⏱️ ", style="dim") + note_text.append("This may take a while depending on target complexity. ", style="dim") + note_text.append("Vulnerabilities will be displayed in real-time.", style="dim") + startup_panel = Panel( Text.assemble( start_text, @@ -36,6 +46,9 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 target_text, "\n" if args.instruction else "", instructions_text if args.instruction else "", + "\n", + results_text, + note_text, ), title="[bold green]🛡️ STRIX PENETRATION TEST INITIATED", title_align="center", @@ -113,9 +126,8 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915 tracer.cleanup() def signal_handler(_signum: int, _frame: Any) -> None: - console.print("\n[bold yellow]Interrupted! Saving reports...[/bold yellow]") tracer.cleanup() - sys.exit(0) + sys.exit(1) atexit.register(cleanup_on_exit) signal.signal(signal.SIGINT, signal_handler) diff --git a/strix/interface/main.py b/strix/interface/main.py index 5bf9bfd..6c6e64d 100644 --- a/strix/interface/main.py +++ b/strix/interface/main.py @@ -752,6 +752,11 @@ def main() -> None: results_path = Path("agent_runs") / args.run_name display_completion_message(args, results_path) + if args.non_interactive: + tracer = get_global_tracer() + if tracer and tracer.vulnerability_reports: + sys.exit(2) + if __name__ == "__main__": main()