app-server: harden command/exec drain and lifecycle races

Close the remaining post-exit and control-path races by draining tail output with a quiet window plus a bounded final ready pass, and by returning consistent not-running errors after a process has already exited.

Add a dedicated helper binary and focused tests so the lifecycle behavior is reviewable on its own, and reject Windows disableTimeout requests that the buffered fallback cannot honor.
This commit is contained in:
Ruslan Nigmatullin
2026-03-05 21:43:50 -08:00
parent e9bd8b20a1
commit 58a5bd9c55
5 changed files with 508 additions and 57 deletions

View File

@@ -648,6 +648,7 @@ Notes:
- `size` is only valid when `tty: true`. It sets the initial PTY size in character cells.
- Buffered Windows sandbox execution accepts `processId` for correlation, but `command/exec/write` and `command/exec/terminate` are still unsupported for those requests.
- Buffered Windows sandbox execution also requires the default output cap; custom `outputBytesCap` and `disableOutputCap` are unsupported there.
- Buffered Windows sandbox execution does not support `disableTimeout`.
- `tty`, `streamStdin`, and `streamStdoutStderr` are optional booleans. Legacy requests that omit them continue to use buffered execution.
- `tty: true` implies PTY mode plus `streamStdin: true` and `streamStdoutStderr: true`.
- `tty` and `streamStdin` do not disable the timeout on their own; omit `timeoutMs` to use the server default timeout, or set `disableTimeout: true` to keep the process alive until exit or explicit termination.