//! Public event types — the wire contract for `kigi-fsnotify`. //! //! Pure data: no I/O, no tokio, no intra-crate deps. Safe to lift into a //! sibling `-types` crate for WASM/no-tokio consumers. //! //! All variants are `#[non_exhaustive]`; add additively. The workspace //! translator (in `kigi-workspace`) maps these to //! `WorkspaceEvent`s and enriches `GitOperationCompleted { head_changed: //! true }` with `commit + branch + vcs` via a git shell-out — that I/O //! belongs at the workspace layer, not on the OS-watcher hot path. use std::path::PathBuf; /// One semantic event from the local workspace. Causal order on the /// source's broadcast channel. `FilesChanged` paths share a single `kind` /// (per-debounce-window grouping); per-event causality would need /// `Vec<{path, kind}>`. #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[serde(tag = "type", content = "data", rename_all = "snake_case")] #[non_exhaustive] pub enum FsEvent { /// Workspace file changes; all paths share `kind`. Paths under /// `git_dir` are excluded (metadata surfaces as `GitMetaChanged`, /// `.lock` files are dropped). FilesChanged { paths: Vec, kind: FsEventKind, }, /// A git metadata file changed (HEAD, index, refs/, FETCH_HEAD). GitMetaChanged { kind: GitMetaKind }, /// VCS lock activity observed: `index.lock`/`gc.pid`/`.sl` `wlock` is /// present, or an event for one arrived with the file already gone (fast /// ops complete inside one debounce batch). State is in flux until the /// matching `GitOperationCompleted` arrives. GitOperationStarted, /// The lock has been gone for [`crate::SETTLE_MS`]: rapid lock cycles /// (rebase/squash picks) merge into one operation, so one pair is emitted /// per burst, not per cycle. `head_changed` reports whether `.git/HEAD` /// differs from its value when the operation's *first* lock appeared. GitOperationCompleted { head_changed: bool }, } /// Aligned with `kigi_workspace_types::FsEventKind` (identity map at /// the workspace boundary). `notify::EventKind::{Access, Any, Other}` are /// filtered upstream and never surface here. #[derive( Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize, )] #[serde(rename_all = "snake_case")] #[non_exhaustive] pub enum FsEventKind { Created, #[default] Modified, Removed, Renamed, } #[derive( Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, serde::Serialize, serde::Deserialize, )] #[serde(rename_all = "snake_case")] #[non_exhaustive] pub enum GitMetaKind { /// `.git/HEAD` (branch switch, commit, rebase step). HeadChanged, /// `.git/index` (`git add`, `git reset`, `git commit`). IndexChanged, /// `.git/refs/*` or `.git/packed-refs` (ref updates). RefsChanged, /// `.git/FETCH_HEAD` (fetch / pull). FetchHeadChanged, }