import type { Event } from "@parcel/watcher";
import { type IgnoreFilter } from "./ignore.js";
/**
 * Whether a watched path should trigger an incremental index. Returns `true` for
 * supported/mapped extensions and `SPECIAL_FILES` by name; for an extensionless
 * regular file it consults content detection (kill-switch-gated). A vanished or
 * unreadable path returns `true` so the change is still reconciled, while a
 * directory/FIFO/other non-regular file returns `false` (never head-read).
 */
export declare function isIndexableFile(filePath: string, extensionLanguageMap?: Map<string, string>): Promise<boolean>;
/**
 * What this event says about an environment: that one has appeared or vanished
 * (`"changed"` — the ignore filter's answer for the tree is now wrong), that it
 * is about an environment but agrees with what the filter already says
 * (`"touches"`), or that it is an ordinary event (`null`).
 *
 * Three shapes reach here, because the native watcher reports them
 * differently. A marker written or deleted in place (`env/pyvenv.cfg`,
 * `env/conda-meta/history`) is an event on the marker. An environment moved
 * away (`mv env env.old`) is one event on the directory, `delete env`, and
 * nothing on the marker inside it — FSEvents and inotify both report the
 * renamed directory only — so a directory the filter knows as an environment
 * root counts too. And one moved into place is one `create` on a directory the
 * filter has never heard of, which is asked for its marker on disk.
 *
 * Agreement between the filter and the disk is `"touches"`, and on its own it
 * schedules nothing: a marker present in a directory already excluded, or gone
 * from one never excluded, changes nothing, and dropping it is what keeps
 * `conda install` — which rewrites `conda-meta/` on every run — from
 * reconciling the whole tree (review finding). It is told apart from an
 * ordinary event all the same, because agreement is only trustworthy while the
 * filter describes the tree: see the caller, where an update is running.
 *
 * Every created path is asked whether it is a directory, before anything is
 * read off its name: a directory may carry a dot — `backend/venv.3.12` moved
 * into place is one `create` on it and nothing else — and a first cut that
 * skipped the stat for a path with an extension dropped exactly that event
 * (review finding). One `lstat` per created path is the price, in a callback
 * that already stats every extensionless one.
 */
export declare function environmentEvent(event: Event, relative: string, ig: IgnoreFilter): "changed" | "touches" | null;
/**
 * Start watching a project directory for file changes.
 * Uses @parcel/watcher for native OS-level file watching (FSEvents on macOS,
 * ReadDirectoryChangesW on Windows, inotify on Linux). Creates a single native
 * subscription for the entire directory tree — no per-file enumeration.
 *
 * On change, triggers an incremental index update (debounced).
 */
export declare function startWatching(projectPath: string, onProgress?: (message: string) => void): Promise<boolean>;
/**
 * Start a watcher only when automatic watching is enabled. Manual mode keeps
 * startWatching available to an explicit codebase_watch start request, while
 * off mode is also enforced inside startWatching as a final safety boundary.
 */
export declare function startWatchingAutomatically(projectPath: string, onProgress?: (message: string) => void): Promise<boolean>;
/** Stop watching a project directory */
export declare function stopWatching(projectPath: string): Promise<void>;
/** Stop all active watchers */
export declare function stopAllWatchers(): Promise<void>;
/** Check if a specific project is being watched */
export declare function isWatching(projectPath: string): boolean;
/** Get list of currently watched project paths */
export declare function getWatchedProjects(): string[];
/**
 * Check if a project is being watched by any process (this one or another).
 * First checks the in-memory subscriptions map (fast, synchronous), then falls
 * back to checking the cross-process file lock for the "watch" operation.
 */
export declare function isWatchedByAnyProcess(projectPath: string): Promise<boolean>;
/** Clear the external watch cache. Exported for testing. */
export declare function clearExternalWatchCache(): void;
/**
 * Ensure the file watcher is running for a project if conditions are met.
 * This is a fire-and-forget, non-blocking, non-fatal helper called by tools
 * (search, status, update, graph) to auto-activate watching on first interaction.
 *
 * Conditions:
 * 1. Not already watching this project
 * 2. No full indexing or incremental update currently in progress
 * 3. A fully indexed and COMPLETED collection exists in Qdrant
 *
 * If any condition fails (including incomplete/interrupted indexes), this
 * silently returns without starting the watcher.
 */
export declare function ensureWatcherStarted(projectPath: string): void;
//# sourceMappingURL=watcher.d.ts.map