Problem
The discovery engine runs all language plugins against the entire repo. When a project vendors dependencies into subdirectories (e.g., Foundry's lib/, Go's vendor/, Node's node_modules/), other plugins find manifest files inside those vendored directories and treat them as source components.
Example from eigenda: the Foundry project at contracts/ has vendored dependencies in contracts/lib/ (openzeppelin, forge-std, eigenlayer-middleware). These contain package.json and go.mod files that the TypeScript and Go plugins pick up, producing 100+ spurious components (duplicate openzeppelin packages, forge-std instances, etc.).
The Solidity plugin excludes its own lib/ paths, but it can't prevent other plugins from scanning the same directories.
Current behavior
Solidity plugin: 3 components (correct — core, integrations, periphery)
TypeScript plugin: 28 components from contracts/lib/**/package.json (spurious)
Go plugin: 2 components from contracts/lib/**/go.mod (spurious)
Desired behavior
Once a plugin claims a directory as containing vendored/external dependencies, no other plugin should scan inside it. The 3 Solidity source components should be the only contracts-related output.
Proposed approach
Add a global exclusion mechanism to the discovery engine:
- Phase 1: Each plugin returns both discovered components AND a list of "vendored directories" that should be excluded from further scanning.
- Phase 2: The engine collects all vendored directories and filters them out before running subsequent plugins.
Or simpler: the engine maintains a global exclude set. When a Foundry project is found at contracts/, its libs path (contracts/lib/) is added to the global exclude set before other plugins run.
This also applies to:
- Go
vendor/ directories (already excluded by Go plugin, but not by others)
- Node
node_modules/ (already excluded by TS plugin, but not by Go/Rust/Solidity)
- Rust
target/ directories
- Python
venv/ / .venv/ directories
The engine should build a unified exclusion set from all plugins' exclude patterns and apply it globally before any plugin scans.
Affected files
agent/discovery/engine.py — needs global exclude set logic
agent/discovery/languages/base.py — LanguagePlugin interface may need a vendored_directories() method
- All language plugins — should declare their vendored paths
Problem
The discovery engine runs all language plugins against the entire repo. When a project vendors dependencies into subdirectories (e.g., Foundry's
lib/, Go'svendor/, Node'snode_modules/), other plugins find manifest files inside those vendored directories and treat them as source components.Example from eigenda: the Foundry project at
contracts/has vendored dependencies incontracts/lib/(openzeppelin, forge-std, eigenlayer-middleware). These containpackage.jsonandgo.modfiles that the TypeScript and Go plugins pick up, producing 100+ spurious components (duplicate openzeppelin packages, forge-std instances, etc.).The Solidity plugin excludes its own
lib/paths, but it can't prevent other plugins from scanning the same directories.Current behavior
Desired behavior
Once a plugin claims a directory as containing vendored/external dependencies, no other plugin should scan inside it. The 3 Solidity source components should be the only contracts-related output.
Proposed approach
Add a global exclusion mechanism to the discovery engine:
Or simpler: the engine maintains a global exclude set. When a Foundry project is found at
contracts/, itslibspath (contracts/lib/) is added to the global exclude set before other plugins run.This also applies to:
vendor/directories (already excluded by Go plugin, but not by others)node_modules/(already excluded by TS plugin, but not by Go/Rust/Solidity)target/directoriesvenv//.venv/directoriesThe engine should build a unified exclusion set from all plugins' exclude patterns and apply it globally before any plugin scans.
Affected files
agent/discovery/engine.py— needs global exclude set logicagent/discovery/languages/base.py—LanguagePlugininterface may need avendored_directories()method