1use clap::Parser;
6
7#[derive(Parser, Debug, Default)]
9pub struct VerbosityShorthand {
10 #[arg(
12 short,
13 long,
14 conflicts_with = "verbosity",
15 help = "Quiet mode (same as -v0)"
16 )]
17 pub quiet: bool,
18
19 #[arg(
21 long,
22 short,
23 conflicts_with = "verbosity",
24 help = "Full output mode, no truncation (same as -v3)"
25 )]
26 pub full: bool,
27}
28
29#[derive(Parser, Debug, Default)]
31pub struct DebugVerbosity {
32 #[arg(
34 long,
35 conflicts_with = "verbosity",
36 help = "Debug mode (same as -v4)",
37 hide = true
38 )]
39 pub debug: bool,
40}
41
42#[derive(Parser, Debug, Default)]
44pub struct QuickPresets {
45 #[arg(
47 long,
48 short = 'Q',
49 help = "Quick mode: 1 dev iteration + 1 review (for rapid prototyping)"
50 )]
51 pub quick: bool,
52
53 #[arg(
55 long,
56 short = 'U',
57 help = "Rapid mode: 2 dev iterations + 1 review (fast but more thorough than quick)"
58 )]
59 pub rapid: bool,
60
61 #[arg(
63 long,
64 short = 'L',
65 help = "Long mode: 15 dev iterations + 10 reviews (for thorough development)"
66 )]
67 pub long: bool,
68}
69
70#[derive(Parser, Debug, Default)]
72pub struct StandardPresets {
73 #[arg(
75 long,
76 short = 'S',
77 help = "Standard mode: 5 dev iterations + 2 reviews (default workflow)"
78 )]
79 pub standard: bool,
80
81 #[arg(
83 long,
84 short = 'T',
85 help = "Thorough mode: 10 dev iterations + 5 reviews (balanced but thorough)"
86 )]
87 pub thorough: bool,
88}
89
90#[derive(Parser, Debug, Default)]
92pub struct UnifiedInitFlags {
93 #[arg(
115 long,
116 conflicts_with_all = ["init_global", "init_config", "init_legacy", "init_prompt"],
117 help = "Smart init: create config or PROMPT.md (infers from current state)",
118 value_name = "TEMPLATE",
119 num_args = 0..=1,
120 default_missing_value = "",
121 )]
124 pub init: Option<String>,
125
126 #[arg(
128 long = "force-overwrite",
129 visible_alias = "overwrite",
130 help = "Overwrite existing PROMPT.md without prompting (use with --init or --init-prompt)",
131 hide = true
132 )]
133 pub force_init: bool,
134
135 #[arg(
137 long,
138 conflicts_with_all = ["init", "init_global", "init_legacy", "init_prompt"],
139 help = "Create ~/.config/ralph-workflow.toml with default settings (recommended)",
140 hide = true
141 )]
142 pub init_config: bool,
143
144 #[arg(
146 long,
147 conflicts_with_all = ["init", "init_config", "init_legacy", "init_prompt"],
148 help = "Create ~/.config/ralph-workflow.toml with default settings (recommended)",
149 hide = true
150 )]
151 pub init_global: bool,
152}
153
154#[derive(Parser, Debug, Default)]
156pub struct LegacyInitFlag {
157 #[arg(
159 long,
160 conflicts_with_all = ["init", "init_global", "init_prompt"],
161 help = "(Legacy) Create .agent/agents.toml with default settings (not recommended)",
162 hide = true
163 )]
164 pub init_legacy: bool,
165}
166
167#[derive(Parser, Debug, Default)]
169pub struct AgentListFlags {
170 #[arg(
172 long,
173 help = "Show all agents from registry and config file",
174 hide = true
175 )]
176 pub list_agents: bool,
177
178 #[arg(
180 long,
181 help = "Show only agents that are installed and available",
182 hide = true
183 )]
184 pub list_available_agents: bool,
185}
186
187#[derive(Parser, Debug, Default)]
189pub struct ProviderListFlag {
190 #[arg(
192 long,
193 help = "Show OpenCode provider types with model prefixes and auth commands",
194 hide = true
195 )]
196 pub list_providers: bool,
197}
198
199#[derive(Parser, Debug, Default)]
201pub struct CompletionFlag {
202 #[arg(
204 long,
205 value_name = "SHELL",
206 value_enum,
207 help = "Generate shell completion script (bash, zsh, fish, elvish, powershell)",
208 hide = true
209 )]
210 pub generate_completion: Option<Shell>,
211}
212
213#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
215pub enum Shell {
216 Bash,
218 Zsh,
220 Fish,
222 Elvish,
224 Pwsh,
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum, Default)]
230pub enum RecoveryStrategyArg {
231 #[default]
233 Fail,
234 Auto,
236 Force,
238}
239
240impl From<RecoveryStrategyArg> for crate::checkpoint::recovery::RecoveryStrategy {
241 fn from(arg: RecoveryStrategyArg) -> Self {
242 match arg {
243 RecoveryStrategyArg::Fail => Self::Fail,
244 RecoveryStrategyArg::Auto => Self::Auto,
245 RecoveryStrategyArg::Force => Self::Force,
246 }
247 }
248}
249
250#[derive(Parser, Debug, Default)]
252pub struct WorkGuideListFlag {
253 #[arg(
255 long = "list-work-guides",
256 visible_alias = "list-templates",
257 help = "Show all available Work Guides for PROMPT.md"
258 )]
259 pub list_work_guides: bool,
260}
261
262#[derive(Parser, Debug, Default)]
264pub struct TemplateCommands {
265 #[arg(
267 long = "init-system-prompts",
268 alias = "init-templates",
269 help = "Create ~/.config/ralph/templates/ with default Agent Prompts (backend AI behavior configuration, NOT Work Guides for PROMPT.md)",
270 default_missing_value = "false",
271 num_args = 0..=1,
272 require_equals = true,
273 hide = true
274 )]
275 pub init_templates: Option<bool>,
276
277 #[arg(
279 long,
280 requires = "init_templates",
281 help = "Overwrite existing system prompt templates during init (use with caution)",
282 hide = true
283 )]
284 pub force: bool,
285
286 #[arg(
288 long,
289 help = "Validate all Agent Prompt templates for syntax errors",
290 hide = true
291 )]
292 pub validate: bool,
293
294 #[arg(
296 long,
297 value_name = "NAME",
298 help = "Show Agent Prompt template content and metadata",
299 hide = true
300 )]
301 pub show: Option<String>,
302
303 #[arg(
305 long,
306 help = "List all Agent Prompt templates with their variables",
307 hide = true
308 )]
309 pub list: bool,
310
311 #[arg(
313 long,
314 help = "List all Agent Prompt templates including deprecated ones"
315 )]
316 pub list_all: bool,
317
318 #[arg(
320 long,
321 value_name = "NAME",
322 help = "Extract variables from an Agent Prompt template",
323 hide = true
324 )]
325 pub variables: Option<String>,
326
327 #[arg(
329 long,
330 value_name = "NAME",
331 help = "Test render a system prompt template with provided variables",
332 hide = true
333 )]
334 pub render: Option<String>,
335}
336
337impl TemplateCommands {
338 pub const fn init_templates_enabled(&self) -> bool {
340 self.init_templates.is_some()
341 }
342}
343
344#[derive(Parser, Debug, Default)]
346pub struct CommitPlumbingFlags {
347 #[arg(
349 long,
350 help = "Run only the commit message generation phase, then exit",
351 hide = true
352 )]
353 pub generate_commit_msg: bool,
354
355 #[arg(
357 long,
358 help = "Stage all changes and commit using .agent/commit-message.txt",
359 hide = true
360 )]
361 pub apply_commit: bool,
362}
363
364#[derive(Parser, Debug, Default)]
368pub struct CommitDisplayFlags {
369 #[arg(long, help = "Read and display .agent/commit-message.txt", hide = true)]
371 pub show_commit_msg: bool,
372
373 #[arg(
375 long,
376 help = "Reset .agent/start_commit to merge-base with main branch (for incremental diff generation)",
377 hide = true
378 )]
379 pub reset_start_commit: bool,
380
381 #[arg(long, help = "Show current review baseline and start commit state")]
384 pub show_baseline: bool,
385}
386
387#[derive(Parser, Debug, Default)]
389pub struct RecoveryFlags {
390 #[arg(
392 long,
393 help = "Resume from last checkpoint (if one exists from a previous interrupted run)",
394 hide = true
395 )]
396 pub resume: bool,
397
398 #[arg(
400 long = "no-resume",
401 help = "Skip interactive resume prompt even if a checkpoint exists (for CI/automation)",
402 hide = true
403 )]
404 pub no_resume: bool,
405
406 #[arg(
408 long = "inspect-checkpoint",
409 help = "Display checkpoint information without resuming (use with --resume to see saved state)",
410 hide = true
411 )]
412 pub inspect_checkpoint: bool,
413
414 #[arg(
416 long,
417 value_enum,
418 default_value = "fail",
419 help = "Recovery strategy when checkpoint validation fails (fail=stop, auto=attempt recovery, force=continue anyway)"
420 )]
421 pub recovery_strategy: RecoveryStrategyArg,
422
423 #[arg(
425 long,
426 help = "Validate configuration and PROMPT.md without running agents",
427 hide = true
428 )]
429 pub dry_run: bool,
430
431 #[arg(
433 long,
434 short = 'd',
435 help = "Show system info, agent status, and config for troubleshooting"
436 )]
437 pub diagnose: bool,
438
439 #[arg(
441 long = "extended-help",
442 visible_alias = "man",
443 help = "Show extended help with shell completion, all presets, and troubleshooting"
444 )]
445 pub extended_help: bool,
446}
447
448#[derive(Parser, Debug, Default)]
450pub struct RebaseFlags {
451 #[arg(
457 long,
458 help = "Enable automatic rebase to main branch before and after pipeline"
459 )]
460 pub with_rebase: bool,
461
462 #[arg(
464 long,
465 help = "Only rebase to main branch, then exit (no pipeline execution)",
466 hide = true
467 )]
468 pub rebase_only: bool,
469
470 #[arg(
472 long,
473 help = "Skip automatic rebase to main branch before and after pipeline",
474 hide = true
475 )]
476 #[deprecated(
477 since = "0.4.2",
478 note = "Rebase is now disabled by default; use --with-rebase to enable"
479 )]
480 pub skip_rebase: bool,
481}
482
483#[derive(Parser, Debug, Default)]
485#[command(name = "ralph")]
486#[command(about = "PROMPT-driven multi-agent orchestrator for git repos")]
487#[command(
488 long_about = "Ralph orchestrates AI coding agents to implement changes based on PROMPT.md.\n\n\
489 It runs a developer agent for code implementation, then a reviewer agent for\n\
490 quality assurance, automatically staging and committing the final result."
491)]
492#[command(version)]
493#[command(after_help = "GETTING STARTED:\n\
494 ralph --init Smart init (infers what you need)\n\
495 ralph --init <work-guide> Create PROMPT.md from a Work Guide\n\
496 ralph \"fix: my bug\" Run the orchestrator\n\
497\n\
498More help: ralph --extended-help (shell completion, all presets, troubleshooting)")]
499pub struct Args {
502 #[command(flatten)]
504 pub verbosity_shorthand: VerbosityShorthand,
505
506 #[command(flatten)]
508 pub debug_verbosity: DebugVerbosity,
509
510 #[command(flatten)]
512 pub quick_presets: QuickPresets,
513
514 #[command(flatten)]
516 pub standard_presets: StandardPresets,
517
518 #[command(flatten)]
520 pub unified_init: UnifiedInitFlags,
521
522 #[command(flatten)]
524 pub legacy_init: LegacyInitFlag,
525
526 #[command(flatten)]
528 pub agent_list: AgentListFlags,
529
530 #[command(flatten)]
532 pub provider_list: ProviderListFlag,
533
534 #[command(flatten)]
536 pub completion: CompletionFlag,
537
538 #[command(flatten)]
540 pub work_guide_list: WorkGuideListFlag,
541
542 #[command(flatten)]
544 pub template_commands: TemplateCommands,
545
546 #[command(flatten)]
548 pub commit_plumbing: CommitPlumbingFlags,
549
550 #[command(flatten)]
552 pub commit_display: CommitDisplayFlags,
553
554 #[command(flatten)]
556 pub recovery: RecoveryFlags,
557
558 #[command(flatten)]
560 pub rebase_flags: RebaseFlags,
561
562 #[arg(
564 default_value = "chore: apply PROMPT loop + review/fix/review",
565 help = "Commit message for the final commit"
566 )]
567 pub commit_msg: String,
568
569 #[arg(
571 long = "developer-iters",
572 short = 'D',
573 env = "RALPH_DEVELOPER_ITERS",
574 value_name = "N",
575 help = "Number of developer agent iterations",
576 aliases = ["developer-iteration", "dev-iter", "d-iters"]
577 )]
578 pub developer_iters: Option<u32>,
579
580 #[arg(
582 long = "reviewer-reviews",
583 short = 'R',
584 env = "RALPH_REVIEWER_REVIEWS",
585 value_name = "N",
586 help = "Number of review-fix cycles (0=skip review, 1=one cycle, default: 2)",
587 aliases = ["reviewer-count", "reviewer-review"]
588 )]
589 pub reviewer_reviews: Option<u32>,
590
591 #[arg(
593 long,
594 env = "RALPH_PRESET",
595 value_name = "NAME",
596 help = "Use a preset agent combination (default, opencode)",
597 hide = true
598 )]
599 pub preset: Option<super::presets::Preset>,
600
601 #[arg(
603 long,
604 short = 'a',
605 env = "RALPH_DEVELOPER_AGENT",
606 aliases = ["driver-agent", "dev-agent", "developer"],
607 value_name = "AGENT",
608 help = "Developer agent for code implementation (default: first in agent_chain.developer)"
609 )]
610 pub developer_agent: Option<String>,
611
612 #[arg(
614 long,
615 short = 'r',
616 env = "RALPH_REVIEWER_AGENT",
617 aliases = ["rev-agent", "reviewer"],
618 value_name = "AGENT",
619 help = "Reviewer agent for code review (default: first in agent_chain.reviewer)"
620 )]
621 pub reviewer_agent: Option<String>,
622
623 #[arg(
625 long,
626 env = "RALPH_DEVELOPER_MODEL",
627 value_name = "MODEL_FLAG",
628 help = "Model flag for developer agent (e.g., '-m opencode/glm-4.7-free')",
629 hide = true
630 )]
631 pub developer_model: Option<String>,
632
633 #[arg(
635 long,
636 env = "RALPH_REVIEWER_MODEL",
637 value_name = "MODEL_FLAG",
638 help = "Model flag for reviewer agent (e.g., '-m opencode/claude-sonnet-4')",
639 hide = true
640 )]
641 pub reviewer_model: Option<String>,
642
643 #[arg(
648 long,
649 env = "RALPH_DEVELOPER_PROVIDER",
650 value_name = "PROVIDER",
651 help = "Provider for developer agent: 'opencode' (Zen), 'zai'/'zhipuai' (Z.AI direct), 'anthropic'/'openai' (direct API)",
652 hide = true
653 )]
654 pub developer_provider: Option<String>,
655
656 #[arg(
661 long,
662 env = "RALPH_REVIEWER_PROVIDER",
663 value_name = "PROVIDER",
664 help = "Provider for reviewer agent: 'opencode' (Zen), 'zai'/'zhipuai' (Z.AI direct), 'anthropic'/'openai' (direct API)",
665 hide = true
666 )]
667 pub reviewer_provider: Option<String>,
668
669 #[arg(
672 long,
673 env = "RALPH_REVIEWER_JSON_PARSER",
674 value_name = "PARSER",
675 help = "JSON parser for reviewer (claude, codex, gemini, opencode, generic); overrides agent config",
676 hide = true
677 )]
678 pub reviewer_json_parser: Option<String>,
679
680 #[arg(
682 short,
683 long,
684 value_name = "LEVEL",
685 value_parser = clap::value_parser!(u8).range(0..=4),
686 help = "Output verbosity (0=quiet, 1=normal, 2=verbose [default], 3=full, 4=debug); overrides RALPH_VERBOSITY"
687 )]
688 pub verbosity: Option<u8>,
689
690 #[arg(
692 long,
693 help = "Disable isolation mode: keep NOTES.md and ISSUES.md between runs",
694 hide = true
695 )]
696 pub no_isolation: bool,
697
698 #[arg(
700 long,
701 value_name = "LEVEL",
702 help = "Review depth: standard (balanced), comprehensive (thorough), security (OWASP-focused), incremental (changed files only)",
703 hide = true
704 )]
705 pub review_depth: Option<String>,
706
707 #[arg(
709 long,
710 short = 'c',
711 value_name = "PATH",
712 help = "Path to configuration file (default: ~/.config/ralph-workflow.toml)",
713 hide = true
714 )]
715 pub config: Option<std::path::PathBuf>,
716
717 #[arg(skip)]
721 pub working_dir_override: Option<std::path::PathBuf>,
722
723 #[arg(
736 long,
737 value_name = "TEMPLATE",
738 help = "Create PROMPT.md from a Work Guide (use --list-work-guides to see options)",
739 hide = true
740 )]
741 pub init_prompt: Option<String>,
742
743 #[arg(
745 long,
746 short = 'i',
747 help = "Interactive mode: prompt to create PROMPT.md from template when missing",
748 hide = true
749 )]
750 pub interactive: bool,
751
752 #[arg(
754 long,
755 env = "RALPH_GIT_USER_NAME",
756 value_name = "NAME",
757 help = "Git user name for commits (overrides config, env, and git config)",
758 hide = true
759 )]
760 pub git_user_name: Option<String>,
761
762 #[arg(
764 long,
765 env = "RALPH_GIT_USER_EMAIL",
766 value_name = "EMAIL",
767 help = "Git user email for commits (overrides config, env, and git config)",
768 hide = true
769 )]
770 pub git_user_email: Option<String>,
771
772 #[arg(
774 long,
775 help = "Display streaming quality metrics (delta stats, repairs, violations) after agent completion",
776 hide = true
777 )]
778 pub show_streaming_metrics: bool,
779}