Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
6517048
Add new ui and new installation
Oct 16, 2025
b56f121
Remove install.py comments
Oct 16, 2025
9c67af9
Remove setup.py comments
Oct 16, 2025
03e016c
Remove uninstall.py comments
Oct 16, 2025
ef892e8
Device With Rich Ui
Oct 16, 2025
d3d508d
Update activity.py and battery.py
Oct 16, 2025
a56e825
Update download.py
Oct 16, 2025
d9ef41a
Update keyboard.py
Oct 16, 2025
3c86bd5
Update list.py
Oct 16, 2025
a1613fa
Update network.py
Oct 16, 2025
7c797d8
Update openurl.py
Oct 16, 2025
b0fee59
Update press.py
Oct 16, 2025
9ab7824
Update screenshot.py
Oct 16, 2025
df96442
Update shell.py
Oct 16, 2025
0f90c5b
Update sleep.py
Oct 16, 2025
75e5bae
Update upload.py
Oct 16, 2025
d4c4230
Update wifi.py
Oct 16, 2025
72efbab
Auto-reconnect
Oct 17, 2025
396df93
Add Device Analyzer & Real-Time Log Viewer
Oct 17, 2025
e0f9a1e
Add help command
Oct 17, 2025
573020a
Remove setup.py
Oct 17, 2025
7c0ac51
Remove setup.py
Oct 17, 2025
6fa71c7
Remove install.py | Add main.py | Add pyproject.toml
Oct 17, 2025
b455950
Revert "Remove setup.py"
Oct 17, 2025
1b20270
Big update
Oct 17, 2025
f50301b
Update pyproject.toml
Oct 17, 2025
0eb33d0
Update pyproject.toml
Oct 17, 2025
3385696
last Update pyproject.toml
Oct 17, 2025
a393e02
Remoce some comments
Oct 17, 2025
6b23dde
Remoce some comments
Oct 17, 2025
c2ad222
Remoce some comments
Oct 17, 2025
38e083b
Remove main.py | update pyproject.toml
Oct 17, 2025
9772826
Add main.py
Oct 17, 2025
5782752
Big update 2
Oct 17, 2025
d578246
update pyproject.toml
Oct 17, 2025
9e93c4b
update REAADME.md
Oct 17, 2025
180e94c
last update
Oct 17, 2025
cf75102
Update pyproject.toml
Oct 17, 2025
81b1d48
Update console.py & device.py
Oct 17, 2025
6f06cbe
Update main to cli
Oct 18, 2025
1040029
Update main to cli
Oct 18, 2025
32d2ebe
Remove requirements.txt & update pyproject.toml
Oct 18, 2025
d602f79
update console.py
Oct 18, 2025
cb8b581
Add __main__.py
Oct 18, 2025
0802ca5
last update
Oct 18, 2025
566c371
last update
Oct 18, 2025
fa39dbf
update interfaace
Oct 18, 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
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,32 @@
<br>
<code>pip3 install git+https://github.com/EntySec/Ghost</code>
</p>

# Ghost

Ghost — staged installation framework

## fast-install

```bash

pip install .[vcs] --break

```

## install

```bash

python -m venv .venv
source .venv/bin/activate


pip install --upgrade pip
pip install .[vcs]


ghost

```

12 changes: 1 addition & 11 deletions ghost/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,4 @@
SOFTWARE.
"""

from ghost.core.console import Console


def cli() -> None:
""" Ghost Framework command-line interface.

:return None: None
"""

console = Console()
console.shell()
__version__ = "…"
4 changes: 4 additions & 0 deletions ghost/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .cli import main

if __name__ == "__main__":
raise SystemExit(main())
5 changes: 5 additions & 0 deletions ghost/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from ghost.core.console import Console

def main() -> int:
Console().shell()
return 0
185 changes: 142 additions & 43 deletions ghost/core/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,26 @@
"""

from badges.cmd import Cmd

from ghost.core.device import Device

from rich.console import Console as RichConsole
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from rich.align import Align
from rich import box
from rich.style import Style
from rich.rule import Rule
from rich.padding import Padding
from rich.columns import Columns

PURPLE = "#7B61FF"
WHITE_ON_PURPLE = Style(color="white", bgcolor=PURPLE, bold=True)
INFO_STYLE = Style(color=PURPLE, bold=True)
WARN_STYLE = Style(color="yellow", bold=True)
ERR_STYLE = Style(color="red", bold=True)
SUCCESS_STYLE = Style(color="green", bold=True)


class Console(Cmd):
""" Subclass of ghost.core module.
Expand All @@ -37,40 +54,141 @@ class Console(Cmd):
def __init__(self) -> None:
super().__init__(
prompt='(%lineghost%end)> ',
intro="""%clear%end
intro="""
.--. .-. .-.
: .--': : .' `.
: : _ : `-. .--. .--.`. .'
: :; :: .. :' .; :`._-.': :
`.__.':_;:_;`.__.'`.__.':_;

--=[ %bold%whiteGhost Framework 8.0.0%end
--=[ Developed by EntySec (%linehttps://entysec.com/%end)
--=[ Ghost Framework 8.0.0
--=[ Developed by EntySec (https://entysec.com/)
"""
)

self.devices = {}

def do_exit(self, _) -> None:
""" Exit Ghost Framework.
# Force ANSI + TrueColor for Linux/modern terminals
self.rich = RichConsole(force_terminal=True, color_system="truecolor")
self.rich.clear()
self._render_header()


:return None: None
:raises EOFError: EOF error
"""
def _render_header(self) -> None:
"""Render a fancy hacker-style header with tools table and quick help."""
title = Text("Ghost Framework 8.0.0", style="bold white")
subtitle = Text("Developed by EntySec — https://entysec.com/", style="dim")

ascii_art = Text(
" .--. .-. .-.\n"
" : .--': : .' `.\n"
" : : _ : `-. .--. .--.`. .'\n"
" : :; :: .. :' .; :`._-.': :\n"
" `.__.':_;:_;`.__.'`.__.':_;",
justify="center",
)

left = Panel(
Align.center(ascii_art),
border_style=PURPLE,
box=box.HEAVY,
padding=(0, 2),
title="[bold]GHOST",
subtitle=title,
)

help_table = Table(title=Text("🚀 Ghost Framework Commands", style="bold white on " + PURPLE, justify="center"),
box=box.DOUBLE_EDGE,
border_style=PURPLE,
expand=False,
show_lines=True)

help_table.add_column("Command", style="bold white on " + "#5A3EFF", no_wrap=True, justify="center")
help_table.add_column("Description", style="italic dim", justify="left")

commands = [
("🔌 connect <host>:[port]", "Connect to device via ADB (default port 5555)"),
("📱 devices", "List connected devices"),
("❌ disconnect <id>", "Disconnect device by ID"),
("💬 interact <id>", "Interact with a connected device"),
("🔍 analyze <id> / an <id>", "Run Device Analyzer"),
("📜 logcat <id> / lc <id>", "Start live logcat stream"),
("🧹 clear", "Clear the terminal screen"),
("🚪 exit", "Quit Ghost Framework"),
("🔄 Index 99", "Return to Menu / Exit (UI helper)")
]

ALT_ROW = "#2E2E2E"
for i, (cmd, desc) in enumerate(commands):
style = Style(bgcolor=ALT_ROW) if i % 2 else Style()
help_table.add_row(cmd, desc, style=style)

right_panel = Panel(
Align.left(
Text.assemble(subtitle, "\n\n", "Theme: ", (PURPLE, "Hacker • Purple"))
),
border_style=PURPLE,
box=box.ROUNDED,
padding=(0, 1),
title="[bold]Info",
)

header_columns = Columns([left, Panel(help_table, padding=(1, 2), border_style=PURPLE), right_panel])
self.rich.print(header_columns)
self.rich.print(Rule(style=PURPLE))
self.rich.print(Align.center(Text("Type [bold]devices[/bold] to list connected devices — Index 99 → Exit", style=INFO_STYLE)))
self.rich.print()

def print_empty(self, message: str = "", end: str = "\n") -> None:
"""Print a simple message."""
self.rich.print(message)
def print_information(self, message: str) -> None:
"""Print an informational message in a panel."""
self.rich.print(Panel(Text(message), border_style=PURPLE, title="[bold white]INFO", box=box.MINIMAL))

def print_warning(self, message: str) -> None:
"""Print a warning message in a panel."""
self.rich.print(Panel(Text(message), border_style="yellow", title="[bold white]WARNING", box=box.MINIMAL))

def print_error(self, message: str) -> None:
"""Print an error message in a panel."""
self.rich.print(Panel(Text(message), border_style="red", title="[bold white]ERROR", box=box.MINIMAL))

def print_success(self, message: str) -> None:
"""Print a success message in a panel."""
self.rich.print(Panel(Text(message), border_style="green", title="[bold white]SUCCESS", box=box.MINIMAL))

def print_usage(self, usage: str) -> None:
"""Print usage information for a command."""
usage_text = Text.assemble(("Usage: ", "bold"), (usage, ""))
footer = Text("Index 99 → Return to Menu", style=INFO_STYLE)
self.rich.print(Panel(usage_text, border_style=PURPLE, title="[bold]USAGE", subtitle=footer))

def print_process(self, message: str) -> None:
"""Show a processing spinner with a message."""
with self.rich.status(Text(message, style=INFO_STYLE), spinner="bouncingBall", spinner_style=PURPLE):
pass

def print_table(self, title: str, columns: tuple, *rows) -> None:
"""Render a stylized table for lists like connected devices."""
table = Table(title=title, box=box.SIMPLE_HEAVY, expand=False, border_style=PURPLE)
for col in columns:
table.add_column(str(col), header_style="bold white")
for row in rows:
table.add_row(*[str(x) for x in row])
footer = Text("Index 99 → Return to Menu", style=INFO_STYLE)
wrapper = Panel(Padding(table, (0, 1)), subtitle=footer, border_style=PURPLE)
self.rich.print(wrapper)

def do_exit(self, _) -> None:
"""Quit Ghost Framework and disconnect all devices."""
for device in list(self.devices):
self.devices[device]['device'].disconnect()
del self.devices[device]

raise EOFError

def do_connect(self, args: list) -> None:
""" Connect device.

:param list args: arguments
:return None: None
"""

"""Connect to a device via ADB."""
if len(args) < 2:
self.print_usage("connect <host>:[port]")
return
Expand All @@ -93,7 +211,6 @@ def do_connect(self, args: list) -> None:
}
})
self.print_empty("")

self.print_information(
f"Type %greendevices%end to list all connected devices.")
self.print_information(
Expand All @@ -102,37 +219,25 @@ def do_connect(self, args: list) -> None:
)

def do_devices(self, _) -> None:
""" Show connected devices.

:return None: None
"""

"""List all connected devices."""
if not self.devices:
self.print_warning("No devices connected.")
return

devices = []

for device in self.devices:
devices.append(
(device, self.devices[device]['host'],
self.devices[device]['port']))

self.print_table("Connected Devices", ('ID', 'Host', 'Port'), *devices)

def do_disconnect(self, args: list) -> None:
""" Disconnect device.

:param list args: arguments
:return None: None
"""

"""Disconnect a connected device by ID."""
if len(args) < 2:
self.print_usage("disconnect <id>")
return

device_id = int(args[1])

if device_id not in self.devices:
self.print_error("Invalid device ID!")
return
Expand All @@ -141,29 +246,23 @@ def do_disconnect(self, args: list) -> None:
self.devices.pop(device_id)

def do_interact(self, args: list) -> None:
""" Interact with device.

:param list args: arguments
:return None: None
"""

"""Interact with a connected device by ID."""
if len(args) < 2:
self.print_usage("interact <id>")
return

device_id = int(args[1])

if device_id not in self.devices:
self.print_error("Invalid device ID!")
return

self.print_process(f"Interacting with device {str(device_id)}...")
self.devices[device_id]['device'].interact()

def shell(self) -> None:
""" Run console shell.

:return None: None
"""
def do_clear(self, _) -> None:
"""Clear the terminal screen."""
self.rich.clear()

def shell(self) -> None:
"""Start the main Ghost Framework loop."""
self.loop()
Loading