1use std::path::PathBuf;
2
3use crate::secrets_cli::SecretsCommand;
4use clap::{Args, Parser, Subcommand, ValueEnum};
5use greentic_component::cmd::{
6 build::BuildArgs as ComponentBuildArgs, doctor::DoctorArgs as ComponentDoctorArgs,
7 flow::FlowCommand as ComponentFlowCommand, hash::HashArgs as ComponentHashArgs,
8 inspect::InspectArgs as ComponentInspectArgs, new::NewArgs as ComponentNewArgs,
9 store::StoreCommand as ComponentStoreCommand,
10 templates::TemplatesArgs as ComponentTemplatesArgs,
11};
12
13#[derive(Parser, Debug)]
14#[command(name = "greentic-dev")]
15#[command(version)]
16#[command(about = "Greentic developer tooling CLI")]
17pub struct Cli {
18 #[command(subcommand)]
19 pub command: Command,
20}
21
22#[derive(Subcommand, Debug)]
23pub enum Command {
24 #[command(subcommand)]
26 Flow(FlowCommand),
27 #[command(subcommand)]
29 Pack(PackCommand),
30 #[command(subcommand)]
32 Component(ComponentCommand),
33 #[command(subcommand)]
35 Config(ConfigCommand),
36 #[command(subcommand)]
38 Mcp(McpCommand),
39 #[command(subcommand)]
41 Gui(GuiCommand),
42 #[command(subcommand)]
44 Secrets(SecretsCommand),
45}
46
47#[derive(Subcommand, Debug)]
48pub enum FlowCommand {
49 Validate(FlowValidateArgs),
51 Doctor(FlowValidateArgs),
53 AddStep(Box<FlowAddStepArgs>),
55}
56
57#[derive(Args, Debug)]
58pub struct FlowValidateArgs {
59 #[arg(short = 'f', long = "file")]
61 pub file: PathBuf,
62 #[arg(long = "json")]
64 pub json: bool,
65}
66
67#[derive(Args, Debug)]
68pub struct FlowAddStepArgs {
69 #[arg(long = "flow")]
71 pub flow_path: PathBuf,
72 #[arg(long = "after")]
74 pub after: Option<String>,
75 #[arg(long = "mode", value_enum, default_value = "default")]
77 pub mode: FlowAddStepMode,
78 #[arg(long = "component")]
80 pub component_id: Option<String>,
81 #[arg(long = "pack-alias")]
83 pub pack_alias: Option<String>,
84 #[arg(long = "operation")]
86 pub operation: Option<String>,
87 #[arg(long = "payload", default_value = "{}")]
89 pub payload: String,
90 #[arg(long = "routing")]
92 pub routing: Option<String>,
93 #[arg(long = "config-flow")]
95 pub config_flow: Option<PathBuf>,
96 #[arg(long = "answers")]
98 pub answers: Option<String>,
99 #[arg(long = "answers-file")]
101 pub answers_file: Option<PathBuf>,
102 #[arg(long = "allow-cycles")]
104 pub allow_cycles: bool,
105 #[arg(long = "write")]
107 pub write: bool,
108 #[arg(long = "validate-only")]
110 pub validate_only: bool,
111 #[arg(long = "manifest")]
113 pub manifests: Vec<PathBuf>,
114 #[arg(long = "node-id")]
116 pub node_id: Option<String>,
117 #[arg(long = "verbose")]
119 pub verbose: bool,
120}
121
122#[derive(Copy, Clone, Debug, Eq, PartialEq, ValueEnum)]
123pub enum FlowAddStepMode {
124 Default,
125 Config,
126}
127
128#[derive(Subcommand, Debug)]
129pub enum GuiCommand {
130 Serve(GuiServeArgs),
132 PackDev(GuiPackDevArgs),
134}
135
136#[derive(Args, Debug)]
137pub struct GuiServeArgs {
138 #[arg(long = "config")]
140 pub config: Option<PathBuf>,
141 #[arg(long = "bind")]
143 pub bind: Option<String>,
144 #[arg(long = "domain")]
146 pub domain: Option<String>,
147 #[arg(long = "gui-bin")]
149 pub gui_bin: Option<PathBuf>,
150 #[arg(long = "no-cargo-fallback")]
152 pub no_cargo_fallback: bool,
153 #[arg(long = "open-browser")]
155 pub open_browser: bool,
156}
157
158#[derive(Args, Debug, Clone)]
159pub struct GuiPackDevArgs {
160 #[arg(long = "dir")]
162 pub dir: PathBuf,
163 #[arg(long = "output")]
165 pub output: PathBuf,
166 #[arg(long = "kind", value_enum, default_value = "layout")]
168 pub kind: GuiPackKind,
169 #[arg(long = "entrypoint", default_value = "index.html")]
171 pub entrypoint: String,
172 #[arg(long = "manifest")]
174 pub manifest: Option<PathBuf>,
175 #[arg(long = "feature-route")]
177 pub feature_route: Option<String>,
178 #[arg(long = "feature-html", default_value = "index.html")]
180 pub feature_html: String,
181 #[arg(long = "feature-authenticated")]
183 pub feature_authenticated: bool,
184 #[arg(long = "build-cmd")]
186 pub build_cmd: Option<String>,
187 #[arg(long = "no-build")]
189 pub no_build: bool,
190}
191
192#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
193pub enum GuiPackKind {
194 Layout,
195 Feature,
196}
197
198#[derive(Subcommand, Debug)]
199pub enum PackCommand {
200 Build(PackcArgs),
202 Lint(PackcArgs),
204 Components(PackcArgs),
206 Update(PackcArgs),
208 New(PackcArgs),
210 Sign(PackcArgs),
212 Verify(PackcArgs),
214 Gui(PackcArgs),
216 Inspect(PackInspectArgs),
218 Plan(PackPlanArgs),
220 #[command(subcommand)]
222 Events(PackEventsCommand),
223 Config(PackcArgs),
225 Run(PackRunArgs),
227 Init(PackInitArgs),
229 NewProvider(PackNewProviderArgs),
231}
232
233#[derive(Args, Debug)]
234pub struct PackRunArgs {
235 #[arg(short = 'p', long = "pack")]
237 pub pack: PathBuf,
238 #[arg(long = "entry")]
240 pub entry: Option<String>,
241 #[arg(long = "input")]
243 pub input: Option<String>,
244 #[arg(long = "json")]
246 pub json: bool,
247 #[arg(long = "offline")]
249 pub offline: bool,
250 #[arg(long = "mock-exec", hide = true)]
252 pub mock_exec: bool,
253 #[arg(long = "allow-external", hide = true)]
255 pub allow_external: bool,
256 #[arg(long = "mock-external", hide = true)]
258 pub mock_external: bool,
259 #[arg(long = "mock-external-payload", hide = true)]
261 pub mock_external_payload: Option<PathBuf>,
262 #[arg(long = "secrets-seed", hide = true)]
264 pub secrets_seed: Option<PathBuf>,
265 #[arg(long = "policy", default_value = "devok", value_enum)]
267 pub policy: RunPolicyArg,
268 #[arg(long = "otlp")]
270 pub otlp: Option<String>,
271 #[arg(long = "allow")]
273 pub allow: Option<String>,
274 #[arg(long = "mocks", default_value = "on", value_enum)]
276 pub mocks: MockSettingArg,
277 #[arg(long = "artifacts")]
279 pub artifacts: Option<PathBuf>,
280}
281
282#[derive(Args, Debug)]
283pub struct PackInitArgs {
284 pub from: String,
286 #[arg(long = "profile")]
288 pub profile: Option<String>,
289}
290
291#[derive(Args, Debug)]
292pub struct PackNewProviderArgs {
293 #[arg(long = "pack")]
295 pub pack: PathBuf,
296 #[arg(long = "id")]
298 pub id: String,
299 #[arg(long = "runtime")]
301 pub runtime: String,
302 #[arg(long = "kind")]
304 pub kind: Option<String>,
305 #[arg(long = "manifest")]
307 pub manifest: Option<PathBuf>,
308 #[arg(long = "dry-run")]
310 pub dry_run: bool,
311 #[arg(long = "force")]
313 pub force: bool,
314 #[arg(long = "json")]
316 pub json: bool,
317 #[arg(long = "scaffold-files")]
319 pub scaffold_files: bool,
320}
321
322#[derive(Args, Debug, Clone, Default)]
323#[command(disable_help_flag = true)]
324pub struct PackcArgs {
325 #[arg(
327 value_name = "ARGS",
328 trailing_var_arg = true,
329 allow_hyphen_values = true
330 )]
331 pub passthrough: Vec<String>,
332}
333
334#[derive(Args, Debug)]
335pub struct PackInspectArgs {
336 #[arg(value_name = "PATH")]
338 pub path: PathBuf,
339 #[arg(long, value_enum, default_value = "devok")]
341 pub policy: PackPolicyArg,
342 #[arg(long)]
344 pub json: bool,
345}
346
347#[derive(Subcommand, Debug)]
348pub enum PackEventsCommand {
349 List(PackEventsListArgs),
351}
352
353#[derive(Args, Debug)]
354pub struct PackEventsListArgs {
355 #[arg(value_name = "PATH")]
357 pub path: PathBuf,
358 #[arg(long, value_enum, default_value = "table")]
360 pub format: PackEventsFormatArg,
361 #[arg(long)]
363 pub verbose: bool,
364}
365
366#[derive(Args, Debug)]
367pub struct PackPlanArgs {
368 #[arg(value_name = "PATH")]
370 pub input: PathBuf,
371 #[arg(long, default_value = "tenant-local")]
373 pub tenant: String,
374 #[arg(long, default_value = "local")]
376 pub environment: String,
377 #[arg(long)]
379 pub json: bool,
380 #[arg(long)]
382 pub verbose: bool,
383}
384
385#[derive(Subcommand, Debug, Clone)]
386pub enum ComponentCommand {
387 Add(ComponentAddArgs),
389 New(ComponentNewArgs),
391 Templates(ComponentTemplatesArgs),
393 Doctor(ComponentDoctorArgs),
395 Inspect(ComponentInspectArgs),
397 Hash(ComponentHashArgs),
399 Build(ComponentBuildArgs),
401 #[command(subcommand)]
403 Flow(ComponentFlowCommand),
404 #[command(subcommand)]
406 Store(ComponentStoreCommand),
407}
408
409#[derive(Args, Debug, Clone)]
410pub struct ComponentAddArgs {
411 pub coordinate: String,
413 #[arg(long = "profile")]
415 pub profile: Option<String>,
416 #[arg(long = "intent", default_value = "dev", value_enum)]
418 pub intent: DevIntentArg,
419}
420
421#[derive(Subcommand, Debug)]
422pub enum McpCommand {
423 Doctor(McpDoctorArgs),
425}
426
427#[derive(Args, Debug)]
428pub struct McpDoctorArgs {
429 pub provider: String,
431 #[arg(long = "json")]
433 pub json: bool,
434}
435
436#[derive(Subcommand, Debug)]
437pub enum ConfigCommand {
438 Set(ConfigSetArgs),
440}
441
442#[derive(Args, Debug)]
443pub struct ConfigSetArgs {
444 pub key: String,
446 pub value: String,
448 #[arg(long = "file")]
450 pub file: Option<PathBuf>,
451}
452
453#[derive(Copy, Clone, Debug, ValueEnum)]
454pub enum PackSignArg {
455 Dev,
456 None,
457}
458
459#[derive(Copy, Clone, Debug, ValueEnum)]
460pub enum PackPolicyArg {
461 Devok,
462 Strict,
463}
464
465#[derive(Copy, Clone, Debug, ValueEnum)]
466pub enum RunPolicyArg {
467 Strict,
468 Devok,
469}
470
471#[derive(Copy, Clone, Debug, ValueEnum)]
472pub enum VerifyPolicyArg {
473 Strict,
474 Devok,
475}
476
477#[derive(Copy, Clone, Debug, ValueEnum)]
478pub enum MockSettingArg {
479 On,
480 Off,
481}
482
483#[derive(Copy, Clone, Debug, ValueEnum)]
484pub enum PackEventsFormatArg {
485 Table,
486 Json,
487 Yaml,
488}
489
490#[derive(Copy, Clone, Debug, ValueEnum)]
491pub enum ConfigFlowModeArg {
492 Default,
493 Custom,
494}
495#[derive(Copy, Clone, Debug, ValueEnum)]
496pub enum DevIntentArg {
497 Dev,
498 Runtime,
499}
500
501#[cfg(test)]
502mod tests {}