oxicode_vtui_compat/ui_protocol/selection.rs
1//! List selection and wizard step types.
2
3/// Rewind action choices for the rewind overlay.
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5pub enum RewindAction {
6 RestoreBoth,
7 RestoreConversation,
8 RestoreCode,
9 SummarizeFromHere,
10 NeverMind,
11}
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum OpenAIServiceTierChoice {
15 ProjectDefault,
16 Flex,
17 Priority,
18}
19
20/// Host-side action bound to a `/providers` row (`ProviderRow` →
21/// `ProviderAction { provider, action }`).
22///
23/// Lives in `vtui-compat` (not `oxicode-cli`) because it is referenced
24/// inside `InlineListSelection::ProviderAction`. Putting it here avoids
25/// an import cycle: `oxicode-cli` already depends on `oxicode-vtui-compat`
26/// but cannot introduce the reverse edge just for an enum.
27#[derive(Clone, Debug, PartialEq, Eq)]
28pub enum AuthAction {
29 /// Prompt for a fresh API key (set / replace).
30 SetApiKey,
31 /// Kick off the OAuth `authorization_code` flow.
32 StartOAuth,
33 /// Remove the currently stored credential.
34 RemoveKey,
35}
36
37/// Selection value returned from a list or wizard overlay.
38///
39/// The `Reasoning` variant carries a `String` reasoning-effort level rather
40/// than a typed enum so that this type stays free of config-crate dependencies.
41/// Callers convert to/from their local `ReasoningEffortLevel` as needed.
42#[derive(Clone, Debug, PartialEq, Eq)]
43pub enum InlineListSelection {
44 Model(usize),
45 DynamicModel(usize),
46 CustomProvider(usize),
47 RefreshDynamicModels,
48 Reasoning(String),
49 DisableReasoning,
50 OpenAIServiceTier(OpenAIServiceTierChoice),
51 CustomModel,
52 /// `/models` catalog browser — index into
53 /// `RenderState::overlay_catalog_models`.
54 CatalogModel(usize),
55 /// `/providers` list — index into `RenderState::overlay_providers`.
56 ProviderRow(usize),
57 /// `/providers` → action-menu selection. Emitted by the per-provider
58 /// action list overlay so the host can route the chosen `AuthAction`
59 /// (set key / start OAuth / remove key) back to the auth pipeline.
60 ProviderAction {
61 provider: String,
62 action: AuthAction,
63 },
64 Theme(String),
65 Session(String),
66 SessionForkMode {
67 session_id: String,
68 summarize: bool,
69 },
70 ConfigAction(String),
71 SlashCommand(String),
72 ToolApproval(bool),
73 ToolApprovalDenyOnce,
74 ToolApprovalSession,
75 ToolApprovalPermanent,
76 ToolApprovalEnable,
77 FileConflictReload,
78 FileConflictViewDiff,
79 FileConflictAbort,
80 SessionLimitIncrease(usize),
81 RewindCheckpoint(usize),
82 RewindAction(RewindAction),
83
84 /// Selection shape used by legacy tabbed HITL flows.
85 AskUserChoice {
86 tab_id: String,
87 choice_id: String,
88 text: Option<String>,
89 },
90
91 /// Selection returned from the `request_user_input` HITL tool.
92 RequestUserInputAnswer {
93 question_id: String,
94 selected: Vec<String>,
95 other: Option<String>,
96 },
97
98 /// Plan confirmation dialog result (human-in-the-loop flow).
99 PlanApprovalExecute,
100 /// Return to planning to edit the plan file.
101 PlanApprovalEditPlan,
102 /// Return to planning to discuss and revise the plan in chat.
103 PlanApprovalDiscuss,
104 /// Auto-accept all future plans in this session.
105 PlanApprovalAutoAccept,
106 /// Hand off to the build primary agent and execute the plan.
107 PlanApprovalSwitchBuild,
108 /// Hand off to the auto primary agent (auto-execute with per-step HITL).
109 PlanApprovalSwitchAuto,
110
111 /// Settings-panel tab switch (`/settings` tabs).
112 SettingsTab(usize),
113 /// Settings-panel sidebar section jump.
114 SettingsSection(usize),
115 /// Settings-panel key-capture submenu targeting a named `SettingKey`.
116 /// Carries the key's Debug name (a `String`) to avoid a dependency from
117 /// `oxicode-vtui-compat` onto `oxicode-cli`'s `SettingKey` enum.
118 SettingKeyCapture(String),
119 /// Settings-panel text editor: Enter on a Text widget row opens a
120 /// single-line prompt; the submitted text is parsed via the def's
121 /// `apply_change` arm and committed (or rejected with an inline
122 /// error). Same String-payload convention as `SettingKeyCapture`.
123 SettingTextEdit(String),
124 /// Settings-panel submenu-select: Enter opens a child list of the
125 /// widget's allowed options; selecting one commits via the def's
126 /// `apply_change` arm.
127 SettingSubmenuOpen(String),
128 /// Settings-panel multiselect: Enter opens a list of the registered
129 /// tools (sourced from the live `ToolRegistry`); each row toggles
130 /// membership in `Settings::disabled_tools`. Essential tools are
131 /// shown but cannot be disabled.
132 SettingMultiselect(String),
133}
134
135/// A selectable item inside a list overlay.
136#[derive(Clone, Debug)]
137pub struct InlineListItem {
138 pub title: String,
139 pub subtitle: Option<String>,
140 pub badge: Option<String>,
141 pub indent: u8,
142 pub selection: Option<InlineListSelection>,
143 pub search_value: Option<String>,
144}
145
146/// A single step in a wizard modal flow.
147#[derive(Clone, Debug)]
148pub struct WizardStep {
149 /// Title displayed in the tab header.
150 pub title: String,
151 /// Question or instruction shown above the list.
152 pub question: String,
153 /// Selectable items for this step.
154 pub items: Vec<InlineListItem>,
155 /// Whether this step has been completed.
156 pub completed: bool,
157 /// The selected answer for this step (if completed).
158 pub answer: Option<InlineListSelection>,
159
160 pub allow_freeform: bool,
161 pub freeform_label: Option<String>,
162 pub freeform_placeholder: Option<String>,
163 pub freeform_default: Option<String>,
164}