Skip to main content

hh_record/
lib.rs

1//! `hh-record` — the Halfhand recorder layer (SRS §6).
2//!
3//! Drives a PTY-recorded agent session: spawns the agent in a PTY
4//! (`runner`), watches the working tree for file changes (`watcher`),
5//! feeds both into the single-writer SQLite store via `hh-core`, and — when a
6//! structured-event adapter applies (FR-1.5, Claude Code today) — drains its
7//! parsed events into the same store with `tool_call`→`tool_result` correlation.
8//! The MCP stdio proxy (FR-2) lives in `mcp_proxy`.
9//!
10//! The threads-vs-tokio decision is recorded in
11//! `docs/adr/0001-threads-vs-tokio.md`.
12
13#![deny(missing_docs)]
14
15mod agent;
16mod error;
17mod git;
18mod mcp_proxy;
19mod runner;
20mod watcher;
21
22pub use agent::detect_agent;
23pub use error::{RecordError, Result};
24pub use git::GitMeta;
25pub use mcp_proxy::{run_mcp_proxy, McpProxyOptions, McpProxyOutcome};
26pub use runner::{run, RunOptions, RunOutcome};
27pub use watcher::{spawn_watcher, watcher_smoke_test, WatchOptions, WatcherHandle};
28
29/// Fuzz-only entry points into the MCP JSON-RPC line classifier; see
30/// [`mcp_proxy::fuzzing`].
31#[cfg(feature = "fuzzing")]
32pub use mcp_proxy::fuzzing;
33
34// Re-export the core types the binary needs to construct RunOptions without
35// reaching into hh-core directly (keeps the binary's `use` surface small).
36pub use hh_core::store::Store;
37
38/// Build the recorder's shared blob store handle: redacting when a
39/// record-time redactor is configured (`[redaction] at_record`), plain
40/// otherwise. Centralized so the PTY runner and the MCP proxy cannot drift —
41/// every recorder blob write goes through the same enforcement point
42/// (docs/redaction-design.md).
43pub(crate) fn make_blob_store(
44    store: &Store,
45    redactor: Option<std::sync::Arc<hh_core::redact::Detectors>>,
46) -> hh_core::blob::BlobStore {
47    let root = store.blobs().root().to_path_buf();
48    match redactor {
49        Some(r) => hh_core::blob::BlobStore::with_redactor(root, r),
50        None => hh_core::blob::BlobStore::new(root),
51    }
52}