Skip to main content

lattice_ai/pi/
modes.rs

1//! `pi-mode` — the minor mode layered on the pi terminal buffer.
2//!
3//! v1 is a Manual-activation **marker** minor over `terminal-mode`, activated
4//! by `:pi` on the terminal running the agent. It carries no per-buffer
5//! resources: pi's own TUI owns the conversation, the prompt (readline,
6//! `/` commands, model switching), history, and session tree, so lattice adds
7//! nothing on the hot path. The mode exists as the buffer's *identity* and as
8//! the **seam** for future lattice-native integration (RPC conversation buffer,
9//! a headerline status row) — mirroring `opencode-mode`'s marker shell.
10
11use lattice_mode::registry::ModeRegistry;
12use lattice_mode::{ActivationPolicy, LifecycleFuture, Mode, ModeContext, ModeId, ModeKind};
13
14/// The pi terminal minor mode.
15pub struct PiMode;
16
17impl PiMode {
18    /// The mode id (`pi-mode`).
19    pub fn mode_id() -> ModeId {
20        ModeId::new("pi-mode")
21    }
22}
23
24impl Mode for PiMode {
25    type Guard = ();
26
27    fn id(&self) -> ModeId {
28        Self::mode_id()
29    }
30
31    fn kind(&self) -> ModeKind {
32        ModeKind::Minor
33    }
34
35    /// Manual — activated explicitly by `:pi` on the agent terminal.
36    fn activation_policy(&self) -> ActivationPolicy {
37        ActivationPolicy::Manual
38    }
39
40    fn on_activate(&self, _ctx: ModeContext) -> LifecycleFuture<'_, ()> {
41        Box::pin(async { Ok(()) })
42    }
43}
44
45/// Register `pi-mode` against `registry`. Called from
46/// [`super::install`].
47pub fn register_pi_modes(registry: &mut ModeRegistry) {
48    registry.register(PiMode).expect("pi-mode register");
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn id_kind_and_policy() {
57        assert_eq!(PiMode::mode_id().as_str(), "pi-mode");
58        assert_eq!(PiMode.kind(), ModeKind::Minor);
59        assert_eq!(PiMode.activation_policy(), ActivationPolicy::Manual);
60    }
61
62    #[test]
63    fn registers_without_conflict() {
64        let mut registry = ModeRegistry::new();
65        register_pi_modes(&mut registry);
66        assert!(registry.is_registered(PiMode::mode_id()));
67    }
68}