rustyclaw_tui/action.rs
1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use strum::Display;
4
5/// Actions that drive the application, inspired by openapi-tui.
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Display)]
7#[strum(serialize_all = "snake_case")]
8pub enum Action {
9 Tick,
10 Render,
11 Resize(u16, u16),
12 Quit,
13 Suspend,
14 Resume,
15 Error(String),
16 Help,
17 FocusNext,
18 FocusPrev,
19 Focus,
20 UnFocus,
21 Up,
22 Down,
23 Submit,
24 Update,
25 Tab(u32),
26 ToggleFullScreen,
27 StatusLine(String),
28 TimedStatusLine(String, u64),
29 /// The user submitted text from the input bar (prompt or /command)
30 InputSubmit(String),
31 /// Request to connect (or reconnect) to the gateway
32 ReconnectGateway,
33 /// Request to disconnect from the gateway
34 DisconnectGateway,
35 /// Request to restart the gateway (stop + start)
36 RestartGateway,
37 /// Send a text message to the gateway (prompt from the input bar)
38 SendToGateway(String),
39 /// The gateway reader detected a connection drop
40 GatewayDisconnected(String),
41 /// Toggle the skills dialog overlay
42 ShowSkills,
43 /// Toggle the secrets dialog overlay
44 ShowSecrets,
45 /// Copy the currently selected message to clipboard
46 CopyMessage,
47 /// Show the provider-selection dialog
48 ShowProviderSelector,
49 /// Set the active provider (triggers auth check + model fetch)
50 SetProvider(String),
51 /// Open the API-key input dialog for the given provider
52 PromptApiKey(String),
53 /// The user entered an API key in the dialog — proceed to store confirmation
54 ConfirmStoreSecret {
55 provider: String,
56 key: String,
57 },
58 /// Fetch models from the provider API, then open the model selector
59 FetchModels(String),
60 /// The model fetch failed
61 FetchModelsFailed(String),
62 /// Open the model-selection dialog with a fetched list
63 ShowModelSelector {
64 provider: String,
65 models: Vec<String>,
66 },
67 /// Begin OAuth device flow authentication for the given provider
68 StartDeviceFlow(String),
69 /// Device flow: verification URL and user code are ready for display
70 DeviceFlowCodeReady {
71 url: String,
72 code: String,
73 },
74 /// Device flow authentication succeeded — store the token and proceed
75 DeviceFlowAuthenticated {
76 provider: String,
77 token: String,
78 },
79 /// Device flow authentication failed
80 DeviceFlowFailed(String),
81 /// Open the credential-management dialog for a secret
82 ShowCredentialDialog {
83 name: String,
84 disabled: bool,
85 policy: String,
86 },
87 /// Open the 2FA (TOTP) setup / management dialog
88 ShowTotpSetup,
89 /// Gateway sent an auth_challenge — prompt user for TOTP code
90 GatewayAuthChallenge,
91 /// User submitted a TOTP code for gateway authentication
92 GatewayAuthResponse(String),
93 /// Gateway vault is locked — prompt user for password
94 GatewayVaultLocked,
95 /// User submitted a password to unlock the gateway vault
96 GatewayUnlockVault(String),
97 /// Close the hatching animation and transition to normal TUI
98 CloseHatching,
99 /// Begin the hatching exchange — send the identity prompt to the gateway
100 BeginHatchingExchange,
101 /// A gateway response routed to the hatching exchange
102 HatchingResponse(String),
103 /// The hatching exchange is complete — save SOUL.md and close
104 FinishHatching(String),
105 /// Gateway returned the secrets list
106 SecretsListResult {
107 entries: Vec<rustyclaw_core::gateway::SecretEntryDto>,
108 },
109 /// Gateway returned a secret value (for provider probing, device flow, etc.)
110 SecretsGetResult {
111 key: String,
112 value: Option<String>,
113 },
114 /// Gateway stored a secret successfully
115 SecretsStoreResult {
116 ok: bool,
117 message: String,
118 },
119 /// Gateway returned peek result (for secret viewer)
120 SecretsPeekResult {
121 name: String,
122 ok: bool,
123 fields: Vec<(String, String)>,
124 message: Option<String>,
125 },
126 /// Gateway set policy result
127 SecretsSetPolicyResult {
128 ok: bool,
129 message: Option<String>,
130 },
131 /// Gateway set disabled result
132 SecretsSetDisabledResult {
133 ok: bool,
134 cred_name: String,
135 disabled: bool,
136 },
137 /// Gateway deleted credential result
138 SecretsDeleteCredentialResult {
139 ok: bool,
140 cred_name: String,
141 },
142 /// Gateway returned TOTP status
143 SecretsHasTotpResult {
144 has_totp: bool,
145 },
146 /// Gateway returned TOTP setup URI
147 SecretsSetupTotpResult {
148 ok: bool,
149 uri: Option<String>,
150 message: Option<String>,
151 },
152 /// Gateway returned TOTP verification result
153 SecretsVerifyTotpResult {
154 ok: bool,
155 },
156 /// Gateway returned TOTP removal result
157 SecretsRemoveTotpResult {
158 ok: bool,
159 },
160 /// Gateway stream started (API connected, waiting for response)
161 GatewayStreamStart,
162 /// Gateway extended thinking started
163 GatewayThinkingStart,
164 /// Gateway extended thinking delta (update loading indicator)
165 GatewayThinkingDelta,
166 /// Gateway extended thinking ended
167 GatewayThinkingEnd,
168 /// Gateway sent a text chunk
169 GatewayChunk(String),
170 /// Gateway response is complete
171 GatewayResponseDone,
172 /// Gateway sent a tool call from the model
173 GatewayToolCall {
174 id: String,
175 name: String,
176 arguments: String,
177 },
178 /// Gateway sent a tool result from execution
179 GatewayToolResult {
180 id: String,
181 name: String,
182 result: String,
183 is_error: bool,
184 },
185 /// Gateway authenticated successfully
186 GatewayAuthenticated,
187 /// Gateway config reloaded with new provider/model
188 GatewayReloaded {
189 provider: String,
190 model: String,
191 },
192 /// Gateway vault unlocked successfully
193 GatewayVaultUnlocked,
194 /// Info message
195 Info(String),
196 /// Success message
197 Success(String),
198 /// Warning message
199 Warning(String),
200 /// Show the tool permissions editor dialog
201 ShowToolPermissions,
202 /// Save updated tool permissions to config
203 SaveToolPermissions(HashMap<String, rustyclaw_core::tools::ToolPermission>),
204 /// Gateway is requesting user approval to run a tool (Ask mode)
205 ToolApprovalRequest {
206 id: String,
207 name: String,
208 arguments: String,
209 },
210 /// User responded to a tool approval request
211 ToolApprovalResponse {
212 id: String,
213 approved: bool,
214 },
215 /// Gateway is requesting structured user input (ask_user tool)
216 UserPromptRequest(rustyclaw_core::user_prompt_types::UserPrompt),
217 /// User responded to a structured prompt
218 UserPromptResponse(rustyclaw_core::user_prompt_types::UserPromptResponse),
219 /// Gateway sent a threads update (unified tasks + threads)
220 ThreadsUpdate {
221 threads: Vec<ThreadInfo>,
222 foreground_id: Option<u64>,
223 },
224 /// Gateway confirmed thread switch
225 ThreadSwitched {
226 thread_id: u64,
227 context_summary: Option<String>,
228 },
229 /// A long-running slash-command tool finished (msg, is_error)
230 ToolCommandDone {
231 message: String,
232 is_error: bool,
233 },
234 Noop,
235}
236
237/// Thread/task info for TUI display (unified).
238#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
239pub struct ThreadInfo {
240 pub id: u64,
241 pub label: String,
242 /// Description (for spawned tasks)
243 pub description: Option<String>,
244 /// Task status (None = simple thread, Some = spawned task)
245 pub status: Option<String>,
246 /// Icon for the thread kind (e.g. chat, sub-agent, background, task)
247 pub kind_icon: Option<String>,
248 /// Icon for the thread status (e.g. running, completed, failed)
249 pub status_icon: Option<String>,
250 pub is_foreground: bool,
251 pub message_count: usize,
252 pub has_summary: bool,
253}
254
255/// Alias for backward compatibility
256pub type TaskInfo = ThreadInfo;