Slice 2 of the CLI harness Effect migration. Drops the last raw
Bun.spawn call sites in withCliFixture.
- `serve` and `acp` both move from `Effect.acquireRelease(Bun.spawn(...))`
to `appProc.spawn(ChildProcess.make(...))`. The spawner's built-in
acquireRelease finalizer handles SIGTERM on scope close — no manual
wiring needed.
- `handle.stdout` / `handle.stderr` are already Effect Streams, so the
`fromBunStream` helper is gone (Stream.fromReadableStream + the
per-pipe error-tag boilerplate it wrapped).
- acp's stdin moves from imperative `proc.stdin.write` + `proc.stdin.end`
to a Queue<Uint8Array> fed into the spawner's stdin Sink via
Stream.fromQueue. `send` is `Queue.offer`, `close` is `Queue.shutdown` —
shutdown propagates as stdin EOF, which is ACP's graceful-exit signal.
- ServeHandle/AcpHandle public shape: `kill`/`close` become
Effect<void> and `exited` becomes Effect<number> (was () => void and
Promise<number>). The platform error that cross-spawn-spawner raises
on signal-kill is collapsed to exit code -1 so `exited` stays a clean
Effect<number> — matches the test contract (just needs proof of exit).
Two consuming tests updated to yield the Effect instead of awaiting
the Promise.