trusty_common/lib.rs
1//! Shared utility surface for trusty-* projects.
2//!
3//! Why: Port auto-detect, data-directory resolution, tracing init, NO_COLOR
4//! handling, and the OpenRouter chat-completions client appeared in both
5//! trusty-memory and trusty-search with subtle divergence. Centralising keeps
6//! them aligned and gives future trusty-* binaries a one-import surface.
7//!
8//! What: pure utility functions — no global state. Each subsystem is a free
9//! function or a small helper struct.
10//!
11//! Test: `cargo test -p trusty-common` covers port walking, data-dir creation,
12//! and the OpenRouter request shape (without hitting the network).
13//!
14//! # Test isolation: `TRUSTY_DATA_DIR_OVERRIDE`
15//!
16//! macOS's [`dirs::data_dir()`] resolves the application-support directory via
17//! `NSFileManager`, a native Cocoa API that completely ignores the `HOME` and
18//! `XDG_DATA_HOME` environment variables. This makes it impossible to redirect
19//! data-directory access in tests using ordinary env-var tricks, because the
20//! kernel query bypasses the environment entirely.
21//!
22//! To work around this, [`resolve_data_dir`] checks the
23//! [`DATA_DIR_OVERRIDE_ENV`] (`TRUSTY_DATA_DIR_OVERRIDE`) environment variable
24//! before consulting `dirs::data_dir()`. When set, the variable's value is used
25//! as the base directory verbatim, and `dirs::data_dir()` is never called.
26//!
27//! **This escape hatch is intended for testing only.** Do not set it in
28//! production deployments; rely on the OS-standard data directory instead.
29
30pub mod chat;
31pub mod claude_config;
32pub mod project_discovery;
33
34/// Shared graceful-shutdown signal helper for trusty-* daemons (issue #534).
35///
36/// Why: trusty-search, trusty-memory, and trusty-analyze all need the same
37/// SIGTERM + SIGINT shutdown future to pass to axum's `with_graceful_shutdown`.
38/// Centralising it here eliminates three-way duplication and guarantees every
39/// daemon responds identically to `launchctl bootout`.
40/// What: exposes [`shutdown_signal`] — an async fn that resolves on SIGTERM
41/// (unix) or SIGINT/Ctrl-C (all platforms), whichever fires first.
42/// Test: `cargo test -p trusty-common -- shutdown`.
43pub mod shutdown;
44pub use shutdown::shutdown_signal;
45
46/// Bounded in-memory ring buffer of recent tracing log lines.
47///
48/// Why: trusty-* daemons expose a `/logs/tail` endpoint so operators can read
49/// recent logs over HTTP without file I/O or a daemon restart. The buffer and
50/// its `tracing_subscriber::Layer` live here so every daemon shares one impl.
51/// What: `LogBuffer` (thread-safe capped `VecDeque<String>`) plus
52/// `LogBufferLayer` (the tracing layer that feeds it).
53/// Test: `cargo test -p trusty-common log_buffer` covers capacity eviction,
54/// tail semantics, and layer capture.
55pub mod log_buffer;
56
57/// Process RSS / CPU sampling and data-directory sizing for daemon health.
58///
59/// Why: every trusty-* daemon's `/health` endpoint reports its own resident
60/// memory, CPU usage, and on-disk footprint; the sampling logic is identical
61/// across them so it lives here once.
62/// What: `SysMetrics` (per-process RSS + CPU sampler) and `dir_size_bytes`
63/// (recursive directory byte count).
64/// Test: `cargo test -p trusty-common sys_metrics`.
65pub mod sys_metrics;
66
67/// Robust executable discovery and daemon `PATH` composition.
68///
69/// Why: launchd relaunches daemons with a minimal `PATH`, breaking spawns of
70/// Homebrew/user-installed tools (`tmux`, `claude`) until the inherited `PATH`
71/// is patched (#1298). This module composes the full set of well-known bin
72/// dirs for a generated launchd plist and provides a `PATH`-then-well-known
73/// binary resolver so the daemon spawns survive a minimal inherited `PATH`.
74/// What: `daemon_path_dirs`, `daemon_path_env`, `resolve_binary`.
75/// Test: `cargo test -p trusty-common bin_resolve`.
76pub mod bin_resolve;
77
78/// macOS LaunchAgent generation and lifecycle management. macOS-only —
79/// the module compiles to nothing on every other platform.
80#[cfg(target_os = "macos")]
81pub mod launchd;
82
83#[cfg(feature = "axum-server")]
84pub mod server;
85
86/// Shared JSON-RPC 2.0 / MCP primitives (formerly the `trusty-mcp-core` crate).
87///
88/// Why: Centralises `Request`/`Response`/`JsonRpcError` envelopes, the
89/// `initialize` response builder, an async stdio dispatch loop, and the
90/// OpenRPC `rpc.discover` helpers so every MCP server in the workspace
91/// imports the same types.
92/// What: Gated behind the `mcp` feature; pulls in no extra dependencies
93/// beyond `serde` / `tokio`, both of which are already required.
94/// Test: `cargo test -p trusty-common --features mcp` runs the module's
95/// own unit tests (envelope round-trips, stdio loop dispatch, OpenRPC
96/// builder shape).
97#[cfg(feature = "mcp")]
98pub mod mcp;
99
100/// General-purpose JSON-RPC client + transports (formerly the library half
101/// of the `trusty-rpc` crate).
102///
103/// Why: Both `trpc` (the CLI) and any future library consumer want one
104/// place that owns the JSON-RPC envelope construction, stdio-subprocess
105/// transport, HTTP transport, and pretty-printers.
106/// What: Gated behind the `rpc` feature; requires `uuid` for request id
107/// generation. The HTTP transport reuses the workspace `reqwest`.
108/// Test: `cargo test -p trusty-common --features rpc` runs the module's
109/// own unit tests (envelope extraction, pretty-print smoke tests).
110#[cfg(feature = "rpc")]
111pub mod rpc;
112
113/// Shared text-embedding abstraction (formerly the `trusty-embedder` crate).
114///
115/// Why: trusty-memory and trusty-search both ship near-identical `Embedder`
116/// traits and `FastEmbedder` implementations; centralising the surface here
117/// keeps them aligned and lets future consumers pick up embedding for free
118/// without a separate published crate.
119/// What: Gated behind the `embedder` feature. Exposes the `Embedder` trait,
120/// `FastEmbedder` (fastembed-rs, all-MiniLM-L6-v2, 384-d) with LRU caching
121/// and ORT warmup, and (under `embedder-test-support`) the `MockEmbedder`
122/// test double.
123/// Test: `cargo test -p trusty-common --features embedder,embedder-test-support`
124/// covers the mock embedder and ONNX-backed `#[ignore]`d integration tests.
125#[cfg(feature = "embedder")]
126pub mod embedder;
127
128/// Unified RPC client surface for the `trusty-embedderd` standalone process.
129///
130/// Why: absorbs both the former `trusty-embedder-client` HTTP crate (PR #163)
131/// and the former `embed_client` UDS module (PR #157) into a single unified
132/// module. Reduces workspace crate count and provides one trait (`EmbedderClient`)
133/// with three concrete implementations (InProcess, HTTP remote, UDS remote) so
134/// call sites are identical regardless of transport. The `embed-client` feature
135/// and `embed_client` module are retired by issue #164; use `embedder-client`
136/// and `trusty_common::embedder_client::UdsEmbedderClient` instead.
137/// What: Gated behind the `embedder-client` feature. Exposes the
138/// `EmbedderClient` trait, `InProcessEmbedderClient`, `RemoteEmbedderClient`
139/// (HTTP), `UdsEmbedderClient` (UDS), `EmbedRequest` / `EmbedResponse` wire
140/// types, and `EmbedderError`. The UDS impl uses `tokio::net::UnixStream`
141/// with newline-framed JSON-RPC 2.0 — no additional dependencies.
142/// Test: `cargo test -p trusty-common --features embedder-client` covers
143/// error-display, JSON round-trip, URL assembly, UDS wire types, and empty-
144/// batch short-circuits. ONNX-backed tests are in
145/// `trusty-embedderd/tests/bit_identical.rs` (`#[ignore]`).
146#[cfg(feature = "embedder-client")]
147pub mod embedder_client;
148
149/// Zero-dependency BM25 lexical index + code-aware tokenizer (issue #156).
150///
151/// Why: trusty-memory, trusty-search, and the per-palace
152/// `trusty-bm25-daemon` subprocess all want one shared BM25 implementation
153/// so the tokenizer's camelCase / PascalCase / alpha↔digit splits stay
154/// consistent across the workspace. Originally ported from open-mpm; now
155/// the single source of truth lives here.
156/// What: Gated behind the `bm25` feature. Adds no new dependencies — pure
157/// `std` + `tracing` (already required).
158/// Test: `cargo test -p trusty-common --features bm25`.
159#[cfg(feature = "bm25")]
160pub mod bm25;
161
162/// Reusable schema-migration kernel (issue #179).
163///
164/// Why: trusty-search, trusty-memory, and other long-lived stores have grown
165/// ad-hoc schema-migration loops that drift apart. Centralising the
166/// `SchemaVersion` newtype, the `Migration<S>` trait, and a `MigrationRunner`
167/// that applies pending steps in order (writing a stamp after each) collapses
168/// those into one shared kernel. The `file_stamp` helper covers the common
169/// "JSON sidecar in the store's data dir" stamp format; redb-stamp users get
170/// a documented recipe instead of a heavyweight dep.
171/// What: gated behind the `migrations` feature flag. Adds no new
172/// dependencies — pure `serde` + `serde_json` + `anyhow` + `tracing` which
173/// the crate already requires.
174/// Test: `cargo test -p trusty-common --features migrations` covers the
175/// runner ordering, crash resumption, write-stamp failure propagation, and
176/// the file-stamp round-trip / atomic-write behaviour.
177#[cfg(feature = "migrations")]
178pub mod migrations;
179
180/// UDS JSON-RPC client for the per-palace `trusty-bm25-daemon` subprocess
181/// (issue #156).
182///
183/// Why: trusty-memory needs a lexical-search lane without holding an
184/// in-process BM25 index. `Bm25Client` delegates to the per-palace daemon
185/// over `$TMPDIR/trusty-bm25-<palace>.sock`, matching the design of
186/// `EmbedClient` and `trusty-embed-daemon` (PR #157).
187/// What: Gated behind the `bm25-client` feature. Pure user of existing
188/// `tokio` / `serde_json` / `anyhow` workspace deps — adds no new
189/// dependencies.
190/// Test: `cargo test -p trusty-common --features bm25-client` covers
191/// request shape and path defaults; end-to-end coverage lives in
192/// `trusty-bm25-daemon/tests/`.
193#[cfg(feature = "bm25-client")]
194pub mod bm25_client;
195
196/// Symbol-graph engine (formerly the `trusty-symgraph` crate).
197///
198/// Why: All trusty-* tools that touch source code (open-mpm, trusty-search,
199/// trusty-analyze) want the same `EntityType` / `RawEntity` / `EdgeKind`
200/// data shapes and (for orchestrators) the same tree-sitter pipeline. Living
201/// here lets the workspace ship one tree-sitter `links =` slot instead of
202/// juggling two crates that both claim it.
203/// What: Gated behind two features. `symgraph` exposes only the contracts
204/// surface (`EntityType`, `RawEntity`, `EdgeKind`, `fact_hash_str`, tables)
205/// — no tree-sitter, no `links` conflict. `symgraph-parser` additionally
206/// pulls in tree-sitter and the full parse → registry → emit stack.
207/// `symgraph-server` enables the HTTP server frontend.
208/// Test: `cargo test -p trusty-common --features symgraph` exercises the
209/// contracts surface; `cargo test -p trusty-symgraph` covers the parser
210/// path through the thin re-export shim.
211#[cfg(feature = "symgraph")]
212pub mod symgraph;
213
214/// Memory Palace storage engine (formerly the `trusty-memory-core` crate).
215///
216/// Why: Centralises the Memory Palace data model (`Palace` / `Wing` /
217/// `Room` / `Drawer`), storage backends (usearch vector index + SQLite
218/// knowledge graph + chat-session log + payload store), retrieval handle,
219/// and the dream / decay / analytics / git-history surfaces so every
220/// trusty-* binary that talks to a palace reuses the same types. Absorbed
221/// into `trusty-common` (issue #5 phase 2d) so we ship one fewer published
222/// crate.
223/// What: Gated behind the `memory-core` feature because it pulls in heavy
224/// storage deps (`usearch`, `rusqlite`, `r2d2`, `git2`, `kuzu`). Enables
225/// the embedder surface automatically (memory-core → embedder).
226/// Test: `cargo test -p trusty-common --features memory-core` exercises
227/// the full surface.
228#[cfg(feature = "memory-core")]
229pub mod memory_core;
230
231/// Unified ticketing MCP server (formerly the `trusty-tickets` crate).
232///
233/// Why: Claude Code and the rest of the trusty-* suite need a single MCP
234/// surface that can talk to GitHub Issues, JIRA, and Linear without the
235/// caller needing to know which backend is configured. Absorbing into
236/// `trusty-common` reduces the workspace crate count and co-locates the
237/// HTTP client surface with the other protocol helpers.
238/// What: Gated behind the `tickets` feature. Exposes `tickets::api::*`
239/// (config, models, Backend trait, three concrete backends), `tickets::server`
240/// (MCP dispatch loop + `run_stdio`), and `tickets::tools` (the tool-list
241/// schema). Requires the `mcp` feature for the stdio loop.
242/// Test: `cargo test -p trusty-common --features tickets` runs the module's
243/// own unit tests (dispatch, tool-list counts, config parsing, serde
244/// round-trips). Live backend tests require env-var credentials.
245#[cfg(feature = "tickets")]
246pub mod tickets;
247
248/// Intent-source resolver (ISR) for the intent/method conformance gates (#1358).
249///
250/// Why: the DOC-15 conformance capability needs one shared resolver that both
251/// the FRONT gate (trusty-mpm) and the BACK gate (trusty-review) call, so
252/// ticket+spec resolution and the precedence rule (ticket > spec) are
253/// implemented once, centrally, and the two gates can never disagree
254/// (`SPEC-CONFORMANCE-03~draft`, spec §6).
255/// What: gated behind the `intent-source` feature (depends on `tickets` and
256/// `chat`). Exposes `intent_source::{resolve, ResolvedIntent, IntentQuery, …}`
257/// plus the pluggable `TicketFetcher` / `IntentTokenResolver` / `SpecLookup` /
258/// `MethodExtractor` seams. Fail-open throughout (`thiserror`, no `unwrap`).
259/// Test: `cargo test -p trusty-common --features intent-source` runs the
260/// module's AC-1..AC-7 unit tests with no network access.
261#[cfg(feature = "intent-source")]
262pub mod intent_source;
263
264/// Declarative CLI help system with "did you mean?" suggestions (issue #216).
265///
266/// Why: every standalone trusty-* binary used to render its `--help` and
267/// unknown-subcommand error output independently, so the formats drifted
268/// apart over time. Centralising the help model into one YAML schema, one
269/// canonical renderer, and one Jaro-Winkler suggester keeps the six binaries
270/// (search, memory, analyze, mpm-cli, tga, open-mpm) speaking with a single
271/// user-facing voice.
272/// What: gated behind the `cli-help` feature. Pulls in `serde_yaml`, `strsim`,
273/// and `indexmap`. Exposes `HelpConfig` / `CommandDef` / `FlagDef` / `Example`
274/// + `load_help` / `render_help` / `suggest`.
275/// Test: `cargo test -p trusty-common --features cli-help`.
276#[cfg(feature = "cli-help")]
277pub mod help;
278
279/// Unified monitor TUI for the trusty-search and trusty-memory daemons
280/// (formerly the `trusty-monitor-tui` crate).
281///
282/// Why: operators run both daemons and want one terminal surface that shows
283/// the health of both at a glance. Living here behind the `monitor-tui`
284/// feature flag matches the workspace's "one fewer published crate" direction
285/// (issue #31 companion) and keeps the dashboard logic unit-testable.
286/// What: gated behind the `monitor-tui` feature, which pulls in `ratatui` and
287/// `crossterm`. Exposes `monitor::run` (the entry point the `trusty-monitor`
288/// binary calls) plus the pure `dashboard` / `search_client` / `memory_client`
289/// submodules.
290/// Test: `cargo test -p trusty-common --features monitor-tui` covers the
291/// rendering, layout, and HTTP-client pieces.
292#[cfg(feature = "monitor-tui")]
293pub mod monitor;
294
295// epic #1104: stdio MCP client + console metrics contract (feature-gated).
296#[cfg(feature = "console-metrics")]
297pub mod console_metrics;
298#[cfg(feature = "stdio-mcp-client")]
299pub mod stdio_mcp_client;
300
301/// Throttled crates.io update-notification helper.
302///
303/// Why: User-facing CLIs should nudge operators when a newer release is
304/// available without adding perceptible latency. A shared implementation
305/// keeps the throttle, cache, opt-out, and User-Agent logic consistent across
306/// every consumer in the workspace.
307/// What: Gated behind the `update-check` feature. Exposes
308/// [`update::check_throttled`] (the main entry — reads a per-crate JSON cache
309/// under the OS cache dir, queries crates.io at most once per 24 h),
310/// [`update::check_crates_io`] (the raw network call), [`update::notice`]
311/// (formatted upgrade message), and [`update::UpdateInfo`] (the result type).
312/// All failures degrade to `None` — the check is best-effort and will not
313/// panic or stall a CLI.
314/// Opt-out: set `TRUSTY_NO_UPDATE_CHECK` or `CI` to any non-empty value.
315/// Test: `cargo test -p trusty-common --features update-check`.
316#[cfg(feature = "update-check")]
317pub mod update;
318
319/// Error-capture layer for the trusty-* consent-gated bug-reporting system
320/// (bug-reporting Phase 1, issue #479).
321///
322/// Why: Every trusty-* daemon encounters runtime errors that developers need
323/// to see but that must be captured locally and only filed to GitHub after
324/// explicit user consent. A shared capture layer in `trusty-common` means
325/// all daemons gain error capture without per-binary changes.
326/// What: Gated behind the `bug-capture` feature. Exposes:
327/// - [`error_capture::CapturedError`] — structured error record.
328/// - [`error_capture::ErrorStore`] — ring buffer + JSONL store.
329/// - [`error_capture::BugCaptureLayer`] — the tracing Layer.
330/// - [`error_capture::bug_capture_layer`] — convenience constructor.
331/// - [`error_capture::TRUSTY_NO_BUG_CAPTURE_ENV`] — opt-out env name.
332/// Additive: does not alter stderr logging. Opt-out via
333/// `TRUSTY_NO_BUG_CAPTURE=1`. New dep: `sha2` (already workspace-optional).
334/// Test: `cargo test -p trusty-common --features bug-capture`.
335#[cfg(feature = "bug-capture")]
336pub mod error_capture;
337
338/// The `~/.trusty-tools/<crate>/config.yaml` cross-crate config convention (#1220).
339///
340/// Why: every trusty-* crate had its own config location/format; #1220
341/// standardises one convention so an operator always knows where a crate's
342/// configuration lives. Centralising the path resolution and typed YAML
343/// load/save here means each crate adopts it by calling two functions.
344/// What: Gated behind the `crate-config` feature. Exposes
345/// [`crate_config::crate_config_path`], [`crate_config::load`],
346/// [`crate_config::load_or_default`], and [`crate_config::save`].
347/// Test: `cargo test -p trusty-common --features crate-config -- crate_config::tests`.
348#[cfg(feature = "crate-config")]
349pub mod crate_config;
350
351// ─── Focused submodules (split from lib.rs in issue #1108) ────────────────
352
353/// TCP port auto-walking helper.
354///
355/// Why: Running multiple daemon instances shouldn't produce noisy failures
356/// when a port is already occupied.
357/// What: Exposes [`bind_with_auto_port`] which walks forward to the next free
358/// port within `max_attempts`.
359/// Test: `cargo test -p trusty-common -- port::tests`.
360pub mod port;
361
362/// Canonical project-slug derivation (issue #1348).
363///
364/// Why: trusty-memory and trusty-installer both need the identical
365/// directory-basename/repo-name → slug rule (the trusty-memory daemon's
366/// `validate_palace_name` rejects a palace whose slug disagrees with the one it
367/// re-derives). Centralising the rule here makes it the single source of truth
368/// so the two crates cannot silently diverge.
369/// What: Exposes [`slug::slugify_string`], re-exported at the crate root as
370/// [`slugify_string`].
371/// Test: `cargo test -p trusty-common -- slug::tests`.
372pub mod slug;
373pub use slug::slugify_string;
374
375/// Canonical trusty-search index-id derivation from a project path (issue #1373).
376///
377/// Why: trusty-mpm (register-and-pin at session launch) and trusty-search
378/// (`detect_project`, MCP serve pin) must derive the byte-for-byte identical
379/// index id from the same project root, or a session pins one id while querying
380/// another. Centralising the rule here — the crate both already depend on —
381/// keeps them in lockstep without a trusty-mpm → trusty-search dependency edge.
382/// What: Exposes [`index_id::derive_index_id`] and [`index_id::resolve_project_root`].
383/// Test: `cargo test -p trusty-common -- index_id::tests`.
384pub mod index_id;
385pub use index_id::{derive_index_id, resolve_project_root};
386
387/// Canonical trusty-memory palace-ID derivation from project identity (#1217/#1605).
388///
389/// Why: trusty-memory (default-palace derivation at the CLI/hook/MCP edges) and
390/// trusty-mpm (managed-session MCP injection — it pins `TRUSTY_MEMORY_PALACE` in
391/// a cloned session's `.mcp.json`) must derive the byte-for-byte identical
392/// palace slug from the same project identity, or a repo-cloned session resolves
393/// the wrong palace. Centralising the pure rule here — the crate both already
394/// depend on — keeps them in lockstep without a trusty-mpm → trusty-memory
395/// dependency edge, exactly as `index_id` does for trusty-search index pinning.
396/// What: Exposes [`palace_id::derive_palace_id`],
397/// [`palace_id::owner_repo_from_git_remote`], [`palace_id::parent_dir_slug`],
398/// and the [`palace_id::PALACE_OVERRIDE_ENV`] / [`palace_id::palace_override_from_env`]
399/// env helpers.
400/// Test: `cargo test -p trusty-common -- palace_id::tests`.
401pub mod palace_id;
402pub use palace_id::{
403 PALACE_OVERRIDE_ENV, derive_palace_id, owner_repo_from_git_remote, palace_override_from_env,
404 parent_dir_slug,
405};
406
407/// Shared GitHub `owner/repo` path derivation (issue #1220).
408///
409/// Why: trusty-mpm's managed-session workspace root
410/// (`~/trusty-mpm-projects/<owner>/<repo>/…`) and trusty-memory's palace-ID
411/// derivation both need the canonical `owner/repo` identity of a project's git
412/// origin remote. Centralising the parsing here keeps the two crates in lockstep.
413/// What: Exposes [`github_path::GithubPath`], [`github_path::parse_github_path`]
414/// (pure URL parse), and [`github_path::derive_github_path`] (reads
415/// `remote.origin.url`).
416/// Test: `cargo test -p trusty-common -- github_path::tests`.
417pub mod github_path;
418
419/// Data-directory resolution and filesystem utilities.
420///
421/// Why: All trusty-* tools share the same per-app data-directory resolution
422/// logic including the macOS `NSFileManager` bypass needed for test isolation.
423/// What: Exposes [`data_dir::resolve_data_dir`], [`data_dir::sanitize_data_root`],
424/// [`data_dir::DATA_DIR_OVERRIDE_ENV`], and [`data_dir::is_dir`].
425/// Test: `cargo test -p trusty-common -- data_dir::tests`.
426pub mod data_dir;
427
428/// Shared CLI daemon-guard helper (probe + spinner + spawn).
429///
430/// Why: trusty-search, trusty-memory, and trusty-analyze each had an identical
431/// probe-spawn-poll-spinner loop in their `commands/daemon_guard.rs` files.
432/// Centralising it here (issue #985) removes the divergence risk and gives
433/// the three crates a single tested implementation to delegate to.
434/// What: Exposes [`daemon_guard::DaemonGuardConfig`],
435/// [`daemon_guard::probe_once`], [`daemon_guard::spin_until_ready`], and
436/// [`daemon_guard::spawn_current_exe`].
437/// Test: `cargo test -p trusty-common -- daemon_guard::tests`.
438pub mod daemon_guard;
439
440/// Daemon HTTP-address file helpers.
441///
442/// Why: Both trusty-search and trusty-memory persist their bound `host:port`
443/// to disk for discovery by CLI and MCP clients. Centralising keeps them in sync.
444/// What: Exposes [`daemon_addr::write_daemon_addr`], [`daemon_addr::read_daemon_addr`],
445/// and [`daemon_addr::check_already_running`].
446/// Test: `cargo test -p trusty-common -- daemon_addr::tests`.
447pub mod daemon_addr;
448
449/// HTTP health-probe helper.
450///
451/// Why: Every daemon uses the same tight-timeout `/health` probe to detect
452/// whether a prior instance is still running.
453/// What: Exposes [`health_probe::probe_health`].
454/// Test: covered via daemon_addr integration tests.
455pub mod health_probe;
456
457/// Global tracing subscriber initialisation helpers.
458///
459/// Why: Every trusty-* binary needs the same verbosity ladder, `RUST_LOG`
460/// override, and (for daemons) the log-buffer + bug-capture layer composition.
461/// What: Exposes [`tracing_init::init_tracing`],
462/// [`tracing_init::init_tracing_with_buffer`],
463/// [`tracing_init::init_tracing_with_buffer_and_capture`] (feature-gated),
464/// and [`tracing_init::maybe_disable_color`].
465/// Test: side-effecting global — covered by downstream integration tests.
466pub mod tracing_init;
467
468/// Deprecated single-shot OpenRouter helpers.
469///
470/// Why: Backward-compatible wrapper for the pre-streaming OpenRouter API.
471/// New code should use `chat::OpenRouterProvider::chat_stream` instead.
472/// What: Exposes [`openrouter_legacy::ChatMessage`],
473/// [`openrouter_legacy::openrouter_chat`] (deprecated), and
474/// [`openrouter_legacy::openrouter_chat_stream`] (deprecated).
475/// Test: `chat_message_round_trips`, `openrouter_chat_rejects_empty_key`.
476pub mod openrouter_legacy;
477
478/// Incremental catch-up engine for the DOC-28 cutover bridge (#1762).
479///
480/// Why: when a native `tm` session starts, the operator needs a summary of
481/// activity since the last session (paused sessions, git commits, memory palace
482/// drawers). Hosting the engine here lets both trusty-mpm and (eventually)
483/// trusty-code share it without code duplication.
484/// What: gated behind the `catchup` feature (pulls in `rusqlite` via the
485/// `mpm_registry` submodule). Exposes `catchup::{CatchupOptions, run_catchup,
486/// run_catchup_blocking, generate_catchup_context, …}` plus per-source
487/// submodules (`git`, `palace`, `state`, `session_finder`, `mpm_session`,
488/// `mpm_registry`).
489/// Test: `cargo test -p trusty-common --features catchup`.
490// CUTOVER BRIDGE — remove post-migration (#1762)
491#[cfg(feature = "catchup")]
492pub mod catchup;
493
494// ─── Re-exports preserving the pre-split public API ───────────────────────
495
496pub use chat::{
497 BedrockProvider, ChatEvent, ChatProvider, DEFAULT_BEDROCK_MODEL, LocalModelConfig,
498 OllamaProvider, OpenRouterProvider, ToolCall, ToolDef, auto_detect_local_provider,
499};
500
501// Port
502pub use port::bind_with_auto_port;
503
504// Data directory
505pub use data_dir::{DATA_DIR_OVERRIDE_ENV, is_dir, resolve_data_dir, sanitize_data_root};
506
507// Daemon address
508pub use daemon_addr::{
509 check_already_running, read_daemon_addr, remove_daemon_addr, write_daemon_addr,
510};
511
512// Health probe
513pub use health_probe::probe_health;
514
515// Tracing init
516#[cfg(feature = "bug-capture")]
517pub use tracing_init::init_tracing_with_buffer_and_capture;
518pub use tracing_init::{init_tracing, init_tracing_with_buffer, maybe_disable_color};
519
520// OpenRouter legacy (deprecated but must remain reachable)
521#[allow(deprecated)]
522pub use openrouter_legacy::{ChatMessage, openrouter_chat, openrouter_chat_stream};