Repository navigation
Background tasks: supervised long-running commands, task bar above the composer, and conservative suggestions #382
Copy link
Copy link
Open
Description
Core terminal workflow feature (not an AI feature). Make long-running commands (adb logcat, tail -f, journalctl -f, docker logs -f, dev servers, watchers, ping, scrcpy) convenient without giving up the normal shell prompt.
Architecture (decided after auditing the session service, Keep Awake, ShellSession and input ownership)
- The real shell runs one foreground job at a time; NMSh does not try to multiplex it. A background task is an NMSh-supervised process in its own PTY and process group, owned by the session service (
nmshd) under the session that started it, so closing the window does not end it and reattach restores it. - The exact command text is run by the session's own shell as
<shell> -c <command>(one argv element, never re-quoted or concatenated), in the live shell's reported working directory, with the session's launch environment plus the livePATH. It does not inherit live aliases, functions, unexported variables or shell options; NMSh says so at the point of choice. Interactive/full-screen programs and commands needing live shell state stay foreground. - A running foreground command is never moved, killed or re-run.
- Output goes to a bounded per-task stream (PTY output, so stdout/stderr are merged exactly as in a terminal) and is presented in the main transcript as NMSh-owned task blocks with source labels, sanitized, never injected into the foreground PTY.
- Stop = SIGINT to the task's own process group, reported only after exit; explicit escalation to SIGTERM/SIGKILL; never signals NMSh's shell or processes NMSh did not start (daemons that detach, such as the adb server, are not in the group).
Acceptance criteria
- Conservative, explainable detector for command families (
adb logcatvsadb devices,tail -fvstail,npm run devas "may run",npm testnot); complex syntax, substitutions, heredocs, redirections, sudo/ssh and full-screen programs are never suggested. - Suggestion before start for recognized families: Background once / Foreground / Always for this family / Never for this family; nothing is backgrounded automatically without an explicit matching rule; per-invocation foreground override.
- Supervisor: own PTY and process group per task; start/stop/escalate/exit states truthful; process-group cleanup; no zombies; bounded output; high-volume and invalid UTF-8 handled.
- Task bar above the composer: collapsed one-line summary by default, expandable, width-aware, Safe/NO_COLOR, overflow, low cost when empty.
- Keyboard: Up from an idle composer (empty draft, not browsing history, no foreground command) focuses the bar, as it does for the agent shelf; ↑↓ select, Enter view,
xstop (again: escalate), Esc back; Shift+Up as an always-available alternative;/background(/bg) as the command path; never active while a foreground program owns input. - Stop / dismiss / remove are distinct operations.
- Transcript: per-task NMSh-owned blocks with live, bounded, sanitized output; focused live view; foreground blocks never interleaved with task output.
-
/backgroundmanager: running/completed tasks, details, output, stop, clear completed, preferences (per-family Ask/Always/Never, suggestions off, reset), retention and notification settings. - Session lifecycle: tasks survive detach, are restored on reattach, never duplicated by restore, ended with documented behavior when the session is exited or deleted; after a service restart, unknown tasks are reported as lost, not controlled.
- Tests with controlled processes mimicking logcat/tail -f/scrcpy/dev servers; physical QA for real adb/scrcpy documented separately.
Delivery
feature/background-tasks-core: detector, preferences, task model, output stream, supervisor (standalone, tested with real PTYs).feature/background-task-ui(stacked): task bar, focus/keys, suggestion strip,/backgroundmanager model, task output view.- Integration (service protocol messages, TerminalApp composer/transcript wiring) after the workflow track's input-routing stabilization checkpoint (Epic: terminal workflow initiative (make one command's result useful for the next) #359), through the acceptance branch; contract in
docs/development/context-workspace-handoff.md.
Related: #330 (workspace), #357 (command queue: unchanged semantics), #348 (input awareness: foreground input ownership), Keep Awake (lifecycle conventions only).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
raiseCatError commentedon Oct 11, 2026
Background task feature heads ready for review (not integrated, not physically validated)
feature/background-tasks-corerelease/v0.18.06884cf0typingAfterRead, the workflow track's input race, not in these files)/backgroundmanager, output viewsfeature/background-task-ui5d0a92eWhat is implemented and tested (real PTYs, controlled programs mimicking logcat / tail -f / scrcpy / an adb-server-style daemon):
<shell> -c <command>, with the command passed as one argument (exact quoting preserved).stoppinguntil its whole group has exited.adb logcatvsadb logcat -dvsadb devices,tail -fvstail,npm run devas "likely",npm testnot recognized). Remembered decisions are per command family; nothing runs in the background automatically without an explicit Always./background(/bg) always work.xstops a task and names the next escalation; Delete removes finished tasks only.Linux CI found three real platform differences, all fixed:
What a task does not inherit: the live shell's aliases, functions, unexported variables, options, or variables exported after the session started (it gets the session's launch environment plus the live PATH and cwd). Commands that need that state should run in the foreground.
Remaining, in order:
nmshd(SessionService.ts,SessionProtocol.ts)./backgroundcommand. Waits for the Epic: terminal workflow initiative (make one command's result useful for the next) #359 stabilization checkpoint.adb logcat(adb server and other adb commands unaffected by stop), realscrcpy, a dev server, detach/reattach, macOS/Linux/WSL2.Contracts:
docs/design/background-tasks.md,docs/design/background-task-ui.md. Handoff:docs/development/context-workspace-handoff.md(#385).