CLI gen: shared option set for request schemas reused across operations
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 92
- Forks
- 8
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 4
Description
Part of #338. Depends on gap #1 (per-parameter flags).
Today
Once gap #1 lands, each operation gets its own per-property flag list. For schemas reused across multiple operations (Firecrawl's ScrapeOptions is used by scrape, batch-scrape, and embedded in crawl), that produces:
- duplicated
Option<T>field definitions across multiple.g.csfiles (drift risk) - no way to share a single
--flagset under a prefix (--scrape-*incrawl)
Firecrawl's hand-written CliOptions.CreateScrapeOptionSet() returns a record with 28 options, used bare in scrape and prefixed --scrape-* in crawl. ~250 lines of careful manual wiring.
Target
When the generator detects a schema used as a request body or nested-in-request-body in 2+ operations:
- Emit a single
OptionSetstatic class with all the per-propertyOption<T>fields. - Each consuming command imports the option set bare or prefixed.
# bare (when ScrapeOptions IS the body)
firecrawl scrape <url> --only-main-content --formats markdown
# prefixed (when ScrapeOptions is nested inside CrawlRequest.scrapeOptions)
firecrawl crawl <url> --scrape-only-main-content --scrape-formats markdown
Proposed approach
- Detect reuse: walk all operation request bodies (plus recursive into nested objects); any
ModelDatareferenced 2+ times qualifies as an option set candidate. - Generate
<ModelName>OptionSetclass with one staticOption<T?>per scalar/array/enum property and aBind(parseResult)method returning the populated model. - Per-command consumption:
- bare:
command.Options.Add(ScrapeOptionsOptionSet.OnlyMainContent); ... - prefixed: a
WithPrefix(\"scrape-\")factory that returns aliasedOption<T>instances pointing at the same backing schema.
- bare:
- Vendor extension
x-cli-option-set: falseto opt out (always inline). - Collision rule: when both a top-level body property and a prefixed nested property would produce
--max-depth, the top-level wins and the nested becomes--<prefix>-max-depth.
Acceptance criteria
- Regenerating Firecrawl produces one
ScrapeOptionsOptionSet.g.csshared betweenscrapeandcrawl. firecrawl crawl <url> --scrape-only-main-content --scrape-formats markdownworks.- No duplicated
Option<T>field definitions across.g.csfiles for the same schema property.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing how request bodies and nested objects become generated .g.cs files, using Firecrawl's hand-written CliOptions.CreateScrapeOptionSet() as the existing behavior reference. Check the generated output for scrape and crawl; done means one shared ScrapeOptionsOptionSet.g.cs, working prefixed flags, and no duplicated Option fields for the same schema property.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, openapi
- Domain
- cli, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100