What happens
internal/workspaceindex.ShouldSkipDir is a fixed, hardcoded denylist of directory
names to skip while scanning (used by repo-map, repo-info, and anything else built
on workspaceindex.Scan). It does not consult the scanned repo's own .gitignore
(Scan has no git dependency at all), and the denylist itself is missing several
directory names that are build output or cache in virtually every ecosystem:
// internal/workspaceindex/workspaceindex.go
func ShouldSkipDir(name string) bool {
switch strings.ToLower(strings.TrimSpace(name)) {
case ".cache", ".git", ".next", ".worktrees", ".zero", "build", "coverage", "dist", "node_modules", "vendor":
return true
default:
return false
}
}
Missing (non-exhaustive, found by reproducing against a real multi-language repo):
target (Cargo/Rust), __pycache__, .venv/venv, .pytest_cache, .terraform,
.mypy_cache, .ruff_cache.
Impact
Scan has a fixed MaxFiles budget (DefaultMaxFiles = 2000). Against a real repo
with several small Rust crates, rust/*/target/debug/.fingerprint/ alone produced
308 files (.d/.rlib/.rmeta/.timestamp) that counted toward that budget before
real source did. repo-map --json against that repo reported "truncated": true at
2000 files, and a repo-map --query ranking run returned 15 results, all of them
build-cache/fingerprint files, zero real source — the query terms matched path
fragments inside target/debug/.fingerprint/* ahead of the actual source file the
query was looking for.
This repo's own .gitignore already excludes target/; the scanner just never looks
at it.
Repro
$ git clone <any repo with a sizeable target/ or __pycache__/ dir>
$ zero repo-map --json | head -5
# fileCount near/at MaxFiles, "truncated": true, driven by target/debug/.fingerprint/*
$ zero repo-map --query "<term that matches a real source file>" --max-files 15
# ranked results dominated by target/**/*.{d,rlib,rmeta,timestamp}, score identical (1000) for all, no real source in the top 15
Proposed fix (narrow, ready as a draft PR on my fork)
Extend the ShouldSkipDir switch with the missing common build-cache directory names
(same pattern already used for node_modules/vendor/dist/build/coverage). I have
this implemented + a regression test (both a ShouldSkipDir unit case and an end-to-end
Scan case reproducing the target/debug/.fingerprint/* scenario) ready on
FabioLeitao/zero, branch to be pushed once I can rebuild/verify locally (hit an
unrelated full-disk condition on my own machine mid-verification, not a repo issue).
Separate, bigger question for maintainers (not proposing this now)
The narrow fix above is whack-a-mole against an ever-growing list of ecosystem-specific
build-cache names. The more durable fix would be for Scan to actually honor the
target repo's .gitignore (and .git/info/exclude) when the root is a git repo,
falling back to the current denylist otherwise. That's a bigger, dependency-adding
change per AGENTS.md §1 ("discuss ... major dependency changes ... before
implementation"), so I'm flagging it here for discussion rather than attempting it
unasked. Happy to take either direction once a maintainer weighs in — the narrow fix
is independently correct and small either way.
I'll follow CONTRIBUTING.md's community-PR process (parent issue + issue-approved
label) before opening a PR against this repo; the fix is staged on my fork in the
meantime.
What happens
internal/workspaceindex.ShouldSkipDiris a fixed, hardcoded denylist of directorynames to skip while scanning (used by
repo-map,repo-info, and anything else builton
workspaceindex.Scan). It does not consult the scanned repo's own.gitignore(
Scanhas no git dependency at all), and the denylist itself is missing severaldirectory names that are build output or cache in virtually every ecosystem:
Missing (non-exhaustive, found by reproducing against a real multi-language repo):
target(Cargo/Rust),__pycache__,.venv/venv,.pytest_cache,.terraform,.mypy_cache,.ruff_cache.Impact
Scanhas a fixedMaxFilesbudget (DefaultMaxFiles = 2000). Against a real repowith several small Rust crates,
rust/*/target/debug/.fingerprint/alone produced308 files (
.d/.rlib/.rmeta/.timestamp) that counted toward that budget beforereal source did.
repo-map --jsonagainst that repo reported"truncated": trueat2000 files, and a
repo-map --queryranking run returned 15 results, all of thembuild-cache/fingerprint files, zero real source — the query terms matched path
fragments inside
target/debug/.fingerprint/*ahead of the actual source file thequery was looking for.
This repo's own
.gitignorealready excludestarget/; the scanner just never looksat it.
Repro
Proposed fix (narrow, ready as a draft PR on my fork)
Extend the
ShouldSkipDirswitch with the missing common build-cache directory names(same pattern already used for
node_modules/vendor/dist/build/coverage). I havethis implemented + a regression test (both a
ShouldSkipDirunit case and an end-to-endScancase reproducing thetarget/debug/.fingerprint/*scenario) ready onFabioLeitao/zero, branch to be pushed once I can rebuild/verify locally (hit anunrelated full-disk condition on my own machine mid-verification, not a repo issue).
Separate, bigger question for maintainers (not proposing this now)
The narrow fix above is whack-a-mole against an ever-growing list of ecosystem-specific
build-cache names. The more durable fix would be for
Scanto actually honor thetarget repo's
.gitignore(and.git/info/exclude) when the root is a git repo,falling back to the current denylist otherwise. That's a bigger, dependency-adding
change per
AGENTS.md§1 ("discuss ... major dependency changes ... beforeimplementation"), so I'm flagging it here for discussion rather than attempting it
unasked. Happy to take either direction once a maintainer weighs in — the narrow fix
is independently correct and small either way.
I'll follow
CONTRIBUTING.md's community-PR process (parent issue +issue-approvedlabel) before opening a PR against this repo; the fix is staged on my fork in the
meantime.