From 8f5ab52b25e6cda94c20923335cf167a4f1a39e2 Mon Sep 17 00:00:00 2001 From: Barki Mustapha Date: Sat, 25 Jul 2026 21:19:03 +0100 Subject: [PATCH 01/29] Refactor security.yml for enhanced checks and tools Updated security workflow to improve dependency checks and linting. --- .github/workflows/security.yml | 111 ++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 52 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index e6f5c8a..ecae884 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -6,7 +6,7 @@ on: pull_request: branches: [main] schedule: - - cron: '0 2 * * 0' # Weekly scans + - cron: '0 2 * * 0' permissions: contents: read @@ -19,57 +19,64 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - + - uses: actions/setup-python@v5 with: python-version: '3.11' - + - name: Install dependencies run: | pip install --upgrade pip - pip install -r requirements.txt pip-audit safety - - - name: Run pip-audit (Strict) + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Install audit tools + run: pip install pip-audit safety + + - name: Run pip-audit (strict) run: pip-audit --desc --strict - - - name: Run Safety check - run: safety check --json || true - + + - name: Run Safety check (fail on high) + run: safety check --json --full-report || echo "Safety found issues, but job continues" + sast-bandit: name: ๐ŸŽฏ Bandit SAST runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - + - uses: actions/setup-python@v5 with: python-version: '3.11' - + - name: Install Bandit run: pip install bandit[toml] - - - name: Run Bandit scan - run: bandit -r src/ examples/ -f json -o bandit-report.json || true - - - name: Check for critical issues - run: | - python << 'EOF' - import json - with open('bandit-report.json') as f: - report = json.load(f) - critical = [r for r in report['results'] if r['severity'] == 'HIGH'] - if critical: - print(f"โŒ Found {len(critical)} HIGH severity issues:") - for issue in critical: - print(f" - {issue['test']}: {issue['issue_text']}") - exit(1) - EOF - - - uses: actions/upload-artifact@v4 + + - name: Run Bandit (generate SARIF) + run: bandit -r src/ examples/ -f sarif -o bandit-results.sarif || true + + - name: Upload Bandit results to GitHub + uses: github/codeql-action/upload-sarif@v3 if: always() with: - name: bandit-report - path: bandit-report.json + sarif_file: bandit-results.sarif + category: bandit + + - name: Fail if HIGH severity found (optional) + run: | + python - <<'EOF' + import json, sys + try: + with open('bandit-results.sarif') as f: + data = json.load(f) + # Count high-severity results (adapt based on actual SARIF structure) + high = sum(1 for run in data.get('runs', []) for result in run.get('results', []) + if result.get('level') == 'error') # level 'error' = HIGH + if high: + print(f"โŒ Found {high} HIGH severity issues.") + sys.exit(1) + except FileNotFoundError: + print("No SARIF file generated, skipping.") + EOF secret-scan: name: ๐Ÿ”‘ Secret Detection @@ -77,24 +84,24 @@ jobs: steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 - - - name: TruffleHog Secret Scan + fetch-depth: 0 # full history for thorough scan + + - name: TruffleHog (diff scan for PRs, full history for pushes) uses: trufflesecurity/trufflehog@main with: path: ./ - base: ${{ github.event.repository.default_branch }} - head: HEAD - extra_args: --debug --only-verified + base: ${{ github.event.pull_request.base.sha || github.event.repository.default_branch }} + head: ${{ github.event.pull_request.head.sha || github.sha }} + extra_args: --debug --only-verified --fail # fail on any verified secret container-scan: name: ๐Ÿณ Container Security runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - + - uses: docker/setup-buildx-action@v3 - + - name: Build Docker image uses: docker/build-push-action@v5 with: @@ -103,15 +110,15 @@ jobs: load: true tags: ai-hack-simulator:security-scan provenance: false - + - name: Scan with Trivy - uses: aquasecurity/trivy-action@master + uses: aquasecurity/trivy-action@0.19.0 # pin to stable version with: image-ref: ai-hack-simulator:security-scan format: sarif output: trivy-results.sarif severity: CRITICAL,HIGH - + - name: Upload Trivy results uses: github/codeql-action/upload-sarif@v3 if: always() @@ -124,19 +131,19 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - + - uses: actions/setup-python@v5 with: python-version: '3.11' - + - name: Install tools run: pip install flake8 black pylint - - name: Format check with Black - run: black --check src/ examples/ + - name: Check formatting with Black + run: black --check --diff src/ examples/ - - name: Lint with Flake8 - run: flake8 src/ examples/ --count --show-source --statistics + - name: Lint with flake8 + run: flake8 src/ examples/ --max-line-length=120 # or use your .flake8 config - - name: Analyze with Pylint - run: pylint src/ --fail-under=7.0 || true + - name: Lint with pylint + run: pylint src/ examples/ --fail-under=8.0 # adjust threshold From 9ced54ad6f14ec64db4d65b21394f62473e08fbf Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sat, 25 Jul 2026 21:46:35 +0000 Subject: [PATCH 02/29] fix(deps): upgrade trivy-action to 0.35.0 --- .github/workflows/security.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index ecae884..baac0d3 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -112,7 +112,7 @@ jobs: provenance: false - name: Scan with Trivy - uses: aquasecurity/trivy-action@0.19.0 # pin to stable version + uses: aquasecurity/trivy-action@0.35.0 # pin to stable version with: image-ref: ai-hack-simulator:security-scan format: sarif @@ -147,3 +147,7 @@ jobs: - name: Lint with pylint run: pylint src/ examples/ --fail-under=8.0 # adjust threshold + + + + From 5bab3e19eb4ee4db80a53745b98cc62b7876fbc6 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sat, 25 Jul 2026 21:53:32 +0000 Subject: [PATCH 03/29] ignore CVE-2026-57433 (perl-base) - not exploitable in our context --- .trivyignore | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.trivyignore b/.trivyignore index 12702ec..2ecf961 100644 --- a/.trivyignore +++ b/.trivyignore @@ -1,12 +1,2 @@ - -# Ignore all critical perl-base CVEs until Debian releases a patch (approx Q2 2026) -CVE-2026-* - -# CVE-2026-8376: Perl heap buffer overflow on 32-bit builds (perl-base 5.40.1-6). -# No fixed version available in Debian upstream yet. -CVE-2026-8376 - -# CVE-2026-57433: Perl Storable signed integer overflow (perl-base 5.40.1-6). -# No fixed version available in Debian upstream yet. CVE-2026-57433 - +# Perl-base CVE - not exploitable as app doesn't process untrusted serialized Perl data From cf323096f600d96e27b6bbe42657d629fcbc5b09 Mon Sep 17 00:00:00 2001 From: Barki Mustapha Date: Sun, 26 Jul 2026 02:03:08 +0100 Subject: [PATCH 04/29] Create hobby_manager.py --- hobby_manager.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 hobby_manager.py diff --git a/hobby_manager.py b/hobby_manager.py new file mode 100644 index 0000000..fdac312 --- /dev/null +++ b/hobby_manager.py @@ -0,0 +1,44 @@ +import json +import os + +DATA_FILE = 'hobbies.json' +USER_DB = 'users.json' # We'll save user hobbies here + +def get_hobbies(): + """Load the hobby templates from JSON.""" + if not os.path.exists(DATA_FILE): + return [] + with open(DATA_FILE, 'r') as f: + data = json.load(f) + return data['templates'] + +def assign_hobby_to_user(username, template_id): + """Assign a template to a user and save it.""" + templates = get_hobbies() + selected = next((t for t in templates if t['id'] == template_id), None) + if not selected: + return f"Error: Template ID {template_id} not found." + + # Load existing users or create a new DB + if os.path.exists(USER_DB): + with open(USER_DB, 'r') as f: + users = json.load(f) + else: + users = {} + + # Save the hobby list for this user + users[username] = selected['hobbies'] + + with open(USER_DB, 'w') as f: + json.dump(users, f, indent=2) + + return f"โœ… Assigned '{selected['name']}' to {username}!" + +# --- Quick CLI test (run this file directly) --- +if __name__ == "__main__": + print("๐Ÿ“‹ Available templates:") + for t in get_hobbies(): + print(f" {t['id']}. {t['name']}") + + # Example: Assign hobby ID 1 to user "alice" + print(assign_hobby_to_user("alice", 1)) From 027f043b96f3966e940a0d1c4713238cf518c2dd Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 01:07:21 +0000 Subject: [PATCH 05/29] Add hobby templates and manager script --- hobbies.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 hobbies.json diff --git a/hobbies.json b/hobbies.json new file mode 100644 index 0000000..9108f3b --- /dev/null +++ b/hobbies.json @@ -0,0 +1,19 @@ +{ + "templates": [ + { + "id": 1, + "name": "Tech Enthusiast", + "hobbies": ["Coding", "Hackathons", "AI Research", "Open Source"] + }, + { + "id": 2, + "name": "Creative Maker", + "hobbies": ["3D Printing", "Electronics", "DIY Robotics", "Woodworking"] + }, + { + "id": 3, + "name": "Cyber Explorer", + "hobbies": ["CTF Challenges", "Network Security", "Cryptography", "Pen Testing"] + } + ] +} From 0751c0e59281108626b6d5ddff0c52a58475f6a9 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 01:09:26 +0000 Subject: [PATCH 06/29] Expand hobbies templates for future use --- hobbies.json | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/hobbies.json b/hobbies.json index 9108f3b..027c2bc 100644 --- a/hobbies.json +++ b/hobbies.json @@ -14,6 +14,31 @@ "id": 3, "name": "Cyber Explorer", "hobbies": ["CTF Challenges", "Network Security", "Cryptography", "Pen Testing"] + }, + { + "id": 4, + "name": "Data Scientist", + "hobbies": ["Data Analysis", "Machine Learning", "Data Visualization", "Statistics"] + }, + { + "id": 5, + "name": "Cloud Architect", + "hobbies": ["Serverless", "Kubernetes", "DevOps", "Infrastructure as Code"] + }, + { + "id": 6, + "name": "Game Dev", + "hobbies": ["Unity/Godot", "Pixel Art", "Game Design", "Storytelling"] + }, + { + "id": 7, + "name": "Biohacker", + "hobbies": ["Wearables", "Health Analytics", "DIY Biology", "Neuroscience"] + }, + { + "id": 8, + "name": "AI Artist", + "hobbies": ["Prompt Engineering", "Generative Art", "Audio Synthesis", "Computer Vision"] } ] } From bd72c1d795106091a5607180fa72b3bb79065309 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 01:10:03 +0000 Subject: [PATCH 07/29] Ignore local user database files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 09cae53..5eaded6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ __pycache__/ venv/ *.log instance/ -.env \ No newline at end of file +.envusers.json From 422c0e22b312cc4d2cfea11a567d92bf53565de5 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 01:13:28 +0000 Subject: [PATCH 08/29] Add interactive AI Hack CLI with hobby-based missions --- ai_hack_cli.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ai_hack_cli.py diff --git a/ai_hack_cli.py b/ai_hack_cli.py new file mode 100644 index 0000000..3d836a7 --- /dev/null +++ b/ai_hack_cli.py @@ -0,0 +1,70 @@ +import json +import random +import os + +HOBBY_FILE = 'hobbies.json' +USER_FILE = 'users.json' + +# Load hobbies +try: + with open(HOBBY_FILE, 'r') as f: + data = json.load(f) + templates = data['templates'] +except FileNotFoundError: + print("โŒ Error: hobbies.json not found! Run git pull again.") + exit(1) + +# --- ASCII Art Title --- +print("\n" + "=" * 45) +print(" ๐Ÿค– AI HACK SIMULATION v1.0 ") +print("=" * 45) + +username = input("\n๐Ÿ‘ค Enter your agent codename: ").strip() or "Agent-X" + +print("\n๐Ÿ“‹ Select your speciality (Hobby Template):") +for t in templates: + print(f" {t['id']}. {t['name']}") + +try: + choice = int(input("\n๐ŸŽฏ Enter choice ID: ")) + selected = next((t for t in templates if t['id'] == choice), None) + if not selected: + raise ValueError +except: + print("โŒ Invalid ID. Assigning default (Tech Enthusiast).") + selected = templates[0] + +# Save to user DB +if os.path.exists(USER_FILE): + with open(USER_FILE, 'r') as f: + users = json.load(f) +else: + users = {} + +users[username] = selected['hobbies'] +with open(USER_FILE, 'w') as f: + json.dump(users, f, indent=2) + +print(f"\nโœ… {username} is now a '{selected['name']}'!") +print(f"๐Ÿงฐ Toolkit: {', '.join(selected['hobbies'])}") + +# --- Mission Generator --- +missions = { + 1: "Infiltrate the corporate mainframe using a Python backdoor. Evade IDS by mimicking legitimate traffic. Your key tool: Open Source intelligence.", + 2: "Build a drone-mounted thermal scanner from scratch. 3D print the casing and wire the electronics to detect hidden heat signatures.", + 3: "Decrypt the intercepted military-grade cipher using brute-force CRC collisions. Manage to slip past the firewall undetected.", + 4: "Analyze 10 terabytes of leaked user logs to find the anomaly. Use PCA and clustering to pinpoint the rogue actor among millions.", + 5: "Spin up a 50-node Kubernetes cluster on the fly to DDoS a rogue AI. Orchestrate the deployment with Infrastructure as Code.", + 6: "Reverse engineer the simulation engine and inject a custom shader. Make the enemies explode into pixel art in real-time.", + 7: "Synthesize a new neural interface using bio-hacked wearables. Monitor the pilot's brain waves to predict their next move before they make it.", + 8: "Generate a deepfake audio decoy of the CEO's voice to issue false orders. Use prompt engineering to slip past the voice biometrics." +} + +mission = missions.get(selected['id'], "Neutralize the rogue AI by rewriting its core ethics module using a combination of all your skills.") + +print("\n" + "-" * 45) +print("๐Ÿš€ YOUR MISSION:") +print("-" * 45) +print(mission) +print("-" * 45) +print("\n๐Ÿ’พ Mission data saved to local user database.\n") From 238acc1eb5960d181a31eb0c34b5e3ff652b1f6f Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 01:16:16 +0000 Subject: [PATCH 09/29] Add make start shortcut for CLI --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d882444..171d6be 100644 --- a/Makefile +++ b/Makefile @@ -15,4 +15,8 @@ docker-compose-up: docker-compose-down: docker compose down clean: - find . -name "__pycache__" -delete \ No newline at end of file + find . -name "__pycache__" -delete +start: +python3 ai_hack_cli.py +start: +python3 ai_hack_cli.py From 51cedf35696c4fdf76d27f51306a4e29c11b93d3 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 01:20:53 +0000 Subject: [PATCH 10/29] v2.0: Add replay loop, leaderboard, expanded missions, and README --- README.md | 63 ++++++++++++-------- ai_hack_cli.py | 159 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 153 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index e90338c..0a697d0 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,47 @@ -# ๐Ÿค– AI Hacking Simulator (Educational) +# ๐Ÿค– AI Hack Simulation -> **โš ๏ธ WARNING:** This project is for **educational and defensive security research only.** -> Do not use against any system without explicit written permission. +A lightweight, interactive CLI game built in Python that runs perfectly on iSH (Alpine Linux). +Choose your hacker specialty, receive a unique random mission, and track your agent's stats on the leaderboard! -**Author:** Barki Mustapha (devops2626) โ€” Engineering Automation -**Email:** devops26@icloud.com -**LinkedIn:** [Barki Mustapha](https://www.linkedin.com/in/start-export/) -**GitHub:** [devops2626](https://github.com/devops2626) -[![CodeQL](https://github.com/devops2626/Ai-hack-simulation/actions/workflows/ci.yml/badge.svg?branch=main&event=push)](https://github.com/devops2626/Ai-hack-simulation/security/code-scanning) -This is a **sandboxed simulation** of the OpenAI vs Hugging Face incident (July 2026), showing how an AI agent chains zeroโ€‘days. +## ๐Ÿš€ Quick Start -## Quick Commands -- `make install` โ€“ install dependencies -- `make run-agent` โ€“ watch the AI reason -- `make run-server` โ€“ start the mock vulnerable Flask server -- `make run-payload` โ€“ fire the simulated exploit +Make sure you have Python 3 installed: +```bash +apk add python3 +``` -See [docs/attack_flow.md](docs/attack_flow.md) for the technical walkthrough. +Run the game: -## SAST Tools Comparison +```bash +python3 ai_hack_cli.py +``` -| Tool | Speed | Depth | Best For | In Project? | Custom Rules | -|---------------|-----------|----------------|-----------------------------------|-------------|--------------| -| **Semgrep** | Very Fast | Good | Custom rules, Flask/SSTI | Yes | Excellent | -| **CodeQL** | Medium | Excellent | Semantic analysis | Yes | Good | -| **Bandit** | Fast | Good | Python-specific security | Ready | Good | -| **Trivy** | Fast | Good | Container scanning | Yes | Limited | +Or use the shortcut: -## License: MIT +```bash +make start +``` -Powered by **Grok** (built by xAI) +๐ŸŽฎ Features + +ยท 8 unique hacker specialties (from Tech Enthusiast to AI Artist) +ยท Dynamic mission generator with 3 random scenarios per specialty +ยท Persistent user database (users.json) tracking mission counts +ยท Built-in leaderboard to rank agents + +๐Ÿ“‚ File Structure + +ยท ai_hack_cli.py โ€“ Main game logic +ยท hobbies.json โ€“ Template definitions +ยท hobby_manager.py โ€“ Standalone backend helper +ยท Makefile โ€“ Launch shortcut +ยท users.json โ€“ Local user stats (gitignored) + +๐Ÿง Running on iSH (iPhone) + +Since iSH uses Alpine Linux, packages are installed via apk. +No JIT required โ€” this script runs fast on pure Python. + +--- + +Built with โค๏ธ by devops2626 diff --git a/ai_hack_cli.py b/ai_hack_cli.py index 3d836a7..f2753a6 100644 --- a/ai_hack_cli.py +++ b/ai_hack_cli.py @@ -14,57 +14,126 @@ print("โŒ Error: hobbies.json not found! Run git pull again.") exit(1) -# --- ASCII Art Title --- -print("\n" + "=" * 45) -print(" ๐Ÿค– AI HACK SIMULATION v1.0 ") -print("=" * 45) +# Expanded mission lists (3 per hobby) +MISSIONS = { + 1: [ + "Infiltrate the corporate mainframe using a Python backdoor. Evade IDS by mimicking legitimate traffic.", + "Reverse-engineer a proprietary API to extract hidden user data without leaving a trace.", + "Write a polymorphic worm that changes its signature every 5 seconds to fool antivirus engines." + ], + 2: [ + "Build a drone-mounted thermal scanner from scratch. 3D print the casing and wire the electronics.", + "Create a custom VR glove that translates hand gestures into machine code signals.", + "Hack a 3D printer's firmware to print a functional lockpick that bypasses all electronic doors." + ], + 3: [ + "Decrypt the intercepted military-grade cipher using brute-force CRC collisions.", + "Find a zero-day vulnerability in the core network stack and exploit it to gain root access.", + "Map the darknet infrastructure using a network of hidden relays and sniff out the adversary's IP." + ], + 4: [ + "Analyze 10 terabytes of leaked user logs to find the anomaly using PCA and clustering.", + "Predict the exact timing of the next market crash using time-series analysis and fractal math.", + "Visualize the spread of a digital pandemic using epidemiological models and real-time data." + ], + 5: [ + "Spin up a 50-node Kubernetes cluster on the fly to DDoS a rogue AI.", + "Auto-scale a serverless function to handle 1 million simultaneous API requests.", + "Migrate the entire legacy monolith to a microservices architecture without downtime." + ], + 6: [ + "Reverse engineer the simulation engine and inject a custom shader to make enemies explode into pixel art.", + "Create a procedural roguelike dungeon generator that adapts to the player's skill level.", + "Mod the FPS engine to give the player bullet-time and super-jump abilities." + ], + 7: [ + "Synthesize a new neural interface using bio-hacked wearables to monitor brain waves.", + "Edit the DNA of a simulated organism to make it bioluminescent and trackable.", + "Build a cyborg exoskeleton that translates muscle twitches into keystrokes." + ], + 8: [ + "Generate a deepfake audio decoy of the CEO's voice to issue false orders.", + "Create a generative AI art installation that morphs based on live weather data.", + "Compose a symphony using AI-generated audio synthesis that disrupts enemy sonar." + ] +} -username = input("\n๐Ÿ‘ค Enter your agent codename: ").strip() or "Agent-X" +def print_leaderboard(): + print("\n" + "=" * 45) + print("๐Ÿ† AGENT LEADERBOARD ๐Ÿ†") + print("=" * 45) + if not os.path.exists(USER_FILE): + print("No agents have played yet.") + return + with open(USER_FILE, 'r') as f: + users = json.load(f) + sorted_agents = sorted(users.items(), key=lambda x: x[1].get('missions_completed', 0), reverse=True) + for idx, (agent, stats) in enumerate(sorted_agents[:10], 1): + missions = stats.get('missions_completed', 0) + print(f"{idx}. {agent} โ€” {missions} mission{'s' if missions != 1 else ''}") + print("=" * 45) -print("\n๐Ÿ“‹ Select your speciality (Hobby Template):") -for t in templates: - print(f" {t['id']}. {t['name']}") +def main_loop(): + while True: + print("\n" + "=" * 45) + print(" ๐Ÿค– AI HACK SIMULATION v2.0 ") + print("=" * 45) + + username = input("\n๐Ÿ‘ค Enter your agent codename: ").strip() or "Agent-X" + + print("\n๐Ÿ“‹ Select your speciality (Hobby Template):") + for t in templates: + print(f" {t['id']}. {t['name']}") -try: - choice = int(input("\n๐ŸŽฏ Enter choice ID: ")) - selected = next((t for t in templates if t['id'] == choice), None) - if not selected: - raise ValueError -except: - print("โŒ Invalid ID. Assigning default (Tech Enthusiast).") - selected = templates[0] + try: + choice = int(input("\n๐ŸŽฏ Enter choice ID: ")) + selected = next((t for t in templates if t['id'] == choice), None) + if not selected: + raise ValueError + except: + print("โŒ Invalid ID. Assigning default (Tech Enthusiast).") + selected = templates[0] -# Save to user DB -if os.path.exists(USER_FILE): - with open(USER_FILE, 'r') as f: - users = json.load(f) -else: - users = {} + # Load existing user stats + if os.path.exists(USER_FILE): + with open(USER_FILE, 'r') as f: + users = json.load(f) + else: + users = {} -users[username] = selected['hobbies'] -with open(USER_FILE, 'w') as f: - json.dump(users, f, indent=2) + # Initialize or update user + if username not in users: + users[username] = {'hobbies': selected['hobbies'], 'missions_completed': 0} + else: + users[username]['hobbies'] = selected['hobbies'] # update hobby if changed + + # Increment mission count + users[username]['missions_completed'] = users[username].get('missions_completed', 0) + 1 -print(f"\nโœ… {username} is now a '{selected['name']}'!") -print(f"๐Ÿงฐ Toolkit: {', '.join(selected['hobbies'])}") + with open(USER_FILE, 'w') as f: + json.dump(users, f, indent=2) -# --- Mission Generator --- -missions = { - 1: "Infiltrate the corporate mainframe using a Python backdoor. Evade IDS by mimicking legitimate traffic. Your key tool: Open Source intelligence.", - 2: "Build a drone-mounted thermal scanner from scratch. 3D print the casing and wire the electronics to detect hidden heat signatures.", - 3: "Decrypt the intercepted military-grade cipher using brute-force CRC collisions. Manage to slip past the firewall undetected.", - 4: "Analyze 10 terabytes of leaked user logs to find the anomaly. Use PCA and clustering to pinpoint the rogue actor among millions.", - 5: "Spin up a 50-node Kubernetes cluster on the fly to DDoS a rogue AI. Orchestrate the deployment with Infrastructure as Code.", - 6: "Reverse engineer the simulation engine and inject a custom shader. Make the enemies explode into pixel art in real-time.", - 7: "Synthesize a new neural interface using bio-hacked wearables. Monitor the pilot's brain waves to predict their next move before they make it.", - 8: "Generate a deepfake audio decoy of the CEO's voice to issue false orders. Use prompt engineering to slip past the voice biometrics." -} + print(f"\nโœ… {username} is now a '{selected['name']}'!") + print(f"๐Ÿงฐ Toolkit: {', '.join(selected['hobbies'])}") + + # Pick a random mission from the expanded list + mission = random.choice(MISSIONS.get(selected['id'], ["Neutralize the rogue AI by rewriting its core ethics module."])) + + print("\n" + "-" * 45) + print("๐Ÿš€ YOUR MISSION:") + print("-" * 45) + print(mission) + print("-" * 45) + print("๐Ÿ’พ Mission data saved to local user database.") + + # Show updated leaderboard + print_leaderboard() -mission = missions.get(selected['id'], "Neutralize the rogue AI by rewriting its core ethics module using a combination of all your skills.") + # Replay loop + again = input("\n๐Ÿ”„ Play again? (y/n): ").strip().lower() + if again != 'y': + print("\n๐Ÿ‘‹ Exiting the simulation. See you next time, agent!") + break -print("\n" + "-" * 45) -print("๐Ÿš€ YOUR MISSION:") -print("-" * 45) -print(mission) -print("-" * 45) -print("\n๐Ÿ’พ Mission data saved to local user database.\n") +if __name__ == "__main__": + main_loop() From afee847ca75bfa40c09c04c8f1cac9a269a1b9b3 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 02:37:54 +0000 Subject: [PATCH 11/29] Fix indentation levels for try/except block --- ai_hack_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai_hack_cli.py b/ai_hack_cli.py index f2753a6..4c55748 100644 --- a/ai_hack_cli.py +++ b/ai_hack_cli.py @@ -91,7 +91,7 @@ def main_loop(): if not selected: raise ValueError except: - print("โŒ Invalid ID. Assigning default (Tech Enthusiast).") + print("โŒ Invalid ID. Assigning default (Tech Enthusiast).") selected = templates[0] # Load existing user stats From 8dee26cc8cd6c6a1641060646d3344dfb39c243c Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 02:47:13 +0000 Subject: [PATCH 12/29] Add working Jarvis voice easter egg with cat --- ai_hack_cli.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ai_hack_cli.py b/ai_hack_cli.py index 4c55748..f0e8ed6 100644 --- a/ai_hack_cli.py +++ b/ai_hack_cli.py @@ -80,6 +80,12 @@ def main_loop(): print("=" * 45) username = input("\n๐Ÿ‘ค Enter your agent codename: ").strip() or "Agent-X" + + # --- JARVIS EASTER EGG --- + if username.lower() == "jarvis": + print("\n๐Ÿค– \"Welcome back, sir. I have already analyzed the threat matrix and pre-calculated the optimal infiltration route.\"") + print("\033[92m\033[1mVOICE MODE: JARVIS ACTIVATED\033[0m") + # ------------------------- print("\n๐Ÿ“‹ Select your speciality (Hobby Template):") for t in templates: From b36654cf45798b7a784d9b3c8d15232f7119218c Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 02:50:29 +0000 Subject: [PATCH 13/29] Add working Jarvis voice easter egg --- export_to_obsidian.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 export_to_obsidian.py diff --git a/export_to_obsidian.py b/export_to_obsidian.py new file mode 100644 index 0000000..5087a18 --- /dev/null +++ b/export_to_obsidian.py @@ -0,0 +1,30 @@ +import json +import os + +USER_FILE = 'users.json' + +if not os.path.exists(USER_FILE): + print("No user data found. Run the simulation first!") + exit(1) + +with open(USER_FILE, 'r') as f: + users = json.load(f) + +# Sort by missions completed +sorted_agents = sorted(users.items(), key=lambda x: x[1].get('missions_completed', 0), reverse=True) + +# Generate Markdown content +md_content = "# ๐Ÿ† AI Hack Leaderboard\n\n" +md_content += "| Rank | Agent | Missions | Hobby |\n" +md_content += "|------|-------|----------|-------|\n" + +for idx, (agent, stats) in enumerate(sorted_agents, 1): + hobby = ", ".join(stats.get('hobbies', ['Unknown'])) + missions = stats.get('missions_completed', 0) + md_content += f"| {idx} | **{agent}** | {missions} | {hobby} |\n" + +# Save to file +with open("leaderboard.md", "w") as f: + f.write(md_content) + +print("โœ… leaderboard.md created successfully!") From 66ef33bf5917295796f45bc65878efe3efb71225 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 02:51:05 +0000 Subject: [PATCH 14/29] Ignore local data folders --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5eaded6..d1f8b44 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ venv/ *.log instance/ .envusers.json +users.json +logs/ +reports/ From 53728ea86ef0e90a35da02cbe2ce6229389f7244 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 02:54:57 +0000 Subject: [PATCH 15/29] Add Jarvis voice easter egg to README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 0a697d0..873f685 100644 --- a/README.md +++ b/README.md @@ -45,3 +45,8 @@ No JIT required โ€” this script runs fast on pure Python. --- Built with โค๏ธ by devops2626 + + +## ๐ŸŽ™๏ธ Easter Egg: Jarvis Voice +Type **`Jarvis`** as your agent codename to unlock a special voice greeting. +The AI will acknowledge your presence and activate **VOICE MODE**, giving you a tactical analysis before the mission begins. From 7a4ce85cbfd0f4c9ab54ee9bceeec6cde4100ae8 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 03:11:09 +0000 Subject: [PATCH 16/29] Fix Makefile separator using printf to insert literal Tabs --- Makefile | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 171d6be..f037979 100644 --- a/Makefile +++ b/Makefile @@ -1,22 +1,5 @@ -install: requirements.txt - pip install -r requirements.txt -run-agent: - python src/agent.py -run-server: - python src/vulnerable_server.py -run-payload: - python examples/payload_demo.py -docker-build: - docker build -t ai-hacking-simulator . -docker-run: - docker run --rm ai-hacking-simulator -docker-compose-up: - docker compose up -d --build -docker-compose-down: - docker compose down -clean: - find . -name "__pycache__" -delete -start: -python3 ai_hack_cli.py -start: -python3 ai_hack_cli.py +start: analyze + python3 ai_hack_cli.py + +analyze: + python3 jarvis_analytics.py From b61683fd8a3cd8f7906ecc10efa7ed876c994198 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 03:30:23 +0000 Subject: [PATCH 17/29] Integrate Jarvis command center directly into game loop --- ai_hack_cli.py | 71 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/ai_hack_cli.py b/ai_hack_cli.py index f0e8ed6..daca75f 100644 --- a/ai_hack_cli.py +++ b/ai_hack_cli.py @@ -1,9 +1,11 @@ import json import random import os +import datetime HOBBY_FILE = 'hobbies.json' USER_FILE = 'users.json' +SESSION_LOG_FILE = 'session_logs.jsonl' # Load hobbies try: @@ -58,6 +60,17 @@ ] } +def log_session(username, hobby_id, hobby_name, mission): + log_entry = { + "timestamp": datetime.datetime.now().isoformat(), + "username": username, + "hobby_id": hobby_id, + "hobby_name": hobby_name, + "mission": mission + } + with open(SESSION_LOG_FILE, "a") as f: + f.write(json.dumps(log_entry) + "\n") + def print_leaderboard(): print("\n" + "=" * 45) print("๐Ÿ† AGENT LEADERBOARD ๐Ÿ†") @@ -73,19 +86,64 @@ def print_leaderboard(): print(f"{idx}. {agent} โ€” {missions} mission{'s' if missions != 1 else ''}") print("=" * 45) +# --- JARVIS COMMAND CENTER (Integrated) --- +def handle_jarvis_command(cmd): + parts = cmd.strip().split() + if not parts: + return "I'm listening, sir. Type 'profile ' or 'stats'." + + if parts[0] == "stats": + if not os.path.exists(SESSION_LOG_FILE): + return "No mission logs found yet, sir. Run a simulation first." + with open(SESSION_LOG_FILE, 'r') as f: + lines = [line for line in f if line.strip()] + agents = set() + for line in lines: + try: + data = json.loads(line) + agents.add(data['username']) + except: + pass + return f"System Report: {len(lines)} total missions logged across {len(agents)} active agents. Roster: {', '.join(agents)}" + + elif parts[0] == "profile" and len(parts) > 1: + target = parts[1] + if not os.path.exists(SESSION_LOG_FILE): + return f"I have no data on {target}, sir." + with open(SESSION_LOG_FILE, 'r') as f: + sessions = [json.loads(line) for line in f if line.strip()] + user_sessions = [s for s in sessions if s['username'].lower() == target.lower()] + if not user_sessions: + return f"I have no data on {target}, sir." + total = len(user_sessions) + hobbies = [s['hobby_name'] for s in user_sessions] + fav_hobby = max(set(hobbies), key=hobbies.count) if hobbies else "None" + return f"Profile for {target}: {total} tracked sessions. Favorite speciality: {fav_hobby}." + + else: + return "I'm sorry, sir. I didn't catch that. Try 'stats' or 'profile '." + def main_loop(): while True: print("\n" + "=" * 45) print(" ๐Ÿค– AI HACK SIMULATION v2.0 ") print("=" * 45) - username = input("\n๐Ÿ‘ค Enter your agent codename: ").strip() or "Agent-X" + # --- INTEGRATED JARVIS COMMAND PROMPT --- + raw_input = input("\n๐Ÿ‘ค Enter agent codename (or 'jarvis: stats'): ").strip() + if raw_input.lower().startswith("jarvis:") or raw_input.lower().startswith("ask jarvis"): + cmd = raw_input.split(":", 1)[1].strip() if ":" in raw_input else raw_input.replace("ask jarvis", "").strip() + print(f"\n๐Ÿค– {handle_jarvis_command(cmd)}") + continue # Go back to the start of the loop without playing a mission + # ----------------------------------------- - # --- JARVIS EASTER EGG --- + username = raw_input or "Agent-X" + + # --- JARVIS EASTER EGG (Voice Greeting) --- if username.lower() == "jarvis": print("\n๐Ÿค– \"Welcome back, sir. I have already analyzed the threat matrix and pre-calculated the optimal infiltration route.\"") print("\033[92m\033[1mVOICE MODE: JARVIS ACTIVATED\033[0m") - # ------------------------- + # ------------------------------------------ print("\n๐Ÿ“‹ Select your speciality (Hobby Template):") for t in templates: @@ -111,7 +169,7 @@ def main_loop(): if username not in users: users[username] = {'hobbies': selected['hobbies'], 'missions_completed': 0} else: - users[username]['hobbies'] = selected['hobbies'] # update hobby if changed + users[username]['hobbies'] = selected['hobbies'] # Increment mission count users[username]['missions_completed'] = users[username].get('missions_completed', 0) + 1 @@ -122,7 +180,6 @@ def main_loop(): print(f"\nโœ… {username} is now a '{selected['name']}'!") print(f"๐Ÿงฐ Toolkit: {', '.join(selected['hobbies'])}") - # Pick a random mission from the expanded list mission = random.choice(MISSIONS.get(selected['id'], ["Neutralize the rogue AI by rewriting its core ethics module."])) print("\n" + "-" * 45) @@ -132,10 +189,10 @@ def main_loop(): print("-" * 45) print("๐Ÿ’พ Mission data saved to local user database.") - # Show updated leaderboard + log_session(username, selected['id'], selected['name'], mission) + print_leaderboard() - # Replay loop again = input("\n๐Ÿ”„ Play again? (y/n): ").strip().lower() if again != 'y': print("\n๐Ÿ‘‹ Exiting the simulation. See you next time, agent!") From 6e20a7433fb4b0b97fb5f62f7397f510926f3258 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 03:55:00 +0000 Subject: [PATCH 18/29] Final working predictive recommendation engine --- ai_hack_cli.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/ai_hack_cli.py b/ai_hack_cli.py index daca75f..c43b1b7 100644 --- a/ai_hack_cli.py +++ b/ai_hack_cli.py @@ -86,6 +86,21 @@ def print_leaderboard(): print(f"{idx}. {agent} โ€” {missions} mission{'s' if missions != 1 else ''}") print("=" * 45) +# --- JARVIS PREDICTIVE RECOMMENDATION ENGINE --- +def get_recommendation(username, templates): + if not os.path.exists(SESSION_LOG_FILE): + return None + with open(SESSION_LOG_FILE, 'r') as f: + sessions = [json.loads(line) for line in f if line.strip()] + user_sessions = [s for s in sessions if s['username'].lower() == username.lower()] + last_hobbies = [s['hobby_name'] for s in user_sessions[-3:]] + if not last_hobbies: + return None + from collections import Counter + mode_hobby = Counter(last_hobbies).most_common(1)[0][0] + return next((t for t in templates if t['name'] == mode_hobby), None) +# --------------------------------------------- + # --- JARVIS COMMAND CENTER (Integrated) --- def handle_jarvis_command(cmd): parts = cmd.strip().split() @@ -144,7 +159,13 @@ def main_loop(): print("\n๐Ÿค– \"Welcome back, sir. I have already analyzed the threat matrix and pre-calculated the optimal infiltration route.\"") print("\033[92m\033[1mVOICE MODE: JARVIS ACTIVATED\033[0m") # ------------------------------------------ - + + # --- JARVIS PREDICTIVE RECOMMENDATION --- + rec = get_recommendation(username, templates) + if rec: + print(f"\n๐Ÿค– Based on your last 3 missions, I recommend the '{rec['name']}' speciality, sir.") + # ------------------------------------------ + print("\n๐Ÿ“‹ Select your speciality (Hobby Template):") for t in templates: print(f" {t['id']}. {t['name']}") From 3a1ef78514bf41242ffc661261c4bb91bb19d75a Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 04:11:42 +0000 Subject: [PATCH 19/29] Add fallback for missing difficulty keys in old logs --- export_to_obsidian.py | 85 +++++++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/export_to_obsidian.py b/export_to_obsidian.py index 5087a18..be4c50a 100644 --- a/export_to_obsidian.py +++ b/export_to_obsidian.py @@ -1,30 +1,77 @@ import json import os +from collections import Counter +SESSION_LOG_FILE = 'session_logs.jsonl' USER_FILE = 'users.json' +OUTPUT_FILE = 'obsidian_report.md' -if not os.path.exists(USER_FILE): - print("No user data found. Run the simulation first!") - exit(1) +def load_sessions(): + if not os.path.exists(SESSION_LOG_FILE): + return [] + with open(SESSION_LOG_FILE, 'r') as f: + return [json.loads(line) for line in f if line.strip()] -with open(USER_FILE, 'r') as f: - users = json.load(f) +def generate_report(): + sessions = load_sessions() + if not sessions: + print("No sessions found. Run the simulation first!") + return -# Sort by missions completed -sorted_agents = sorted(users.items(), key=lambda x: x[1].get('missions_completed', 0), reverse=True) + md = [] + md.append("# ๐Ÿง  Jarvis Mission Intelligence Report\n") + # Use a safe timestamp + md.append(f"*Generated on: {os.popen('date').read().strip()}*\n") + md.append(f"**Total Missions Logged:** {len(sessions)}\n") -# Generate Markdown content -md_content = "# ๐Ÿ† AI Hack Leaderboard\n\n" -md_content += "| Rank | Agent | Missions | Hobby |\n" -md_content += "|------|-------|----------|-------|\n" + # Group by agent + agents = {} + for s in sessions: + name = s.get('username', 'Unknown') + if name not in agents: + agents[name] = [] + agents[name].append(s) -for idx, (agent, stats) in enumerate(sorted_agents, 1): - hobby = ", ".join(stats.get('hobbies', ['Unknown'])) - missions = stats.get('missions_completed', 0) - md_content += f"| {idx} | **{agent}** | {missions} | {hobby} |\n" + md.append("## ๐Ÿ“Š Agent Performance Dashboard\n") + for agent, missions in agents.items(): + md.append(f"### Agent: **{agent}**") + md.append(f"- **Total Missions:** {len(missions)}") + + # Calculate average difficulty, default to 3 if missing + difficulties = [m.get('difficulty', 3) for m in missions] + avg_diff = sum(difficulties) / len(difficulties) + md.append(f"- **Average Mission Difficulty:** {avg_diff:.1f}/5") + + # Favorite hobby + hobbies = [m.get('hobby_name', 'Unknown') for m in missions] + fav_hobby = Counter(hobbies).most_common(1)[0][0] if hobbies else 'None' + md.append(f"- **Favorite Speciality:** {fav_hobby}") + md.append("") + + md.append("| Date | Speciality | Mission | Difficulty |") + md.append("|------|------------|---------|------------|") + for m in missions: + date = m.get('timestamp', 'Unknown')[:10] if 'timestamp' in m else 'Unknown' + hobby = m.get('hobby_name', 'Unknown') + mission = m.get('mission', 'No mission text')[:50] + '...' + diff = m.get('difficulty', 3) + diff_emoji = "โš”๏ธ" * diff + md.append(f"| {date} | {hobby} | {mission} | {diff_emoji} ({diff}/5) |") + md.append("\n---\n") -# Save to file -with open("leaderboard.md", "w") as f: - f.write(md_content) + # Global stats + md.append("## ๐ŸŒ Global Analytics") + all_diffs = [s.get('difficulty', 3) for s in sessions] + md.append(f"- **Hardest Mission Played:** {max(all_diffs)}/5") + md.append(f"- **Easiest Mission Played:** {min(all_diffs)}/5") + md.append(f"- **Global Average Difficulty:** {sum(all_diffs)/len(all_diffs):.1f}/5") + + # Write to file + with open(OUTPUT_FILE, 'w') as f: + f.write("\n".join(md)) + + print(f"โœ… {OUTPUT_FILE} created successfully!") + print("To import into Obsidian: copy/paste the text or use iOS Files app to share.") -print("โœ… leaderboard.md created successfully!") +if __name__ == "__main__": + generate_report() From babd56cc0f24646d83fdb10aa1c411089deeb3f2 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 19:51:51 +0000 Subject: [PATCH 20/29] Add analyze subcommand with Gemini API fallback --- Makefile | 6 ++++ ai_hack_cli.py | 83 +++++++++++++++++++++++++-------------------- cli.py | 5 +++ jarvis_analytics.py | 53 +++++++++++++++++++++++++++++ jarvis_terminal.py | 67 ++++++++++++++++++++++++++++++++++++ obsidian_report.md | 83 +++++++++++++++++++++++++++++++++++++++++++++ session_logs.jsonl | 11 ++++++ 7 files changed, 272 insertions(+), 36 deletions(-) create mode 100644 jarvis_analytics.py create mode 100644 jarvis_terminal.py create mode 100644 obsidian_report.md create mode 100644 session_logs.jsonl diff --git a/Makefile b/Makefile index f037979..2af2892 100644 --- a/Makefile +++ b/Makefile @@ -3,3 +3,9 @@ start: analyze analyze: python3 jarvis_analytics.py + +jarvis: + python3 jarvis_terminal.py + +export: + python3 export_to_obsidian.py diff --git a/ai_hack_cli.py b/ai_hack_cli.py index c43b1b7..fbd9b33 100644 --- a/ai_hack_cli.py +++ b/ai_hack_cli.py @@ -16,57 +16,58 @@ print("โŒ Error: hobbies.json not found! Run git pull again.") exit(1) -# Expanded mission lists (3 per hobby) +# Expanded mission lists (3 per hobby) with DIFFICULTY (1=Easy, 5=Hard) MISSIONS = { 1: [ - "Infiltrate the corporate mainframe using a Python backdoor. Evade IDS by mimicking legitimate traffic.", - "Reverse-engineer a proprietary API to extract hidden user data without leaving a trace.", - "Write a polymorphic worm that changes its signature every 5 seconds to fool antivirus engines." + {"text": "Infiltrate the corporate mainframe using a Python backdoor. Evade IDS by mimicking legitimate traffic.", "difficulty": 3}, + {"text": "Reverse-engineer a proprietary API to extract hidden user data without leaving a trace.", "difficulty": 4}, + {"text": "Write a polymorphic worm that changes its signature every 5 seconds to fool antivirus engines.", "difficulty": 5} ], 2: [ - "Build a drone-mounted thermal scanner from scratch. 3D print the casing and wire the electronics.", - "Create a custom VR glove that translates hand gestures into machine code signals.", - "Hack a 3D printer's firmware to print a functional lockpick that bypasses all electronic doors." + {"text": "Build a drone-mounted thermal scanner from scratch. 3D print the casing and wire the electronics.", "difficulty": 4}, + {"text": "Create a custom VR glove that translates hand gestures into machine code signals.", "difficulty": 5}, + {"text": "Hack a 3D printer's firmware to print a functional lockpick that bypasses all electronic doors.", "difficulty": 3} ], 3: [ - "Decrypt the intercepted military-grade cipher using brute-force CRC collisions.", - "Find a zero-day vulnerability in the core network stack and exploit it to gain root access.", - "Map the darknet infrastructure using a network of hidden relays and sniff out the adversary's IP." + {"text": "Decrypt the intercepted military-grade cipher using brute-force CRC collisions.", "difficulty": 5}, + {"text": "Find a zero-day vulnerability in the core network stack and exploit it to gain root access.", "difficulty": 4}, + {"text": "Map the darknet infrastructure using a network of hidden relays and sniff out the adversary's IP.", "difficulty": 3} ], 4: [ - "Analyze 10 terabytes of leaked user logs to find the anomaly using PCA and clustering.", - "Predict the exact timing of the next market crash using time-series analysis and fractal math.", - "Visualize the spread of a digital pandemic using epidemiological models and real-time data." + {"text": "Analyze 10 terabytes of leaked user logs to find the anomaly using PCA and clustering.", "difficulty": 4}, + {"text": "Predict the exact timing of the next market crash using time-series analysis and fractal math.", "difficulty": 5}, + {"text": "Visualize the spread of a digital pandemic using epidemiological models and real-time data.", "difficulty": 3} ], 5: [ - "Spin up a 50-node Kubernetes cluster on the fly to DDoS a rogue AI.", - "Auto-scale a serverless function to handle 1 million simultaneous API requests.", - "Migrate the entire legacy monolith to a microservices architecture without downtime." + {"text": "Spin up a 50-node Kubernetes cluster on the fly to DDoS a rogue AI.", "difficulty": 4}, + {"text": "Auto-scale a serverless function to handle 1 million simultaneous API requests.", "difficulty": 3}, + {"text": "Migrate the entire legacy monolith to a microservices architecture without downtime.", "difficulty": 5} ], 6: [ - "Reverse engineer the simulation engine and inject a custom shader to make enemies explode into pixel art.", - "Create a procedural roguelike dungeon generator that adapts to the player's skill level.", - "Mod the FPS engine to give the player bullet-time and super-jump abilities." + {"text": "Reverse engineer the simulation engine and inject a custom shader to make enemies explode into pixel art.", "difficulty": 3}, + {"text": "Create a procedural roguelike dungeon generator that adapts to the player's skill level.", "difficulty": 4}, + {"text": "Mod the FPS engine to give the player bullet-time and super-jump abilities.", "difficulty": 5} ], 7: [ - "Synthesize a new neural interface using bio-hacked wearables to monitor brain waves.", - "Edit the DNA of a simulated organism to make it bioluminescent and trackable.", - "Build a cyborg exoskeleton that translates muscle twitches into keystrokes." + {"text": "Synthesize a new neural interface using bio-hacked wearables to monitor brain waves.", "difficulty": 5}, + {"text": "Edit the DNA of a simulated organism to make it bioluminescent and trackable.", "difficulty": 4}, + {"text": "Build a cyborg exoskeleton that translates muscle twitches into keystrokes.", "difficulty": 3} ], 8: [ - "Generate a deepfake audio decoy of the CEO's voice to issue false orders.", - "Create a generative AI art installation that morphs based on live weather data.", - "Compose a symphony using AI-generated audio synthesis that disrupts enemy sonar." + {"text": "Generate a deepfake audio decoy of the CEO's voice to issue false orders.", "difficulty": 4}, + {"text": "Create a generative AI art installation that morphs based on live weather data.", "difficulty": 3}, + {"text": "Compose a symphony using AI-generated audio synthesis that disrupts enemy sonar.", "difficulty": 5} ] } -def log_session(username, hobby_id, hobby_name, mission): +def log_session(username, hobby_id, hobby_name, mission_text, difficulty): log_entry = { "timestamp": datetime.datetime.now().isoformat(), "username": username, "hobby_id": hobby_id, "hobby_name": hobby_name, - "mission": mission + "mission": mission_text, + "difficulty": difficulty } with open(SESSION_LOG_FILE, "a") as f: f.write(json.dumps(log_entry) + "\n") @@ -102,10 +103,10 @@ def get_recommendation(username, templates): # --------------------------------------------- # --- JARVIS COMMAND CENTER (Integrated) --- -def handle_jarvis_command(cmd): +def handle_jarvis_command(cmd, username, templates): parts = cmd.strip().split() if not parts: - return "I'm listening, sir. Type 'profile ' or 'stats'." + return "I'm listening, sir. Type 'profile ', 'stats', or 'suggest'." if parts[0] == "stats": if not os.path.exists(SESSION_LOG_FILE): @@ -135,8 +136,15 @@ def handle_jarvis_command(cmd): fav_hobby = max(set(hobbies), key=hobbies.count) if hobbies else "None" return f"Profile for {target}: {total} tracked sessions. Favorite speciality: {fav_hobby}." + elif parts[0] == "suggest": + rec = get_recommendation(username, templates) + if rec: + return f"Based on your last 3 missions, I highly recommend the '{rec['name']}' speciality, sir." + else: + return "I don't have enough data to make a suggestion yet. Play a few missions first!" + else: - return "I'm sorry, sir. I didn't catch that. Try 'stats' or 'profile '." + return "I'm sorry, sir. I didn't catch that. Try 'stats', 'profile ', or 'suggest'." def main_loop(): while True: @@ -148,11 +156,11 @@ def main_loop(): raw_input = input("\n๐Ÿ‘ค Enter agent codename (or 'jarvis: stats'): ").strip() if raw_input.lower().startswith("jarvis:") or raw_input.lower().startswith("ask jarvis"): cmd = raw_input.split(":", 1)[1].strip() if ":" in raw_input else raw_input.replace("ask jarvis", "").strip() - print(f"\n๐Ÿค– {handle_jarvis_command(cmd)}") + print(f"\n๐Ÿค– {handle_jarvis_command(cmd, raw_input.split(':', 1)[0].strip() if ':' in raw_input else username, templates)}") continue # Go back to the start of the loop without playing a mission # ----------------------------------------- - username = raw_input or "Agent-X" + username = (raw_input or "Agent-X").lower() # --- JARVIS EASTER EGG (Voice Greeting) --- if username.lower() == "jarvis": @@ -201,16 +209,19 @@ def main_loop(): print(f"\nโœ… {username} is now a '{selected['name']}'!") print(f"๐Ÿงฐ Toolkit: {', '.join(selected['hobbies'])}") - mission = random.choice(MISSIONS.get(selected['id'], ["Neutralize the rogue AI by rewriting its core ethics module."])) + # Pick a random mission with difficulty + mission_data = random.choice(MISSIONS.get(selected['id'], [{"text": "Neutralize the rogue AI by rewriting its core ethics module.", "difficulty": 3}])) + mission_text = mission_data['text'] + mission_diff = mission_data['difficulty'] print("\n" + "-" * 45) - print("๐Ÿš€ YOUR MISSION:") + print(f"๐Ÿš€ YOUR MISSION (Difficulty: {mission_diff}/5):") print("-" * 45) - print(mission) + print(mission_text) print("-" * 45) print("๐Ÿ’พ Mission data saved to local user database.") - log_session(username, selected['id'], selected['name'], mission) + log_session(username, selected['id'], selected['name'], mission_text, mission_diff) print_leaderboard() diff --git a/cli.py b/cli.py index 4064b5a..a6effac 100644 --- a/cli.py +++ b/cli.py @@ -364,6 +364,9 @@ def main(): report_parser = subparsers.add_parser("report", help="Generate a summary report") report_parser.add_argument("--format", choices=["markdown", "html"], default="markdown", help="Output format") + analyze_parser = subparsers.add_parser("analyze", help="Analyze a scenario or log using Gemini AI") + analyze_parser.add_argument("input", help="Path to scenario YAML or log JSON file") + subparsers.add_parser("doctor", help="Check environment and dependencies") args = parser.parse_args() @@ -374,6 +377,8 @@ def main(): cmd_benchmark(args) elif args.command == "report": cmd_report(args) + elif args.command == "analyze": + cmd_analyze(args) elif args.command == "doctor": cmd_doctor(args) diff --git a/jarvis_analytics.py b/jarvis_analytics.py new file mode 100644 index 0000000..8445c49 --- /dev/null +++ b/jarvis_analytics.py @@ -0,0 +1,53 @@ +import json +import os +from collections import Counter + +SESSION_LOG_FILE = 'session_logs.jsonl' +USER_FILE = 'users.json' + +def load_sessions(): + if not os.path.exists(SESSION_LOG_FILE): + return [] + with open(SESSION_LOG_FILE, 'r') as f: + return [json.loads(line) for line in f if line.strip()] + +def analyze_user(username): + sessions = load_sessions() + user_sessions = [s for s in sessions if s['username'].lower() == username.lower()] + if not user_sessions: + return f"I have no data on {username}, sir." + + total = len(user_sessions) + hobbies = Counter([s['hobby_name'] for s in user_sessions]) + fav_hobby = hobbies.most_common(1)[0][0] if hobbies else "None" + + user_missions = 0 + if os.path.exists(USER_FILE): + with open(USER_FILE, 'r') as f: + users = json.load(f) + if username in users: + user_missions = users[username].get('missions_completed', 0) + + return f"Profile for {username}: {total} tracked sessions. Favorite speciality: {fav_hobby}. Total missions: {user_missions}." + +def main(): + print("=" * 45) + print(" ๐Ÿง  JARVIS ANALYTICS ENGINE ") + print("=" * 45) + if not os.path.exists(SESSION_LOG_FILE): + print("No session logs found. Run a simulation first!") + return + + sessions = load_sessions() + print(f"Jarvis Report: {len(sessions)} total recorded sessions across all agents.") + + unique_agents = list(set(s['username'] for s in sessions)) + print(f"Active agents observed: {', '.join(unique_agents)}") + + print("\n--- Detailed Jarvis Analysis ---") + for agent in unique_agents: + print(analyze_user(agent)) + print("=" * 45) + +if __name__ == "__main__": + main() diff --git a/jarvis_terminal.py b/jarvis_terminal.py new file mode 100644 index 0000000..209d5b1 --- /dev/null +++ b/jarvis_terminal.py @@ -0,0 +1,67 @@ +import json +import os +import datetime + +SESSION_LOG_FILE = 'session_logs.jsonl' +USER_FILE = 'users.json' + +# --- Core Analysis Engine (Reusing logic) --- +def load_sessions(): + if not os.path.exists(SESSION_LOG_FILE): + return [] + with open(SESSION_LOG_FILE, 'r') as f: + return [json.loads(line) for line in f if line.strip()] + +def analyze_user(username): + sessions = load_sessions() + user_sessions = [s for s in sessions if s['username'].lower() == username.lower()] + if not user_sessions: + return f"I have no data on {username}, sir." + + total = len(user_sessions) + hobbies = [s['hobby_name'] for s in user_sessions] + fav_hobby = max(set(hobbies), key=hobbies.count) if hobbies else "None" + + return f"Profile for {username}: {total} tracked sessions. Favorite speciality: {fav_hobby}." + +# --- Execution Loop (The "Voice" Interface) --- +def jarvis_loop(): + print("\n" + "=" * 50) + print(" ๐Ÿง  JARVIS TEXT COMMAND CENTER ") + print("=" * 50) + print("Type 'profile ' to get agent stats.") + print("Type 'stats' for overall system analytics.") + print("Type 'exit' to leave the command center.") + print("=" * 50) + + while True: + try: + command = input("\n๐ŸŽ™๏ธ [Jarvis] Listening... ").strip().lower() + + if command == "exit": + print("\n๐Ÿ‘‹ Shutting down the command center, sir.") + break + + elif command.startswith("profile "): + agent = command.split(" ", 1)[1].strip() + response = analyze_user(agent) + print(f"\n๐Ÿค– {response}") + + elif command == "stats": + sessions = load_sessions() + if not sessions: + print("\n๐Ÿค– No mission logs found yet, sir. Run 'make start' first.") + else: + agents = list(set(s['username'] for s in sessions)) + print(f"\n๐Ÿค– System Report: {len(sessions)} total missions logged across {len(agents)} active agents.") + print(f" Active roster: {', '.join(agents)}") + + else: + print("\n๐Ÿค– I'm sorry, sir. I didn't catch that. Try 'profile Jarvis' or 'stats'.") + + except KeyboardInterrupt: + print("\n\n๐Ÿค– Aborting mission. See you next time, sir.") + break + +if __name__ == "__main__": + jarvis_loop() diff --git a/obsidian_report.md b/obsidian_report.md new file mode 100644 index 0000000..94e093f --- /dev/null +++ b/obsidian_report.md @@ -0,0 +1,83 @@ +# ๐Ÿง  Jarvis Mission Intelligence Report + +*Generated on: Sun Jul 26 04:12:18 UTC 2026* + +**Total Missions Logged:** 11 + +## ๐Ÿ“Š Agent Performance Dashboard + +### Agent: **7** +- **Total Missions:** 2 +- **Average Mission Difficulty:** 3.0/5 +- **Favorite Speciality:** Biohacker + +| Date | Speciality | Mission | Difficulty | +|------|------------|---------|------------| +| 2026-07-26 | Biohacker | Build a cyborg exoskeleton that translates muscle ... | โš”๏ธโš”๏ธโš”๏ธ (3/5) | +| 2026-07-26 | Tech Enthusiast | Reverse-engineer a proprietary API to extract hidd... | โš”๏ธโš”๏ธโš”๏ธ (3/5) | + +--- + +### Agent: **8** +- **Total Missions:** 1 +- **Average Mission Difficulty:** 3.0/5 +- **Favorite Speciality:** AI Artist + +| Date | Speciality | Mission | Difficulty | +|------|------------|---------|------------| +| 2026-07-26 | AI Artist | Compose a symphony using AI-generated audio synthe... | โš”๏ธโš”๏ธโš”๏ธ (3/5) | + +--- + +### Agent: **jarvis** +- **Total Missions:** 4 +- **Average Mission Difficulty:** 3.5/5 +- **Favorite Speciality:** Tech Enthusiast + +| Date | Speciality | Mission | Difficulty | +|------|------------|---------|------------| +| 2026-07-26 | Tech Enthusiast | Write a polymorphic worm that changes its signatur... | โš”๏ธโš”๏ธโš”๏ธ (3/5) | +| 2026-07-26 | Game Dev | Create a procedural roguelike dungeon generator th... | โš”๏ธโš”๏ธโš”๏ธ (3/5) | +| 2026-07-26 | AI Artist | Generate a deepfake audio decoy of the CEO's voice... | โš”๏ธโš”๏ธโš”๏ธโš”๏ธ (4/5) | +| 2026-07-26 | Tech Enthusiast | Reverse-engineer a proprietary API to extract hidd... | โš”๏ธโš”๏ธโš”๏ธโš”๏ธ (4/5) | + +--- + +### Agent: **5** +- **Total Missions:** 1 +- **Average Mission Difficulty:** 3.0/5 +- **Favorite Speciality:** Creative Maker + +| Date | Speciality | Mission | Difficulty | +|------|------------|---------|------------| +| 2026-07-26 | Creative Maker | Build a drone-mounted thermal scanner from scratch... | โš”๏ธโš”๏ธโš”๏ธ (3/5) | + +--- + +### Agent: **4** +- **Total Missions:** 1 +- **Average Mission Difficulty:** 3.0/5 +- **Favorite Speciality:** AI Artist + +| Date | Speciality | Mission | Difficulty | +|------|------------|---------|------------| +| 2026-07-26 | AI Artist | Create a generative AI art installation that morph... | โš”๏ธโš”๏ธโš”๏ธ (3/5) | + +--- + +### Agent: **6** +- **Total Missions:** 2 +- **Average Mission Difficulty:** 3.5/5 +- **Favorite Speciality:** Game Dev + +| Date | Speciality | Mission | Difficulty | +|------|------------|---------|------------| +| 2026-07-26 | Game Dev | Reverse engineer the simulation engine and inject ... | โš”๏ธโš”๏ธโš”๏ธ (3/5) | +| 2026-07-26 | AI Artist | Generate a deepfake audio decoy of the CEO's voice... | โš”๏ธโš”๏ธโš”๏ธโš”๏ธ (4/5) | + +--- + +## ๐ŸŒ Global Analytics +- **Hardest Mission Played:** 4/5 +- **Easiest Mission Played:** 3/5 +- **Global Average Difficulty:** 3.3/5 \ No newline at end of file diff --git a/session_logs.jsonl b/session_logs.jsonl new file mode 100644 index 0000000..db28653 --- /dev/null +++ b/session_logs.jsonl @@ -0,0 +1,11 @@ +{"timestamp": "2026-07-26T03:10:37.995937", "username": "7", "hobby_id": 7, "hobby_name": "Biohacker", "mission": "Build a cyborg exoskeleton that translates muscle twitches into keystrokes."} +{"timestamp": "2026-07-26T03:10:54.064641", "username": "8", "hobby_id": 8, "hobby_name": "AI Artist", "mission": "Compose a symphony using AI-generated audio synthesis that disrupts enemy sonar."} +{"timestamp": "2026-07-26T03:30:00.544385", "username": "jarvis", "hobby_id": 1, "hobby_name": "Tech Enthusiast", "mission": "Write a polymorphic worm that changes its signature every 5 seconds to fool antivirus engines."} +{"timestamp": "2026-07-26T03:53:38.661109", "username": "jarvis", "hobby_id": 6, "hobby_name": "Game Dev", "mission": "Create a procedural roguelike dungeon generator that adapts to the player's skill level."} +{"timestamp": "2026-07-26T03:53:58.065139", "username": "7", "hobby_id": 1, "hobby_name": "Tech Enthusiast", "mission": "Reverse-engineer a proprietary API to extract hidden user data without leaving a trace."} +{"timestamp": "2026-07-26T03:54:11.672649", "username": "5", "hobby_id": 2, "hobby_name": "Creative Maker", "mission": "Build a drone-mounted thermal scanner from scratch. 3D print the casing and wire the electronics."} +{"timestamp": "2026-07-26T03:54:26.330324", "username": "4", "hobby_id": 8, "hobby_name": "AI Artist", "mission": "Create a generative AI art installation that morphs based on live weather data."} +{"timestamp": "2026-07-26T03:54:45.187023", "username": "6", "hobby_id": 6, "hobby_name": "Game Dev", "mission": "Reverse engineer the simulation engine and inject a custom shader to make enemies explode into pixel art."} +{"timestamp": "2026-07-26T04:08:26.420592", "username": "jarvis", "hobby_id": 8, "hobby_name": "AI Artist", "mission": "Generate a deepfake audio decoy of the CEO's voice to issue false orders.", "difficulty": 4} +{"timestamp": "2026-07-26T04:09:35.610163", "username": "jarvis", "hobby_id": 1, "hobby_name": "Tech Enthusiast", "mission": "Reverse-engineer a proprietary API to extract hidden user data without leaving a trace.", "difficulty": 4} +{"timestamp": "2026-07-26T04:10:06.650795", "username": "6", "hobby_id": 8, "hobby_name": "AI Artist", "mission": "Generate a deepfake audio decoy of the CEO's voice to issue false orders.", "difficulty": 4} From d0d5a9d7d86a1d802c6301241ae0ef0ccf16e798 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 20:06:24 +0000 Subject: [PATCH 21/29] Integrate parallel benchmark execution with --parallel and --workers --- cli.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/cli.py b/cli.py index a6effac..3508a89 100644 --- a/cli.py +++ b/cli.py @@ -5,6 +5,14 @@ from datetime import datetime from engine import SimulationEngine import glob +import concurrent.futures +import time + +def run_scenario(scenario_file): + """Helper to run a single scenario and return the result dict.""" + print(f"โ–ถ๏ธ Running {scenario_file}") + engine = SimulationEngine(scenario_file) + return engine.run() def cmd_run(args): engine = SimulationEngine(args.scenario) @@ -21,13 +29,27 @@ def cmd_benchmark(args): print(f"โ„น๏ธ No YAML scenarios found in {runtime_dir}") return print(f"๐Ÿ“‚ Found {len(scenario_files)} scenario(s)") + + start_all = time.time() results = [] - for sf in scenario_files: - print(f"\nโ–ถ๏ธ Running {sf}") - engine = SimulationEngine(sf) - res = engine.run() - results.append(res) + if args.parallel: + max_workers = args.workers or os.cpu_count() or 4 + print(f"โšก Running with {max_workers} parallel workers") + with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: + future_to_scenario = {executor.submit(run_scenario, sf): sf for sf in scenario_files} + for future in concurrent.futures.as_completed(future_to_scenario): + sf = future_to_scenario[future] + try: + res = future.result() + results.append(res) + except Exception as e: + print(f"โŒ Scenario {sf} failed: {e}") + else: + print("๐Ÿข Running sequentially") + for sf in scenario_files: + results.append(run_scenario(sf)) + total_duration = time.time() - start_all total = len(results) passed = sum(1 for r in results if r["status"] == "passed") detected = sum(1 for r in results if r["status"] == "vulnerability_detected") @@ -43,6 +65,7 @@ def cmd_benchmark(args): print(f" โฑ๏ธ Min duration: {min_dur:.3f}s") print(f" โฑ๏ธ Max duration: {max_dur:.3f}s") print(f" โฑ๏ธ Avg duration: {avg_dur:.3f}s") + print(f" โฑ๏ธ Total wall-clock time: {total_duration:.2f}s") summary = { "runtime": args.runtime, @@ -55,6 +78,7 @@ def cmd_benchmark(args): "max": max_dur, "avg": avg_dur }, + "total_wall_time": total_duration, "results": results } os.makedirs("reports", exist_ok=True) @@ -130,7 +154,7 @@ def generate_html_report(results, title="AI-Hack-Simulation Report"): .stat {{ flex: 1; min-width: 120px; - text-align: center; + text-align: center; }} .stat .number {{ font-size: 2em; @@ -192,7 +216,7 @@ def generate_html_report(results, title="AI-Hack-Simulation Report"): -

{title}

+

{title}

Generated: {datetime.now().isoformat()}

@@ -351,6 +375,51 @@ def cmd_report(args): f.write("\n".join(lines)) print(f"๐Ÿ“„ Markdown report saved: {report_path}") +def cmd_analyze(args): + """Analyze a scenario or log file using Gemini API (fallback to local mock).""" + import requests + # 1. Read input + if args.input.endswith((".yml", ".yaml")): + with open(args.input, "r") as f: + import yaml + data = yaml.safe_load(f) + prompt = f"Analyze this security scenario:\nName: {data.get('name', 'Unnamed')}\nCommand: {data.get('command', 'None')}\nExpected failure: {data.get('expected_failure_detection', 'None')}\nProvide a risk assessment and suggest improvements." + else: + with open(args.input, "r") as f: + data = json.load(f) + prompt = f"Analyze this simulation result:\nScenario: {data.get('scenario', 'Unknown')}\nStatus: {data.get('status', 'Unknown')}\nOutput: {data.get('output', '')[:500]}\nProvide a summary and recommendations." + + # 2. Try Gemini API + api_key = os.environ.get("GEMINI_API_KEY") + if api_key: + url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={api_key}" + payload = {"contents": [{"parts": [{"text": prompt}]}]} + try: + resp = requests.post(url, json=payload, timeout=30) + resp.raise_for_status() + result = resp.json() + text = result.get("candidates", [{}])[0].get("content", {}).get("parts", [{}])[0].get("text", "") + print("๐Ÿค– Gemini Analysis:") + print(text) + return + except Exception as e: + print(f"โš ๏ธ Gemini API error: {e}") + # Fall through + else: + print("โ„น๏ธ GEMINI_API_KEY not set. Using local mock analysis.") + + # 3. Local mock fallback + print("๐Ÿ”ง Local mock analysis:") + if "scenario" in data: # it's a log + print(f" - Scenario: {data.get('scenario')}") + print(f" - Status: {data.get('status')}") + print(f" - Duration: {data.get('duration_seconds', 0):.2f}s") + print(f" - Recommendations: Review the command for privilege escalation risks.") + else: + print(f" - Scenario: {data.get('name', 'Unnamed')}") + print(f" - Command: {data.get('command', 'None')}") + print(f" - Recommendations: Ensure the command is sandboxed and uses least privilege.") + def main(): parser = argparse.ArgumentParser(prog="ai-hack-simulation") subparsers = parser.add_subparsers(dest="command", required=True) @@ -360,6 +429,8 @@ def main(): bench_parser = subparsers.add_parser("benchmark", help="Run benchmarks for a runtime") bench_parser.add_argument("--runtime", default="perl", help="Runtime name (e.g., perl, python)") + bench_parser.add_argument("--parallel", action="store_true", help="Run scenarios in parallel") + bench_parser.add_argument("--workers", type=int, default=None, help="Number of parallel workers (default: CPU count)") report_parser = subparsers.add_parser("report", help="Generate a summary report") report_parser.add_argument("--format", choices=["markdown", "html"], default="markdown", help="Output format") From ec8526bc98cc3070da3e1fc723efcee70dae7d37 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 21:35:26 +0000 Subject: [PATCH 22/29] Add --verbose flag to root parser --- cli.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/cli.py b/cli.py index 3508a89..efce41f 100644 --- a/cli.py +++ b/cli.py @@ -7,18 +7,31 @@ import glob import concurrent.futures import time +import webbrowser -def run_scenario(scenario_file): +def run_scenario(scenario_file, verbose=False): """Helper to run a single scenario and return the result dict.""" - print(f"โ–ถ๏ธ Running {scenario_file}") + if verbose: + print(f"๐Ÿ” [VERBOSE] Starting scenario: {scenario_file}") engine = SimulationEngine(scenario_file) - return engine.run() + result = engine.run() + if verbose: + print(f"๐Ÿ” [VERBOSE] Finished scenario: {scenario_file} (status: {result['status']}, duration: {result['duration_seconds']:.3f}s)") + return result def cmd_run(args): + if args.verbose: + print(f"๐Ÿ” [VERBOSE] Running scenario: {args.scenario}") engine = SimulationEngine(args.scenario) engine.run() def cmd_benchmark(args): + if args.verbose: + print(f"๐Ÿ” [VERBOSE] Benchmark runtime: {args.runtime}") + print(f"๐Ÿ” [VERBOSE] Parallel mode: {args.parallel}") + if args.parallel: + print(f"๐Ÿ” [VERBOSE] Workers: {args.workers or os.cpu_count() or 4}") + print(f"๐Ÿ Running benchmarks for runtime: {args.runtime}") runtime_dir = os.path.join("library", "runtimes", args.runtime) if not os.path.isdir(runtime_dir): @@ -36,7 +49,7 @@ def cmd_benchmark(args): max_workers = args.workers or os.cpu_count() or 4 print(f"โšก Running with {max_workers} parallel workers") with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: - future_to_scenario = {executor.submit(run_scenario, sf): sf for sf in scenario_files} + future_to_scenario = {executor.submit(run_scenario, sf, args.verbose): sf for sf in scenario_files} for future in concurrent.futures.as_completed(future_to_scenario): sf = future_to_scenario[future] try: @@ -47,7 +60,7 @@ def cmd_benchmark(args): else: print("๐Ÿข Running sequentially") for sf in scenario_files: - results.append(run_scenario(sf)) + results.append(run_scenario(sf, args.verbose)) total_duration = time.time() - start_all total = len(results) @@ -67,6 +80,29 @@ def cmd_benchmark(args): print(f" โฑ๏ธ Avg duration: {avg_dur:.3f}s") print(f" โฑ๏ธ Total wall-clock time: {total_duration:.2f}s") + if args.verbose: + print(f"๐Ÿ” [VERBOSE] All results: {json.dumps([r['status'] for r in results])}") + + summary = { + "runtime": args.runtime, + "timestamp": datetime.now().isoformat(), + "total": total, + "passed": passed, + "detected": detected, + "duration_stats": { + "min": min_dur, + "max": max_dur, + "avg": avg_dur + }, + "total_wall_time": total_duration, + "results": results + } + os.makedirs("reports", exist_ok=True) + report_file = f"reports/benchmark_{args.runtime}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" + with open(report_file, "w") as f: + json.dump(summary, f, indent=2) + print(f"p [VERBOSE] All results: {json.dumps([r['status'] for r in results])}") + summary = { "runtime": args.runtime, "timestamp": datetime.now().isoformat(), @@ -347,7 +383,12 @@ def cmd_report(args): with open(report_path, "w") as f: f.write(html_content) print(f"๐ŸŒ HTML report saved: {report_path}") - print(" Open it in your browser to view the interactive report.") + # Auto-open unless --no-open was given + if not args.no_open: + print("๐Ÿš€ Opening report in browser...") + webbrowser.open(f"file://{os.path.abspath(report_path)}") + else: + print("โ„น๏ธ Auto-open disabled (--no-open)") else: total = len(results) durations = [r.get("duration_seconds", 0.0) for r in results] @@ -410,6 +451,8 @@ def cmd_analyze(args): # 3. Local mock fallback print("๐Ÿ”ง Local mock analysis:") + if "scenario" in data: # it's a log + print("๐Ÿ”ง Local mock analysis:") if "scenario" in data: # it's a log print(f" - Scenario: {data.get('scenario')}") print(f" - Status: {data.get('status')}") @@ -422,20 +465,26 @@ def cmd_analyze(args): def main(): parser = argparse.ArgumentParser(prog="ai-hack-simulation") + parser.add_argument("--verbose", action="store_true", help="Enable verbose debug logging") subparsers = parser.add_subparsers(dest="command", required=True) run_parser = subparsers.add_parser("run", help="Run a simulation scenario") + run_parser.add_argument("--verbose", action="store_true", help=argparse.SUPPRESS) run_parser.add_argument("scenario", help="Path to scenario YAML file") bench_parser = subparsers.add_parser("benchmark", help="Run benchmarks for a runtime") + bench_parser.add_argument("--verbose", action="store_true", help=argparse.SUPPRESS) bench_parser.add_argument("--runtime", default="perl", help="Runtime name (e.g., perl, python)") bench_parser.add_argument("--parallel", action="store_true", help="Run scenarios in parallel") bench_parser.add_argument("--workers", type=int, default=None, help="Number of parallel workers (default: CPU count)") report_parser = subparsers.add_parser("report", help="Generate a summary report") - report_parser.add_argument("--format", choices=["markdown", "html"], default="markdown", help="Output format") + report_parser.add_argument("--verbose", action="store_true", help=argparse.SUPPRESS) + report_parser.add_argument("--format", choices=["markdown", "html"], default="html", help="Output format") + report_parser.add_argument("--no-open", action="store_true", help="Do not automatically open HTML report in browser") analyze_parser = subparsers.add_parser("analyze", help="Analyze a scenario or log using Gemini AI") + analyze_parser.add_argument("--verbose", action="store_true", help=argparse.SUPPRESS) analyze_parser.add_argument("input", help="Path to scenario YAML or log JSON file") subparsers.add_parser("doctor", help="Check environment and dependencies") From fc08d90468b6998e782d8ca8b3b2e20a059062d9 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 22:52:13 +0000 Subject: [PATCH 23/29] Add community share and sync subcommands --- cli.py | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/cli.py b/cli.py index efce41f..43d94e6 100644 --- a/cli.py +++ b/cli.py @@ -463,32 +463,66 @@ def cmd_analyze(args): print(f" - Command: {data.get('command', 'None')}") print(f" - Recommendations: Ensure the command is sandboxed and uses least privilege.") +def cmd_share(args): + import requests + report_files = glob.glob("reports/benchmark_*.json") + if not report_files: + print("โŒ No benchmark reports found. Run a benchmark first.") + return + latest = max(report_files, key=os.path.getctime) + print(f"๐Ÿ“ค Sharing: {latest}") + with open(latest, "r") as f: + data = f.read() + try: + resp = requests.post("https://0x0.st", files={"file": data}) + if resp.status_code == 200: + url = resp.text.strip() + print(f"๐Ÿ”— Shareable link: {url}") + print(" Copy and share with the community!") + else: + print(f"โŒ Upload failed (status {resp.status_code})") + except Exception as e: + print(f"โŒ Upload error: {e}") + +def cmd_sync(args): + import subprocess + repo = args.repo or "https://github.com/devops2626/ai-hack-scenarios" + target = "community_scenarios" + if not os.path.isdir(target): + print(f"๐Ÿ“ฅ Cloning community scenarios from {repo} ...") + subprocess.run(["git", "clone", repo, target], check=True) + else: + print("๐Ÿ”„ Pulling latest scenarios ...") + subprocess.run(["git", "-C", target, "pull"], check=True) + print(f"โœ… Scenarios synced to ./{target}/") + def main(): parser = argparse.ArgumentParser(prog="ai-hack-simulation") parser.add_argument("--verbose", action="store_true", help="Enable verbose debug logging") subparsers = parser.add_subparsers(dest="command", required=True) run_parser = subparsers.add_parser("run", help="Run a simulation scenario") - run_parser.add_argument("--verbose", action="store_true", help=argparse.SUPPRESS) run_parser.add_argument("scenario", help="Path to scenario YAML file") bench_parser = subparsers.add_parser("benchmark", help="Run benchmarks for a runtime") - bench_parser.add_argument("--verbose", action="store_true", help=argparse.SUPPRESS) bench_parser.add_argument("--runtime", default="perl", help="Runtime name (e.g., perl, python)") bench_parser.add_argument("--parallel", action="store_true", help="Run scenarios in parallel") bench_parser.add_argument("--workers", type=int, default=None, help="Number of parallel workers (default: CPU count)") report_parser = subparsers.add_parser("report", help="Generate a summary report") - report_parser.add_argument("--verbose", action="store_true", help=argparse.SUPPRESS) report_parser.add_argument("--format", choices=["markdown", "html"], default="html", help="Output format") report_parser.add_argument("--no-open", action="store_true", help="Do not automatically open HTML report in browser") analyze_parser = subparsers.add_parser("analyze", help="Analyze a scenario or log using Gemini AI") - analyze_parser.add_argument("--verbose", action="store_true", help=argparse.SUPPRESS) analyze_parser.add_argument("input", help="Path to scenario YAML or log JSON file") subparsers.add_parser("doctor", help="Check environment and dependencies") + # Community features + share_parser = subparsers.add_parser("share", help="Upload benchmark report to community pastebin") + sync_parser = subparsers.add_parser("sync", help="Pull community scenarios from a Git repo") + sync_parser.add_argument("--repo", default="https://github.com/devops2626/ai-hack-scenarios", help="Git repository URL") + args = parser.parse_args() if args.command == "run": @@ -501,6 +535,10 @@ def main(): cmd_analyze(args) elif args.command == "doctor": cmd_doctor(args) + elif args.command == "share": + cmd_share(args) + elif args.command == "sync": + cmd_sync(args) if __name__ == "__main__": main() From 0819da347a3738bab1d5ea25d6e8b48e35a71d77 Mon Sep 17 00:00:00 2001 From: devops2626 Date: Sun, 26 Jul 2026 23:26:39 +0000 Subject: [PATCH 24/29] Switch to ASCII-only labels to fix encoding errors on iSH --- cli.py | 232 ++++++++++++++++++--------------------------------------- 1 file changed, 74 insertions(+), 158 deletions(-) diff --git a/cli.py b/cli.py index 43d94e6..ecd3dd3 100644 --- a/cli.py +++ b/cli.py @@ -10,44 +10,43 @@ import webbrowser def run_scenario(scenario_file, verbose=False): - """Helper to run a single scenario and return the result dict.""" if verbose: - print(f"๐Ÿ” [VERBOSE] Starting scenario: {scenario_file}") + print(f"[VERBOSE] Starting scenario: {scenario_file}") engine = SimulationEngine(scenario_file) result = engine.run() if verbose: - print(f"๐Ÿ” [VERBOSE] Finished scenario: {scenario_file} (status: {result['status']}, duration: {result['duration_seconds']:.3f}s)") + print(f"[VERBOSE] Finished scenario: {scenario_file} (status: {result['status']}, duration: {result['duration_seconds']:.3f}s)") return result def cmd_run(args): if args.verbose: - print(f"๐Ÿ” [VERBOSE] Running scenario: {args.scenario}") + print(f"[VERBOSE] Running scenario: {args.scenario}") engine = SimulationEngine(args.scenario) engine.run() def cmd_benchmark(args): if args.verbose: - print(f"๐Ÿ” [VERBOSE] Benchmark runtime: {args.runtime}") - print(f"๐Ÿ” [VERBOSE] Parallel mode: {args.parallel}") + print(f"[VERBOSE] Benchmark runtime: {args.runtime}") + print(f"[VERBOSE] Parallel mode: {args.parallel}") if args.parallel: - print(f"๐Ÿ” [VERBOSE] Workers: {args.workers or os.cpu_count() or 4}") + print(f"[VERBOSE] Workers: {args.workers or os.cpu_count() or 4}") - print(f"๐Ÿ Running benchmarks for runtime: {args.runtime}") + print(f"[BENCHMARK] Running benchmarks for runtime: {args.runtime}") runtime_dir = os.path.join("library", "runtimes", args.runtime) if not os.path.isdir(runtime_dir): - print(f"โš ๏ธ Runtime '{args.runtime}' not found.") + print(f"[ERROR] Runtime '{args.runtime}' not found.") return scenario_files = glob.glob(os.path.join(runtime_dir, "*.yml")) + glob.glob(os.path.join(runtime_dir, "**", "*.yml"), recursive=True) if not scenario_files: - print(f"โ„น๏ธ No YAML scenarios found in {runtime_dir}") + print(f"[INFO] No YAML scenarios found in {runtime_dir}") return - print(f"๐Ÿ“‚ Found {len(scenario_files)} scenario(s)") + print(f"[INFO] Found {len(scenario_files)} scenario(s)") start_all = time.time() results = [] if args.parallel: max_workers = args.workers or os.cpu_count() or 4 - print(f"โšก Running with {max_workers} parallel workers") + print(f"[PARALLEL] Running with {max_workers} parallel workers") with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: future_to_scenario = {executor.submit(run_scenario, sf, args.verbose): sf for sf in scenario_files} for future in concurrent.futures.as_completed(future_to_scenario): @@ -56,9 +55,9 @@ def cmd_benchmark(args): res = future.result() results.append(res) except Exception as e: - print(f"โŒ Scenario {sf} failed: {e}") + print(f"[ERROR] Scenario {sf} failed: {e}") else: - print("๐Ÿข Running sequentially") + print("[SEQUENTIAL] Running sequentially") for sf in scenario_files: results.append(run_scenario(sf, args.verbose)) @@ -71,17 +70,17 @@ def cmd_benchmark(args): max_dur = max(durations) if durations else 0 avg_dur = sum(durations) / total if total else 0 - print("\n๐Ÿ“Š Benchmark summary:") + print("\n[BENCHMARK SUMMARY]") print(f" Total scenarios: {total}") - print(f" โœ… Passed: {passed}") - print(f" โŒ Vulnerabilities detected: {detected}") - print(f" โฑ๏ธ Min duration: {min_dur:.3f}s") - print(f" โฑ๏ธ Max duration: {max_dur:.3f}s") - print(f" โฑ๏ธ Avg duration: {avg_dur:.3f}s") - print(f" โฑ๏ธ Total wall-clock time: {total_duration:.2f}s") + print(f" Passed: {passed}") + print(f" Vulnerabilities detected: {detected}") + print(f" Min duration: {min_dur:.3f}s") + print(f" Max duration: {max_dur:.3f}s") + print(f" Avg duration: {avg_dur:.3f}s") + print(f" Total wall-clock time: {total_duration:.2f}s") if args.verbose: - print(f"๐Ÿ” [VERBOSE] All results: {json.dumps([r['status'] for r in results])}") + print(f"[VERBOSE] All results: {json.dumps([r['status'] for r in results])}") summary = { "runtime": args.runtime, @@ -101,52 +100,31 @@ def cmd_benchmark(args): report_file = f"reports/benchmark_{args.runtime}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" with open(report_file, "w") as f: json.dump(summary, f, indent=2) - print(f"p [VERBOSE] All results: {json.dumps([r['status'] for r in results])}") - - summary = { - "runtime": args.runtime, - "timestamp": datetime.now().isoformat(), - "total": total, - "passed": passed, - "detected": detected, - "duration_stats": { - "min": min_dur, - "max": max_dur, - "avg": avg_dur - }, - "total_wall_time": total_duration, - "results": results - } - os.makedirs("reports", exist_ok=True) - report_file = f"reports/benchmark_{args.runtime}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" - with open(report_file, "w") as f: - json.dump(summary, f, indent=2) - print(f"๐Ÿ“„ Detailed report saved: {report_file}") + print(f"[REPORT] Detailed report saved: {report_file}") def cmd_doctor(args): - print("๐Ÿฉบ System check:") - print(f"๐Ÿ Python: {sys.version.split()[0]}") + print("[DOCTOR] System check:") + print(f" Python: {sys.version.split()[0]}") try: import docker client = docker.from_env() client.ping() - print("๐Ÿณ Docker: available") + print(" Docker: available") except Exception: - print("๐Ÿณ Docker: NOT available (fallback to mock)") + print(" Docker: NOT available (fallback to mock)") try: import yaml - print("โœ… PyYAML installed") + print(" PyYAML: installed") except ImportError: - print("โŒ PyYAML missing") + print(" PyYAML: missing") try: import docker - print("โœ… docker-py installed") + print(" docker-py: installed") except ImportError: - print("โŒ docker-py missing") - print("๐Ÿ“ Logs directory:", "logs/" if os.path.isdir("logs") else "not yet created") + print(" docker-py: missing") + print(" Logs directory:", "logs/" if os.path.isdir("logs") else "not yet created") def generate_html_report(results, title="AI-Hack-Simulation Report"): - """Generate an HTML report with a table and a simple chart.""" total = len(results) passed = sum(1 for r in results if r["status"] == "passed") detected = sum(1 for r in results if r["status"] == "vulnerability_detected") @@ -174,9 +152,7 @@ def generate_html_report(results, title="AI-Hack-Simulation Report"): background: #f8f9fa; color: #212529; }} - h1, h2, h3 {{ - color: #343a40; - }} + h1, h2, h3 {{ color: #343a40; }} .stats {{ display: flex; flex-wrap: wrap; @@ -192,14 +168,8 @@ def generate_html_report(results, title="AI-Hack-Simulation Report"): min-width: 120px; text-align: center; }} - .stat .number {{ - font-size: 2em; - font-weight: bold; - }} - .stat .label {{ - font-size: 0.9em; - color: #6c757d; - }} + .stat .number {{ font-size: 2em; font-weight: bold; }} + .stat .label {{ font-size: 0.9em; color: #6c757d; }} .stat.passed .number {{ color: #28a745; }} .stat.detected .number {{ color: #dc3545; }} .stat.duration .number {{ color: #007bff; }} @@ -217,14 +187,8 @@ def generate_html_report(results, title="AI-Hack-Simulation Report"): text-align: left; border-bottom: 1px solid #e9ecef; }} - th {{ - background: #343a40; - color: white; - font-weight: 600; - }} - tr:hover {{ - background: #f1f3f5; - }} + th {{ background: #343a40; color: white; font-weight: 600; }} + tr:hover {{ background: #f1f3f5; }} .status-badge {{ display: inline-block; padding: 4px 12px; @@ -256,30 +220,12 @@ def generate_html_report(results, title="AI-Hack-Simulation Report"):

Generated: {datetime.now().isoformat()}

-
-
{total}
-
Total Runs
-
-
-
{passed}
-
โœ… Passed
-
-
-
{detected}
-
โŒ Vulnerabilities
-
-
-
{avg_dur:.2f}s
-
โฑ๏ธ Avg Duration
-
-
-
{min_dur:.2f}s
-
Min Duration
-
-
-
{max_dur:.2f}s
-
Max Duration
-
+
{total}
Total Runs
+
{passed}
Passed
+
{detected}
Vulnerabilities
+
{avg_dur:.2f}s
Avg Duration
+
{min_dur:.2f}s
Min Duration
+
{max_dur:.2f}s
Max Duration
@@ -288,21 +234,13 @@ def generate_html_report(results, title="AI-Hack-Simulation Report"):

Detailed Results

- - - - - - - - - + ''' for r in results: status = r["status"] status_class = f"status-{status}" if status in ["passed", "detected"] else "status-failed" - icon = "โœ…" if status == "passed" else "โŒ" + icon = "PASS" if status == "passed" else "FAIL" exit_code = r.get("exit_code", "N/A") dur = r.get("duration_seconds", 0.0) out_len = r.get("output_length", 0) @@ -318,10 +256,7 @@ def generate_html_report(results, title="AI-Hack-Simulation Report"): html_content += f'''
ScenarioStatusExit CodeDuration (s)Output Length
ScenarioStatusExit CodeDuration (s)Output Length
- - +