@@ -296,10 +296,11 @@ func authLoginRun(opts *LoginOptions) error {
296296 }
297297
298298 // Step 2: Show user code and verification URL.
299- // Both branches surface AgentTimeoutHint, but on different channels:
300- // JSON mode embeds it as a structured field (so an agent that captures
301- // stdout into a JSON parser sees it without stream-mixing surprises),
302- // text mode prints to stderr (alongside the URL prompt).
299+ // JSON mode embeds AgentTimeoutHint as a structured field so agents that
300+ // capture stdout into a JSON parser see it without stream-mixing surprises.
301+ // Text mode prints the hint to stderr only when running under a non-TTY
302+ // (i.e. piped / agent harness), since humans reading a terminal don't need
303+ // the agent-oriented instructions.
303304 if opts .JSON {
304305 data := map [string ]interface {}{
305306 "event" : "device_authorization" ,
@@ -317,7 +318,9 @@ func authLoginRun(opts *LoginOptions) error {
317318 } else {
318319 fmt .Fprintf (f .IOStreams .ErrOut , msg .OpenURL )
319320 fmt .Fprintf (f .IOStreams .ErrOut , " %s\n \n " , authResp .VerificationUriComplete )
320- fmt .Fprintln (f .IOStreams .ErrOut , msg .AgentTimeoutHint )
321+ if f .IOStreams != nil && ! f .IOStreams .IsTerminal {
322+ fmt .Fprintln (f .IOStreams .ErrOut , msg .AgentTimeoutHint )
323+ }
321324 }
322325
323326 // Step 3: Poll for token
@@ -404,10 +407,11 @@ func authLoginPollDeviceCode(opts *LoginOptions, config *core.CliConfig, msg *lo
404407 fmt .Fprintf (f .IOStreams .ErrOut , "[lark-cli] [WARN] auth login: failed to remove cached requested scopes: %v\n " , err )
405408 }
406409 }
407- // Skip the stderr hint in JSON mode — the --no-wait call that issued the
408- // device_code already returned the hint as a JSON field, and writing
409- // text to stderr would pollute consumers that combine streams via 2>&1.
410- if ! opts .JSON {
410+ // Skip the stderr hint in JSON mode (the --no-wait call that issued
411+ // the device_code already surfaced it as a JSON field), and also skip it
412+ // when running on an interactive terminal — the agent-oriented
413+ // instructions only matter for piped / harness environments.
414+ if ! opts .JSON && f .IOStreams != nil && ! f .IOStreams .IsTerminal {
411415 fmt .Fprintln (f .IOStreams .ErrOut , msg .AgentTimeoutHint )
412416 }
413417 log (msg .WaitingAuth )
0 commit comments