From 92a910d679dc84f6ac1d44edab7e6750f4c82de8 Mon Sep 17 00:00:00 2001 From: Roberto Salgado Date: Tue, 28 Jul 2026 22:45:56 -0700 Subject: [PATCH 1/2] Clarify installation and update guidance --- README.md | 30 +++++++++++++++++++++++------- panoptic/update.py | 6 ++++-- tests/test_update.py | 4 +++- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9758f4e..fcbaca5 100644 --- a/README.md +++ b/README.md @@ -49,20 +49,30 @@ path traversal vulnerabilities. ## Requirements * Python 3.10+ -* Dependencies: `httpx[socks]`, `rich`, `rich-argparse` +* Git +* Dependencies: `httpx[socks]`, `rich`, `rich-argparse`, and + `tomli` on Python 3.10 ## Installation ```bash git clone https://github.com/lightos/Panoptic.git cd Panoptic -pip install -e . +python3 -m venv .venv +source .venv/bin/activate +python -m pip install -e . +panoptic --version ``` +On Windows, activate with `.venv\Scripts\activate`. The editable install +keeps Panoptic connected to this checkout for `--update`, so keep the +directory in place. Do not run `pip install panoptic`: that PyPI name +belongs to an unrelated project. + For development: ```bash -pip install -e ".[dev]" +python -m pip install -e ".[dev]" ``` ## Usage @@ -343,10 +353,16 @@ panoptic --update # fast-forward update from the official GitHub repo `--update` only works from a git checkout whose `origin` remote uses HTTPS or SSH and matches the official upstream (verified before pulling, to resist insecure or tampered remote configuration). It fast-forwards -the checked-out `main` branch from the explicit upstream `main` ref; for -pip installs it prints the correct -`pip install -U` command instead. When run from a checkout, the banner -also shows the current short git revision. +the checked-out `main` branch from the explicit upstream `main` ref. +Non-checkout installations can be refreshed safely from the official +GitHub archive: + +```bash +python -m pip install --upgrade https://github.com/lightos/Panoptic/archive/refs/heads/main.zip +``` + +When run from a checkout, the banner also shows the current short git +revision. ## Exit Codes diff --git a/panoptic/update.py b/panoptic/update.py index 5bdae18..6f0bc97 100644 --- a/panoptic/update.py +++ b/panoptic/update.py @@ -14,6 +14,8 @@ GIT_REPOSITORY_URL = "https://github.com/lightos/Panoptic.git" GIT_UPSTREAM_BRANCH = "main" GIT_UPSTREAM_REF = f"refs/heads/{GIT_UPSTREAM_BRANCH}" +PIP_UPDATE_URL = f"https://github.com/lightos/Panoptic/archive/refs/heads/{GIT_UPSTREAM_BRANCH}.zip" +PIP_UPDATE_COMMAND = f"python -m pip install --upgrade {PIP_UPDATE_URL}" _PACKAGE_DIR = os.path.dirname(os.path.abspath(__file__)) _PROJECT_ROOT = os.path.dirname(_PACKAGE_DIR) @@ -51,7 +53,7 @@ def do_update() -> int: if not os.path.exists(git_dir): print("[i] Panoptic appears to be installed via pip.") - print("[i] To update, run: pip install -U panoptic") + print(f"[i] To update, run: {PIP_UPDATE_COMMAND}") return 0 print("[i] Checking for updates...") @@ -67,7 +69,7 @@ def do_update() -> int: ) except FileNotFoundError: print("[!] 'git' is not installed or not in PATH.") - print("[i] Please install git or update via: pip install -U panoptic") + print(f"[i] Please install git or update via: {PIP_UPDATE_COMMAND}") return 2 except subprocess.TimeoutExpired: print("[!] Timed out while checking the git remote.") diff --git a/tests/test_update.py b/tests/test_update.py index 4e64663..84f9926 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -7,6 +7,7 @@ from panoptic.update import ( GIT_UPSTREAM_REF, + PIP_UPDATE_COMMAND, _normalise_git_url, _uses_secure_git_transport, do_update, @@ -44,7 +45,8 @@ def test_git_checkout_rejects_non_main_branch(self, mock_exists: Any, mock_run: def test_pip_installed_prints_guidance(self, mock_exists: Any, capsys: pytest.CaptureFixture[str]) -> None: assert do_update() == 0 captured = capsys.readouterr() - assert "pip" in captured.out.lower() + assert PIP_UPDATE_COMMAND in captured.out + assert "pip install -U panoptic" not in captured.out def test_ssh_and_https_remotes_are_equivalent(self) -> None: assert _normalise_git_url("git@github.com:lightos/Panoptic.git") == _normalise_git_url( From 17471943868261fde01d3dfafbea10bb929e5209 Mon Sep 17 00:00:00 2001 From: Roberto Salgado Date: Tue, 28 Jul 2026 22:49:01 -0700 Subject: [PATCH 2/2] Address install guidance review --- README.md | 9 +++++---- tests/test_update.py | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fcbaca5..eeab8cb 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,11 @@ python -m pip install -e . panoptic --version ``` -On Windows, activate with `.venv\Scripts\activate`. The editable install -keeps Panoptic connected to this checkout for `--update`, so keep the -directory in place. Do not run `pip install panoptic`: that PyPI name -belongs to an unrelated project. +On Windows Command Prompt, activate with `.venv\Scripts\activate.bat`; +in PowerShell, use `.venv\Scripts\Activate.ps1`. The editable install keeps +Panoptic connected to this checkout for `--update`, so keep the directory +in place. Do not run `pip install panoptic`: that PyPI name belongs to an +unrelated project. For development: diff --git a/tests/test_update.py b/tests/test_update.py index 84f9926..22cc19a 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -7,7 +7,6 @@ from panoptic.update import ( GIT_UPSTREAM_REF, - PIP_UPDATE_COMMAND, _normalise_git_url, _uses_secure_git_transport, do_update, @@ -45,7 +44,9 @@ def test_git_checkout_rejects_non_main_branch(self, mock_exists: Any, mock_run: def test_pip_installed_prints_guidance(self, mock_exists: Any, capsys: pytest.CaptureFixture[str]) -> None: assert do_update() == 0 captured = capsys.readouterr() - assert PIP_UPDATE_COMMAND in captured.out + assert ( + "python -m pip install --upgrade https://github.com/lightos/Panoptic/archive/refs/heads/main.zip" + ) in captured.out assert "pip install -U panoptic" not in captured.out def test_ssh_and_https_remotes_are_equivalent(self) -> None: