You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
What's Changed
Fixed
The tool installer aborted on the first hard failure (install-tools.sh): apt-get update, apt-get install and the pip fallback chain ran under set -euo pipefail, so a broken package index, an unreachable mirror or a failed venv creation killed the whole run and left the system half-provisioned with no summary. The installer is now failure-tolerant: every step is individually guarded, failures are collected, and the run always reaches the summary and prints copy-pasteable repair commands. It also no longer exits non-zero on a partial install.
install-tools.sh reported false successes: linpeas/winpeas printed "installed" whenever chmod succeeded — even if the download had failed and left a 0-byte file. Downloads are now validated (size + integrity) before a tool is counted as installed, and a corrupt artefact is reported as a failure.
ligolo-ng could never be installed from a release archive (install-tools.sh): the tarball extracts to a versioned directory (ligolo-ng_agent_<ver>/agent), but the script moved a hardcoded /tmp/agent — the mv always failed. The binary is now located inside the extracted tree before it is placed.
chisel was unpacked with the wrong tool (install-tools.sh): its release asset is a plain .gz, not a .tar.gz, so tar -xzf failed. Release assets are now unpacked according to their actual format.
Go fix-hints in the installer summary were unusable: failures were recorded by binary name, so the hint printed go install subfinder@latest instead of the real module path. The full module path is now retained and printed verbatim.
doctor.sh could not install any Go tool (db/doctor.sh): the recipe stripped only the go prefix from the hint, so go was invoked as go install "install github.com/…" — an invalid package path that always failed. The full go install prefix is now stripped.
doctor.sh mis-detected tools whose console script differs from the package name: bloodhound (bloodhound-python), kiterunner (kr) and testssl.sh (testssl) were always reported missing. Detection now knows the real command names.
The auto-discovered skill was a stale copy (.opencode/skills/opencode-pentester/SKILL.md): it was 5 KB behind the source of truth and was missing the Mode Routing, Graceful Degradation and Tool Fallback Matrix sections plus the version: frontmatter — so the primary usage path (running opencode inside the repo) silently executed an older skill than the globally installed one. The copy is now generated from SKILL.md and CI fails the build if it drifts.
The globally installed skill was missing most of its own runtime (install.sh): the support bundle shipped only playbooks/, templates/, db/doctor.sh and db/lib/common.sh, while SKILL.md references db/findings.sh, db/leads.sh, db/session.sh, db/schema.sql, db/seed.py, engine/scope_guard.py and more. Every DB command in a global install was a dead path. The bundle now ships the full runtime (db/, engine/, pipelines/, rules/, agents/, docs/reference/).
CVE matching in the JIT router was unconditional and unbounded (engine/router.py): get_relevant_context() hit the NVD API for every service on every call, with a 10 s timeout per service, no rate-limit handling, and an in-memory cache that never expired (CVE_CACHE_TTL was dead code). A 40-service scan meant 40 sequential NVD requests, which NVD answers with 403 after ~5 requests per 30 s. CVE lookup is now opt-in (PENTEST_CVE=1 / --cve-match), offline-safe (PENTEST_NO_NETWORK=1), rate-limit aware (bounded retries with backoff, optional NVD_API_KEY) and cached on disk with the TTL honoured.
A malformed service string crashed the router (engine/router.py): --services http/tcp/http raised an unhandled ValueError from int(parts[0]). Malformed entries are now skipped with a warning and the rest of the command still runs.
Version metadata disagreed across the repo: README.md badge and plugin.json still said 1.11.1 while the code was at 1.12.0. All version references are now 1.13.0 and CI asserts VERSION == the SKILL.md frontmatter.
Added
Resilient tool installer (install-tools.sh): --dry-run (plan only, changes nothing), --offline (zero network I/O, honours PENTEST_NO_NETWORK=1), --only <group> / --skip <group> (system|python|go|binary), --verify-only, and --help. Already-installed tools are detected and skipped, git checkouts are updated instead of re-cloned, and every network call is bounded by a timeout and retried with backoff.
Writable binary directory detection (install-tools.sh): the installer no longer assumes /usr/local/bin is writable — it falls back to ~/.local/bin (or PENTEST_BIN_DIR) so it works without root.
Correct pip → console-script mapping (install-tools.sh): scoutsuite→scout, bloodhound→bloodhound-python, impacket→impacket-smbserver, and library-only packages (requests, beautifulsoup4) are detected by import instead of being given a bogus symlink.
Go binary discovery fix (install-tools.sh): GOPATH/GOBIN are exported, $GOPATH/bin is added to PATH, and stale symlinks in the binary directory are repaired on every run.
dnf/yum support (install-tools.sh): the package manager was detected but had no install branch, so Fedora/RHEL hosts silently installed nothing.
CI packaging guards (.github/workflows/smoke.yml): a "Skill packaging integrity" step fails the build when the auto-discovered skill copy drifts from SKILL.md, when VERSION disagrees with the SKILL.md frontmatter, or when a path referenced by SKILL.md is missing. A Shellcheck error-level gate was added for every shell script.
Smoke-test coverage for the fixes (db/smoke.sh): 18 new checks covering skill-bundle completeness, install/uninstall round-trips, installer flag handling, the doctor.sh Go recipe, and the router's offline/malformed-input behaviour (169 → 187 checks).
Changed
install.sh gained --local-only and --yes; a failing tool install no longer aborts the script before the skill registration summary is printed.
The generated skill bundle is no longer committed to git — only SKILL.md is source-controlled, the rest is a deployment artefact produced by install.sh.
*.state files (feroxbuster / dirsearch scanner state) are now ignored by git.