From 30c4fce61bc1b2ecda693506e32bef77328a6ed0 Mon Sep 17 00:00:00 2001 From: Hardik Zinzuvadiya <25708027+Z4nzu@users.noreply.github.com> Date: Sun, 15 Mar 2026 18:51:19 +0530 Subject: [PATCH] Feature: Open Folder option to manually access tool directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HackingTool: - Add _get_tool_dir() — finds the tool's local directory by checking: 1. Git clone target dir (from INSTALL_COMMANDS) 2. "cd foo && bar" pattern in RUN_COMMANDS 3. Binary location via shutil.which() → dirname - Add open_folder() — opens the tool's directory in a new shell ($SHELL) so the user can inspect files, run manual install steps, or debug If dir not found: shows a helpful message with git clone command - Added as option 4 in every tool menu (Install, Run, Update, Open Folder) - Updated inline help to mention the tool menu options --- core.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/core.py b/core.py index 88d7e9a..985d85a 100644 --- a/core.py +++ b/core.py @@ -62,6 +62,7 @@ def _show_inline_help(): (" ─────────────────────────────────\n", "dim"), (" 1–N ", "bold cyan"), ("select item\n", "white"), (" 97 ", "bold cyan"), ("install all (in category)\n", "white"), + ("\n Tool menu: Install, Run, Update, Open Folder\n", "dim"), (" 99 ", "bold cyan"), ("go back\n", "white"), (" 98 ", "bold cyan"), ("open project page / archived\n", "white"), (" ? ", "bold cyan"), ("show this help\n", "white"), @@ -110,6 +111,7 @@ class HackingTool: if runnable: self.OPTIONS.append(("Run", self.run)) self.OPTIONS.append(("Update", self.update)) + self.OPTIONS.append(("Open Folder", self.open_folder)) self.OPTIONS.extend(options) @property @@ -269,6 +271,55 @@ class HackingTool: else: console.print("[dim]No automatic update method available for this tool.[/dim]") + def _get_tool_dir(self) -> str | None: + """Find the tool's local directory — clone target, pip location, or binary path.""" + # 1. Check git clone target dir + for ic in (self.INSTALL_COMMANDS or []): + if "git clone" in ic: + parts = ic.split() + # If last arg is not a URL, it's a custom dir name + repo_urls = [p for p in parts if p.startswith("http")] + if repo_urls: + dirname = repo_urls[0].rstrip("/").rsplit("/", 1)[-1].replace(".git", "") + # Check custom target dir (arg after URL) + url_idx = parts.index(repo_urls[0]) + if url_idx + 1 < len(parts): + dirname = parts[url_idx + 1] + if os.path.isdir(dirname): + return os.path.abspath(dirname) + + # 2. Check binary location via which + if self.RUN_COMMANDS: + cmd = self.RUN_COMMANDS[0] + if "&&" in cmd: + # "cd foo && bar" → check "foo" + cd_part = cmd.split("&&")[0].strip() + if cd_part.startswith("cd "): + d = cd_part[3:].strip() + if os.path.isdir(d): + return os.path.abspath(d) + binary = cmd.split()[0] if cmd else "" + if binary.startswith("sudo"): + binary = cmd.split()[1] if len(cmd.split()) > 1 else "" + path = shutil.which(binary) if binary else None + if path: + return os.path.dirname(os.path.realpath(path)) + + return None + + def open_folder(self): + """Open the tool's directory in a new shell so the user can work manually.""" + tool_dir = self._get_tool_dir() + if tool_dir: + console.print(f"[success]Opening folder: {tool_dir}[/success]") + console.print("[dim]Type 'exit' to return to hackingtool.[/dim]") + os.system(f'cd "{tool_dir}" && $SHELL') + else: + console.print("[warning]Tool directory not found.[/warning]") + if self.PROJECT_URL: + console.print(f"[dim]You can clone it manually:[/dim]") + console.print(f"[cyan] git clone {self.PROJECT_URL}.git[/cyan]") + def before_run(self): pass def run(self):