1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use uuid::Uuid;
6
7use crate::types::ids::AgentId;
8use crate::types::logs::LogOption;
9use crate::types::message::Message;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(tag = "type")]
14pub enum LocalCommandResult {
15 #[serde(rename = "text")]
16 Text { value: String },
17 #[serde(rename = "compact")]
18 Compact {
19 #[serde(rename = "compactionResult")]
20 compaction_result: serde_json::Value,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 #[serde(rename = "displayText")]
23 display_text: Option<String>,
24 },
25 #[serde(rename = "skip")]
26 Skip,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
31#[serde(rename_all = "camelCase")]
32pub enum SettingSource {
33 UserSettings,
34 ProjectSettings,
35 LocalSettings,
36 PolicySettings,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct PromptCommand {
42 #[serde(rename = "type")]
43 pub command_type: String, #[serde(rename = "progressMessage")]
45 pub progress_message: String,
46 #[serde(rename = "contentLength")]
47 pub content_length: usize,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 #[serde(rename = "argNames")]
50 pub arg_names: Option<Vec<String>>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 #[serde(rename = "allowedTools")]
53 pub allowed_tools: Option<Vec<String>>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub model: Option<String>,
56 pub source: CommandSource,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 #[serde(rename = "pluginInfo")]
59 pub plugin_info: Option<PluginInfo>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 #[serde(rename = "disableNonInteractive")]
62 pub disable_non_interactive: Option<bool>,
63 #[serde(skip_serializing_if = "Option::is_none")]
65 pub hooks: Option<serde_json::Value>,
66 #[serde(skip_serializing_if = "Option::is_none")]
68 #[serde(rename = "skillRoot")]
69 pub skill_root: Option<String>,
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub context: Option<ExecutionContext>,
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub agent: Option<String>,
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub effort: Option<String>,
79 #[serde(skip_serializing_if = "Option::is_none")]
81 pub paths: Option<Vec<String>>,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
86#[serde(rename_all = "snake_case")]
87pub enum CommandSource {
88 UserSettings,
89 ProjectSettings,
90 LocalSettings,
91 PolicySettings,
92 Builtin,
93 Mcp,
94 Plugin,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct PluginInfo {
100 #[serde(rename = "pluginManifest")]
101 pub plugin_manifest: serde_json::Value,
102 pub repository: String,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
107#[serde(rename_all = "lowercase")]
108pub enum ExecutionContext {
109 Inline,
110 Fork,
111}
112
113pub type LocalCommandModule = serde_json::Value;
115
116pub struct LocalCommand {
118 pub command_type: String, pub supports_non_interactive: bool,
120 pub load: Box<
121 dyn Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = LocalCommandModule> + Send>>
122 + Send
123 + Sync,
124 >,
125}
126
127#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
129#[serde(rename_all = "snake_case")]
130pub enum ResumeEntrypoint {
131 CliFlag,
132 SlashCommandPicker,
133 SlashCommandSessionId,
134 SlashCommandTitle,
135 Fork,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
140#[serde(rename_all = "lowercase")]
141pub enum CommandResultDisplay {
142 Skip,
143 System,
144 User,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct CommandCompleteOptions {
150 #[serde(skip_serializing_if = "Option::is_none")]
152 pub display: Option<CommandResultDisplay>,
153 #[serde(skip_serializing_if = "Option::is_none")]
155 #[serde(rename = "shouldQuery")]
156 pub should_query: Option<bool>,
157 #[serde(skip_serializing_if = "Option::is_none")]
159 #[serde(rename = "metaMessages")]
160 pub meta_messages: Option<Vec<String>>,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 #[serde(rename = "nextInput")]
163 pub next_input: Option<String>,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 #[serde(rename = "submitNextInput")]
166 pub submit_next_input: Option<bool>,
167}
168
169pub type LocalJsxCommandOnDone =
171 Box<dyn Fn(Option<String>, Option<CommandCompleteOptions>) + Send + Sync>;
172
173pub type LocalJsxCommandModule = serde_json::Value;
175
176pub struct LocalJsxCommand {
178 pub command_type: String, pub load: Box<
180 dyn Fn()
181 -> std::pin::Pin<Box<dyn std::future::Future<Output = LocalJsxCommandModule> + Send>>
182 + Send
183 + Sync,
184 >,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
192#[serde(rename_all = "kebab-case")]
193pub enum CommandAvailability {
194 ClaudeAi,
196 Console,
198}
199
200pub struct CommandBase {
202 pub availability: Option<Vec<CommandAvailability>>,
203 pub description: String,
204 pub has_user_specified_description: Option<bool>,
205 pub is_enabled: Option<Box<dyn Fn() -> bool + Send + Sync>>,
207 pub is_hidden: Option<bool>,
209 pub name: String,
210 pub aliases: Option<Vec<String>>,
211 pub is_mcp: Option<bool>,
212 pub argument_hint: Option<String>,
213 pub when_to_use: Option<String>,
215 pub version: Option<String>,
217 pub disable_model_invocation: Option<bool>,
219 pub user_invocable: Option<bool>,
221 pub loaded_from: Option<CommandLoadSource>,
223 pub kind: Option<CommandKind>,
225 pub immediate: Option<bool>,
227 pub is_sensitive: Option<bool>,
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
233#[serde(rename_all = "snake_case")]
234pub enum CommandLoadSource {
235 CommandsDeprecated,
236 Skills,
237 Plugin,
238 Managed,
239 Bundled,
240 Mcp,
241}
242
243#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
245#[serde(rename_all = "lowercase")]
246pub enum CommandKind {
247 Workflow,
248}
249
250pub fn get_command_name(cmd: &CommandBase) -> &str {
252 &cmd.name
253}
254
255pub fn is_command_enabled(is_enabled: Option<&Box<dyn Fn() -> bool + Send + Sync>>) -> bool {
257 match is_enabled {
258 Some(f) => f(),
259 None => true,
260 }
261}
262
263pub enum Command {
265 Prompt {
266 base: CommandBase,
267 prompt: PromptCommand,
268 },
269 Local {
270 base: CommandBase,
271 local: LocalCommand,
272 },
273 LocalJsx {
274 base: CommandBase,
275 local_jsx: LocalJsxCommand,
276 },
277}