1use std::path::PathBuf;
2
3use clap::{Args, Parser, Subcommand, ValueEnum};
4
5#[derive(Debug, Clone, Parser)]
6#[command(
7 name = "sbox",
8 version,
9 about = "Policy-driven sandboxed command runner"
10)]
11pub struct Cli {
12 #[arg(long, global = true)]
13 pub config: Option<PathBuf>,
14
15 #[arg(long, global = true)]
16 pub workspace: Option<PathBuf>,
17
18 #[arg(long, global = true, value_enum)]
19 pub backend: Option<CliBackendKind>,
20
21 #[arg(long, global = true)]
22 pub image: Option<String>,
23
24 #[arg(long, global = true)]
25 pub profile: Option<String>,
26
27 #[arg(long, global = true, value_enum)]
28 pub mode: Option<CliExecutionMode>,
29
30 #[arg(short = 'v', long, global = true, action = clap::ArgAction::Count)]
31 pub verbose: u8,
32
33 #[arg(long, global = true)]
34 pub quiet: bool,
35
36 #[arg(long, global = true)]
37 pub strict_security: bool,
38
39 #[command(subcommand)]
40 pub command: Commands,
41}
42
43#[derive(Debug, Clone, Subcommand)]
44pub enum Commands {
45 Init(InitCommand),
46 Run(RunCommand),
47 Exec(ExecCommand),
48 Shell(ShellCommand),
49 Plan(PlanCommand),
50 Doctor(DoctorCommand),
51 Clean(CleanCommand),
52 Shim(ShimCommand),
53 Bootstrap(BootstrapCommand),
54 Audit(AuditCommand),
55}
56
57#[derive(Debug, Clone, Args)]
58pub struct InitCommand {
59 #[arg(long)]
60 pub force: bool,
61
62 #[arg(long)]
63 pub preset: Option<String>,
64
65 #[arg(long)]
66 pub output: Option<PathBuf>,
67
68 #[arg(long, short = 'i')]
70 pub interactive: bool,
71}
72
73#[derive(Debug, Clone, Args)]
74#[command(trailing_var_arg = true)]
75pub struct RunCommand {
76 #[arg(required = true, num_args = 1.., allow_hyphen_values = true)]
77 pub command: Vec<String>,
78}
79
80#[derive(Debug, Clone, Args)]
81#[command(trailing_var_arg = true)]
82pub struct ExecCommand {
83 pub profile: String,
84
85 #[arg(required = true, num_args = 1.., allow_hyphen_values = true)]
86 pub command: Vec<String>,
87}
88
89#[derive(Debug, Clone, Args, Default)]
90pub struct ShellCommand {
91 #[arg(long)]
92 pub shell: Option<String>,
93}
94
95#[derive(Debug, Clone, Args)]
96#[command(trailing_var_arg = true)]
97pub struct PlanCommand {
98 #[arg(long)]
99 pub show_command: bool,
100
101 #[arg(num_args = 0.., allow_hyphen_values = true)]
103 pub command: Vec<String>,
104}
105
106#[derive(Debug, Clone, Args, Default)]
107pub struct DoctorCommand {
108 #[arg(long)]
109 pub strict: bool,
110}
111
112#[derive(Debug, Clone, Args, Default)]
113pub struct CleanCommand {
114 #[arg(long)]
115 pub sessions: bool,
116
117 #[arg(long)]
118 pub images: bool,
119
120 #[arg(long)]
121 pub caches: bool,
122
123 #[arg(long)]
124 pub all: bool,
125
126 #[arg(long = "global")]
127 pub global_scope: bool,
128}
129
130#[derive(Debug, Clone, Copy, ValueEnum)]
131pub enum CliBackendKind {
132 Podman,
133 Docker,
134}
135
136#[derive(Debug, Clone, Copy, ValueEnum)]
137pub enum CliExecutionMode {
138 Host,
139 Sandbox,
140}
141
142#[derive(Debug, Clone, Args, Default)]
146pub struct AuditCommand {
147 #[arg(num_args = 0.., allow_hyphen_values = true)]
149 pub extra_args: Vec<String>,
150}
151
152#[derive(Debug, Clone, Args, Default)]
156pub struct BootstrapCommand {}
157
158#[derive(Debug, Clone, Args)]
159pub struct ShimCommand {
160 #[arg(long)]
162 pub dir: Option<PathBuf>,
163
164 #[arg(long)]
166 pub force: bool,
167
168 #[arg(long)]
170 pub dry_run: bool,
171}