Skip to content

Let completion output drain before exit - #178

Merged
myobie merged 2 commits into
mainfrom
agent/flush-completions
Sep 6, 2026
Merged

Let completion output drain before exit#178
myobie merged 2 commits into
mainfrom
agent/flush-completions

Conversation

@myobie

@myobie myobie commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

pty completions fish and pty completions zsh could exit before a pipe drained. Both commands returned success with truncated output.

This change sets the exit code and returns from the CLI entry point. Node then finishes pending stdout writes before it exits.

The direct failure reproduced on Linux with Node 24.18.0. It did not reproduce on macOS with Node 22.21.1 or Node 24.0.2, so the unmodified race is runtime and platform dependent.

The regression delays each stdout write. Under both Node 22.21.1 and Node 24.0.2, it received empty output before the fix and each complete artifact after the fix. This control does not depend on pipe size or scheduling luck.

Remaining forced-exit audit

The production source has 152 other process.exit() calls. Of these, 146 can follow output written by this process:

  • 125 stderr exits follow error text. They cover CLI parsing and command failures across run, attach, exec, peek, send, events, list, remote-serve, restart, kill, recover, gc, tag, rm, metadata, evidence, rename, tag-multi, emit, up, down, and stats, plus client and daemon failures.
  • Three stdout exits follow unknown-command usage, tag-multi --help, or invalid emit usage.
  • Two exits follow interactive restart prompts.
  • Eight local or remote attach and peek callbacks can exit after streamed terminal output.
  • One client fallback can exit after attach output, and one stdio remote-control exit can follow protocol output.
  • Four TUI exits follow terminal restoration writes.
  • Two event signal handlers can exit after event output.

The remaining six sites do not leave process-owned output pending. Four follow synchronous child commands with inherited stdio, one finishes a silent send, and one finishes a normal daemon shutdown.

These paths are reachable through ordinary commands, validation failures, session lifecycle, remote access, and signals. A terminal user usually sees short errors immediately. Pipes and log collectors can lose them while preserving only the exit status. The stdout, streamed-output, protocol, and terminal-restoration paths are directly visible and can truncate user data.

This pull request changes only the completion exit. The other sites need separate review.

Verification

  • Completion tests: 15 of 15 passed.
  • Piped output matched the checked-in fish, bash, and zsh files byte for byte.
  • Build, type check, documentation verification, and diff check passed.
  • The full suite passed 1,677 tests and skipped 21.
  • Two Nano tests failed because the environment reports Incomplete terminfo entry; this change does not affect them.

@myobie
myobie merged commit 314d6ec into main Sep 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant