1use super::output::OutputFormat;
6use clap::{Args, Parser, Subcommand};
7
8#[derive(Parser)]
10#[command(name = "hivemind")]
11#[command(
12 version,
13 about,
14 long_about = "CLI-first orchestration for agentic coding workflows.\n\nStart with: docs/overview/quickstart.md"
15)]
16#[command(propagate_version = true)]
17pub struct Cli {
18 #[arg(long, short = 'f', global = true, default_value = "table")]
20 pub format: OutputFormat,
21
22 #[arg(long, short = 'v', global = true)]
24 pub verbose: bool,
25
26 #[command(subcommand)]
27 pub command: Option<Commands>,
28}
29
30#[derive(Subcommand)]
32pub enum Commands {
33 Version,
35
36 Serve(ServeArgs),
38
39 #[command(subcommand)]
41 Project(ProjectCommands),
42
43 #[command(subcommand)]
45 Task(TaskCommands),
46
47 #[command(subcommand)]
49 Graph(GraphCommands),
50
51 #[command(subcommand)]
53 Flow(FlowCommands),
54
55 #[command(subcommand)]
57 Events(EventCommands),
58
59 #[command(subcommand)]
61 Runtime(RuntimeCommands),
62
63 #[command(subcommand)]
65 Verify(VerifyCommands),
66
67 #[command(subcommand)]
69 Merge(MergeCommands),
70
71 #[command(subcommand)]
73 Attempt(AttemptCommands),
74
75 #[command(subcommand)]
77 Checkpoint(CheckpointCommands),
78
79 #[command(subcommand)]
81 Worktree(WorktreeCommands),
82}
83
84#[derive(Subcommand)]
86pub enum CheckpointCommands {
87 Complete(CheckpointCompleteArgs),
89}
90
91#[derive(Args)]
93pub struct CheckpointCompleteArgs {
94 #[arg(long)]
96 pub attempt_id: Option<String>,
97
98 #[arg(long = "id")]
100 pub checkpoint_id: String,
101
102 #[arg(long)]
104 pub summary: Option<String>,
105}
106
107#[derive(Args)]
108pub struct ServeArgs {
109 #[arg(long, default_value = "127.0.0.1")]
110 pub host: String,
111
112 #[arg(long, default_value_t = 8787)]
113 pub port: u16,
114
115 #[arg(long, default_value_t = 200)]
116 pub events_limit: usize,
117}
118
119#[derive(Subcommand)]
120pub enum WorktreeCommands {
121 List(WorktreeListArgs),
123 Inspect(WorktreeInspectArgs),
125 Cleanup(WorktreeCleanupArgs),
127}
128
129#[derive(Args)]
130pub struct WorktreeListArgs {
131 pub flow_id: String,
133}
134
135#[derive(Args)]
136pub struct WorktreeInspectArgs {
137 pub task_id: String,
139}
140
141#[derive(Args)]
142pub struct WorktreeCleanupArgs {
143 pub flow_id: String,
145}
146
147#[derive(Subcommand)]
148pub enum GraphCommands {
149 Create(GraphCreateArgs),
151 AddDependency(GraphAddDependencyArgs),
153 AddCheck(GraphAddCheckArgs),
155 Validate(GraphValidateArgs),
157 List(GraphListArgs),
159}
160
161#[derive(Args)]
162pub struct GraphCreateArgs {
163 pub project: String,
165 pub name: String,
167
168 #[arg(long, num_args = 1..)]
170 pub from_tasks: Vec<String>,
171}
172
173#[derive(Args)]
174pub struct GraphAddDependencyArgs {
175 pub graph_id: String,
177 pub from_task: String,
179 pub to_task: String,
181}
182
183#[derive(Args)]
184pub struct GraphAddCheckArgs {
185 pub graph_id: String,
187 pub task_id: String,
189
190 #[arg(long)]
192 pub name: String,
193
194 #[arg(long)]
196 pub command: String,
197
198 #[arg(long, default_value_t = true)]
200 pub required: bool,
201
202 #[arg(long)]
204 pub timeout_ms: Option<u64>,
205}
206
207#[derive(Args)]
208pub struct GraphValidateArgs {
209 pub graph_id: String,
211}
212
213#[derive(Args)]
214pub struct GraphListArgs {
215 #[arg(long)]
217 pub project: Option<String>,
218}
219
220#[derive(Subcommand)]
221pub enum FlowCommands {
222 Create(FlowCreateArgs),
224 List(FlowListArgs),
226 Start(FlowStartArgs),
228 Tick(FlowTickArgs),
230 Pause(FlowPauseArgs),
232 Resume(FlowResumeArgs),
234 Abort(FlowAbortArgs),
236 Status(FlowStatusArgs),
238}
239
240#[derive(Args)]
241pub struct FlowCreateArgs {
242 pub graph_id: String,
244 #[arg(long)]
246 pub name: Option<String>,
247}
248
249#[derive(Args)]
250pub struct FlowListArgs {
251 #[arg(long)]
253 pub project: Option<String>,
254}
255
256#[derive(Args)]
257pub struct FlowStartArgs {
258 pub flow_id: String,
260}
261
262#[derive(Args)]
263pub struct FlowTickArgs {
264 pub flow_id: String,
266
267 #[arg(long)]
269 pub interactive: bool,
270
271 #[arg(long)]
273 pub max_parallel: Option<u16>,
274}
275
276#[derive(Args)]
277pub struct FlowPauseArgs {
278 pub flow_id: String,
280 #[arg(long)]
282 pub wait: bool,
283}
284
285#[derive(Args)]
286pub struct FlowResumeArgs {
287 pub flow_id: String,
289}
290
291#[derive(Args)]
292pub struct FlowAbortArgs {
293 pub flow_id: String,
295 #[arg(long)]
296 pub force: bool,
297 #[arg(long)]
298 pub reason: Option<String>,
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
302pub enum TaskRetryMode {
303 Clean,
304 Continue,
305}
306
307#[derive(Args)]
308pub struct TaskRetryArgs {
309 pub task_id: String,
310 #[arg(long)]
311 pub reset_count: bool,
312 #[arg(long, value_enum, default_value_t = TaskRetryMode::Clean)]
313 pub mode: TaskRetryMode,
314}
315
316#[derive(Args)]
317pub struct TaskAbortArgs {
318 pub task_id: String,
320 #[arg(long)]
322 pub reason: Option<String>,
323}
324
325#[derive(Args)]
326pub struct FlowStatusArgs {
327 pub flow_id: String,
329}
330
331#[derive(Subcommand)]
333pub enum ProjectCommands {
334 Create(ProjectCreateArgs),
336
337 List,
339
340 Inspect(ProjectInspectArgs),
342
343 Update(ProjectUpdateArgs),
345
346 RuntimeSet(ProjectRuntimeSetArgs),
348
349 AttachRepo(AttachRepoArgs),
351
352 DetachRepo(DetachRepoArgs),
354}
355
356#[derive(Args)]
358pub struct ProjectCreateArgs {
359 pub name: String,
361
362 #[arg(long, short = 'd')]
364 pub description: Option<String>,
365}
366
367#[derive(Args)]
368pub struct ProjectRuntimeSetArgs {
369 pub project: String,
371
372 #[arg(long, default_value = "opencode")]
374 pub adapter: String,
375
376 #[arg(long, default_value = "opencode")]
378 pub binary_path: String,
379
380 #[arg(long)]
382 pub model: Option<String>,
383
384 #[arg(long = "arg", allow_hyphen_values = true)]
386 pub args: Vec<String>,
387
388 #[arg(long = "env")]
391 pub env: Vec<String>,
392
393 #[arg(long, default_value = "600000")]
395 pub timeout_ms: u64,
396
397 #[arg(long, default_value_t = 1)]
399 pub max_parallel_tasks: u16,
400}
401
402#[derive(Args)]
404pub struct ProjectInspectArgs {
405 pub project: String,
407}
408
409#[derive(Args)]
411pub struct ProjectUpdateArgs {
412 pub project: String,
414
415 #[arg(long)]
417 pub name: Option<String>,
418
419 #[arg(long, short = 'd')]
421 pub description: Option<String>,
422}
423
424#[derive(Args)]
426pub struct AttachRepoArgs {
427 pub project: String,
429
430 pub path: String,
432
433 #[arg(long)]
435 pub name: Option<String>,
436
437 #[arg(long, default_value = "rw")]
439 pub access: String,
440}
441
442#[derive(Args)]
444pub struct DetachRepoArgs {
445 pub project: String,
447
448 pub repo_name: String,
450}
451
452#[derive(Subcommand)]
454pub enum TaskCommands {
455 Create(TaskCreateArgs),
457
458 List(TaskListArgs),
460
461 Inspect(TaskInspectArgs),
463
464 Update(TaskUpdateArgs),
466
467 RuntimeSet(TaskRuntimeSetArgs),
469
470 Close(TaskCloseArgs),
472
473 Start(TaskStartArgs),
475 Complete(TaskCompleteArgs),
477
478 Retry(TaskRetryArgs),
480 Abort(TaskAbortArgs),
482}
483
484#[derive(Args)]
485pub struct TaskStartArgs {
486 pub task_id: String,
488}
489
490#[derive(Args)]
491pub struct TaskCompleteArgs {
492 pub task_id: String,
494}
495
496#[derive(Args)]
498pub struct TaskCreateArgs {
499 pub project: String,
501
502 pub title: String,
504
505 #[arg(long, short = 'd')]
507 pub description: Option<String>,
508
509 #[arg(long)]
512 pub scope: Option<String>,
513}
514
515#[derive(Args)]
517pub struct TaskListArgs {
518 pub project: String,
520
521 #[arg(long)]
523 pub state: Option<String>,
524}
525
526#[derive(Args)]
528pub struct TaskInspectArgs {
529 pub task_id: String,
531}
532
533#[derive(Args)]
535pub struct TaskUpdateArgs {
536 pub task_id: String,
538
539 #[arg(long)]
541 pub title: Option<String>,
542
543 #[arg(long, short = 'd')]
545 pub description: Option<String>,
546}
547
548#[derive(Args)]
550pub struct TaskRuntimeSetArgs {
551 pub task_id: String,
553
554 #[arg(long)]
556 pub clear: bool,
557
558 #[arg(long, default_value = "opencode")]
560 pub adapter: String,
561
562 #[arg(long, default_value = "opencode")]
564 pub binary_path: String,
565
566 #[arg(long)]
568 pub model: Option<String>,
569
570 #[arg(long = "arg", allow_hyphen_values = true)]
572 pub args: Vec<String>,
573
574 #[arg(long = "env")]
576 pub env: Vec<String>,
577
578 #[arg(long, default_value = "600000")]
580 pub timeout_ms: u64,
581}
582
583#[derive(Subcommand)]
585pub enum RuntimeCommands {
586 List,
588 Health(RuntimeHealthArgs),
590}
591
592#[derive(Args)]
594pub struct RuntimeHealthArgs {
595 #[arg(long)]
597 pub project: Option<String>,
598
599 #[arg(long)]
601 pub task: Option<String>,
602}
603
604#[derive(Args)]
606pub struct TaskCloseArgs {
607 pub task_id: String,
609
610 #[arg(long)]
612 pub reason: Option<String>,
613}
614
615#[derive(Subcommand)]
617pub enum EventCommands {
618 List(EventListArgs),
620
621 Inspect(EventInspectArgs),
623
624 Stream(EventStreamArgs),
626
627 Replay(EventReplayArgs),
629}
630
631#[derive(Args)]
633pub struct EventListArgs {
634 #[arg(long)]
636 pub project: Option<String>,
637
638 #[arg(long)]
640 pub graph: Option<String>,
641
642 #[arg(long)]
644 pub flow: Option<String>,
645
646 #[arg(long)]
648 pub task: Option<String>,
649
650 #[arg(long)]
652 pub attempt: Option<String>,
653
654 #[arg(long)]
656 pub since: Option<String>,
657
658 #[arg(long)]
660 pub until: Option<String>,
661
662 #[arg(long, default_value = "50")]
664 pub limit: usize,
665}
666
667#[derive(Args)]
669pub struct EventInspectArgs {
670 pub event_id: String,
672}
673
674#[derive(Args)]
676pub struct EventStreamArgs {
677 #[arg(long)]
679 pub flow: Option<String>,
680
681 #[arg(long)]
683 pub task: Option<String>,
684
685 #[arg(long)]
687 pub project: Option<String>,
688
689 #[arg(long)]
691 pub graph: Option<String>,
692
693 #[arg(long)]
695 pub attempt: Option<String>,
696
697 #[arg(long)]
699 pub since: Option<String>,
700
701 #[arg(long)]
703 pub until: Option<String>,
704
705 #[arg(long, default_value = "100")]
707 pub limit: usize,
708}
709
710#[derive(Args)]
712pub struct EventReplayArgs {
713 pub flow_id: String,
715
716 #[arg(long)]
718 pub verify: bool,
719}
720
721#[derive(Subcommand)]
723pub enum VerifyCommands {
724 Override(VerifyOverrideArgs),
726
727 Run(VerifyRunArgs),
729
730 Results(VerifyResultsArgs),
732}
733
734#[derive(Args)]
736pub struct VerifyOverrideArgs {
737 pub task_id: String,
739
740 pub decision: String,
742
743 #[arg(long)]
745 pub reason: String,
746}
747
748#[derive(Args)]
749pub struct VerifyRunArgs {
750 pub task_id: String,
752}
753
754#[derive(Args)]
755pub struct VerifyResultsArgs {
756 pub attempt_id: String,
758
759 #[arg(long)]
761 pub output: bool,
762}
763
764#[derive(Subcommand)]
766pub enum MergeCommands {
767 #[command(
768 about = "Prepare a completed flow for integration (sandbox merge)",
769 long_about = "Prepare a completed flow for merge by building an integration sandbox, applying successful task branches, and running required integration checks before approval."
770 )]
771 Prepare(MergePrepareArgs),
772
773 #[command(
774 about = "Approve a prepared merge (explicit human gate)",
775 long_about = "Record the approving HUMAN user (HIVEMIND_USER or USER), ensure no unresolved conflicts/check failures remain, and emit MergeApproved so execute can proceed."
776 )]
777 Approve(MergeApproveArgs),
778
779 #[command(
780 about = "Execute an approved merge (fast-forward target)",
781 long_about = "Acquire the per-flow integration lock and fast-forward the chosen target branch from integration/<flow>/prepare, then clean up integration/<flow>/prepare, integration/<flow>/<task>, _integration_prepare, and exec branches. Emits MergeCompleted."
782 )]
783 Execute(MergeExecuteArgs),
784}
785
786#[derive(Args)]
788pub struct MergePrepareArgs {
789 pub flow_id: String,
791
792 #[arg(long)]
794 pub target: Option<String>,
795}
796
797#[derive(Args)]
799pub struct MergeApproveArgs {
800 pub flow_id: String,
802}
803
804#[derive(Args)]
806pub struct MergeExecuteArgs {
807 pub flow_id: String,
809}
810
811#[derive(Subcommand)]
813pub enum AttemptCommands {
814 Inspect(AttemptInspectArgs),
816}
817
818#[derive(Args)]
820pub struct AttemptInspectArgs {
821 pub attempt_id: String,
823
824 #[arg(long)]
826 pub context: bool,
827
828 #[arg(long)]
830 pub diff: bool,
831
832 #[arg(long)]
834 pub output: bool,
835}