1use lattice_grammar::args::Args;
15use lattice_grammar::command::LatencyClass;
16use lattice_grammar::effect::Effect;
17use lattice_grammar::registry::{CommandRegistry, ExCommandSpec, SurfaceForm};
18use std::sync::Arc;
19
20pub fn register_ai_log_command(registry: &mut CommandRegistry) {
27 registry.register_ex_command(
28 "ai-log",
29 "Open the AI agent log buffer (picker when several sessions exist).",
30 ExCommandSpec {
31 latency_class: LatencyClass::Reflex,
32 accepts_bang: false,
33 accepts_range: false,
34 parse_args: Arc::new(lattice_agent::parse_rest_as_text),
35 apply: Arc::new(move |ctx| {
36 let session = match &ctx.args {
37 Args::String(t) if !t.is_empty() => Some(t.clone()),
38 _ => None,
39 };
40 Ok(Effect::OpenAiLog { session })
41 }),
42 args_schema: vec![],
43 surface_form: SurfaceForm::Keyword,
44 },
45 );
46}
47
48#[cfg(test)]
49mod tests {
50 #![allow(clippy::unwrap_used, clippy::panic)]
51 use super::*;
52 use lattice_grammar::registry::ExCommandContext;
53 use lattice_grammar::{CancellationToken, Count, Register};
54
55 fn ctx_with(args: Args) -> ExCommandContext {
56 ExCommandContext {
57 bang: false,
58 args,
59 range: None,
60 register: Register::default(),
61 count: Count::default(),
62 buffer_id: lattice_core::BufferId::default(),
63 cursor: Default::default(),
70 buffer: Default::default(),
71 path: None,
72 syntax: None,
73 cancel: CancellationToken::new(),
74 }
75 }
76
77 #[test]
80 fn ai_log_no_arg_opens_without_prefilter() {
81 let mut registry = CommandRegistry::new();
82 register_ai_log_command(&mut registry);
83
84 let id = registry
85 .id_by_name("ai-log")
86 .expect("`:ai-log` is registered");
87 let spec = registry.ex_command_spec(id).expect("spec present");
88 let effect = (spec.apply)(&ctx_with(Args::None)).expect("apply ok");
89
90 match effect {
91 Effect::OpenAiLog { session } => assert_eq!(session, None),
92 other => panic!("expected OpenAiLog, got {other:?}"),
93 }
94 }
95
96 #[test]
97 fn ai_log_with_arg_carries_provider_prefilter() {
98 let mut registry = CommandRegistry::new();
99 register_ai_log_command(&mut registry);
100
101 let id = registry
102 .id_by_name("ai-log")
103 .expect("`:ai-log` is registered");
104 let spec = registry.ex_command_spec(id).expect("spec present");
105 let effect =
106 (spec.apply)(&ctx_with(Args::String("opencode".to_string()))).expect("apply ok");
107
108 match effect {
109 Effect::OpenAiLog { session } => assert_eq!(session.as_deref(), Some("opencode")),
110 other => panic!("expected OpenAiLog, got {other:?}"),
111 }
112 }
113}