Skip to content

bughunter/ restructure left 54 tool invocations pointing at the old tools/ path #175

Closed

Description

@spierenburg

Summary

Moving tools/ under bughunter/ didn't update the paths that invoke those
tools. On a clean checkout of 40b03ee there is no top-level tools/ directory,
but 54 invocations across commands/ and skills/ still reference tools/*.

The scripts themselves are fine — only the call sites and docs are stale.

Reproduce

git clone https://github.com/Awarexone/Agentic-Bug-Hunter /tmp/abh && cd /tmp/abh
ls tools/
# ls: tools/: No such file or directory

grep -rhoE '(bash|python3?) tools/[a-z_]+\.(py|sh)' commands/ skills/ | wc -l
# 54

grep -rhoE '(bash|python3?) tools/[a-z_]+\.(py|sh)' commands/ skills/ | sort | uniq -c | sort -rn | head -5
#   17 python3 tools/hunt.py
#    9 bash tools/recon_engine.sh
#    6 python3 tools/token_scanner.py
#    6 python3 tools/lead_board.py
#    6 bash tools/graphql_audit.sh

Scope

Location Stale tools/* references
commands/ + skills/ (executable invocations) 54, across 40 distinct paths
CLAUDE.md 34
AGENTS.md 7
docs/TUTORIAL.md, docs/auth-sessions.md, docs/mcp-tools.md 21

Deliberately excluded from those counts: docs/phase*.md, docs/TODOS.md and
docs/CAPABILITY-GAPS.md. Those read as historical/planning records where stale
paths are expected and harmless.

Why it matters more for agents than for humans

The files in commands/ are instructions an agent executes directly, and
CLAUDE.md is loaded into context every session. An agent told to run
python3 tools/hunt.py gets No such file or directory and then has to
rediscover the layout — or does something else entirely. A human reading the
tutorial will just notice the path is wrong and adapt.

What's already correct

Two parts of the restructure were handled, which is why the fix is narrow:

  • install.sh is layout-aware — its resolve_src helper resolves agents/ and
    mcp/ from either the old or the new location.
  • bughunter/tools/vuln_scanner.sh:78-79 self-locates via SCRIPT_DIR /
    BASE_DIR, so the scripts behave correctly once invoked at their real path.
    tests/test_vuln_scanner_review_fixes.py::test_scanner_uses_current_repo_paths
    already asserts this.

Suggested fix

Rather than rewriting 54 call sites to bughunter/tools/... — which breaks again
on the next move — point them at the bughunter CLI entry point that
install.sh --agent standalone already installs:

python3 tools/hunt.py target.com     ->   bughunter hunt target.com
bash tools/recon_engine.sh target    ->   bughunter recon target.com

That makes the call sites layout-independent. A CI guard would stop the
regression recurring, e.g.:

# fail if any command/skill references a path that doesn't exist
grep -rhoE '(bash|python3?) [a-z/_]+\.(py|sh)' commands/ skills/ \
  | awk '{print $2}' | sort -u \
  | while read -r p; do [ -f "$p" ] || echo "MISSING: $p"; done

Running that on 40b03ee reports 11 distinct missing paths. One of them —
php_filter_chain_generator.py — is referenced with no directory prefix at all,
so it is broken independently of this restructure and worth a look while you're
in there.

In-flight PRs will reintroduce this on merge

Worth fixing the paths and adding the guard together, because open PRs are still
targeting the old layout. PR #157 adds a new file at tools/report_gate.py and
edits the tools list in CLAUDE.md.

To be fair to that PR: it was opened on 2026-09-22, the same day the restructure
landed in 025367b (#148, 11:46 +0800), so it was almost certainly branched before
the move — this is a rebase artifact, not someone ignoring the new layout. But the
effect at merge time is the same either way: a file lands at a path that no longer
exists, and the docs gain another stale reference. Any other PR opened before
2026-09-22 is in the same position.

A CI guard would catch this on each PR rather than after merge, which is probably
more valuable than the one-time path cleanup.

Same cause, different file: .gitignore still anchored to the old layout

.gitignore:53 is:

memory/leads/

That pattern contains an internal slash, so git anchors it to the repository
root. It matches /memory/leads/ and nothing else — in particular it does not
match bughunter/memory/leads/, where the lead board actually writes now.

Confirmed empirically:

mkdir -p memory/leads bughunter/memory/leads
: > memory/leads/probe.jsonl
: > bughunter/memory/leads/probe.jsonl
git check-ignore -v memory/leads/probe.jsonl
#   .gitignore:53:memory/leads/   memory/leads/probe.jsonl
git check-ignore -v bughunter/memory/leads/probe.jsonl
#   (no output, exit 1 — not ignored)

The practical effect: running the test suite dirties the working tree.
tests/test_lead_board.py writes bughunter/memory/leads/example.com.jsonl and
a .lock beside it, both untracked, so after pytest tests/ a contributor sees

?? bughunter/memory/leads/

and git add -A would commit test fixtures into their branch.

Fix is one character — anchor-free, or repointed:

-memory/leads/
+bughunter/memory/leads/

or, to cover both layouts, drop the leading path so the pattern matches at any
depth. Worth a sweep of the rest of .gitignore for the same issue while you're
there — any entry with an internal slash that used to point at a now-moved
directory has quietly stopped matching.

Environment

macOS 15.x arm64, bash 3.2.57, clean checkout of 40b03ee.

Activity

  1. shuvonsec commented on Oct 23, 2026

    @shuvonsec
    Member

    Confirmed, and thanks @spierenburg — this is a precise report. You're right that the bughunter/ move (025367b / #148) updated the script locations but not the ~54 call sites in commands/+skills/, the docs, or the .gitignore:53 anchor (memory/leads/ no longer matches bughunter/memory/leads/, which is why the test suite dirties the tree).

    Agreed on the fix direction too: repoint invocations at the bughunter CLI entry point (bughunter hunt / bughunter recon) rather than hardcoding bughunter/tools/..., so it's layout-independent and doesn't break on the next move. And the CI guard that fails on any commands//skills/ path that doesn't resolve is the part that keeps this from regressing — that's more valuable than the one-time cleanup, especially since older branches (e.g. #157) will reintroduce stale paths on merge.

    This is the same follow-up I flagged on your PR #174 — please go ahead and open the PR for it, happy to review. Ideally one PR carrying: (1) call-site + doc repoint, (2) the .gitignore anchor fix, (3) the CI guard, and a look at the prefix-less php_filter_chain_generator.py reference while you're in there. Labeling this as a confirmed bug and keeping it open to track.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions