Skip to content

/track: periodically refresh a command's output in one live block #393

Open

Description

@raiseCatError

Goal

Add /track, a lightweight live-updating command block: periodically re-run a finite command and replace the previous displayed result in the same block, rather than appending a new transcript entry at every interval. The normal NMSh composer stays usable.

This is distinct from watch/existing /watch behavior and from #382's long-running streaming background commands. /track is periodic re-execution plus a current-result snapshot, not a terminal takeover, a foreground rerun, or an append-only log.

Example UX

/track df -h /Volumes/T7Projects
/track docker system df
/track --every 5s -- docker system df

Example presentation (illustrative only):

↻ TRACK 02  docker system df              LIVE
  Every 5s · last completed 13:49:25 · exit 0

  TYPE             TOTAL   ACTIVE    SIZE
  Images               8        3    6.2GB
  Containers           5        2    1.1GB
  Local Volumes        4        3    3.4GB
  Build Cache         21        0    2.8GB

  [Pause] [Refresh] [Stop] [Copy]

On every completed refresh, update this block in place. Preserve the user's scroll position and selection, avoid whole-frame flicker, and do not flood normal history/search/copy with one entry per poll. Other commands can run in the foreground while tracks update. More than one tracker may be active.

Command and lifecycle contract

  • /track <command> starts an explicitly requested tracker, with a conservative configurable default cadence (propose 5s; settle after resource/UX testing). Support /track --every 5s -- <command> to disambiguate flags and commands. Show the effective interval.
  • Offer /track or /track list as a manager, with identifiable entries and pause, resume, refresh, stop actions (plus block-local controls). Stopping stops the scheduler and terminates only the currently owned task, using Background tasks: supervised long-running commands, task bar above the composer, and conservative suggestions #382's safe process-group rules.
  • Each interval starts only after the previous execution ends. No overlapping runs, duplicated dispatch or runaway catch-up; use a monotonic schedule/backoff and a minimum interval. Manual refresh cannot create overlap.
  • Keep the last completed snapshot visible while the next run is pending/running; label first run, last completion time, elapsed time, exit code, missed/slow refresh, current running state and staleness truthfully. A nonzero exit, timeout or spawn error must be visible, never silently presented as a healthy refreshed result. Define whether to preserve the last good snapshot alongside error output; no misleading timestamps.
  • Snapshot output is bounded (bytes, rows, retention and refresh/render rate). One current result plus at most one optional previous snapshot for deterministic change highlighting; no unlimited per-interval accumulation. Optional value/line delta highlight must not claim numeric understanding without an explicit parser.
  • Copy defaults to the latest completed output under the existing NMSh copy/sanitization semantics, without track chrome or concatenated prior samples. Distinguish raw process bytes, sanitized presentation and clipboard policy. Search/folding/session transcript semantics must state that this is a single evolving NMSh-owned track block, not repeatedly submitted foreground commands.
  • Preserve stable track identity and user focus/selection across updates and resize. Consider detach/reattach through session service; persist/live-restore only while the owning session/task supervisor can truthfully claim ownership. After service restart, mark unowned tracks stopped/lost rather than implying an orphan is supervised.
  • Pause/stop must be idempotent; account for slow/hung children, cancel/exit races, shell/session exit, cleanup and no leaked timers/PTYs/process groups. Do not disturb the foreground shell or queued commands.

Execution and safety boundaries

Reuse #382's supervised separate PTY/process group and session-service ownership; do not inject recurring commands into the live persistent shell, steal its input, or replace the existing same-shell queue (#357).

The tracker runs the explicitly provided text via the session shell -c as one argument, using an explicit starting cwd (default: cwd at tracker creation) and documented environment/PATH rules. It does not inherit the live shell's aliases, functions, unexported variables or shell options. Do not silently follow later cd changes. Do not claim Docker, shell or other mutable live-session state is automatically shared.

Periodic execution can repeat side effects. Provide conservative warnings/confirmation for obvious destructive or state-changing commands; allow deliberate expert override, with clear frequency/cost. Never auto-track arbitrary clipboard content, history, suggestions or previous commands. Reject or safely handle interactive/password/fullscreen commands. No external transmission or polling is implied by NMSh itself; launched commands retain their own effects.

Default behavior must avoid excessive CPU, disk, subprocess churn and unbounded output. Explicit resource caps, backoff and well-defined error states are required.

Implementation dependencies

Acceptance criteria

  • df -h /Volumes/T7Projects and docker system df refresh correctly in place and remain readable while running unrelated foreground commands.
  • Stable per-track block identity, no duplicate transcript blocks, no scroll/focus theft, and correct narrow/short/NO_COLOR/Safe rendering.
  • Configurable cadence, finite completion, slow-command serialization, manual refresh, pause/resume/stop and multi-track independence.
  • Exact-once per scheduled run; controlled failure, timeout, malformed ANSI, large/fast output and interrupted task; bounded resource usage and cleanup.
  • Copy/search/fold use documented latest-snapshot semantics; no accidental historical sample concatenation or leaked UI control bytes.
  • Safe task process-group cancellation, foreground and queue isolation, and honest detach/reattach/restart handling.
  • Real PTY/unit integration tests with fake finite commands (including slow, failing, side-effectful and high-output cases); physical Ghostty/Terminal.app and Linux/Fish checks, including running Docker examples only where Docker is actually available.
  • Commands, security limitations and execution-context differences documented with accurate examples.

Scheduling / release coordination

Target: v0.21 or later. This is a separate feature backlog item, not a change to the accepted v0.19 workflow freeze or the v0.20 release-candidate scope. Do not interrupt Opus's v0.19/v0.20 integration, reopen Codex's frozen frontend, or prematurely wire /track into the RC. Design and implement after the #382 background supervisor is integrated and independently verified.

Activity

  1. raiseCatError commented on Oct 18, 2026

    @raiseCatError
    OwnerAuthor

    v0.21 candidate clarification: PR #394 implements a post-v0.20 draft partial /track slice on an older release branch. Rebase/reconcile against published master/dev after the branch baseline is refreshed; do not merge it as-is. Respect side-effect and process-group risk, session-owned detach/reattach, bounded intervals, raw versus sanitized copy and real physical terminal QA before claiming full acceptance.

  2. raiseCatError commented on Oct 18, 2026

    @raiseCatError
    OwnerAuthor

    v0.21: #416 completes /track on the /watch scheduler; it supersedes draft #394, whose scheduler and panel code and tests were carried in as written. One block holds the latest result, refreshed in place: never stored or searched, with a stable height and truthful states. /track copy|refresh|pause|resume|stop; stopping leaves the last result once. Samples use the live shell's PATH and never overlap. Trackers stay window-owned; service-owned scheduling is deferred. Real-PTY test included. Physical checks: section 5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions