Skip to main content

zeph_commands/handlers/
status.rs

1// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Status display handlers: `/status`, `/guardrail`, `/focus`, `/sidequest`.
5
6use std::future::Future;
7use std::pin::Pin;
8
9use crate::context::CommandContext;
10use crate::{CommandError, CommandHandler, CommandOutput, SlashCategory};
11
12/// Display the current session status (provider, model, tokens, uptime, etc.).
13pub struct StatusCommand;
14
15impl CommandHandler<CommandContext<'_>> for StatusCommand {
16    fn name(&self) -> &'static str {
17        "/status"
18    }
19
20    fn description(&self) -> &'static str {
21        "Show current session status (provider, model, tokens, uptime)"
22    }
23
24    fn category(&self) -> SlashCategory {
25        SlashCategory::Debugging
26    }
27
28    fn handle<'a>(
29        &'a self,
30        ctx: &'a mut CommandContext<'_>,
31        _args: &'a str,
32    ) -> Pin<Box<dyn Future<Output = Result<CommandOutput, CommandError>> + Send + 'a>> {
33        Box::pin(async move {
34            let result = ctx.agent.session_status().await?;
35            Ok(CommandOutput::Message(result))
36        })
37    }
38}
39
40/// Display guardrail configuration and runtime statistics.
41pub struct GuardrailCommand;
42
43impl CommandHandler<CommandContext<'_>> for GuardrailCommand {
44    fn name(&self) -> &'static str {
45        "/guardrail"
46    }
47
48    fn description(&self) -> &'static str {
49        "Show guardrail status (provider, model, action, timeout, stats)"
50    }
51
52    fn category(&self) -> SlashCategory {
53        SlashCategory::Debugging
54    }
55
56    fn feature_gate(&self) -> Option<&'static str> {
57        Some("guardrail")
58    }
59
60    fn handle<'a>(
61        &'a self,
62        ctx: &'a mut CommandContext<'_>,
63        _args: &'a str,
64    ) -> Pin<Box<dyn Future<Output = Result<CommandOutput, CommandError>> + Send + 'a>> {
65        Box::pin(async move {
66            let result = ctx.agent.guardrail_status();
67            Ok(CommandOutput::Message(result))
68        })
69    }
70}
71
72/// Display Focus Agent status (active session, knowledge block size).
73pub struct FocusCommand;
74
75impl CommandHandler<CommandContext<'_>> for FocusCommand {
76    fn name(&self) -> &'static str {
77        "/focus"
78    }
79
80    fn description(&self) -> &'static str {
81        "Show Focus Agent status (active session, knowledge block size)"
82    }
83
84    fn category(&self) -> SlashCategory {
85        SlashCategory::Advanced
86    }
87
88    fn feature_gate(&self) -> Option<&'static str> {
89        Some("context-compression")
90    }
91
92    fn handle<'a>(
93        &'a self,
94        ctx: &'a mut CommandContext<'_>,
95        _args: &'a str,
96    ) -> Pin<Box<dyn Future<Output = Result<CommandOutput, CommandError>> + Send + 'a>> {
97        Box::pin(async move {
98            let result = ctx.agent.focus_status();
99            Ok(CommandOutput::Message(result))
100        })
101    }
102}
103
104/// Display `SideQuest` eviction statistics (passes run, tokens freed).
105pub struct SideQuestCommand;
106
107impl CommandHandler<CommandContext<'_>> for SideQuestCommand {
108    fn name(&self) -> &'static str {
109        "/sidequest"
110    }
111
112    fn description(&self) -> &'static str {
113        "Show SideQuest eviction stats (passes run, tokens freed)"
114    }
115
116    fn category(&self) -> SlashCategory {
117        SlashCategory::Advanced
118    }
119
120    fn feature_gate(&self) -> Option<&'static str> {
121        Some("context-compression")
122    }
123
124    fn handle<'a>(
125        &'a self,
126        ctx: &'a mut CommandContext<'_>,
127        _args: &'a str,
128    ) -> Pin<Box<dyn Future<Output = Result<CommandOutput, CommandError>> + Send + 'a>> {
129        Box::pin(async move {
130            let result = ctx.agent.sidequest_status();
131            Ok(CommandOutput::Message(result))
132        })
133    }
134}