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(
95 long,
96 conflicts_with_all = ["init_global", "init_legacy", "init_prompt"],
97 help = "Create ~/.config/ralph-workflow.toml with default settings (recommended)",
98 hide = true
99 )]
100 pub init: bool,
101
102 #[arg(
104 long,
105 conflicts_with_all = ["init", "init_legacy", "init_prompt"],
106 help = "Create ~/.config/ralph-workflow.toml with default settings (recommended)",
107 hide = true
108 )]
109 pub init_global: bool,
110}
111
112#[derive(Parser, Debug, Default)]
114pub struct LegacyInitFlag {
115 #[arg(
117 long,
118 conflicts_with_all = ["init", "init_global", "init_prompt"],
119 help = "(Legacy) Create .agent/agents.toml with default settings (not recommended)",
120 hide = true
121 )]
122 pub init_legacy: bool,
123}
124
125#[derive(Parser, Debug, Default)]
127pub struct AgentListFlags {
128 #[arg(
130 long,
131 help = "Show all agents from registry and config file",
132 hide = true
133 )]
134 pub list_agents: bool,
135
136 #[arg(
138 long,
139 help = "Show only agents that are installed and available",
140 hide = true
141 )]
142 pub list_available_agents: bool,
143}
144
145#[derive(Parser, Debug, Default)]
147pub struct ProviderListFlag {
148 #[arg(
150 long,
151 help = "Show OpenCode provider types with model prefixes and auth commands",
152 hide = true
153 )]
154 pub list_providers: bool,
155}
156
157#[derive(Parser, Debug, Default)]
159pub struct TemplateListFlag {
160 #[arg(
162 long,
163 help = "Show all available PROMPT.md templates with descriptions"
164 )]
165 pub list_templates: bool,
166}
167
168#[derive(Parser, Debug, Default)]
170pub struct TemplateCommands {
171 #[arg(
173 long = "init-templates",
174 help = "Create ~/.config/ralph/templates/ with default templates",
175 default_missing_value = "false",
176 num_args = 0..=1,
177 require_equals = true
178 )]
179 pub init_templates: Option<bool>,
180
181 #[arg(
183 long,
184 requires = "init_templates",
185 help = "Overwrite existing templates during init"
186 )]
187 pub force: bool,
188
189 #[arg(long, help = "Validate all templates for syntax errors")]
191 pub validate: bool,
192
193 #[arg(long, value_name = "NAME", help = "Show template content and metadata")]
195 pub show: Option<String>,
196
197 #[arg(long, help = "List all prompt templates with their variables")]
199 pub list: bool,
200
201 #[arg(long, value_name = "NAME", help = "Extract variables from a template")]
203 pub variables: Option<String>,
204
205 #[arg(
207 long,
208 value_name = "NAME",
209 help = "Test render a template with provided variables"
210 )]
211 pub render: Option<String>,
212}
213
214impl TemplateCommands {
215 pub const fn init_templates_enabled(&self) -> bool {
217 self.init_templates.is_some()
218 }
219}
220
221#[derive(Parser, Debug, Default)]
223pub struct CommitPlumbingFlags {
224 #[arg(
226 long,
227 help = "Run only the commit message generation phase, then exit",
228 hide = true
229 )]
230 pub generate_commit_msg: bool,
231
232 #[arg(
234 long,
235 help = "Stage all changes and commit using .agent/commit-message.txt",
236 hide = true
237 )]
238 pub apply_commit: bool,
239}
240
241#[derive(Parser, Debug, Default)]
243pub struct CommitDisplayFlags {
244 #[arg(long, help = "Read and display .agent/commit-message.txt", hide = true)]
246 pub show_commit_msg: bool,
247
248 #[arg(
250 long,
251 help = "Reset .agent/start_commit to current HEAD (for incremental diff generation)",
252 hide = true
253 )]
254 pub reset_start_commit: bool,
255}
256
257#[derive(Parser, Debug, Default)]
259pub struct RecoveryFlags {
260 #[arg(
262 long,
263 help = "Resume from last checkpoint (if one exists from a previous interrupted run)",
264 hide = true
265 )]
266 pub resume: bool,
267
268 #[arg(
270 long,
271 help = "Validate configuration and PROMPT.md without running agents",
272 hide = true
273 )]
274 pub dry_run: bool,
275
276 #[arg(
278 long,
279 short = 'd',
280 help = "Show system info, agent status, and config for troubleshooting"
281 )]
282 pub diagnose: bool,
283}
284
285#[derive(Parser, Debug, Default)]
287pub struct RebaseFlags {
288 #[arg(
290 long,
291 help = "Skip automatic rebase to main branch before and after pipeline"
292 )]
293 pub skip_rebase: bool,
294
295 #[arg(
297 long,
298 help = "Only rebase to main branch, then exit (no pipeline execution)"
299 )]
300 pub rebase_only: bool,
301}
302
303#[derive(Parser, Debug)]
305#[command(name = "ralph")]
306#[command(about = "PROMPT-driven multi-agent orchestrator for git repos")]
307#[command(
308 long_about = "Ralph orchestrates AI coding agents to implement changes based on PROMPT.md.\n\n\
309 It runs a developer agent for code implementation, then a reviewer agent for\n\
310 quality assurance, automatically staging and committing the final result."
311)]
312#[command(version)]
313#[command(
314 after_help = "╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\
315\n\
316NEW TO RALPH?\n\
317 Just want to get started? Run:\n\
318 ralph --init-prompt feature-spec # Create a prompt template\n\
319 ralph \"fix: my bug\" # Run with AI agents\n\
320\n\
321╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\
322\n\
323PRESET MODES (pick how thorough AI should be):\n\
324 -Q Quick: 1 dev + 1 review (typos, small fixes)\n\
325 -U Rapid: 2 dev + 1 review (minor changes)\n\
326 -S Standard: 5 dev + 2 reviews (default for most tasks)\n\
327 -T Thorough: 10 dev + 5 reviews (complex features)\n\
328 -L Long: 15 dev + 10 reviews (most thorough)\n\
329\n\
330╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\
331\n\
332COMMON SHORTHANDS:\n\
333 -D N, -R N Set dev iterations and review cycles\n\
334 -a AGENT Pick developer agent (claude, opencode, etc.)\n\
335 -r AGENT Pick reviewer agent\n\
336 -v N / -q / -f Set verbosity (quiet/normal/full)\n\
337 -d Diagnose/show system info\n\
338 -i Interactive mode (prompt if PROMPT.md missing)\n\
339 -c PATH Use specific config file\n\
340\n\
341╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\
342\n\
343QUICK EXAMPLES:\n\
344 ralph \"fix: typo\" Run with default settings\n\
345 ralph -Q \"fix: small bug\" Quick mode for tiny fixes\n\
346 ralph -U \"feat: add button\" Rapid mode for minor features\n\
347 ralph -a claude \"fix: bug\" Use specific agent\n\
348 ralph --list-templates See all prompt templates\n\
349╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
350)]
351pub struct Args {
354 #[command(flatten)]
356 pub verbosity_shorthand: VerbosityShorthand,
357
358 #[command(flatten)]
360 pub debug_verbosity: DebugVerbosity,
361
362 #[command(flatten)]
364 pub quick_presets: QuickPresets,
365
366 #[command(flatten)]
368 pub standard_presets: StandardPresets,
369
370 #[command(flatten)]
372 pub unified_init: UnifiedInitFlags,
373
374 #[command(flatten)]
376 pub legacy_init: LegacyInitFlag,
377
378 #[command(flatten)]
380 pub agent_list: AgentListFlags,
381
382 #[command(flatten)]
384 pub provider_list: ProviderListFlag,
385
386 #[command(flatten)]
388 pub template_list: TemplateListFlag,
389
390 #[command(flatten)]
392 pub template_commands: TemplateCommands,
393
394 #[command(flatten)]
396 pub commit_plumbing: CommitPlumbingFlags,
397
398 #[command(flatten)]
400 pub commit_display: CommitDisplayFlags,
401
402 #[command(flatten)]
404 pub recovery: RecoveryFlags,
405
406 #[command(flatten)]
408 pub rebase_flags: RebaseFlags,
409
410 #[arg(
412 default_value = "chore: apply PROMPT loop + review/fix/review",
413 help = "Commit message for the final commit"
414 )]
415 pub commit_msg: String,
416
417 #[arg(
419 long = "developer-iters",
420 short = 'D',
421 env = "RALPH_DEVELOPER_ITERS",
422 value_name = "N",
423 help = "Number of developer agent iterations",
424 aliases = ["developer-iteration", "dev-iter", "d-iters"]
425 )]
426 pub developer_iters: Option<u32>,
427
428 #[arg(
430 long = "reviewer-reviews",
431 short = 'R',
432 env = "RALPH_REVIEWER_REVIEWS",
433 value_name = "N",
434 help = "Number of review-fix cycles (0=skip review, 1=one cycle, default: 2)",
435 aliases = ["reviewer-count", "reviewer-review"]
436 )]
437 pub reviewer_reviews: Option<u32>,
438
439 #[arg(
441 long,
442 env = "RALPH_PRESET",
443 value_name = "NAME",
444 help = "Use a preset agent combination (default, opencode)",
445 hide = true
446 )]
447 pub preset: Option<super::presets::Preset>,
448
449 #[arg(
451 long,
452 short = 'a',
453 env = "RALPH_DEVELOPER_AGENT",
454 aliases = ["driver-agent", "dev-agent", "developer"],
455 value_name = "AGENT",
456 help = "Developer agent for code implementation (default: first in agent_chain.developer)"
457 )]
458 pub developer_agent: Option<String>,
459
460 #[arg(
462 long,
463 short = 'r',
464 env = "RALPH_REVIEWER_AGENT",
465 aliases = ["rev-agent", "reviewer"],
466 value_name = "AGENT",
467 help = "Reviewer agent for code review (default: first in agent_chain.reviewer)"
468 )]
469 pub reviewer_agent: Option<String>,
470
471 #[arg(
473 long,
474 env = "RALPH_DEVELOPER_MODEL",
475 value_name = "MODEL_FLAG",
476 help = "Model flag for developer agent (e.g., '-m opencode/glm-4.7-free')",
477 hide = true
478 )]
479 pub developer_model: Option<String>,
480
481 #[arg(
483 long,
484 env = "RALPH_REVIEWER_MODEL",
485 value_name = "MODEL_FLAG",
486 help = "Model flag for reviewer agent (e.g., '-m opencode/claude-sonnet-4')",
487 hide = true
488 )]
489 pub reviewer_model: Option<String>,
490
491 #[arg(
496 long,
497 env = "RALPH_DEVELOPER_PROVIDER",
498 value_name = "PROVIDER",
499 help = "Provider for developer agent: 'opencode' (Zen), 'zai'/'zhipuai' (Z.AI direct), 'anthropic'/'openai' (direct API)",
500 hide = true
501 )]
502 pub developer_provider: Option<String>,
503
504 #[arg(
509 long,
510 env = "RALPH_REVIEWER_PROVIDER",
511 value_name = "PROVIDER",
512 help = "Provider for reviewer agent: 'opencode' (Zen), 'zai'/'zhipuai' (Z.AI direct), 'anthropic'/'openai' (direct API)",
513 hide = true
514 )]
515 pub reviewer_provider: Option<String>,
516
517 #[arg(
520 long,
521 env = "RALPH_REVIEWER_JSON_PARSER",
522 value_name = "PARSER",
523 help = "JSON parser for reviewer (claude, codex, gemini, opencode, generic); overrides agent config",
524 hide = true
525 )]
526 pub reviewer_json_parser: Option<String>,
527
528 #[arg(
530 short,
531 long,
532 value_name = "LEVEL",
533 value_parser = clap::value_parser!(u8).range(0..=4),
534 help = "Output verbosity (0=quiet, 1=normal, 2=verbose [default], 3=full, 4=debug); overrides RALPH_VERBOSITY"
535 )]
536 pub verbosity: Option<u8>,
537
538 #[arg(
540 long,
541 help = "Disable isolation mode: keep NOTES.md and ISSUES.md between runs",
542 hide = true
543 )]
544 pub no_isolation: bool,
545
546 #[arg(
548 long,
549 value_name = "LEVEL",
550 help = "Review depth: standard (balanced), comprehensive (thorough), security (OWASP-focused), incremental (changed files only)",
551 hide = true
552 )]
553 pub review_depth: Option<String>,
554
555 #[arg(
557 long,
558 short = 'c',
559 value_name = "PATH",
560 help = "Path to configuration file (default: ~/.config/ralph-workflow.toml)",
561 hide = true
562 )]
563 pub config: Option<std::path::PathBuf>,
564
565 #[arg(
567 long,
568 value_name = "TEMPLATE",
569 help = "Create PROMPT.md from a template (use --list-templates to see options)"
570 )]
571 pub init_prompt: Option<String>,
572
573 #[arg(
575 long,
576 short = 'i',
577 help = "Interactive mode: prompt to create PROMPT.md from template when missing"
578 )]
579 pub interactive: bool,
580
581 #[arg(
583 long,
584 env = "RALPH_GIT_USER_NAME",
585 value_name = "NAME",
586 help = "Git user name for commits (overrides config, env, and git config)"
587 )]
588 pub git_user_name: Option<String>,
589
590 #[arg(
592 long,
593 env = "RALPH_GIT_USER_EMAIL",
594 value_name = "EMAIL",
595 help = "Git user email for commits (overrides config, env, and git config)"
596 )]
597 pub git_user_email: Option<String>,
598
599 #[arg(
601 long,
602 help = "Display streaming quality metrics (delta stats, repairs, violations) after agent completion"
603 )]
604 pub show_streaming_metrics: bool,
605}