@@ -15,12 +15,13 @@ var runCmd = &cobra.Command{
1515 Use : "run [--description <desc>] [--] <command> [args...]" ,
1616 Short : "Add a job and wait for it to complete" ,
1717 DisableFlagParsing : true ,
18- Long : `Add a new background job and immediately wait for it to complete.
18+ Long : `Add a new background job and wait for it to complete.
1919
20- This is equivalent to running 'gob add' followed by 'gob await'.
20+ The job is started as a detached process. Output is suppressed on success
21+ and dumped on failure. Use 'gob add' + 'gob await' for real-time streaming.
2122
22- The job is started as a detached process and its output is streamed in real-time .
23- The command exits with the job's exit code when it completes .
23+ On success: prints a summary with helper commands to inspect output .
24+ On failure: prints the full stdout and stderr, then a summary .
2425
2526Examples:
2627 # Run a build and wait for it
@@ -40,7 +41,9 @@ Examples:
4041 gob run -d "Run tests" -- npm test
4142
4243Output:
43- Shows job statistics (if available), then streams the job's output.
44+ Shows job statistics (if available), then waits silently.
45+ On success: summary with commands to view output.
46+ On failure: full stdout/stderr followed by summary.
4447
4548Exit codes:
4649 Exits with the job's exit code (0 if successful, non-zero otherwise).
@@ -165,21 +168,21 @@ Exit codes:
165168 fmt .Printf (" Stuck detection: timeout after %s\n " , formatDuration (stuckTimeout ))
166169 }
167170
168- // Follow the output until completion
169- followResult , err := followJob ( result . Job . ID , result .Job .PID , result .Job .StdoutPath , avgDurationMs )
171+ // Wait for job to complete (without streaming output)
172+ waitResult , err := waitForJob ( result .Job .PID , result .Job .StdoutPath , avgDurationMs )
170173 if err != nil {
171174 return err
172175 }
173176
174- if followResult .PossiblyStuck {
177+ if waitResult .PossiblyStuck {
175178 fmt .Printf ("\n Job %s possibly stuck (no output for 1m)\n " , result .Job .ID )
176179 fmt .Printf (" gob stdout %s # check current output\n " , result .Job .ID )
177180 fmt .Printf (" gob await %s # continue waiting with output\n " , result .Job .ID )
178181 fmt .Printf (" gob stop %s # stop the job\n " , result .Job .ID )
179182 return nil
180183 }
181184
182- if ! followResult .Completed {
185+ if ! waitResult .Completed {
183186 fmt .Printf ("\n Job %s continues running in background\n " , result .Job .ID )
184187 fmt .Printf (" gob await %s # wait for completion with live output\n " , result .Job .ID )
185188 fmt .Printf (" gob stop %s # stop the job\n " , result .Job .ID )
@@ -192,9 +195,23 @@ Exit codes:
192195 return err
193196 }
194197
198+ // On failure (non-zero or killed by signal), dump stdout/stderr
199+ if job .ExitCode == nil || * job .ExitCode != 0 {
200+ if err := printJobOutput (job ); err != nil {
201+ return err
202+ }
203+ }
204+
195205 // Show summary
196206 printJobSummary (job )
197207
208+ // On success, show helper commands for inspecting output
209+ if job .ExitCode != nil && * job .ExitCode == 0 {
210+ fmt .Printf (" gob stdout %s # view stdout\n " , result .Job .ID )
211+ fmt .Printf (" gob stderr %s # view stderr\n " , result .Job .ID )
212+ fmt .Printf (" gob logs %s # view both\n " , result .Job .ID )
213+ }
214+
198215 // Exit with job's exit code
199216 if job .ExitCode != nil && * job .ExitCode != 0 {
200217 os .Exit (* job .ExitCode )
0 commit comments