Skip to content

Auto-generate HTML report + modern, research-grade report redesign - #23

Merged
YashvantHange merged 3 commits into
mainfrom
feat/auto-html-modern-report
Jul 18, 2026
Merged

Auto-generate HTML report + modern, research-grade report redesign#23
YashvantHange merged 3 commits into
mainfrom
feat/auto-html-modern-report

Conversation

@YashvantHange

Copy link
Copy Markdown
Owner

What & why

The report (HTML on screen, PDF in print) is Investo's user-facing deliverable, and three things fell short: it was never produced automatically, the look was a deliberately austere print note, and the PDF was not research-grade (uppercase chrome tracked so heavily it rendered/copied as I N V E S T O, plus a fragile running header/footer and tables that could overflow). This PR fixes all three.

Changes

Auto-generate the HTML report

  • CLI: investo analyze <name> now writes a self-contained HTML note by default (named investo-<SYMBOL>-<date>.html in the cwd). The notice goes to stderr so --json stays pipeable. --no-html opts out; --html FILE/--pdf still override, and an explicit artifact suppresses the duplicate auto-HTML.
  • MCP: analyze_company writes an HTML note too and returns html_report_path (plus generated_at, investo_version, html_bytes); emit_html=false opts out. The tool is now correctly annotated as a file writer.

Modern, visual redesign (render/css.py, render/html.py)

  • Design-token system in :root: spacing scale, radii, shadows and a semantic status palette, consumed everywhere (no hardcoded colour at a call site).
  • New components: masthead rating block, a row of KPI cards, colour status badges from one shared verdict→colour mapping, card-framed zebra tables, a table of contents, a colophon, <meta name="description">, and accessible table <caption>s.
  • Drops the heavy letter-spacing/all-caps that was the root of the I N V E S T O artifact.
  • Verdicts use Investo's own vocabulary (rating /100, quality, valuation stance) — never BUY/HOLD/SELL, which would contradict the built-in disclaimer.

Research-grade PDF (print CSS + export.py)

  • Per-page running header/footer via a repeating <thead>/<tfoot> group — the reliable technique in Chromium — replacing position:fixed furniture that rendered inverted and clipped body text on full pages.
  • Tables/charts fit the page (the 6-column peer table wraps cleanly), table headers repeat across pages, badge/card colours print, and a cover page break.
  • Playwright path uses prefer_css_page_size so the document's @page rule owns size/margins.

Verification

  • pytest -q284 pass (updated the stale "no coloured pill" and read-only-tool tests and the CLI tests; added coverage for auto-HTML on CLI + MCP, badges/cards/TOC, captions, and a no-BUY/SELL guard).
  • Rendered RELIANCE.NS end-to-end to HTML and an 11-page PDF via headless Chrome and inspected every representative page (cover, thesis/rating, tables): header/footer correct with no overlap, tables fit, sensible page breaks, colours correct.
  • Confirmed the MCP analyze_company path returns a valid html_report_path and that emit_html=false writes nothing.

Note

The stylesheet's original docstring codified "no cards, no coloured pills, status as typography." This PR deliberately reverses that toward a modern, visual look (docstring and the CSS-substring tests updated to match).

Follow-up to the quality-aware scoring change (#21), which shipped without
user-facing docs.

- CHANGELOG: add an [Unreleased] Changed entry covering the quality factor,
  the net-cash reward, the Debt -> Balance Sheet rename, the reweighting, and
  the preserved rank order.
- README: update the rating-buckets table to the shipped weights
  (15/17/10/11/10/12/10/5/5/5, +5 ESG) with the Balance Sheet bucket, and add a
  short note explaining quality-aware valuation and the net-cash effect.
Deliver the analysis as a document automatically and make it read as
professional equity research in both HTML and PDF.

Auto-HTML
- `investo analyze` writes a self-contained HTML note by default (--no-html to
  skip; announced on stderr so --json stays pipeable).
- The MCP `analyze_company` tool writes one too, returning html_report_path
  (plus generated_at, investo_version, html_bytes); emit_html=false opts out.
  The tool is now correctly marked as a file writer.

Modern redesign (render/css.py, render/html.py)
- Design-token system: spacing scale, radii, shadows and a semantic status
  palette in :root, consumed everywhere.
- New furniture: masthead rating block, KPI cards, colour status badges from
  one shared mapping, card-framed zebra tables, a table of contents, a
  colophon, <meta description> and accessible table captions.
- Removes the heavy letter-spacing that made PDF text render and copy as
  "I N V E S T O".

Research-grade PDF (print CSS + export.py)
- Per-page running header/footer via a repeating thead/tfoot group, replacing
  fixed-position furniture that rendered inverted and clipped body text on full
  pages.
- Tables and charts fit the page, table headers repeat, colours print, cover
  page break.

Tests updated and added (auto-HTML on CLI/MCP, badges/cards/TOC, captions, a
no-BUY/SELL guard); all 284 pass.
- mypy: annotate the KPI growth-signal local as str | None (the two branches
  assign different Literal types, which mypy rejected as an implicit narrow).
- ruff: pre-existing nits the newer CI linter now flags — sort the finutils
  import members and rewrite a test-helper dict() call as a literal.
@YashvantHange
YashvantHange merged commit 78349d5 into main Jul 18, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant