args.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. use std::path::PathBuf;
  2. use clap::{Parser, Subcommand, ValueEnum};
  3. #[derive(Debug, Clone, Parser, PartialEq, Eq)]
  4. #[command(
  5. name = "rusty-claude-cli",
  6. version,
  7. about = "Rust Claude CLI prototype"
  8. )]
  9. pub struct Cli {
  10. #[arg(long, default_value = "claude-opus-4-6")]
  11. pub model: String,
  12. #[arg(long, value_enum, default_value_t = PermissionMode::DangerFullAccess)]
  13. pub permission_mode: PermissionMode,
  14. #[arg(long)]
  15. pub config: Option<PathBuf>,
  16. #[arg(long, value_enum, default_value_t = OutputFormat::Text)]
  17. pub output_format: OutputFormat,
  18. #[command(subcommand)]
  19. pub command: Option<Command>,
  20. }
  21. #[derive(Debug, Clone, Subcommand, PartialEq, Eq)]
  22. pub enum Command {
  23. /// Read upstream TS sources and print extracted counts
  24. DumpManifests,
  25. /// Print the current bootstrap phase skeleton
  26. BootstrapPlan,
  27. /// Start the OAuth login flow
  28. Login,
  29. /// Clear saved OAuth credentials
  30. Logout,
  31. /// Run a non-interactive prompt and exit
  32. Prompt { prompt: Vec<String> },
  33. }
  34. #[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)]
  35. pub enum PermissionMode {
  36. ReadOnly,
  37. WorkspaceWrite,
  38. DangerFullAccess,
  39. }
  40. #[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)]
  41. pub enum OutputFormat {
  42. Text,
  43. Json,
  44. Ndjson,
  45. }
  46. #[cfg(test)]
  47. mod tests {
  48. use clap::Parser;
  49. use super::{Cli, Command, OutputFormat, PermissionMode};
  50. #[test]
  51. fn parses_requested_flags() {
  52. let cli = Cli::parse_from([
  53. "rusty-claude-cli",
  54. "--model",
  55. "claude-3-5-haiku",
  56. "--permission-mode",
  57. "read-only",
  58. "--config",
  59. "/tmp/config.toml",
  60. "--output-format",
  61. "ndjson",
  62. "prompt",
  63. "hello",
  64. "world",
  65. ]);
  66. assert_eq!(cli.model, "claude-3-5-haiku");
  67. assert_eq!(cli.permission_mode, PermissionMode::ReadOnly);
  68. assert_eq!(
  69. cli.config.as_deref(),
  70. Some(std::path::Path::new("/tmp/config.toml"))
  71. );
  72. assert_eq!(cli.output_format, OutputFormat::Ndjson);
  73. assert_eq!(
  74. cli.command,
  75. Some(Command::Prompt {
  76. prompt: vec!["hello".into(), "world".into()]
  77. })
  78. );
  79. }
  80. #[test]
  81. fn parses_login_and_logout_commands() {
  82. let login = Cli::parse_from(["rusty-claude-cli", "login"]);
  83. assert_eq!(login.command, Some(Command::Login));
  84. let logout = Cli::parse_from(["rusty-claude-cli", "logout"]);
  85. assert_eq!(logout.command, Some(Command::Logout));
  86. }
  87. #[test]
  88. fn defaults_to_danger_full_access_permission_mode() {
  89. let cli = Cli::parse_from(["rusty-claude-cli"]);
  90. assert_eq!(cli.permission_mode, PermissionMode::DangerFullAccess);
  91. }
  92. }