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 Browser {
327 #[arg(default_value = "https://example.com")]
329 url: String,
330 },
331}
332
333#[derive(Subcommand)]
334pub enum AgentAction {
335 Create { name: String },
336 List,
337 Edit { name: String },
338 Rm { name: String },
339 Run { name: String, task: String },
340 Mention { name: String, message: String },
341}
342
343#[derive(Subcommand)]
344pub enum AuthAction {
345 Add {
346 provider: String,
347 },
348 List,
349 Rm {
350 provider: String,
351 },
352 Login {
354 provider: String,
355 #[arg(long)]
357 client_id: Option<String>,
358 },
359}
360
361#[derive(Subcommand)]
362pub enum SkillsAction {
363 List,
364 View {
365 name: String,
366 },
367 Create {
368 name: String,
369 },
370 Install {
371 source: String,
372 },
373 Update {
374 name: String,
375 },
376 Prune,
377 Rm {
379 name: String,
380 },
381}
382
383#[derive(Subcommand)]
384pub enum PluginsAction {
385 List,
386 Install {
387 source: String,
388 #[arg(long)]
389 allow: bool,
390 },
391 Rm {
392 name: String,
393 },
394}
395
396#[derive(Subcommand)]
397pub enum GithubAction {
398 Review {
400 pr: u64,
402 #[arg(long)]
404 dry_run: bool,
405 #[arg(long)]
407 model: Option<String>,
408 #[arg(long)]
410 allowed_tools: Option<String>,
411 },
412 Status,
414 Logs { run_id: String },
416}
417
418#[derive(Subcommand)]
419pub enum SecurityAction {
420 Audit {
422 #[arg(long)]
424 json: bool,
425 },
426}
427
428#[derive(Subcommand)]
429pub enum ToolsAction {
430 List {
431 #[arg(long)]
432 surface: Option<String>,
433 },
434 Enable {
435 tool: String,
436 },
437 Disable {
438 tool: String,
439 },
440}
441
442#[derive(Subcommand)]
443pub enum McpAction {
444 Add {
445 server: String,
446
447 #[arg(long)]
449 command: Option<String>,
450
451 #[arg(long, value_delimiter = ' ', allow_hyphen_values = true)]
453 args: Vec<String>,
454
455 #[arg(long)]
457 transport: Option<String>,
458 },
459 List,
460 Rm {
461 server: String,
462 },
463}
464
465#[derive(Subcommand)]
466pub enum CheckpointAction {
467 List,
469 Diff {
471 id: String,
473 },
474 Prune {
476 #[arg(long, default_value = "30")]
478 older_than_days: u64,
479 },
480}
481
482#[derive(Subcommand)]
483pub enum GatewayAction {
484 Start,
485 Status,
486 Health,
487 Abort { run: String },
488 Stop,
489}
490
491#[derive(Subcommand)]
492pub enum SessionAction {
493 List,
494 Export {
495 id: String,
496 path: Option<PathBuf>,
497 },
498 Cleanup {
499 #[arg(long, default_value_t = 30)]
500 older_than_days: u64,
501 },
502 Search {
504 query: String,
505 #[arg(long, default_value_t = 10)]
506 limit: usize,
507 },
508}
509
510#[derive(Subcommand)]
511pub enum ProfileAction {
512 Create { name: String },
513 List,
514 Use { name: String },
515}
516
517#[derive(Subcommand)]
518pub enum ImportSource {
519 Openclaw { path: Option<PathBuf> },
520}
521
522#[derive(Subcommand)]
523pub enum MemoryAction {
524 List,
525 Forget {
526 id: String,
527 },
528 Add {
529 key: String,
530 value: String,
531 },
532 Replace {
533 id: String,
534 key: String,
535 value: String,
536 },
537 Recall {
538 query: String,
539 #[arg(long, default_value_t = 10)]
540 limit: usize,
541 },
542 Consolidate,
543 Docs,
544 Search {
545 query: String,
546 #[arg(long, default_value_t = 10)]
547 limit: usize,
548 },
549 Scroll {
550 session: String,
551 #[arg(long, default_value_t = 0)]
552 around: usize,
553 #[arg(long, default_value_t = 3)]
554 before: usize,
555 #[arg(long, default_value_t = 3)]
556 after: usize,
557 },
558 Graph {
559 #[command(subcommand)]
560 action: GraphAction,
561 },
562}
563
564#[derive(Subcommand)]
565pub enum GraphAction {
566 UpsertNode {
567 id: String,
568 label: String,
569 #[arg(long, default_value = "entity")]
570 kind: String,
571 #[arg(long, default_value = "{}")]
572 properties: String,
573 },
574 UpsertEdge {
575 from_id: String,
576 relation: String,
577 to_id: String,
578 #[arg(long)]
579 id: Option<String>,
580 #[arg(long, default_value_t = 1.0)]
581 weight: f64,
582 #[arg(long, default_value = "{}")]
583 properties: String,
584 },
585 Get {
586 id: String,
587 },
588 Neighbors {
589 id: String,
590 #[arg(long, default_value = "both")]
591 direction: String,
592 #[arg(long, default_value_t = 20)]
593 limit: usize,
594 },
595 Search {
596 query: String,
597 #[arg(long, default_value_t = 20)]
598 limit: usize,
599 },
600 Export,
601 DeleteNode {
602 id: String,
603 },
604 DeleteEdge {
605 id: String,
606 },
607 SyncNeo4j,
608}
609
610#[derive(Subcommand)]
611pub enum PermissionAction {
612 List,
614 Set { mode: String },
616 AllowTool { tool: String },
618 AskTool { tool: String },
620 DenyTool { tool: String },
622 AllowPath { path: PathBuf },
624 DenyPath { path: PathBuf },
626}
627
628#[derive(Subcommand)]
629pub enum RouteAction {
630 Set {
633 provider: String,
635 },
636 Clear,
638 Show,
640}
641
642#[derive(Subcommand)]
643pub enum HookAction {
644 Install,
646 Scan {
648 #[arg(long)]
650 all: bool,
651 },
652}
653
654#[derive(Subcommand)]
655pub enum VoiceAction {
656 Speak { text: String },
658 Transcribe { file: String },
660 Providers,
662}