@@ -33,7 +33,7 @@ func main() {
3333 cmd := & cli.Command {
3434 Name : "agent-fetch" ,
3535 Usage : "Fetch web content and return markdown-friendly output" ,
36- UsageText : "agent-fetch [options] <url>" ,
36+ UsageText : "agent-fetch [options] <url> [url ...] " ,
3737 Version : versionString (),
3838 Flags : []cli.Flag {
3939 & cli.StringFlag {Name : "mode" , Value : defaultCfg .Mode , Usage : "fetch mode: auto|static|browser|raw" },
@@ -44,13 +44,14 @@ func main() {
4444 & cli.StringFlag {Name : "wait-selector" , Usage : "CSS selector to wait for in browser mode" },
4545 & cli.StringFlag {Name : "user-agent" , Value : defaultCfg .UserAgent , Usage : "User-Agent header" },
4646 & cli.Int64Flag {Name : "max-body-bytes" , Value : defaultCfg .MaxBodyBytes , Usage : "max response bytes to read" },
47+ & cli.IntFlag {Name : "concurrency" , Value : 4 , Usage : "max concurrent URL fetches when multiple URLs are provided" },
4748 & cli.StringSliceFlag {
4849 Name : "header" ,
4950 Usage : "custom request header, repeatable. Example: --header 'Authorization: Bearer token'" ,
5051 },
5152 },
5253 Action : func (ctx context.Context , c * cli.Command ) error {
53- if c .Args ().Len () != 1 {
54+ if c .Args ().Len () < 1 {
5455 _ = cli .ShowRootCommandHelp (c )
5556 return & exitStatusError {code : 2 }
5657 }
@@ -71,18 +72,34 @@ func main() {
7172 }
7273 cfg .Headers = parsedHeaders
7374
74- url := c .Args ().First ()
75- reqCtx , cancel := context .WithTimeout (ctx , maxDuration (cfg .Timeout , cfg .BrowserTimeout )+ 5 * time .Second )
76- defer cancel ()
75+ urls := c .Args ().Slice ()
76+ concurrency := c .Int ("concurrency" )
77+ if concurrency < 1 {
78+ return & exitStatusError {code : 2 , msg : "invalid concurrency: must be >= 1" }
79+ }
7780
78- res , err := fetcher .Fetch (reqCtx , url , cfg )
79- if err != nil {
80- return & exitStatusError {code : 1 , msg : fmt .Sprintf ("fetch failed: %v" , err )}
81+ if len (urls ) == 1 {
82+ reqCtx , cancel := context .WithTimeout (ctx , maxDuration (cfg .Timeout , cfg .BrowserTimeout )+ 5 * time .Second )
83+ defer cancel ()
84+
85+ res , err := fetcher .Fetch (reqCtx , urls [0 ], cfg )
86+ if err != nil {
87+ return & exitStatusError {code : 1 , msg : fmt .Sprintf ("fetch failed: %v" , err )}
88+ }
89+
90+ if _ , err := os .Stdout .WriteString (res .Markdown ); err != nil {
91+ return & exitStatusError {code : 1 , msg : fmt .Sprintf ("write failed: %v" , err )}
92+ }
93+ return nil
8194 }
8295
83- if _ , err := os .Stdout .WriteString (res .Markdown ); err != nil {
96+ results := fetchBatch (ctx , urls , cfg , concurrency , fetcher .Fetch )
97+ if err := writeBatchMarkdown (os .Stdout , results ); err != nil {
8498 return & exitStatusError {code : 1 , msg : fmt .Sprintf ("write failed: %v" , err )}
8599 }
100+ if failed := failedCount (results ); failed > 0 {
101+ return & exitStatusError {code : 1 }
102+ }
86103 return nil
87104 },
88105 }
0 commit comments