How the ignore-filter handles custom .understandignore patterns in Understand-Anything

The ignore-filter merges hard-coded default patterns with user-defined rules from .understandignore files, applying a three-layer precedence system where workspace-specific configurations override project-root settings, which in turn override the built-in defaults.

The ignore-filter is a core component of the Egonex-AI/Understand-Anything repository that determines which files are excluded from the knowledge-graph analysis pipeline. By combining curated default patterns with custom .understandignore configurations, the system gives developers precise control over file inclusion while maintaining sensible out-of-the-box behavior.

Architecture of the Ignore-Filter System

The filtering logic is centralized in [ignore-filter.ts](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/ignore-filter.ts). The primary entry point is the createIgnoreFilter(projectRoot) function, which instantiates an ignore object, populates it with rules from three distinct sources, and returns an isIgnored interface for path evaluation.

Default Ignore Patterns

The engine initializes every filter with DEFAULT_IGNORE_PATTERNS, a hard-coded array that guards against common noisy files and directories. These defaults include build artifacts (dist/, build/), dependency folders (node_modules/), lock files (package-lock.json, yarn.lock), minified assets (*.min.js), IDE configurations (.vscode/, .idea/), and version-control internals (.git/).

The Three-Layer Precedence Model

When createIgnoreFilter executes, it layers rules in the following strict order:

  1. Hard-coded defaults – Added first via ig.add(DEFAULT_IGNORE_PATTERNS), establishing baseline exclusions.
  2. Project-root .understandignore – Located at the repository root, this file is read and added after the defaults, allowing project-wide customization.
  3. Workspace-specific .understandanything/.understandignore – Located under .understandanything/.understandignore, this file is processed last, giving it the highest precedence to override both defaults and root-level rules.

How Custom Patterns Are Processed

Loading the Project-Root .understandignore

The filter checks for a file named .understandignore at the projectRoot. If present, its raw text content is read and passed directly to the underlying ignore instance via ig.add(content). Patterns defined here take precedence over the hard-coded defaults but yield to workspace-specific configurations.

Workspace-Specific Overrides

For monorepo or multi-workspace scenarios, the filter looks for .understandanything/.understandignore. Because this file is processed after the root ignore file, its patterns can selectively un-ignore paths (using negation patterns like !path) or add stricter exclusions that apply only to the current workspace context.

Practical Usage Examples

The following TypeScript example demonstrates how to instantiate the filter and query file paths:

import { createIgnoreFilter } from '@understand-anything/core';

// Initialize the filter for the repository root
const filter = createIgnoreFilter('/my/project');

// Default patterns automatically exclude common artifacts
filter.isIgnored('node_modules/lodash/index.js'); // true
filter.isIgnored('dist/bundle.js');               // true
filter.isIgnored('.git/config');                  // true

// Source files are allowed by default
filter.isIgnored('src/components/Button.tsx');    // false

When a custom .understandignore exists at the project root, its patterns are evaluated alongside the defaults:

// Assuming /my/project/.understandignore contains:
// __tests__/**/*.test.ts

filter.isIgnored('__tests__/unit/auth.test.ts'); // true
filter.isIgnored('src/utils.test.ts');          // true (if matched by pattern)
filter.isIgnored('src/utils.ts');               // false

Workspace-specific files can override these rules. If .understandanything/.understandignore contains:

!__tests__/keep_this.test.ts

Then despite the root file ignoring all __tests__/**/*.test.ts, the workspace rule re-includes the specific file:

filter.isIgnored('__tests__/keep_this.test.ts'); // false

Key Source Files and References

File Purpose Link
ignore-filter.ts Core logic implementing createIgnoreFilter and the three-layer merge Source
ignore-generator.ts Utility for scaffolding starter ignore files Source
ignore-filter.test.ts Unit tests verifying default and custom pattern behavior Tests
2026-04-10-understandignore-design.md Specification for the .understandignore format Design Doc
2026-04-10-understandignore-impl.md Implementation plan detailing precedence rules Plan

Summary

  • The ignore-filter is implemented in ignore-filter.ts and exposed via the createIgnoreFilter function.
  • It combines three layers of rules: hard-coded defaults, project-root .understandignore, and workspace-specific .understandanything/.understandignore.
  • Precedence increases with each layer; workspace configurations override root settings, which override defaults.
  • The isIgnored(relativePath) method provides a simple boolean interface to test any file path against the merged pattern set.
  • Negation patterns (e.g., !important.js) can be used in custom files to selectively re-include paths excluded by earlier layers.

Frequently Asked Questions

What is the default precedence order for ignore patterns?

The ignore-filter processes patterns in three stages: first the hard-coded defaults, then the project-root .understandignore, and finally the workspace-specific .understandanything/.understandignore. Because later additions are processed after earlier ones, workspace patterns have the highest precedence, followed by root patterns, with defaults serving as the fallback.

Can I un-ignore a file that matches a default pattern?

Yes. By adding a negation pattern (starting with !) to your .understandignore or workspace-specific ignore file, you can re-include files that would otherwise be excluded by the DEFAULT_IGNORE_PATTERNS. For example, !vendor/important.js in your workspace ignore file will ensure that specific file is analyzed even if vendor/ is in the default list.

Where should I place my custom .understandignore file?

For project-wide exclusions, place .understandignore in the repository root. For workspace-specific overrides (such as in a monorepo), create .understandanything/.understandignore inside the relevant workspace directory. The filter automatically discovers both locations when createIgnoreFilter is invoked with the project root path.

How does the ignore-filter handle negation patterns?

The underlying ignore library supports standard Gitignore-style negation using the ! prefix. When you include a negation pattern in a custom ignore file, it overrides any preceding positive match from the defaults or earlier configuration files. This allows fine-grained control where you can ignore broad categories (like *.log) but carve out exceptions (like !important.log) in subsequent layers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →