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(long)]
78 pub dry_run: bool,
79
80 #[arg(short = 'e', long = "env", value_name = "NAME=VALUE")]
82 pub env: Vec<String>,
83
84 #[arg(required = true, num_args = 1.., allow_hyphen_values = true)]
85 pub command: Vec<String>,
86}
87
88#[derive(Debug, Clone, Args)]
89#[command(trailing_var_arg = true)]
90pub struct ExecCommand {
91 pub profile: String,
92
93 #[arg(required = true, num_args = 1.., allow_hyphen_values = true)]
94 pub command: Vec<String>,
95}
96
97#[derive(Debug, Clone, Args, Default)]
98pub struct ShellCommand {
99 #[arg(long)]
100 pub shell: Option<String>,
101}
102
103#[derive(Debug, Clone, Args)]
104#[command(trailing_var_arg = true)]
105pub struct PlanCommand {
106 #[arg(long)]
107 pub show_command: bool,
108
109 #[arg(num_args = 0.., allow_hyphen_values = true)]
111 pub command: Vec<String>,
112}
113
114#[derive(Debug, Clone, Args, Default)]
115pub struct DoctorCommand {
116 #[arg(long)]
117 pub strict: bool,
118}
119
120#[derive(Debug, Clone, Args, Default)]
121pub struct CleanCommand {
122 #[arg(long)]
123 pub sessions: bool,
124
125 #[arg(long)]
126 pub images: bool,
127
128 #[arg(long)]
129 pub caches: bool,
130
131 #[arg(long)]
132 pub all: bool,
133
134 #[arg(long = "global")]
135 pub global_scope: bool,
136}
137
138#[derive(Debug, Clone, Copy, ValueEnum)]
139pub enum CliBackendKind {
140 Podman,
141 Docker,
142}
143
144#[derive(Debug, Clone, Copy, ValueEnum)]
145pub enum CliExecutionMode {
146 Host,
147 Sandbox,
148}
149
150#[derive(Debug, Clone, Args, Default)]
154pub struct AuditCommand {
155 #[arg(num_args = 0.., allow_hyphen_values = true)]
157 pub extra_args: Vec<String>,
158}
159
160#[derive(Debug, Clone, Args, Default)]
164pub struct BootstrapCommand {}
165
166#[derive(Debug, Clone, Args)]
167pub struct ShimCommand {
168 #[arg(long)]
170 pub dir: Option<PathBuf>,
171
172 #[arg(long)]
174 pub force: bool,
175
176 #[arg(long)]
178 pub dry_run: bool,
179}