1use clap::{Parser, Subcommand};
2use std::path::PathBuf;
3
4#[derive(Parser)]
5#[command(name = "sparrow", about = "one cli · grows with you", version)]
6pub struct Cli {
7 #[command(subcommand)]
8 pub command: Option<Commands>,
9
10 #[arg(long)]
12 pub tui: bool,
13
14 #[arg(long)]
16 pub web: bool,
17
18 #[arg(long)]
20 pub json: bool,
21
22 #[arg(long)]
24 pub autonomy: Option<String>,
25
26 #[arg(long)]
28 pub model: Option<String>,
29
30 #[arg(long)]
32 pub local: bool,
33
34 #[arg(long)]
36 pub budget: Option<f64>,
37
38 #[arg(long)]
41 pub max_cost_usd: Option<f64>,
42
43 #[arg(long)]
45 pub max_wall_secs: Option<u64>,
46
47 #[arg(long)]
49 pub max_tokens: Option<u64>,
50
51 #[arg(long)]
54 pub bind: Option<String>,
55
56 #[arg(long)]
58 pub sandbox: Option<String>,
59
60 #[arg(long)]
62 pub profile: Option<String>,
63
64 #[arg(long)]
66 pub no_checkpoint: bool,
67
68 #[arg(long)]
70 pub agent: Option<String>,
71}
72
73#[derive(Subcommand)]
74pub enum Commands {
75 Run {
77 task: String,
79
80 #[arg(long)]
83 json: bool,
84 },
85
86 Plan {
88 task: String,
90
91 #[arg(long)]
93 json: bool,
94 },
95
96 Chat,
98
99 Tui,
101
102 Launch {
104 #[arg(long, default_value = "9339")]
106 port: u16,
107
108 #[arg(long)]
110 tui: bool,
111 },
112
113 Console {
115 #[arg(long, default_value = "9339")]
117 port: u16,
118 },
119
120 Daemon,
122
123 Agent {
125 #[command(subcommand)]
126 action: AgentAction,
127 },
128
129 Swarm {
131 task: String,
133 },
134
135 Schedule {
137 task: String,
139
140 #[arg(long)]
142 cron: String,
143
144 #[arg(long)]
146 autonomy: Option<String>,
147
148 #[arg(long)]
150 report: Vec<String>,
151 },
152
153 Model {
155 #[arg(long)]
157 set: Option<String>,
158
159 #[arg(long)]
161 list: bool,
162 },
163
164 Route {
166 #[command(subcommand)]
167 action: RouteAction,
168 },
169
170 Auth {
172 #[command(subcommand)]
173 action: AuthAction,
174 },
175
176 Skills {
178 #[command(subcommand)]
179 action: SkillsAction,
180 },
181
182 Plugins {
184 #[command(subcommand)]
185 action: PluginsAction,
186 },
187
188 Tools {
190 #[command(subcommand)]
191 action: ToolsAction,
192 },
193
194 Security {
196 #[command(subcommand)]
197 action: SecurityAction,
198 },
199
200 Github {
202 #[command(subcommand)]
203 action: GithubAction,
204 },
205
206 Compact {
208 #[arg(long)]
210 task: Option<String>,
211 #[arg(long)]
213 out: Option<PathBuf>,
214 #[arg(long)]
216 json: bool,
217 },
218
219 Mcp {
221 #[command(subcommand)]
222 action: McpAction,
223 },
224
225 Checkpoint {
227 #[command(subcommand)]
228 action: CheckpointAction,
229 },
230
231 Rewind {
233 id: String,
235 },
236
237 Replay {
239 run_id: String,
241 #[arg(long)]
243 scrub: bool,
244 },
245
246 Gateway {
248 #[command(subcommand)]
249 action: GatewayAction,
250 },
251
252 Sessions {
254 #[command(subcommand)]
255 action: SessionAction,
256 },
257
258 Learn,
260
261 Init,
263
264 Status,
266
267 Memory {
269 #[command(subcommand)]
270 action: MemoryAction,
271 },
272
273 Permissions {
275 #[command(subcommand)]
276 action: PermissionAction,
277 },
278
279 Profile {
281 #[command(subcommand)]
282 action: ProfileAction,
283 },
284
285 Import {
287 #[command(subcommand)]
288 source: ImportSource,
289 },
290
291 Config {
293 #[arg(short)]
295 edit: bool,
296 },
297
298 Update,
300
301 Doctor,
303
304 Setup,
306
307 Demo,
309
310 Share,
312
313 Hook {
315 #[command(subcommand)]
316 action: HookAction,
317 },
318
319 Voice {
321 #[command(subcommand)]
322 action: VoiceAction,
323 },
324}
325
326#[derive(Subcommand)]
327pub enum AgentAction {
328 Create { name: String },
329 List,
330 Edit { name: String },
331 Rm { name: String },
332 Run { name: String, task: String },
333 Mention { name: String, message: String },
334}
335
336#[derive(Subcommand)]
337pub enum AuthAction {
338 Add {
339 provider: String,
340 },
341 List,
342 Rm {
343 provider: String,
344 },
345 Login {
347 provider: String,
348 #[arg(long)]
350 client_id: Option<String>,
351 },
352}
353
354#[derive(Subcommand)]
355pub enum SkillsAction {
356 List,
357 View {
358 name: String,
359 },
360 Create {
361 name: String,
362 },
363 Install {
364 source: String,
365 },
366 Update {
367 name: String,
368 },
369 Prune,
370 Rm {
372 name: String,
373 },
374}
375
376#[derive(Subcommand)]
377pub enum PluginsAction {
378 List,
379 Install {
380 source: String,
381 #[arg(long)]
382 allow: bool,
383 },
384 Rm {
385 name: String,
386 },
387}
388
389#[derive(Subcommand)]
390pub enum GithubAction {
391 Review {
393 pr: u64,
395 #[arg(long)]
397 dry_run: bool,
398 #[arg(long)]
400 model: Option<String>,
401 #[arg(long)]
403 allowed_tools: Option<String>,
404 },
405 Status,
407 Logs { run_id: String },
409}
410
411#[derive(Subcommand)]
412pub enum SecurityAction {
413 Audit {
415 #[arg(long)]
417 json: bool,
418 },
419}
420
421#[derive(Subcommand)]
422pub enum ToolsAction {
423 List {
424 #[arg(long)]
425 surface: Option<String>,
426 },
427 Enable {
428 tool: String,
429 },
430 Disable {
431 tool: String,
432 },
433}
434
435#[derive(Subcommand)]
436pub enum McpAction {
437 Add {
438 server: String,
439
440 #[arg(long)]
442 command: Option<String>,
443
444 #[arg(long, value_delimiter = ' ', allow_hyphen_values = true)]
446 args: Vec<String>,
447
448 #[arg(long)]
450 transport: Option<String>,
451 },
452 List,
453 Rm {
454 server: String,
455 },
456}
457
458#[derive(Subcommand)]
459pub enum CheckpointAction {
460 List,
462 Diff {
464 id: String,
466 },
467 Prune {
469 #[arg(long, default_value = "30")]
471 older_than_days: u64,
472 },
473}
474
475#[derive(Subcommand)]
476pub enum GatewayAction {
477 Start,
478 Status,
479 Health,
480 Abort { run: String },
481 Stop,
482}
483
484#[derive(Subcommand)]
485pub enum SessionAction {
486 List,
487 Export {
488 id: String,
489 path: Option<PathBuf>,
490 },
491 Cleanup {
492 #[arg(long, default_value_t = 30)]
493 older_than_days: u64,
494 },
495}
496
497#[derive(Subcommand)]
498pub enum ProfileAction {
499 Create { name: String },
500 List,
501 Use { name: String },
502}
503
504#[derive(Subcommand)]
505pub enum ImportSource {
506 Openclaw { path: Option<PathBuf> },
507}
508
509#[derive(Subcommand)]
510pub enum MemoryAction {
511 List,
512 Forget {
513 id: String,
514 },
515 Add {
516 key: String,
517 value: String,
518 },
519 Replace {
520 id: String,
521 key: String,
522 value: String,
523 },
524 Recall {
525 query: String,
526 #[arg(long, default_value_t = 10)]
527 limit: usize,
528 },
529 Consolidate,
530 Docs,
531 Search {
532 query: String,
533 #[arg(long, default_value_t = 10)]
534 limit: usize,
535 },
536 Scroll {
537 session: String,
538 #[arg(long, default_value_t = 0)]
539 around: usize,
540 #[arg(long, default_value_t = 3)]
541 before: usize,
542 #[arg(long, default_value_t = 3)]
543 after: usize,
544 },
545 Graph {
546 #[command(subcommand)]
547 action: GraphAction,
548 },
549}
550
551#[derive(Subcommand)]
552pub enum GraphAction {
553 UpsertNode {
554 id: String,
555 label: String,
556 #[arg(long, default_value = "entity")]
557 kind: String,
558 #[arg(long, default_value = "{}")]
559 properties: String,
560 },
561 UpsertEdge {
562 from_id: String,
563 relation: String,
564 to_id: String,
565 #[arg(long)]
566 id: Option<String>,
567 #[arg(long, default_value_t = 1.0)]
568 weight: f64,
569 #[arg(long, default_value = "{}")]
570 properties: String,
571 },
572 Get {
573 id: String,
574 },
575 Neighbors {
576 id: String,
577 #[arg(long, default_value = "both")]
578 direction: String,
579 #[arg(long, default_value_t = 20)]
580 limit: usize,
581 },
582 Search {
583 query: String,
584 #[arg(long, default_value_t = 20)]
585 limit: usize,
586 },
587 Export,
588 DeleteNode {
589 id: String,
590 },
591 DeleteEdge {
592 id: String,
593 },
594 SyncNeo4j,
595}
596
597#[derive(Subcommand)]
598pub enum PermissionAction {
599 List,
601 Set { mode: String },
603 AllowTool { tool: String },
605 AskTool { tool: String },
607 DenyTool { tool: String },
609 AllowPath { path: PathBuf },
611 DenyPath { path: PathBuf },
613}
614
615#[derive(Subcommand)]
616pub enum RouteAction {
617 Set {
620 provider: String,
622 },
623 Clear,
625 Show,
627}
628
629#[derive(Subcommand)]
630pub enum HookAction {
631 Install,
633 Scan {
635 #[arg(long)]
637 all: bool,
638 },
639}
640
641#[derive(Subcommand)]
642pub enum VoiceAction {
643 Speak { text: String },
645 Transcribe { file: String },
647 Providers,
649}