Skip to main content

bijux_cli/interface/repl/
types.rs

1use std::collections::BTreeMap;
2use std::path::PathBuf;
3
4use crate::contracts::ExecutionPolicy;
5
6/// REPL startup latency budget in milliseconds.
7pub const REPL_STARTUP_LATENCY_BUDGET_MS: u128 = 50;
8/// REPL memory budget in bytes.
9pub const REPL_MEMORY_BUDGET_BYTES: usize = 2 * 1024 * 1024;
10
11/// REPL startup command prefix.
12pub(crate) const META_PREFIX: char = ':';
13/// Max number of characters retained per history command.
14pub const REPL_HISTORY_ENTRY_MAX_CHARS: usize = 8 * 1024;
15/// Max bytes accepted when reading a persisted history file.
16pub const REPL_HISTORY_FILE_MAX_BYTES: u64 = 8 * 1024 * 1024;
17/// Max number of history entries retained by configuration.
18pub const REPL_HISTORY_MAX_ENTRIES: usize = 50_000;
19/// Max command completion candidates returned to callers.
20pub const REPL_COMPLETION_MAX_CANDIDATES: usize = 512;
21/// Max number of completion entries accepted per registry.
22pub const REPL_COMPLETION_REGISTRY_MAX_ENTRIES: usize = 1024;
23/// Max number of characters retained per completion entry.
24pub const REPL_COMPLETION_ENTRY_MAX_CHARS: usize = 256;
25/// Max number of completion registry owners retained in a session.
26pub const REPL_COMPLETION_REGISTRY_MAX_OWNERS: usize = 256;
27/// Max number of plugin completion namespaces retained in a session.
28pub const REPL_PLUGIN_COMPLETION_MAX_NAMESPACES: usize = 256;
29/// Max number of characters retained for profile labels.
30pub const REPL_PROFILE_MAX_CHARS: usize = 64;
31/// Max number of characters retained for prompt text.
32pub const REPL_PROMPT_MAX_CHARS: usize = 128;
33/// Max diagnostics entries emitted during startup checks.
34pub const REPL_STARTUP_DIAGNOSTIC_MAX_ENTRIES: usize = 128;
35/// Max characters retained for `last_error` state.
36pub const REPL_LAST_ERROR_MAX_CHARS: usize = 2_048;
37/// Max characters retained in pending multiline REPL buffers.
38pub const REPL_MULTILINE_BUFFER_MAX_CHARS: usize = 64 * 1024;
39/// Max characters accepted for a fully assembled REPL command.
40pub const REPL_COMMAND_MAX_CHARS: usize = 64 * 1024;
41
42/// Stable REPL startup contract.
43#[derive(Debug, Clone, PartialEq, Eq)]
44pub struct ReplStartupContract {
45    /// Prompt format string.
46    pub prompt: String,
47    /// Whether profile/context is displayed in prompt.
48    pub include_profile_context: bool,
49    /// Effective startup policy.
50    pub policy: ExecutionPolicy,
51}
52
53/// Stable REPL shutdown contract.
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub struct ReplShutdownContract {
56    /// Session id.
57    pub session_id: String,
58    /// Number of commands executed.
59    pub commands_executed: usize,
60}
61
62/// REPL session model.
63#[derive(Debug, Clone, PartialEq, Eq)]
64pub struct ReplSession {
65    /// Session identifier.
66    pub session_id: String,
67    /// Prompt displayed to user.
68    pub prompt: String,
69    /// Profile label shown in prompt.
70    pub profile: String,
71    /// Effective execution policy.
72    pub policy: ExecutionPolicy,
73    /// Command counter.
74    pub commands_executed: usize,
75    /// Last mapped exit code as integer.
76    pub last_exit_code: i32,
77    /// Trace mode toggle.
78    pub trace_mode: bool,
79    /// Persistent command history buffer.
80    pub history: Vec<String>,
81    /// Max history size.
82    pub history_limit: usize,
83    /// Whether history persistence is enabled.
84    pub history_enabled: bool,
85    /// History file location.
86    pub history_file: Option<PathBuf>,
87    /// Optional config path override propagated into nested command execution.
88    pub config_path: Option<String>,
89    /// Pending multiline input buffer.
90    pub pending_multiline: Option<String>,
91    /// Last observed error message.
92    pub last_error: Option<String>,
93    /// Plugin completion hooks by namespace.
94    pub plugin_completion_hooks: BTreeMap<String, Vec<String>>,
95    /// Extension completion registries keyed by owner identifier.
96    pub completion_registries: BTreeMap<String, Vec<String>>,
97}
98
99/// REPL emission stream.
100#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub enum ReplStream {
102    /// Standard output.
103    Stdout,
104    /// Standard error.
105    Stderr,
106}
107
108/// Repl output frame.
109#[derive(Debug, Clone, PartialEq, Eq)]
110pub struct ReplFrame {
111    /// Stream target.
112    pub stream: ReplStream,
113    /// Serialized output.
114    pub content: String,
115}
116
117/// Input event for interactive session loop.
118#[derive(Debug, Clone, PartialEq, Eq)]
119pub enum ReplInput {
120    /// Normal command line.
121    Line(String),
122    /// Ctrl-C interrupt event.
123    Interrupt,
124    /// EOF event.
125    Eof,
126}
127
128/// Result of processing a REPL input event.
129#[derive(Debug, Clone, PartialEq, Eq)]
130pub enum ReplEvent {
131    /// Keep session alive.
132    Continue(Option<ReplFrame>),
133    /// Exit session.
134    Exit(Option<ReplFrame>),
135    /// Interrupted command input.
136    Interrupted(ReplFrame),
137}
138
139/// REPL runtime errors.
140#[derive(Debug, thiserror::Error)]
141pub enum ReplError {
142    /// Command parser failed.
143    #[error(transparent)]
144    Parser(#[from] crate::routing::parser::ParseError),
145    /// Routing failed.
146    #[error(transparent)]
147    Route(#[from] crate::routing::registry::RouteError),
148    /// Kernel failed.
149    #[error("kernel execution failed")]
150    Kernel(crate::kernel::KernelError),
151    /// Core app execution failed.
152    #[error("core execution failed: {0}")]
153    Core(String),
154    /// Output encoding failed.
155    #[error(transparent)]
156    Emit(#[from] crate::shared::output::EmitError),
157    /// History serialization failed.
158    #[error(transparent)]
159    Json(#[from] serde_json::Error),
160    /// IO failure.
161    #[error(transparent)]
162    Io(#[from] std::io::Error),
163    /// Invalid REPL command.
164    #[error("invalid repl command: {0}")]
165    InvalidMetaCommand(String),
166    /// Invalid command-line tokenization input.
167    #[error("invalid command input: {0}")]
168    InvalidCommandInput(String),
169    /// History replay index was invalid.
170    #[error("history index out of bounds: {0}")]
171    HistoryIndexOutOfBounds(usize),
172}