Skip to main content

vtcode_core/tools/registry/
plan_mode_facade.rs

1//! Plan mode state accessors for ToolRegistry.
2
3use crate::tools::handlers::PlanModeState;
4
5use super::ToolRegistry;
6
7impl ToolRegistry {
8    /// Enable plan mode (read-only enforcement).
9    ///
10    /// When enabled, mutating tools (`unified_file` writes/edits, `apply_patch`,
11    /// `unified_exec` runs, etc.)
12    /// are blocked and the agent can only read/analyze the codebase.
13    ///
14    /// `PlanModeState` is the single source of truth; this method delegates to it
15    /// so that `is_plan_mode()` and `plan_mode_state().is_active()` are always in
16    /// agreement.
17    pub fn enable_plan_mode(&self) {
18        let was_active = self.plan_mode_state.is_active();
19        self.plan_mode_state.enable();
20        if !was_active {
21            // Invalidate the tool catalog cache so the next snapshot reflects the
22            // plan-mode-filtered tool set rather than serving a stale pre-transition entry.
23            self.tool_catalog_state
24                .note_explicit_refresh("plan_mode_enabled");
25        }
26    }
27
28    /// Disable plan mode (allow mutating tools again).
29    pub fn disable_plan_mode(&self) {
30        let was_active = self.plan_mode_state.is_active();
31        self.plan_mode_state.disable();
32        if was_active {
33            // Invalidate the catalog cache so mutating tools reappear immediately.
34            self.tool_catalog_state
35                .note_explicit_refresh("plan_mode_disabled");
36        }
37    }
38
39    /// Check if plan mode is currently enabled.
40    ///
41    /// Reads directly from `PlanModeState` — the single authoritative flag.
42    #[inline]
43    pub fn is_plan_mode(&self) -> bool {
44        self.plan_mode_state.is_active()
45    }
46
47    /// Get the shared Plan Mode state (used by plan mode tools and pipeline transitions).
48    #[inline]
49    pub fn plan_mode_state(&self) -> PlanModeState {
50        self.plan_mode_state.clone()
51    }
52}