Skip to content

refactor(output): split CLI, daemon, client, MCP, and replay presentation owners #2148

Description

@thymikee

Parent: #2129

Blocked by: #2133, #2134, and #2135. Wave 3; the formatter consumes the final text-surface, Android-helper, repeated-nav, and scroll/evidence paths.

Scope — exact tracked files

Production:

  • src/utils/doctor-output.ts
  • src/utils/doctor-progress.ts
  • src/utils/duration-format.ts
  • src/utils/error-candidates.ts
  • src/utils/output.ts
  • src/utils/result-serialization.ts
  • src/utils/screenshot-result.ts
  • src/utils/status-markers.ts

Tests:

  • src/utils/__tests__/error-candidates.test.ts
  • src/utils/__tests__/output-error.test.ts
  • src/utils/__tests__/output.test.ts
  • src/utils/__tests__/result-serialization.test.ts

Destination and importer edits

Move/split by the existing owner boundaries; no shared output replacement or internal barrel:

  • output.ts -> src/commands/output/json.ts, error.ts, snapshot.ts, diff.ts, and color.ts by exported function (printJson, printHumanError, formatSnapshotText, the two diff formatters, supportsColor, and colorize)
  • doctor-output.ts -> src/daemon/handlers/doctor-output.ts
  • doctor-progress.ts -> src/daemon/client/doctor-progress.ts
  • status-markers.ts -> src/daemon/handlers/status-markers.ts
  • duration-format.ts -> src/replay/test/duration-format.ts
  • screenshot-result.ts -> src/client/screenshot-result.ts
  • buildAppIdentifiers and buildDeviceIdentifiers from result-serialization.ts -> src/client/client-identifiers.ts
  • the session/device/deploy/install/open/close/snapshot serializers from result-serialization.ts -> src/daemon/result-serialization.ts

Move/split tests:

  • error-candidates.test.ts -> src/daemon/handlers/__tests__/interaction-error-candidates.test.ts
  • output-error.test.ts and the error cases from output.test.ts -> src/commands/output/error.test.ts
  • the snapshot cases from output.test.ts -> src/commands/output/snapshot.test.ts
  • the diff/color cases from output.test.ts -> src/commands/output/diff.test.ts and src/commands/output/color.test.ts
  • the identifier/serializer sections of result-serialization.test.ts -> src/client/__tests__/client-identifiers.test.ts and src/daemon/__tests__/result-serialization.test.ts

Update exact production importers:

  • src/cli.ts, src/cli/commands/shared.ts, src/cli/commands/web.ts, src/replay/test/reporting.ts -> command JSON output
  • src/cli.ts, src/mcp/tool-error.ts only through their existing owners -> human error/candidate rendering as applicable
  • src/commands/capture/output.ts, scripts/__tests__/help-conformance-sample-producers.ts -> snapshot output
  • src/cli/commands/screenshot.ts -> diff output and client screenshot-result
  • src/cli/commands/proxy.ts, src/replay/test/progress.ts, src/replay/test/reporters/default.ts, src/__tests__/proxy-command.test.ts -> color output
  • src/replay/test/progress.ts, src/replay/test/reporters/default.ts, src/replay/test/trace.ts -> replay duration
  • src/replay/test/progress.ts and src/daemon/handlers/doctor-output.ts -> status markers
  • src/daemon/handlers/session-doctor-output.ts, src/commands/management/output.ts, src/daemon/client/daemon-client-progress.ts -> doctor output/progress
  • src/agent-device-client.ts, src/cli/commands/screenshot.ts -> client screenshot-result
  • src/client/client-normalizers.ts -> client identifiers
  • src/commands/capture/output.ts, src/commands/management/output.ts, src/daemon/handlers/session-app-deployment.ts, src/daemon/handlers/session-app-source-deployment.ts, src/mcp/tool-result.ts -> their exact serializer functions
  • src/daemon/handlers/find-match-resolution.ts, src/daemon/handlers/interaction-ambiguity-publication.ts, src/mcp/tool-error.ts, src/mcp/tool-ref-pins.ts -> interaction error candidates

The final destination paths must stay in existing ranked zones (commands, client, daemon, or replay); do not add a new top-level output or common zone.

Behavior invariants

Preserve every human/JSON output byte, snapshot raw/regular/unchanged/visibility/warning/Android-helper rendering, diff formatting, color/TTY detection, candidate caps and ref-generation pinning, doctor marker/progress state, duration formatting, screenshot overlay/result parsing, and all public client/daemon/MCP serializer keys, omission rules, success text, and error behavior. Preserve help-conformance sample output and lazy CLI closure. No wire shape, retry, timeout, snapshot policy, or MCP projection changes.

The mixed 1,861-line output test must be split along these exact production owners and no resulting test may remain over the 1,000-line ratchet.

Focused validation

Run all moved output/serializer tests, then:

  • pnpm vitest run src/commands/output/*.test.ts src/daemon/handlers/__tests__/interaction-error-candidates.test.ts src/client/__tests__/client-identifiers.test.ts src/daemon/__tests__/result-serialization.test.ts
  • the existing CLI, capture, management, MCP, replay, screenshot, and help-conformance tests
  • pnpm vitest run scripts/__tests__/test-file-size-ratchet.test.ts
  • pnpm check:affected --run

Planted-red proof

No new structural rule is added. Temporarily alter one help-conformance sample, omit one serializer key, or disable candidate ref pinning and observe the independent named test fail before restoring the original. The split must not turn tests into comparisons against the same moved implementation.

Dependency order

Start only after #2133, #2134, and #2135. The terminal child is blocked by this child. The transport child remains independent.

Shrink target

Delete all eight old production modules and four old utility tests. Split output.ts and its 1,861-line test below the file-size ratchet. After discounting physical moves, the aggregate production diff must be negative (additions minus deletions <= -1); remove redundant re-export/helper lines rather than adding a shared facade.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions