SIGN IN SIGN UP

feat(chat): show live background tasks under the composer

Renders the AIR async-task channel as a strip docked beside the
session-failure banner: one row per running or paused task, with the tool
it last ran, its token cost, a link to its output file, and a stop button.

Only non-terminal tasks show. A settled task leaves at once — its outcome
belongs to the transcript, and a permanent list of finished jobs under the
composer would grow all session. The reducer still keeps the settled row,
since the adapter goes on revising it.

The reducer mirrors the backend merge (partial deltas, absent means
unchanged, only a spawn frame creates), and hydrates whole rows from the
snapshot so a client attaching mid-episode learns about work already
running.

Two affordances are gated on being able to honour them: the stop button
needs a live owned connection, and the output link needs a local desktop
window — `openPath` silently no-ops in web and remote-desktop windows,
where the path belongs to another host. A declined stop is surfaced,
because a successful one announces itself by the row disappearing and
silence would look identical to a click that did nothing.
X
xintaofei committed
6a0a79d438a45b3c008a7c8b8d5277aa9f200234
Parent: 52818ca