Skip to content

[rushd][WS1] Wire layer: protocol, transport & presentation #5896

Description

@bmiddha

Ship the engine-agnostic wire layer every client speaks and move presentation out of the engine. Deliver the frame taxonomy + length-prefixed codec, adopt @rushstack/reporter's event contract (#5858) as the daemon event schema, and stand up the workspace-keyed socket/pipe transport; have the engine dual-emit presentation-free structured events + per-operation raw byte streams that a client-side renderer turns back into faithful terminal UI, with per-client verbosity and color/width.

Depends on: @rushstack/reporter (#5858) phases 1 & 4; #5895

Scope

  • @rushstack/rush-daemon-protocol. The frame taxonomy (0x01 control-json, 0x02/0x03 log-stdout/stderr, 0x04 stdin, 0x05 event), a length-prefixed binary (de)serializer, and a PROTOCOL_VERSION constant.
  • Adopt the reporter event contract. Use @rushstack/reporter's IReporterEventEnvelope + its closed core event union (sessionStarted, commandStarted, operationRegistered, operationStatusChanged, activityChanged, watchCycleCompleted, diagnosticEmitted, externalOutput, commandResult, …) as the 0x05 event schema; add only daemon-specific events via the reporter's namespaced extension mechanism.
  • @rushstack/rush-daemon-transport. Workspace-key hashing (sha256(canonicalRepoRoot + rushVersion + startupOptions)), per-user runtime-dir socket/pipe path derivation, a net listener + connector, and PID/lock/stale-socket handling.
  • Conformance suite. Round-trip framing (non-UTF-8, interleaved/split stdout+stderr), backpressure, and version negotiation.
  • Engine dual-emit. Emit structured status events for every state currently written as colorized text via Colorize.* in OperationGraph, keeping today's terminal output until clients consume events.
  • Per-operation raw streams. Expose each operation's raw stdout/stderr as an id-tagged per-operation stream, separate from the collated sink.
  • @rushstack/rush-terminal-renderer. The CLI client's reporter host — driving @rushstack/reporter's built-in default/ai/plaintext reporters from the event stream and hosting StreamCollator for faithful per-op collation; apply quiet/debug/verbose as a per-client filter at event serialization (never mutating the shared graph); thread columns/colorLevel from the request envelope into child spawns (FORCE_COLOR/COLUMNS).

Acceptance criteria

  • All five frame types encode/decode through the length-prefixed codec; log/stdin frames round-trip arbitrary (including non-UTF-8) bytes losslessly, and PROTOCOL_VERSION is exported and asserted.
  • The 0x05 event frame carries IReporterEventEnvelope (core event union referenced, not re-declared); daemon-only events are namespaced extensions verified by a type-level test.
  • Two distinct workspaces (or differing rushVersion/startup options) resolve to distinct keys/paths while the same workspace stays stable across runs; listener + connector exchange a frame over a Unix socket (POSIX) and a named pipe (Windows); a stale socket/PID is detected and reclaimed without manual cleanup.
  • The conformance suite proves framing round-trips non-UTF-8 and interleaved stdout/stderr with no corruption/reordering, a slow consumer exercises backpressure without loss, and version negotiation handles both match and (typed-error) mismatch.
  • Every operation state transition emits a structured event with no information loss vs. the text, while today's colorized output is unchanged under dual-emit.
  • Each operation's raw stdout/stderr is retrievable as an id-tagged stream independent of the collated sink, and concatenated per-op bytes match the collated output (including binary/non-UTF-8).
  • The renderer reuses the reporter's default/ai/plaintext reporters (no re-implementation) and matches the in-process renderer for the same event stream (golden-output test); daemon-specific chrome is additive and isolated.
  • Verbosity is applied per subscription without mutating shared graph state (two clients at different verbosities each get the correct subset); a TTY client's child receives its FORCE_COLOR/COLUMNS while a non-TTY client's child receives neither, with no cross-contamination between concurrent clients.
  • New packages carry no rush-lib dependency and commit their API Extractor reports; Rush 5 behavior is preserved; tests green in CI.

Part of #5894.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    Needs triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions