Installation #
Install ez-search globally to use the CLI, or as a project dependency for the library API.
Global (CLI)
npm install -g @ez-corp/ez-search Project dependency (Library)
npm install @ez-corp/ez-search Requires Node.js >= 20. ESM only.
Quick Start #
1 Install
npm install -g @ez-corp/ez-search 2 Index
ez-search index . 3 Search
ez-search query "authentication logic" ez-search index #
Index a directory for semantic search. Scans files, splits them into chunks, and generates embeddings stored locally in .ez-search/.
ez-search index <path> Flags
| Flag | Description | Default |
|---|---|---|
| --no-ignore | Disable .gitignore and .cursorignore filtering | — |
| --type <type> | Filter files by type: code | text | image | — |
| --quiet, -q | Suppress status output | — |
| --clear | Remove existing index before indexing | — |
| --format <mode> | Output format: json (default) or text | json |
Examples
Index the current directory
ez-search index . Index only code files
ez-search index . --type code Fresh re-index with quiet output
ez-search index . --clear -q ez-search query #
Search the index with a natural language query. Returns ranked results grouped by type (code, text, image).
ez-search query <text> Flags
| Flag | Description | Default |
|---|---|---|
| --top-k <n>, -k | Number of results to return | 10 |
| --dir <path> | Scope search to a subdirectory | — |
| --threshold <score> | Minimum relevance score (0-1) to include | — |
| --type <type> | Search specific type only: code | text | image | — |
| --no-auto-index | Disable automatic indexing when no index exists | — |
| --format <mode> | Output format: json (default) or text | json |
Examples
Search for authentication logic
ez-search query "authentication logic" Top 5 code results in src/
ez-search query "error handling" --type code -k 5 --dir src High-confidence results only
ez-search query "database connection" --threshold 0.7 ez-search status #
Show indexing status for the current directory, including file counts, staleness, and per-type breakdown.
ez-search status Flags
| Flag | Description | Default |
|---|---|---|
| --no-ignore | Disable .gitignore and .cursorignore filtering | — |
| --format <mode> | Output format: json (default) or text | json |
Examples
Check index status
ez-search status Status as text
ez-search status --format text index() #
Index a directory for semantic search. Returns statistics about what was scanned, indexed, and stored.
async function index(
targetPath: string,
options?: IndexOptions
): Promise<IndexStats> Parameters
| Parameter | Type | Description |
|---|---|---|
| targetPath | string | Directory to index |
| options.ignore? | boolean | Respect .gitignore (default: true) |
| options.type? | 'code' | 'text' | 'image' | Filter by file type |
| options.clear? | boolean | Wipe existing index before indexing |
Returns
Promise<IndexStats> — Statistics about indexed files, chunks created/reused, and duration.
Examples
Basic indexing
import { index } from '@ez-corp/ez-search';
const stats = await index('/path/to/project');
console.log(`Indexed ${stats.filesIndexed} files in ${stats.durationMs}ms`); Index only code files with fresh start
const stats = await index('.', { type: 'code', clear: true }); query() #
Search the index with a natural language query. Returns grouped results with code, text, and image arrays.
async function query(
text: string,
options?: QueryOptions
): Promise<QueryResult> Parameters
| Parameter | Type | Description |
|---|---|---|
| text | string | Natural language search query |
| options.projectDir? | string | Project directory (default: cwd) |
| options.topK? | number | Results per type (default: 10) |
| options.dir? | string | Scope to a subdirectory |
| options.threshold? | number | Minimum relevance 0-1 |
| options.type? | 'code' | 'text' | 'image' | Search specific type only |
| options.autoIndex? | boolean | Auto-index if missing (default: true) |
Returns
Promise<QueryResult> — Results grouped by type, with scores and file locations.
Examples
Search and display code results
import { query } from '@ez-corp/ez-search';
const results = await query('authentication logic', {
projectDir: '/path/to/project',
topK: 5,
});
for (const match of results.code) {
console.log(`${match.file}:${match.lines.start}-${match.lines.end} (score: ${match.score})`);
} Search with threshold filter
const results = await query('database connection', {
threshold: 0.7,
type: 'code',
}); status() #
Get indexing status for a project directory. Returns file/chunk counts, staleness info, and per-type breakdown.
async function status(
options?: StatusOptions
): Promise<StatusResult> Parameters
| Parameter | Type | Description |
|---|---|---|
| options.projectDir? | string | Project directory (default: cwd) |
| options.ignore? | boolean | Respect .gitignore (default: true) |
Returns
Promise<StatusResult> — Index status with file counts, storage size, and type breakdown.
Examples
Check index health
import { status } from '@ez-corp/ez-search';
const info = await status({ projectDir: '/path/to/project' });
console.log(`${info.fileCount} files, ${info.chunkCount} chunks`);
console.log(`Last indexed: ${info.lastIndexed}`);
if (info.staleFileCount > 0) {
console.warn(`${info.staleFileCount} files have changed since last index`);
} Error Handling #
Library functions throw EzSearchError on failure.
Each error includes a machine-readable code and a human-readable suggestion.
import { index, EzSearchError } from '@ez-corp/ez-search';
try {
await index('/path/to/project');
} catch (err) {
if (err instanceof EzSearchError) {
console.error(`[${err.code}] ${err.message}`);
console.error(`Suggestion: ${err.suggestion}`);
} else {
throw err;
}
} Error Codes
| Code | Meaning | Suggestion |
|---|---|---|
| NO_INDEX | No index found for the project | Run index() or ez-search index first |
| EMPTY_DIR | No supported files found in directory | Check the path and file extensions |
| UNSUPPORTED_TYPE | Invalid file type filter | Use "code", "text", or "image" |
| CORRUPT_MANIFEST | Index manifest exists but data is missing | Re-index with --clear flag |
| GENERAL_ERROR | Unexpected error during operation | Check the error message for details |
Types #
All types are exported from the package and available for TypeScript projects.
IndexStats
interface IndexStats {
status: string;
path: string;
filesScanned: number;
filesIndexed: number;
filesSkipped: number;
chunksCreated: number;
chunksReused: number;
chunksRemoved: number;
durationMs: number;
storageDir: string;
} IndexOptions
interface IndexOptions {
ignore?: boolean;
type?: 'code' | 'text' | 'image';
clear?: boolean;
} QueryResult
interface QueryResult {
query: string;
totalIndexed: number;
searchScope: string;
indexing?: { status: string; filesIndexed: number; durationMs: number };
stale?: boolean;
staleFileCount?: number;
code: CodeQueryResult[];
text: TextQueryResult[];
image: ImageQueryResult[];
} CodeQueryResult
interface CodeQueryResult {
file: string;
lines: { start: number; end: number };
score: number;
text: string;
} TextQueryResult
interface TextQueryResult {
file: string;
score: number;
text: string;
} ImageQueryResult
interface ImageQueryResult {
file: string;
score: number;
} QueryOptions
interface QueryOptions {
projectDir?: string;
topK?: number;
dir?: string;
threshold?: number;
type?: 'code' | 'text' | 'image';
autoIndex?: boolean;
} StatusResult
interface StatusResult {
fileCount: number;
chunkCount: number;
lastIndexed: string;
modelTypes: string[];
indexSizeBytes: number;
storagePath: string;
staleFileCount: number;
byType: Record<'code' | 'text' | 'image', TypeBreakdown>;
warning?: string;
suggestion?: string;
} TypeBreakdown
interface TypeBreakdown {
files: number;
chunks: number;
} StatusOptions
interface StatusOptions {
projectDir?: string;
ignore?: boolean;
} EzSearchError
class EzSearchError extends Error {
readonly code: ErrorCode;
readonly suggestion: string;
constructor(code: ErrorCode, message: string, suggestion: string);
} ErrorCode
type ErrorCode =
| 'NO_INDEX'
| 'EMPTY_DIR'
| 'UNSUPPORTED_TYPE'
| 'CORRUPT_MANIFEST'
| 'GENERAL_ERROR'; FileType
type FileType = 'code' | 'text' | 'image'; Supported File Types #
ez-search categorizes files into three types based on extension.
| Type | Extensions |
|---|---|
| Code | .ts .tsx .js .jsx .py .go .rs .java .c .cpp .h .hpp .rb .php .swift .kt .scala .sh .bash .zsh .css .scss .html .json .yaml .yml .toml |
| Text | .md .mdx .txt .rst .csv .pdf |
| Image | .jpg .jpeg .png .gif .webp .svg |
Built-in Exclusions
These paths and patterns are always excluded from indexing:
Storage #
ez-search stores all index data locally in a .ez-search/ directory at the root of your project.
.ez-search/
├── manifest.json # File metadata and hashes
├── code.bin # Code embedding vectors
├── text.bin # Text embedding vectors
└── image.bin # Image embedding vectors - - Add .ez-search/ to your .gitignore — it should not be committed.
- - Delete .ez-search/ to remove all index data. Re-run ez-search index to rebuild.
- - Index data is machine-local. Embeddings are not portable across different machines.