Skip to content

Add --format flag and structured output pipeline #222

@calchiwo

Description

@calchiwo

Problem

Currently the CLI only outputs human-readable text.

Not usable for:

  • piping into other tools

  • CI usage

  • storing structured results

  • testing output reliably

Handlers also mix:

  • reading

  • analysis

  • generation

  • printing

That makes output fragile and hard to control.

Proposal

Add:

--format text   (default)
--format json

Rules:

  • --format controls output structure

  • analysis flags control computation

Flags remain independent:

  • --quick

  • --simple

  • --detailed

  • --stack

  • --map

Core rule

  • stdout is the data interface

  • text mode → human-readable output to stdout

  • json mode → machine-readable output to stdout

  • stderr → logs, diagnostics, progress

stdout must stay clean in json mode

Format vs Output

  • --format = structure (text or json)

  • --output = destination (stdout or file)

They must stay independent

JSON contract

In --format json:

  • exactly one JSON object on stdout

  • no spinners

  • no banners

  • no extra text

  • exit code != 0 on failure

  • no logs in stdout

Required shape (v1):

{
  "schema_version": 1,
  "ok": true,
  "tool": "explainthisrepo",
  "version": "0.x.y",
  "mode": "detailed",
  "target": {},
  "provider": "openai",
  "output": {},
  "signals": {},
  "warnings": [],
  "timings_ms": {}
}

Failure:

{
  "schema_version": 1,
  "ok": false,
  "error": {
    "type": "ProviderError",
    "message": "..."
  }
}

Mode-specific fields allowed (stack, map, etc), but top-level stays stable.

Architecture change

Split into:

  1. Acquisition
  • files

  • repo tree

  • GitHub data

  • README

  • languages

  1. Analysis
  • returns structured result

  • no printing

Example:

@dataclass
class AnalysisResult:
    ok: bool
    mode: str
    target: dict
    provider: str | None
    output: dict | None
    warnings: list[str]
    error: dict | None = None
  1. Presentation
  • render_text(result)

  • render_json(result)

Implementation plan

  • add --format text|json

  • refactor handlers to return structured result

  • add emit(result, format)

  • implement render_json(...)

  • suppress stdout logs in json mode

  • move logs to stderr

  • centralize error handling

  • add schema_version: 1

Tests

  • stdout is valid JSON

  • no stray stdout text in json mode

  • correct exit codes on failure

Acceptance criteria

  • --format json → valid JSON only on stdout

  • no mixed output in json mode

  • --format text → current behavior unchanged

  • works with all modes

  • failures return structured JSON + nonzero exit code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions