fob_cli/cli/commands.rs
1use clap::{Args, Subcommand};
2use std::path::PathBuf;
3
4use crate::cli::enums::*;
5use crate::cli::validation::parse_global;
6
7/// Available Fob subcommands
8#[derive(Subcommand, Debug)]
9pub enum Command {
10 /// Build a library or application
11 ///
12 /// Bundles entry points into optimized output with support for multiple
13 /// formats, TypeScript declarations, source maps, and tree shaking.
14 Build(BuildArgs),
15
16 /// Start development server with watch mode
17 ///
18 /// Runs a development server with hot module replacement and automatic
19 /// rebuilding when source files change.
20 Dev(DevArgs),
21
22 /// Initialize a new Fob project
23 ///
24 /// Creates a new project with sensible defaults and optional templates
25 /// for common project types (library, application, monorepo).
26 Init(InitArgs),
27
28 /// Validate configuration and dependencies
29 ///
30 /// Checks fob.config.json for errors and validates that all dependencies
31 /// are correctly installed and compatible.
32 Check(CheckArgs),
33}
34
35/// Arguments for the build command
36#[derive(Args, Debug)]
37pub struct BuildArgs {
38 /// Entry points to bundle
39 ///
40 /// Specify one or more entry points. Each entry point will be bundled
41 /// into a separate output file. If not specified, reads from fob.config.json.
42 ///
43 /// Examples:
44 /// fob build src/index.ts
45 /// fob build src/main.ts src/worker.ts
46 #[arg(value_name = "ENTRY")]
47 pub entry: Option<Vec<String>>,
48
49 /// Output format for the bundle
50 ///
51 /// - esm: ECMAScript modules (modern, tree-shakeable)
52 /// - cjs: CommonJS (Node.js compatible)
53 /// - iife: Immediately Invoked Function Expression (browser script tag)
54 #[arg(short = 'f', long, value_enum, default_value = "esm")]
55 pub format: Format,
56
57 /// Output directory for bundled files
58 ///
59 /// All generated files (bundles, source maps, declarations) will be
60 /// written to this directory. Created if it doesn't exist.
61 #[arg(short = 'd', long, default_value = "dist", value_name = "DIR")]
62 pub out_dir: PathBuf,
63
64 /// Generate TypeScript declaration files (.d.ts)
65 ///
66 /// Extracts type definitions from TypeScript source files. Useful for
67 /// library authors who want to provide type safety to consumers.
68 #[arg(long)]
69 pub dts: bool,
70
71 /// Bundle declaration files into a single .d.ts file
72 ///
73 /// Combines all declaration files into one output file, making it easier
74 /// for consumers to import types. Requires --dts to be enabled.
75 #[arg(long, requires = "dts")]
76 pub dts_bundle: bool,
77
78 /// Generate API documentation from JSDoc / TSDoc comments
79 ///
80 /// Emits Markdown or JSON files describing exported symbols.
81 #[arg(long)]
82 pub docs: bool,
83
84 /// Format for generated documentation (md, json, both)
85 #[arg(long, value_enum, value_name = "FORMAT", requires = "docs")]
86 pub docs_format: Option<DocsFormat>,
87
88 /// Output directory for generated documentation files
89 #[arg(long, value_name = "DIR", requires = "docs")]
90 pub docs_dir: Option<PathBuf>,
91
92 /// Include symbols annotated with @internal
93 #[arg(long, requires = "docs")]
94 pub docs_include_internal: bool,
95
96 /// Enable LLM-powered documentation enhancement
97 ///
98 /// Uses Ollama to automatically generate comprehensive documentation
99 /// for symbols with missing or incomplete JSDoc comments.
100 /// Requires Ollama to be installed and running (ollama serve).
101 #[arg(long, requires = "docs")]
102 pub docs_enhance: bool,
103
104 /// LLM enhancement mode (missing, incomplete, all)
105 ///
106 /// - missing: Only enhance symbols with no JSDoc at all (fastest)
107 /// - incomplete: Enhance symbols missing params, returns, or examples
108 /// - all: Enhance all symbols, merging with existing docs (most thorough)
109 #[arg(long, value_enum, value_name = "MODE", requires = "docs_enhance")]
110 pub docs_enhance_mode: Option<DocsEnhanceMode>,
111
112 /// LLM model to use for enhancement
113 ///
114 /// Specifies which Ollama model to use for generating documentation.
115 /// Examples: llama3.2:3b (default, fast), codellama:7b (better quality),
116 /// deepseek-coder:6.7b (code-focused), qwen2.5-coder:7b (latest)
117 #[arg(long, value_name = "MODEL", requires = "docs_enhance")]
118 pub docs_llm_model: Option<String>,
119
120 /// Disable LLM response caching
121 ///
122 /// By default, LLM responses are cached using BLAKE3-based smart invalidation
123 /// that auto-invalidates when code changes. Use this flag to disable caching
124 /// and always query the LLM (useful for testing different prompts).
125 #[arg(long, requires = "docs_enhance")]
126 pub docs_no_cache: bool,
127
128 /// Custom Ollama server URL
129 ///
130 /// Specify a custom Ollama server endpoint. Useful for remote Ollama instances
131 /// or non-standard ports. Defaults to http://localhost:11434
132 #[arg(long, value_name = "URL", requires = "docs_enhance")]
133 pub docs_llm_url: Option<String>,
134
135 /// Write enhanced documentation back to source files
136 ///
137 /// Instead of generating external docs, this modifies the original
138 /// source files by adding or updating JSDoc comments with LLM-enhanced
139 /// documentation. Creates .bak backup files by default.
140 #[arg(long, requires = "docs_enhance")]
141 pub docs_write_back: bool,
142
143 /// JSDoc merge strategy when writing back
144 ///
145 /// Controls how to handle existing JSDoc comments:
146 /// - merge: Merge LLM output with existing JSDoc (default, preserves custom tags)
147 /// - replace: Replace existing JSDoc entirely with LLM output
148 /// - skip: Skip symbols that already have JSDoc
149 #[arg(
150 long,
151 value_enum,
152 value_name = "STRATEGY",
153 requires = "docs_write_back"
154 )]
155 pub docs_merge_strategy: Option<DocsMergeStrategy>,
156
157 /// Skip creating backup files when writing back
158 ///
159 /// By default, original files are backed up with .bak extension before modification.
160 /// Use this flag to skip backup creation (useful for version-controlled code).
161 #[arg(long, requires = "docs_write_back")]
162 pub docs_no_backup: bool,
163
164 /// External packages to exclude from bundle
165 ///
166 /// Dependencies listed here will not be included in the output bundle.
167 /// They must be provided by the consuming environment.
168 ///
169 /// Examples:
170 /// --external react --external react-dom
171 /// --external react,react-dom
172 #[arg(short, long, value_name = "PACKAGE")]
173 pub external: Vec<String>,
174
175 /// Target platform environment
176 ///
177 /// - browser: Optimizes for browser environments (no Node.js APIs)
178 /// - node: Optimizes for Node.js (enables require, process, etc.)
179 #[arg(long, value_enum, default_value = "browser")]
180 pub platform: Platform,
181
182 /// Source map generation mode
183 ///
184 /// - inline: Embeds source maps in the bundle (larger file, single file)
185 /// - external: Generates separate .map files (smaller bundle, two files)
186 /// - hidden: Generates maps but doesn't reference them (debugging builds)
187 #[arg(long, value_enum, value_name = "MODE")]
188 pub sourcemap: Option<SourceMapMode>,
189
190 /// Enable minification of output
191 ///
192 /// Reduces bundle size by removing whitespace, shortening variable names,
193 /// and applying other optimizations. Recommended for production builds.
194 #[arg(short = 'm', long)]
195 pub minify: bool,
196
197 /// JavaScript language target version
198 ///
199 /// Determines which JavaScript features are available in the output.
200 /// Later targets produce smaller, faster code but require modern runtimes.
201 #[arg(long, value_enum, default_value = "es2020", value_name = "TARGET")]
202 pub target: EsTarget,
203
204 /// Global variable name for IIFE/UMD bundles
205 ///
206 /// When using IIFE format, this is the global variable name that will
207 /// contain the exported module. Must be a valid JavaScript identifier.
208 ///
209 /// Example: --global-name MyLibrary
210 #[arg(long, value_parser = parse_global, value_name = "NAME")]
211 pub global_name: Option<String>,
212
213 /// Bundle dependencies into output
214 ///
215 /// - true: Include all dependencies in the bundle (standalone app/library)
216 /// - false: Externalize dependencies (require them at runtime)
217 ///
218 /// Use false for npm packages, true for browser apps.
219 #[arg(long, default_value = "true")]
220 pub bundle: bool,
221
222 /// Enable code splitting
223 ///
224 /// Splits the bundle into multiple chunks for lazy loading. Useful for
225 /// large applications to reduce initial load time. Only works with ESM format.
226 /// Requires --bundle.
227 #[arg(long)]
228 pub splitting: bool,
229
230 /// Disable tree shaking optimizations
231 ///
232 /// By default, unused exports are removed. This flag preserves all code,
233 /// which may be useful for debugging or specific compatibility requirements.
234 #[arg(long)]
235 pub no_treeshake: bool,
236
237 /// Clean output directory before build
238 ///
239 /// Removes all files from the output directory before starting the build.
240 /// Ensures no stale artifacts remain from previous builds.
241 #[arg(long)]
242 pub clean: bool,
243
244 /// Working directory for the build
245 ///
246 /// All relative paths in the build process are resolved relative to this
247 /// directory. Defaults to the current working directory.
248 #[arg(long, value_name = "DIR")]
249 pub cwd: Option<PathBuf>,
250}
251
252/// Arguments for the dev command (development server)
253#[derive(Args, Debug)]
254pub struct DevArgs {
255 /// Entry point for development server
256 ///
257 /// The main file to serve. If not specified, reads from fob.config.json.
258 /// The dev server will rebuild this entry point and its dependencies
259 /// whenever files change.
260 #[arg(value_name = "ENTRY")]
261 pub entry: Option<PathBuf>,
262
263 /// Port for development server
264 ///
265 /// The HTTP port to listen on. The server will automatically find an
266 /// available port if this one is in use.
267 #[arg(short, long, default_value = "3000", value_name = "PORT")]
268 pub port: u16,
269
270 /// Enable HTTPS with automatic certificate generation
271 ///
272 /// Generates a self-signed certificate for local HTTPS development.
273 /// Useful for testing service workers or other HTTPS-only features.
274 #[arg(long)]
275 pub https: bool,
276
277 /// Open browser automatically on server start
278 ///
279 /// Launches the default web browser and navigates to the dev server URL.
280 #[arg(long)]
281 pub open: bool,
282
283 /// Working directory for the dev server (defaults to auto-detected project root)
284 ///
285 /// All relative paths are resolved relative to this directory. If not specified,
286 /// fob will automatically detect the project root by finding the nearest package.json.
287 #[arg(long, value_name = "DIR")]
288 pub cwd: Option<PathBuf>,
289}
290
291/// Arguments for the init command (project scaffolding)
292#[derive(Args, Debug)]
293pub struct InitArgs {
294 /// Project name
295 ///
296 /// Name of the project to create. If omitted, uses the current directory
297 /// name. Must be a valid npm package name.
298 #[arg(value_name = "NAME")]
299 pub name: Option<String>,
300
301 /// Template to use for project initialization
302 ///
303 /// Available templates:
304 /// - library: TypeScript library with type declarations
305 /// - app: Web application with dev server
306 /// - component-library: React component library (aliases: components)
307 /// - meta-framework: Educational framework example (aliases: framework)
308 ///
309 /// If not specified, an interactive prompt will ask for preferences.
310 #[arg(short, long, value_name = "TEMPLATE")]
311 pub template: Option<String>,
312
313 /// Skip interactive prompts and use defaults
314 ///
315 /// Creates a basic project without asking for customization options.
316 /// Useful for automated workflows or quick prototyping.
317 #[arg(short = 'y', long)]
318 pub yes: bool,
319
320 /// Use npm as package manager (default)
321 #[arg(long, conflicts_with_all = ["use_yarn", "use_pnpm"])]
322 pub use_npm: bool,
323
324 /// Use Yarn as package manager
325 #[arg(long, conflicts_with_all = ["use_npm", "use_pnpm"])]
326 pub use_yarn: bool,
327
328 /// Use pnpm as package manager
329 #[arg(long, conflicts_with_all = ["use_npm", "use_yarn"])]
330 pub use_pnpm: bool,
331}
332
333/// Arguments for the check command (configuration validation)
334#[derive(Args, Debug)]
335pub struct CheckArgs {
336 /// Path to fob.config.json
337 ///
338 /// Specify a custom configuration file location. If not provided,
339 /// searches for fob.config.json in the current directory.
340 #[arg(short, long, value_name = "FILE")]
341 pub config: Option<PathBuf>,
342
343 /// Also validate package.json dependencies
344 ///
345 /// Checks that all dependencies are installed and that their versions
346 /// are compatible with the project requirements.
347 #[arg(long)]
348 pub deps: bool,
349
350 /// Show warnings in addition to errors
351 ///
352 /// Displays potential issues that won't prevent building but might
353 /// indicate configuration problems or suboptimal settings.
354 #[arg(short, long)]
355 pub warnings: bool,
356}