🤖 Generated by the Daily AI Engineer
Problem
Long-running / interactive CLI commands print progress and instruction notices to
stderr while they run, but those notices don't reach the user until the command
returns. The error-handler executor (pkg/cli/ui/errorhandler/executor.go) redirects
stderr into a buffer for the duration of cmd.Execute() and only flushes it afterward,
so a command that writes a notice and then blocks shows that notice too late to be
useful.
Affected commands (each writes to ErrOrStderr() then blocks):
ksail workload watch — "watching: <dir>" / "press Ctrl+C to stop" (workload/watch.go:197-203)
ksail workload intercept — "intercepting inbound traffic … press Ctrl-C to stop" (workload/intercept.go:345-350)
ksail open web — its browser-launch fallback notice
Evidence
Flagged in review of #6216 (Codex P2, "Stream stderr before long-running commands
return"). Reproduced against the real binary: running ksail workload watch and
capturing stderr while it is still running shows watching: … / press Ctrl+C to stop only because those are written to the process stderr — but with the current
buffer-until-return design they would be withheld until the watch loop exits (i.e. after
Ctrl+C), which is exactly when the "press Ctrl+C to stop" hint is no longer useful.
Why this wasn't fixed in #6216
#6216 fixes the custom-exit-code half of the same warning-discard class (its finding 1).
The streaming half was deferred there on the premise that live streaming conflicts with
the executor's capture-for-normalization design (a naive tee would double-print the error
on failures). That premise doesn't hold once the capture is removed rather than tee'd
(see below), so this is tracked here as a focused follow-up rather than dropped.
Proposed approach (verified)
Remove the executor's stderr capture entirely:
- Set
cmd.SilenceErrors = true so Cobra no longer prints its own error line — the
executor owns error reporting and normalizes the returned error directly. Every
real ksail command sets SilenceUsage, so Cobra's err.Error() already carries the
full message; the capture was redundant.
- Commands then write warnings/notices straight to the real stderr, live, on every
exit path (success, real error, custom-exit).
This avoids the double-print the #6216 thread worried about (there is no tee of Cobra's
error line, because Cobra no longer prints it). Verified locally against the real binary:
workload watch notices stream live, the error path prints a single normalized message
(no duplicate), and the unknown-command message is unchanged for real commands (the
synthetic-test usage hint moves to Cobra's usage output, gated by SilenceUsage).
Acceptance criteria
Rough size: S (executor-only change + test updates). Land after #6216 merges to
avoid a branch collision on executor.go.
Problem
Long-running / interactive CLI commands print progress and instruction notices to
stderr while they run, but those notices don't reach the user until the command
returns. The error-handler executor (
pkg/cli/ui/errorhandler/executor.go) redirectsstderr into a buffer for the duration of
cmd.Execute()and only flushes it afterward,so a command that writes a notice and then blocks shows that notice too late to be
useful.
Affected commands (each writes to
ErrOrStderr()then blocks):ksail workload watch—"watching: <dir>"/"press Ctrl+C to stop"(workload/watch.go:197-203)ksail workload intercept—"intercepting inbound traffic … press Ctrl-C to stop"(workload/intercept.go:345-350)ksail open web— its browser-launch fallback noticeEvidence
Flagged in review of #6216 (Codex P2, "Stream stderr before long-running commands
return"). Reproduced against the real binary: running
ksail workload watchandcapturing stderr while it is still running shows
watching: …/press Ctrl+C to stoponly because those are written to the process stderr — but with the currentbuffer-until-return design they would be withheld until the watch loop exits (i.e. after
Ctrl+C), which is exactly when the "press Ctrl+C to stop" hint is no longer useful.
Why this wasn't fixed in #6216
#6216 fixes the custom-exit-code half of the same warning-discard class (its finding 1).
The streaming half was deferred there on the premise that live streaming conflicts with
the executor's capture-for-normalization design (a naive tee would double-print the error
on failures). That premise doesn't hold once the capture is removed rather than tee'd
(see below), so this is tracked here as a focused follow-up rather than dropped.
Proposed approach (verified)
Remove the executor's stderr capture entirely:
cmd.SilenceErrors = trueso Cobra no longer prints its own error line — theexecutor owns error reporting and normalizes the returned error directly. Every
real ksail command sets
SilenceUsage, so Cobra'serr.Error()already carries thefull message; the capture was redundant.
exit path (success, real error, custom-exit).
This avoids the double-print the #6216 thread worried about (there is no tee of Cobra's
error line, because Cobra no longer prints it). Verified locally against the real binary:
workload watchnotices stream live, the error path prints a single normalized message(no duplicate), and the unknown-command message is unchanged for real commands (the
synthetic-test usage hint moves to Cobra's usage output, gated by
SilenceUsage).Acceptance criteria
execution, not after it returns (RED/GREEN test).
DriftExitError) behavior preserved.go test ./pkg/cli/... .green;golangci-lint runclean; real-binary user-eval.Rough size: S (executor-only change + test updates). Land after #6216 merges to
avoid a branch collision on
executor.go.