@@ -70,15 +70,18 @@ function createScrapeCommand(): Command {
7070 const scrapeCmd = new Command ( 'scrape' )
7171 . description ( 'Scrape a URL using Firecrawl' )
7272 . argument ( '[url]' , 'URL to scrape' )
73+ . argument (
74+ '[formats...]' ,
75+ 'Output format(s) as positional args (e.g., markdown screenshot links)'
76+ )
7377 . option (
7478 '-u, --url <url>' ,
7579 'URL to scrape (alternative to positional argument)'
7680 )
7781 . option ( '-H, --html' , 'Output raw HTML (shortcut for --format html)' )
7882 . option (
7983 '-f, --format <formats>' ,
80- 'Output format(s). Multiple formats can be specified with commas (e.g., "markdown,links,images"). Available: markdown, html, rawHtml, links, images, screenshot, summary, changeTracking, json, attributes, branding. Single format outputs raw content; multiple formats output JSON.' ,
81- 'markdown'
84+ 'Output format(s). Multiple formats can be specified with commas (e.g., "markdown,links,images"). Available: markdown, html, rawHtml, links, images, screenshot, summary, changeTracking, json, attributes, branding. Single format outputs raw content; multiple formats output JSON.'
8285 )
8386 . option ( '--only-main-content' , 'Include only main content' , false )
8487 . option (
@@ -100,7 +103,7 @@ function createScrapeCommand(): Command {
100103 'Show request timing and other useful information' ,
101104 false
102105 )
103- . action ( async ( positionalUrl , options ) => {
106+ . action ( async ( positionalUrl , positionalFormats , options ) => {
104107 // Use positional URL if provided, otherwise use --url option
105108 const url = positionalUrl || options . url ;
106109 if ( ! url ) {
@@ -110,8 +113,21 @@ function createScrapeCommand(): Command {
110113 process . exit ( 1 ) ;
111114 }
112115
113- // Handle --html shortcut flag
114- const format = options . html ? 'html' : options . format ;
116+ // Merge formats: positional formats take precedence, then --format flag, then default to markdown
117+ let format : string ;
118+ if ( positionalFormats && positionalFormats . length > 0 ) {
119+ // Positional formats: join them with commas for parseFormats
120+ format = positionalFormats . join ( ',' ) ;
121+ } else if ( options . html ) {
122+ // Handle --html shortcut flag
123+ format = 'html' ;
124+ } else if ( options . format ) {
125+ // Use --format option
126+ format = options . format ;
127+ } else {
128+ // Default to markdown
129+ format = 'markdown' ;
130+ }
115131
116132 const scrapeOptions = parseScrapeOptions ( { ...options , url, format } ) ;
117133 await handleScrapeCommand ( scrapeOptions ) ;
@@ -547,14 +563,33 @@ async function main() {
547563 // Treat as scrape command with URL - reuse commander's parsing
548564 const url = normalizeUrl ( args [ 0 ] ) ;
549565
550- // Modify argv to include scrape command with URL as positional argument
566+ // Collect any positional format arguments (non-flag arguments after the URL)
567+ const remainingArgs = args . slice ( 1 ) ;
568+ const positionalFormats : string [ ] = [ ] ;
569+ const otherArgs : string [ ] = [ ] ;
570+
571+ for ( const arg of remainingArgs ) {
572+ // If it starts with a dash, it's a flag (and everything after goes to otherArgs)
573+ if ( arg . startsWith ( '-' ) ) {
574+ otherArgs . push ( arg ) ;
575+ } else if ( otherArgs . length === 0 ) {
576+ // Only treat as positional format if we haven't hit a flag yet
577+ positionalFormats . push ( arg ) ;
578+ } else {
579+ // This is an argument to a flag
580+ otherArgs . push ( arg ) ;
581+ }
582+ }
583+
584+ // Modify argv to include scrape command with URL and formats as positional arguments
551585 // This allows commander to parse it normally with all hooks and options
552586 const modifiedArgv = [
553587 process . argv [ 0 ] ,
554588 process . argv [ 1 ] ,
555589 'scrape' ,
556590 url ,
557- ...args . slice ( 1 ) ,
591+ ...positionalFormats ,
592+ ...otherArgs ,
558593 ] ;
559594
560595 // Parse using the main program (which includes hooks and global options)
0 commit comments