Docs

adapter

Source: crates/lvcs/src/adapter/mod.rs.

/// The Claude Code hook events `lvcs hook` handles, named as Claude Code
/// names them.
///
/// One op per hook (decision 117): `SessionStart`,
/// `UserPromptSubmit`, and `Stop` call `notifications` (`Stop` reads `open`),
/// `PreToolUse` calls `track_edit`, and `PostToolUse` calls `track_read`
/// after a `Read` and `track_write` after a `Write` or `Edit`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub(crate) enum HookEvent {
    #[value(name = "SessionStart")]
    SessionStart,
    #[value(name = "PreToolUse")]
    PreToolUse,
    #[value(name = "PostToolUse")]
    PostToolUse,
    #[value(name = "UserPromptSubmit")]
    UserPromptSubmit,
    #[value(name = "Stop")]
    Stop,
}

/// One `lvcs hook` run: the event, the participant (`--as`, else
/// `LVCS_PARTICIPANT`; with neither the hook prints nothing), and the
/// project root (`--root`, else `CLAUDE_PROJECT_DIR`, else the first
/// ancestor of the working directory holding `.lvcs/`). The hook connects
/// to this user's daemon (decision 272) only when the root holds `.lvcs/`
/// and the socket's server, by `peer_cred`, is this user, and names the
/// root in `hello`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct Hook {
    pub(crate) event: HookEvent,
    pub(crate) participant: Option<String>,
    pub(crate) root: Option<PathBuf>,
}

/// Run `hook`: read the hook JSON on stdin, call its op, and print the hook
/// output JSON or nothing. Always exits 0.
pub(crate) fn run_hook(hook: &Hook) -> ExitCode {
    hook::run(hook);
    ExitCode::SUCCESS
}