Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ec93f36
[UPDATE] Command folder name
hullabaloo-vincent Nov 17, 2024
51b8768
[ADD] Chip creator
hullabaloo-vincent Nov 17, 2024
19ece91
[ADD] Dirs
hullabaloo-vincent Nov 17, 2024
6d827a5
[UPDATE] Script improvements
hullabaloo-vincent Nov 17, 2024
769bd5d
[UPDATE] Subprocess
hullabaloo-vincent Nov 18, 2024
f00bf6a
[UPDATE] Sanitize input
hullabaloo-vincent Nov 18, 2024
acca36d
Turn off false-positives
hullabaloo-vincent Nov 18, 2024
d95a82c
Added Local to navi_internal
AlexKollar Nov 18, 2024
f52791d
Navi3b (llama) install / setup included in install.sh
AlexKollar Nov 18, 2024
9bc1fb3
Merge pull request #118 from SaintsSec/vincent/chip-org
AlexKollar Nov 18, 2024
955f2fa
Removed 3bfolder - Added toggle for remote
AlexKollar Nov 19, 2024
28c9923
removed Navi history file + added toggle for remote server.
AlexKollar Nov 19, 2024
f9d2d3d
Brushed up the linguistics from 'server' to 'remote'
AlexKollar Nov 19, 2024
9e0dffa
Started working on the revised navi3b installer.
AlexKollar Dec 3, 2024
e9db402
Revised Navi3b Installer, added 3b banner, removed forced 3b in insta…
AlexKollar Dec 12, 2024
6564808
First pass
hullabaloo-vincent Dec 15, 2024
47b2675
[WIP] Navi settings app
hullabaloo-vincent Dec 15, 2024
8d92b1e
[UPDATE] macOS Ollama installer
hullabaloo-vincent Dec 15, 2024
7cc03dc
[FIX] Starting ollama and file not found exception
hullabaloo-vincent Dec 15, 2024
bee634d
Update .gitignore
hullabaloo-vincent Dec 15, 2024
49b1f20
[UPDATE] Settings user interaction
hullabaloo-vincent Dec 15, 2024
78e9003
[FIX] Misaligned character
hullabaloo-vincent Dec 15, 2024
d3b614e
[UPDATE] Chip template
hullabaloo-vincent Dec 16, 2024
fe97552
[UPDATE] Rename vars and remove unused vars
hullabaloo-vincent Dec 16, 2024
600fa6d
[ADD] Config for update branch
hullabaloo-vincent Dec 16, 2024
20c0d1a
[FIX] Windows ollama installer
hullabaloo-vincent Dec 16, 2024
924b6c8
[UPDATE] Clean up Windows Ollama installation
hullabaloo-vincent Dec 16, 2024
5e6c6a5
[UPDATE] Improve prompt
hullabaloo-vincent Dec 16, 2024
f44b6e4
Fixed install folder being deleted.
AlexKollar Dec 16, 2024
02dc7aa
Merge pull request #119 from SaintsSec/alex/navi-local
AlexKollar Dec 20, 2024
8ba4a8c
Update README.md
AlexKollar Dec 21, 2024
2f9583d
Update README.md
AlexKollar Dec 21, 2024
73d2dcb
[ADD] Memory functionality
hullabaloo-vincent Jan 1, 2025
14965d1
[FIX] Accidental overwrite of history
hullabaloo-vincent Jan 1, 2025
ba6b347
[ADD] Remove memory
hullabaloo-vincent Jan 1, 2025
b84f618
Update chip-template.txt
hullabaloo-vincent Jan 1, 2025
72a1faa
[UPDATE] Remove session error text
hullabaloo-vincent Jan 1, 2025
52c2507
[UPDATE] Reference
hullabaloo-vincent Jan 1, 2025
860f7ef
[ADD] RAG
hullabaloo-vincent Jan 1, 2025
8684739
Merge pull request #121 from SaintsSec/vincent/memory
AlexKollar Jan 2, 2025
084501f
[UPDATE] Code cleanup
hullabaloo-vincent Jan 2, 2025
738055f
[FIX] Comment
hullabaloo-vincent Jan 2, 2025
68e70f8
[UPDATE] Improved token management
hullabaloo-vincent Jan 2, 2025
518ddbf
Merge pull request #123 from SaintsSec/vincent/cleanup
AlexKollar Jan 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
__pycache__/
.vscode/settings.json
.DS_Store
.idea/
*.log
navienv/
verification_test
.navi_version
.navi_history
config
qodana.yaml
memories/
data/
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">
<h1> Navi | CLI - An innovation in cybersec AI</h1>
<h1>v0.6.5 - "CSI - Con"</h1>
<h1>v0.6.6 - "Specter"</h1>
</div>

## 🤝 Sponsors / Endorsements: Thank you so much!
Expand All @@ -15,14 +15,11 @@

## ✨ **Key Features of Navi v0.6.5**

- **Upgraded Navi Shell** - The shell can now execute system commands, without breaking the flow of conversation. See more below!
- **Navi chips Upgrade** - The new alias variable within the custom scripts allow for Navi to execute scripts right from the chat. Once again not disrupting the flow.
- **Chip Creators Guide** - We are in the process of streamlining documentation on making custom chips.
- **Navi Nmap Chip** - We moved the Nmap Script over to being its own chip.
- **Navi3b** - The first iteration of our local AI system. Currently running Llama3.2-3b with ollama in the background.
- **Streamlined 3b install** - The install process is included the first time you launch navi (from edge currently) `navi --edge`
- **Navi chips Upgrade** - The chips system has been upgraded yet again with some qol, as well as a chip creator + template
- **Chip Creators Guide** - The chip documentation has been updated to reflect recent changes to the sytem.
- **Wiki Re-write** - With new power comes new documentation
- **Llama3.2 Integration** - We are running Meta's Llama AI on the backend.
- **[Navi Mind](https://github.com/SaintsSec/Navi-Mind)** - Planning phase of the first Navi AI Model we are calling *Navi Mind*.
- **[Navi Public Training](https://github.com/SaintsSec/Navi-Training)** - We want to be transparent about the data going into Navi. So we are building out a whole repo just for that.

### **Work In Progress**

Expand Down
Empty file added chips/Com/Community-Chips
Empty file.
Empty file added chips/Dev/Developer-Chips
Empty file.
Empty file added chips/SSG/SSG-Chips
Empty file.
50 changes: 50 additions & 0 deletions chips/SSG/chip-template.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import navi_internal

# Chip documentation: https://github.com/SaintsSec/Navi/wiki/4.-Developing-Chips-%E2%80%90-Indepth

command: str = "{{CHIP_NAME}}"
use: str = "What does this chip do?"
aliases: list = ['{{CHIP_NAME}}']
params: dict = {
'-help': 'Display help information',
'-h': 'Display help information',
}

help_params: tuple = ('-help', '-h')


def print_params() -> None:
# Print the header
print(f"{'Parameter':<10} | {'Description'}")
print("-" * 40)

# Print each dictionary item
for param, description in params.items():
print(f"{param:<10} | {description}")

# What Navi calls to run this Chip
def run(arguments=None) -> None:
# Get the instance of Navi. Required to access Navi-specific functions
navi_instance = navi_internal.navi_instance
navi_instance.print_message(f"How can I help you, {navi_instance.get_user()}?")

# To get a dictionary of current navi settings, and modify dictionary. Some modifications
# might require app restart. To prevent circular imports, keep this in a function or class.
#from navi_shell import get_navi_settings, modify_navi_settings

# Optional: Converts argument tokens into a list
arg_array = arguments.text.split()

# Remove the command itself
arg_array.pop(0)

# Optional: Check for parameters
if arg_array is not None:
for arg in arg_array:
match arg:
case x if x in help_params:
print_params()
return
case _:
navi_instance.print_message(f"Invalid parameter: {arg}")
return
178 changes: 178 additions & 0 deletions chips/SSG/navi_chip_creator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import os
import re
import subprocess # nosec
import sys
import webbrowser

from colorama import Fore

import navi_internal
from navi_shell import restart_navi

command: str = "chip-create"
use: str = "Creates a new Navi chip"
aliases: list = ['chip-create', 'cc']
params: dict[str, str] = {
'-help': 'Display help information',
'-h': 'Display help information',
}

help_params: tuple = ('-help', '-h')
template_file: str = "chips/SSG/chip-template.txt"
chip_install_path: str = "chips/Dev/"
chip_documentation_link: str = "https://github.com/SaintsSec/Navi/wiki/4.-Developing-Chips-%E2%80%90-Indepth"


def print_params() -> None:
"""Prints the available parameters and their descriptions."""
print(f"{'Parameter':<10} | {'Description'}")
print("-" * 40)
for param, description in params.items():
print(f"{param:<10} | {description}")


def get_user_input(prompt):
"""Gets input from the user."""
return input(prompt).strip()


def confirm_details(chip_name, chip_file_name, navi_instance):
"""Asks the user to confirm the chip details or make changes."""
while True:
navi_instance.print_message(f"Perfect! Here's a recap:"
f"\nChip Name: {chip_name}"
f"\nPython File Name: {chip_file_name}.py\n")
choice = get_user_input("Are you ready to proceed or do you want to make changes? "
f"({Fore.YELLOW}c{Fore.RESET})ontinue or ({Fore.YELLOW}m{Fore.RESET})ake changes: ").lower()
if choice == 'c':
return chip_name, chip_file_name
elif choice == 'm':
return make_changes(chip_name, chip_file_name, navi_instance)
else:
navi_instance.print_message("Invalid input. Please choose 'c' to continue or 'm' to make changes.")


def make_changes(chip_name, chip_file_name, navi_instance):
"""Allows the user to change the chip name or file name."""
while True:
change_choice = get_user_input(f"What do you want to change? ({Fore.YELLOW}chip{Fore.RESET}) name or "
f"({Fore.YELLOW}file{Fore.RESET}) name: ").lower()
if change_choice == 'chip':
navi_instance.print_message("Let's update the Chip Name.")
chip_name = get_user_input("New Chip Name: ")
return confirm_details(chip_name, chip_file_name, navi_instance)
elif change_choice == 'file':
navi_instance.print_message("Let's update the File Name.")
chip_file_name = get_user_input("New File Name: ")
return confirm_details(chip_name, chip_file_name, navi_instance)
else:
navi_instance.print_message("Invalid choice. Please enter 'chip' or 'file'.")


def create_chip_file(chip_name, chip_file_name):
"""Creates the chip file from a template."""
if not os.path.exists(template_file):
print(f"{Fore.RED}ERROR:{Fore.RESET} Template file '{template_file}' is missing. Aborting.")
return None

with open(template_file, "r") as template:
template_content = template.read()

chip_file_name_final = chip_file_name.replace(".py", "") + ".py"
template_content = template_content.replace("{{CHIP_NAME}}", chip_name)
chip_file_path = os.path.join(os.getcwd(), chip_install_path, chip_file_name_final)

with open(chip_file_path, "w") as chip_dev:
chip_dev.write(template_content)

print(f"{Fore.GREEN}Chip '{chip_name}' created successfully!{Fore.RESET}")
return chip_file_path


def post_creation_options(chip_file_path, navi_instance):
"""Provides options to the user after chip creation."""
navi_instance.print_message(f"Here are some options for you:\n"
f"{Fore.YELLOW}1{Fore.RESET}: Open directory of Chip location\n"
f"{Fore.YELLOW}2{Fore.RESET}: Open in your preferred code editor\n"
f"{Fore.YELLOW}3{Fore.RESET}: Reload Navi to load the new Chip\n"
f"{Fore.YELLOW}4{Fore.RESET}: Review the documentation online\n"
f"{Fore.YELLOW}5{Fore.RESET} or other value: I'm finished")
choice = get_user_input("Please enter 1, 2, 3, 4, or 5: ")
try:
if choice == '1':
print("Opening directory of Chip location")
directory = os.path.dirname(chip_file_path)
if sys.platform.startswith('win'):
subprocess.run(['explorer', directory], check=True) # nosec
elif sys.platform == 'darwin':
subprocess.run(['open', directory], check=True) # nosec
else:
subprocess.run(['xdg-open', directory], check=True) # nosec
elif choice == '2':
print("Opening in your preferred code editor")
if sys.platform.startswith('win'):
subprocess.run(['explorer', chip_file_path], check=True) # nosec
elif sys.platform == 'darwin':
subprocess.run(['open', chip_file_path], check=True) # nosec
else:
subprocess.run(['xdg-open', chip_file_path], check=True) # nosec
elif choice == '3':
restart_navi()
elif choice == '4':
webbrowser.open(chip_documentation_link)
else:
pass
except FileNotFoundError:
print("Couldn't find the file or directory.")
except subprocess.SubprocessError as e:
print(f"Failed to execute the command: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")


def sanitize_input(name):
"""
Sanitizes the user-provided chip name.
Ensures it is safe and valid for use in file paths.
"""
sanitized_name = name.strip()
if len(name) > 50:
print(f"{Fore.RED}Warning:{Fore.RESET} Input is too long (50 characters max). Trimming to 49 characters.")
sanitized_name = sanitized_name[:50]

# Replace invalid characters with underscores
old_name = sanitized_name
sanitized_name = re.sub(r'[^\w\-]', '_', name)
if old_name != sanitized_name:
print(f"{Fore.RED}Warning:{Fore.RESET} Invalid characters in '{old_name}'. Replacing with '{sanitized_name}'.")

return sanitized_name


def run(arguments=None):
navi_instance = navi_internal.navi_instance
arg_array = arguments.text.split()[1:] # Exclude the command itself

if arg_array:
for arg in arg_array:
if arg in help_params:
print_params()
return
else:
choice = get_user_input(f"Invalid parameter: {arg}\n"
f"Do you want to review the available parameters? (y/n): ").lower()
if choice == 'y':
print_params()
return

navi_instance.print_message(
f"Welcome to Navi Chip creator, {navi_instance.get_user()}. Please enter the name of your new Chip.")
chip_name = sanitize_input(get_user_input("Chip Name: "))
navi_instance.print_message(
f"Great name, {navi_instance.get_user()}! What do you want the python file to be called?")
chip_file_name = sanitize_input(get_user_input("Chip File Name: "))

chip_name, chip_file_name = confirm_details(chip_name, chip_file_name, navi_instance)
chip_file_path = create_chip_file(chip_name, chip_file_name)
if chip_file_path:
post_creation_options(chip_file_path, navi_instance)
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import os
import sys
import requests
import zipfile
import shutil
import subprocess # nosec
import sys
import uuid
import navi_internal
import zipfile

import requests
from colorama import Fore

import navi_internal
from navi import get_parameters
from navi_shell import restart_navi

Expand Down Expand Up @@ -83,7 +84,7 @@ def download_and_extract(download_url):
return None, None


def copy_files_to_install_path(extracted_dir, install_path="/commands"):
def copy_files_to_install_path(extracted_dir, install_path="/chips/Com"):
installed_files = []
try:
for item in os.listdir(extracted_dir):
Expand Down Expand Up @@ -114,7 +115,7 @@ def install_requirements(extracted_dir):
os.remove(requirements_path)


def update_script(download_url, install_path="commands"):
def update_script(download_url, install_path="chips/Com"):
print("Downloading chip...")
extracted_dir, download_guid = download_and_extract(download_url)
if extracted_dir:
Expand Down Expand Up @@ -236,21 +237,39 @@ def get_installed_chips() -> list[dict[str, str]] | None:
return modules


def get_dev_chips():
import chips
dev_chips = []
for command_name, module in chips.modules.items():
if module.__name__.startswith("chips.Dev"):
command_aliases = getattr(module, 'aliases', [])
command_use = getattr(module, 'use', "")
dev_chips.append((command_name, command_use, command_aliases))
return dev_chips


def list_installed_chips() -> None:
chips = get_installed_chips()
if chips:
print("Installed Chips:")
print("Installed Community Chips:")
for module in chips:
print(f"- {module['name']} (Owner: {module['owner']}, Version: {module['version']})")
else:
print("No chips are installed.")
print("No Community Chips are installed.")
dev_chips = get_dev_chips()
if not dev_chips:
print("No Developer Chips are installed.")
else:
print("\nDeveloper Chips:")
for chip in dev_chips:
print(f"- {chip[0]} (Use: {chip[1]}, Aliases: {chip[2]})")


def about_chip(name) -> dict[str, str] | None:
log_file_path = "installed_chips.txt"

if not os.path.exists(log_file_path):
print("No chips are installed.")
print("No Community Chips are installed.")
return None

with open(log_file_path, 'r') as log_file:
Expand Down Expand Up @@ -290,7 +309,7 @@ def about_chip(name) -> dict[str, str] | None:
"latest_version": latest_version
}

print(f"The chip '{name}' is not installed.")
print(f"The Community Chip '{name}' is not installed.")
return None


Expand All @@ -310,9 +329,9 @@ def update_chip(chip_name: str) -> None:

def help_text() -> None:
navi.print_message("Chip Manager\n"
"chips [install | uninstall | search | update] [app/query]\n\n"
"List currently installed chips\n"
"chips list")
"chips [install | uninstall | search | update] [app/query]\n\n"
"List currently installed chips\n"
"chips list")


def run(arguments=None) -> None:
Expand Down
1 change: 0 additions & 1 deletion commands/navi_clear.py → chips/SSG/navi_clear.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/bin/python3
import navi_internal

command = "clear"
Expand Down
1 change: 0 additions & 1 deletion commands/navi_exit.py → chips/SSG/navi_exit.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/bin/python3
import navi_internal

command = "exit"
Expand Down
4 changes: 2 additions & 2 deletions commands/navi_help.py → chips/SSG/navi_help.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/python3
import commands
import chips

command = "navi_help"
use = "Displays the help screen"
Expand All @@ -12,7 +12,7 @@ def run(arguments=None):
max_alias_length = 0
command_data = []

for command_name, module in commands.modules.items():
for command_name, module in chips.modules.items():
command_aliases = getattr(module, 'aliases', [])
command_use = getattr(module, 'use', "")

Expand Down
Loading
Loading