greentic_dev/
cli.rs

1use std::path::PathBuf;
2
3use clap::{Args, Parser, Subcommand, ValueEnum};
4use greentic_component::cmd::{
5    build::BuildArgs as ComponentBuildArgs, doctor::DoctorArgs as ComponentDoctorArgs,
6    flow::FlowCommand as ComponentFlowCommand, hash::HashArgs as ComponentHashArgs,
7    inspect::InspectArgs as ComponentInspectArgs, new::NewArgs as ComponentNewArgs,
8    store::StoreCommand as ComponentStoreCommand,
9    templates::TemplatesArgs as ComponentTemplatesArgs,
10};
11
12#[derive(Parser, Debug)]
13#[command(name = "greentic-dev")]
14#[command(version)]
15#[command(about = "Greentic developer tooling CLI")]
16pub struct Cli {
17    #[command(subcommand)]
18    pub command: Command,
19}
20
21#[derive(Subcommand, Debug)]
22pub enum Command {
23    /// Flow tooling (validate, lint, bundle inspection)
24    #[command(subcommand)]
25    Flow(FlowCommand),
26    /// Pack tooling (delegates to packc for build/lint/sign/verify/new; uses greentic-pack for inspect/plan/events)
27    #[command(subcommand)]
28    Pack(PackCommand),
29    /// Component tooling (delegates to greentic-component built-ins + distributor add)
30    #[command(subcommand)]
31    Component(ComponentCommand),
32    /// Manage greentic-dev configuration
33    #[command(subcommand)]
34    Config(ConfigCommand),
35    /// MCP tooling
36    #[command(subcommand)]
37    Mcp(McpCommand),
38}
39
40#[derive(Subcommand, Debug)]
41pub enum FlowCommand {
42    /// Validate a flow YAML file and emit the canonical bundle JSON
43    Validate(FlowValidateArgs),
44    /// Add a configured component step to a flow via config-flow
45    AddStep(FlowAddStepArgs),
46}
47
48#[derive(Args, Debug)]
49pub struct FlowValidateArgs {
50    /// Path to the flow definition (YAML)
51    #[arg(short = 'f', long = "file")]
52    pub file: PathBuf,
53    /// Emit compact JSON instead of pretty-printing
54    #[arg(long = "json")]
55    pub json: bool,
56}
57
58#[derive(Args, Debug)]
59pub struct FlowAddStepArgs {
60    /// Path to component.manifest.json (defaults to ./component.manifest.json)
61    #[arg(long = "manifest")]
62    pub manifest: Option<PathBuf>,
63    /// Flow identifier inside manifest.dev_flows (default: default)
64    #[arg(long = "flow", default_value = "default")]
65    pub flow: String,
66    /// Flow identifier (maps to flows/<id>.ygtc)
67    pub flow_id: String,
68    /// Component coordinate (store://... or repo://...). If omitted, greentic-dev will prompt.
69    #[arg(long = "coordinate")]
70    pub coordinate: Option<String>,
71    /// Distributor profile to use (overrides GREENTIC_DISTRIBUTOR_PROFILE/env config)
72    #[arg(long = "profile")]
73    pub profile: Option<String>,
74    /// Config flow selection
75    #[arg(long = "mode", value_enum)]
76    pub mode: Option<ConfigFlowModeArg>,
77    /// Automatically append routing from an existing node (if provided)
78    #[arg(long = "after")]
79    pub after: Option<String>,
80}
81
82#[derive(Subcommand, Debug)]
83pub enum PackCommand {
84    /// Delegate to packc build
85    Build(PackcArgs),
86    /// Delegate to packc lint
87    Lint(PackcArgs),
88    /// Delegate to packc new
89    New(PackcArgs),
90    /// Delegate to packc sign
91    Sign(PackcArgs),
92    /// Delegate to packc verify
93    Verify(PackcArgs),
94    /// Inspect a .gtpack (or directory via temporary build)
95    Inspect(PackInspectArgs),
96    /// Generate a deployment plan
97    Plan(PackPlanArgs),
98    /// Events helpers
99    #[command(subcommand)]
100    Events(PackEventsCommand),
101    /// Execute a pack locally with mocks/telemetry support
102    Run(PackRunArgs),
103    /// Initialize a pack workspace from a remote coordinate
104    Init(PackInitArgs),
105}
106
107#[derive(Args, Debug)]
108pub struct PackRunArgs {
109    /// Path to the pack (.gtpack) to execute
110    #[arg(short = 'p', long = "pack")]
111    pub pack: PathBuf,
112    /// Flow entry identifier override
113    #[arg(long = "entry")]
114    pub entry: Option<String>,
115    /// JSON payload to use as run input
116    #[arg(long = "input")]
117    pub input: Option<String>,
118    /// Enforcement policy for pack signatures
119    #[arg(long = "policy", default_value = "devok", value_enum)]
120    pub policy: RunPolicyArg,
121    /// OTLP collector endpoint (optional)
122    #[arg(long = "otlp")]
123    pub otlp: Option<String>,
124    /// Comma-separated list of allowed outbound hosts
125    #[arg(long = "allow")]
126    pub allow: Option<String>,
127    /// Mocks toggle
128    #[arg(long = "mocks", default_value = "on", value_enum)]
129    pub mocks: MockSettingArg,
130    /// Directory to persist run artifacts (transcripts, logs)
131    #[arg(long = "artifacts")]
132    pub artifacts: Option<PathBuf>,
133}
134
135#[derive(Args, Debug)]
136pub struct PackInitArgs {
137    /// Remote pack coordinate (e.g. pack://org/name@1.0.0)
138    pub from: String,
139    /// Distributor profile to use (overrides GREENTIC_DISTRIBUTOR_PROFILE/env config)
140    #[arg(long = "profile")]
141    pub profile: Option<String>,
142}
143
144#[derive(Args, Debug, Clone, Default)]
145#[command(disable_help_flag = true)]
146pub struct PackcArgs {
147    /// Arguments passed directly to the `packc` command
148    #[arg(
149        value_name = "ARGS",
150        trailing_var_arg = true,
151        allow_hyphen_values = true
152    )]
153    pub passthrough: Vec<String>,
154}
155
156#[derive(Args, Debug)]
157pub struct PackInspectArgs {
158    /// Path to the .gtpack file or pack directory
159    #[arg(value_name = "PATH")]
160    pub path: PathBuf,
161    /// Signature policy to enforce
162    #[arg(long, value_enum, default_value = "devok")]
163    pub policy: PackPolicyArg,
164    /// Emit JSON output
165    #[arg(long)]
166    pub json: bool,
167}
168
169#[derive(Subcommand, Debug)]
170pub enum PackEventsCommand {
171    /// List event providers declared in a pack
172    List(PackEventsListArgs),
173}
174
175#[derive(Args, Debug)]
176pub struct PackEventsListArgs {
177    /// Path to a .gtpack archive or pack source directory.
178    #[arg(value_name = "PATH")]
179    pub path: PathBuf,
180    /// Output format: table (default), json, yaml.
181    #[arg(long, value_enum, default_value = "table")]
182    pub format: PackEventsFormatArg,
183    /// When set, print additional diagnostics (for directory builds).
184    #[arg(long)]
185    pub verbose: bool,
186}
187
188#[derive(Args, Debug)]
189pub struct PackPlanArgs {
190    /// Path to a .gtpack archive or pack source directory.
191    #[arg(value_name = "PATH")]
192    pub input: PathBuf,
193    /// Tenant identifier to embed in the plan.
194    #[arg(long, default_value = "tenant-local")]
195    pub tenant: String,
196    /// Environment identifier to embed in the plan.
197    #[arg(long, default_value = "local")]
198    pub environment: String,
199    /// Emit compact JSON output instead of pretty-printing.
200    #[arg(long)]
201    pub json: bool,
202    /// When set, print additional diagnostics (for directory builds).
203    #[arg(long)]
204    pub verbose: bool,
205}
206
207#[derive(Subcommand, Debug, Clone)]
208pub enum ComponentCommand {
209    /// Add a remote component to the current workspace via the distributor
210    Add(ComponentAddArgs),
211    /// Scaffold a new Greentic component project
212    New(ComponentNewArgs),
213    /// List available component templates
214    Templates(ComponentTemplatesArgs),
215    /// Run component doctor checks
216    Doctor(ComponentDoctorArgs),
217    /// Inspect manifests and describe payloads
218    Inspect(ComponentInspectArgs),
219    /// Recompute manifest hashes
220    Hash(ComponentHashArgs),
221    /// Build component wasm + scaffold config flows
222    Build(ComponentBuildArgs),
223    /// Flow utilities (config flow scaffolding)
224    #[command(subcommand)]
225    Flow(ComponentFlowCommand),
226    /// Interact with the component store
227    #[command(subcommand)]
228    Store(ComponentStoreCommand),
229}
230
231#[derive(Args, Debug, Clone)]
232pub struct ComponentAddArgs {
233    /// Remote component coordinate (e.g. component://org/name@^1.0)
234    pub coordinate: String,
235    /// Distributor profile to use (overrides GREENTIC_DISTRIBUTOR_PROFILE/env config)
236    #[arg(long = "profile")]
237    pub profile: Option<String>,
238    /// Resolution intent (dev or runtime)
239    #[arg(long = "intent", default_value = "dev", value_enum)]
240    pub intent: DevIntentArg,
241}
242
243#[derive(Subcommand, Debug)]
244pub enum McpCommand {
245    /// Inspect MCP provider metadata
246    Doctor(McpDoctorArgs),
247}
248
249#[derive(Args, Debug)]
250pub struct McpDoctorArgs {
251    /// MCP provider identifier or config path
252    pub provider: String,
253    /// Emit compact JSON instead of pretty output
254    #[arg(long = "json")]
255    pub json: bool,
256}
257
258#[derive(Subcommand, Debug)]
259pub enum ConfigCommand {
260    /// Set a key in ~/.greentic/config.toml (e.g. defaults.component.org)
261    Set(ConfigSetArgs),
262}
263
264#[derive(Args, Debug)]
265pub struct ConfigSetArgs {
266    /// Config key path (e.g. defaults.component.org)
267    pub key: String,
268    /// Value to assign to the key (stored as a string)
269    pub value: String,
270    /// Override config file path (default: ~/.greentic/config.toml)
271    #[arg(long = "file")]
272    pub file: Option<PathBuf>,
273}
274
275#[derive(Copy, Clone, Debug, ValueEnum)]
276pub enum PackSignArg {
277    Dev,
278    None,
279}
280
281#[derive(Copy, Clone, Debug, ValueEnum)]
282pub enum PackPolicyArg {
283    Devok,
284    Strict,
285}
286
287#[derive(Copy, Clone, Debug, ValueEnum)]
288pub enum RunPolicyArg {
289    Strict,
290    Devok,
291}
292
293#[derive(Copy, Clone, Debug, ValueEnum)]
294pub enum VerifyPolicyArg {
295    Strict,
296    Devok,
297}
298
299#[derive(Copy, Clone, Debug, ValueEnum)]
300pub enum MockSettingArg {
301    On,
302    Off,
303}
304
305#[derive(Copy, Clone, Debug, ValueEnum)]
306pub enum PackEventsFormatArg {
307    Table,
308    Json,
309    Yaml,
310}
311
312#[derive(Copy, Clone, Debug, ValueEnum)]
313pub enum ConfigFlowModeArg {
314    Default,
315    Custom,
316}
317#[derive(Copy, Clone, Debug, ValueEnum)]
318pub enum DevIntentArg {
319    Dev,
320    Runtime,
321}
322
323#[cfg(test)]
324mod tests {}