// SPDX-License-Identifier: Apache-2.0
//! kei-buddy — KeiBuddy personal-assistant Telegram bot scaffold.
//!
//! Module layout (Constructor Pattern — one file, one responsibility):
//!   * `state`      — `OnboardState` enum
//!   * `transition` — `StepOutput` output struct
//!   * `extractor`  — `LlmExtractor` trait + `MockExtractor` + `OpenAiExtractor` (feature-gated)
//!   * `machine`    — `handle_step` — the 11-arm onboarding FSM
//!   * `error`      — `BuddyError` error type
//!   * `schema`     — buddy-specific SQLite DDL
//!   * `store`      — `BuddyStore` trait + `SqliteBuddyStore` impl

pub mod chat_log;
pub(crate) mod command_exec;
pub mod commands;
pub mod contacts;
pub mod contacts_sync;
pub mod conversational;
pub mod error;
pub mod extractor;
pub mod machine;
pub(crate) mod machine_helpers;
pub(crate) mod machine_lang;
pub mod persona_merge;
pub mod provision_decrypt;
pub mod retrieval;
pub mod schema;
pub mod state;
pub mod store;
pub(crate) mod store_ops;
pub mod strings;
pub mod tick;
pub mod topic_classify;
pub mod topics;
pub mod transition;

#[cfg(feature = "serve")]
pub mod serve;
#[cfg(feature = "serve")]
pub(crate) mod serve_runner;
#[cfg(feature = "serve")]
pub mod serve_telegram;
#[cfg(feature = "serve")]
pub mod voice;

pub use chat_log::ChatLog;
pub use commands::{parse_command, execute_command, Command, CommandStores};
pub use contacts_sync::{sync_from_apple, sync_from_google, SyncReport};
pub use contacts::Contacts;
pub use error::BuddyError;
pub use extractor::LlmExtractor;
pub use machine::handle_step;
pub use state::OnboardState;
pub use store::{BuddyStore, SqliteBuddyStore};
pub use strings::{Lang, Strings};
pub use tick::{run_tick, run_tick_with, TickConfig, TickReport};
pub use topics::Topics;
pub use transition::StepOutput;
#[cfg(feature = "serve")]
pub use voice::VoiceHandler;
