Skip to content

docs: plain README, with the bugs it listed fixed in code - #24

Merged
abrichr merged 9 commits into
mainfrom
docs/plain-readme
Oct 14, 2026
Merged

abrichr merged 9 commits into
mainfrom
docs/plain-readme

Conversation

@abrichr

@abrichr abrichr commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

The README now opens with what the package does, who it is for, and a two-command quick start. It then shows the directory layout that openadapt-viewer benchmark reads, so a reader can view their own run.

The old "What it doesn't do" list described bugs. This PR fixes them in code, with tests, and removes the list:

  • PageBuilder(dark_mode=False) now renders light. The argument was stored and never read.
  • benchmark --standalone now embeds screenshots as data URIs, so the file keeps its images after you move it. Before, the generator ignored the flag.
  • __version__ now comes from package metadata, and there is a new openadapt-viewer --version flag. 0.2.0 reported 0.1.0.
  • A legacy capture.db directory: fix(viewers): report a legacy capture directory, and inline the timeline assets #22 already fixed this. A new CLI test checks that benchmark exits 1, prints the migration script, and prints no "Generated:" line.

Running every README example in a browser turned up four more bugs, also fixed here with tests:

  • The capture player broke on every page with at least one step. The steps JSON went raw into x-data="...", so its first " ended the attribute and the browser printed the component source as text. The JSON, capture id, and goal are now HTML-escaped.
  • The capture player's click marker lost its position and circle, because a string :style replaces the static style in Alpine. It also used a fixed 16:9 box instead of the image to place the marker. Measured in Chromium, (0.42, 0.31) now lands at (0.42, 0.31) on the frame.
  • An execution.json with no task_id defaulted to "unknown", so a hand-written run showed every task as failed with zero steps.
  • The status filter read "All Statuss". The README screenshot is regenerated.

A second pass, following the README from a fresh venv, found three more:

  • Without --standalone, screenshot links were relative to the run directory, but the browser resolves them against the HTML file. The README's example writes my-run.html beside my-run/, so every screenshot was broken. Links are now relative to the output file.
  • The task list and detail panel were meant to sit side by side, but the grid was on an element with one child, so the panel stacked under the list and the right two thirds of the page stayed empty. In Chromium at 1100px the list is now at x=24 and the panel at x=391.
  • The header's theme toggle showed a dot, because its outline sun icon was filled instead of stroked.

What is still true goes in a short Limits section: PyPI has 0.2.0, which lacks these fixes; Alpine.js loads from a CDN; benchmark reads one layout; and recordings from before 2026-07-17 need converting first. The README never used admission or ledger language, so there was nothing to move to a compliance doc. Image and file links are now absolute, so they also work on PyPI.

How I checked it:

  • uv run ruff check . passes.
  • uv run pytest tests/ passes (213 passed, 45 skipped), with the openadapt-capture example recordings available.
  • I built a wheel from this branch, installed it in an empty venv, and ran every README command and Python block.
  • I built a two-step run by hand, ran benchmark --standalone, moved the HTML, and rendered it in Chromium. The screenshots were still there.
  • I ran benchmark on a copy of the turn-off-nightshift example recording with an episodes.json.
  • I rendered the capture player in Chromium with no page errors.

The PyPI page and pip install openadapt-viewer stay on 0.2.0 until the next release. In a fresh venv, 0.2.0 marks the README's example task failed, ignores --standalone, does not read recording.db, and renders the capture player as source text. The first Limits bullet says so and gives pip install git+https://github.com/OpenAdaptAI/openadapt-viewer; remove it after the next release. This PR does not trigger a release.

🤖 Generated with Claude Code

abrichr and others added 6 commits October 14, 2026 03:08
…rsion

`benchmark --standalone` reached generate_benchmark_html and was ignored
there, so every screenshot stayed a path relative to the data directory and a
viewer lost its images once moved or mailed. It now embeds each readable
screenshot as a base64 data URI, resolving relative paths against --data and
then the working directory. Data URIs, URLs and unreadable paths pass through
unchanged. The help text now says what the flag does; it never embedded
Alpine.js and still does not.

`openadapt_viewer.__version__` was a hardcoded "0.1.0" that the release
workflow never bumped, so 0.2.0 reported 0.1.0. It is now read from the
installed distribution's metadata, and `openadapt-viewer --version` prints it.

The `capture` and `screenshots` help strings now say that the first renders
five sample steps and the second needs a source checkout.

Tests: --standalone embeds and the default links; a legacy capture.db
directory makes `benchmark` exit 1 with the migration script on stderr and no
"Generated:" line (fixed in #22, now pinned at the CLI); __version__ and
--version match package metadata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PageBuilder stored `dark_mode` and never read it, so `dark_mode=False`
rendered the same dark page as the default. The stylesheet is dark by default
and `.oa-light` overrides it, so a light page now opens with
`<body class="oa-light">`. The header toggle flips the same class and keeps
working from either starting theme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the click marker on the frame

generate_capture_html wrote the steps JSON raw into a double-quoted
x-data="..." attribute. The first '"' in the JSON closed the attribute, Alpine
hit a syntax error, and the browser printed the rest of the component as page
text. That happened for every capture page with at least one step. The steps
and episodes JSON, the capture id and the goal are now HTML-escaped.

With the page rendering, two more defects showed:

- The click marker bound `:style` to a string, which Alpine applies by
  replacing the static style, so the marker lost `position: absolute` and its
  circle and showed as a bare "H" beside the image. The binding is now an
  object, which Alpine merges.
- The marker was positioned against a fixed 16:9 box rather than the image,
  so x/y fractions were off for any frame that did not fill that box. The
  image and marker now share a wrapper sized by the image. Measured in
  Chromium: (0.42, 0.31) lands at (0.42, 0.31) on a 2880x1800 frame, and
  (0.0, 1.0) at the corner of a 320x180 one.

A timestamp of 0.0 also showed as "N/A"; it now shows "0.00s".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The benchmark viewer matches tasks to executions by task_id, and an
execution.json without one defaulted to "unknown". A hand-written run
directory therefore showed every task as failed with zero steps, though the
file sat in the task's own directory. The id now defaults to the task.json
task_id, or the directory name when there is no task.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
filter_dropdown appended "s" to the label, so the benchmark viewer's status
filter read "All Statuss". The README screenshot is regenerated with
scripts/generate_demo_screenshot.py to show the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first screen now says what the package does, who it is for, and a
two-command quick start, followed by the directory layout that `benchmark`
reads, so a reader can view their own run without opening the source. Every
command and code block was run against a wheel built from this branch in an
empty venv; the run layout was checked by building a two-step run by hand,
generating it with --standalone, moving the HTML, and rendering it in
Chromium.

The "What it doesn't do" list is gone. Its items were fixed in this branch or
in #22: dark_mode, --standalone, __version__, the swallowed
LegacyCaptureError, and the episode timeline assets. What remains true goes in
a short Limits section: Alpine.js loads from a CDN, `benchmark` reads one
layout, and legacy capture.db recordings need converting first.

Image and file links are absolute so they also work on the PyPI page, and
the PyPI summary line says what the package does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📸 Generated Screenshots Preview

Screenshots have been generated. Download the artifacts to preview them.

Generated Files:

  • demo_new_controls.png (0.10 MB)
  • demo_new_events.png (0.09 MB)
  • demo_new_full.png (0.12 MB)
  • demo_viewer.png (0.30 MB)
  • turn-off-nightshift_controls.png (0.10 MB)
  • turn-off-nightshift_events.png (0.10 MB)
  • turn-off-nightshift_full.png (0.12 MB)

🔗 Download screenshots artifact

abrichr and others added 3 commits October 14, 2026 03:34
…etail panel beside the task list

Without --standalone, screenshot links were relative to the run directory,
but a browser resolves <img src> against the HTML file. The README's own
example, `benchmark --data my-run --output my-run.html`, writes the page
beside the run, so every screenshot was broken. Relative paths are now
resolved the same way --standalone resolves them and rewritten relative to
the output file. Absolute paths, URLs and data URIs are left alone.

The two-column grid sat on the <section>, whose only child is the Alpine
root, so the detail panel stacked under the task list and the right two
thirds of the page stayed empty. The grid now sits on the Alpine root.
Measured in Chromium at 1100px: the list at x=24 (343px wide), the panel at
x=391 (685px wide). Below 1024px they still stack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The icon is an outline path but was rendered with fill and no stroke, so
its rays had no area and the button showed a bare dot. Fixed in PageBuilder
and in the capture player, which carries its own copy. The button also gets
an aria-label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Limits now says that PyPI has 0.2.0 as of October 2026, lists what it
  lacks, and gives the GitHub install command. Run in a fresh venv, 0.2.0
  marks the README's example task failed, embeds no screenshots with
  --standalone, and renders the capture player as source text.
- The first paragraph no longer says the reasoning sits beside the
  screenshots (it is under each one), and says sending the file to someone
  needs the screenshots embedded.
- "Two test modules" read real recordings; it is three.
- openadapt-ml is linked, and the catalog sentence names the command that
  uses the catalog instead of "the segmentation viewer".

The screenshot is regenerated from `openadapt-viewer demo` with task_003
failed, to match its alt text, and now shows the two-column layout and the
sun icon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📸 Generated Screenshots Preview

Screenshots have been generated. Download the artifacts to preview them.

Generated Files:

  • demo_new_controls.png (0.10 MB)
  • demo_new_events.png (0.09 MB)
  • demo_new_full.png (0.12 MB)
  • demo_viewer.png (0.30 MB)
  • turn-off-nightshift_controls.png (0.10 MB)
  • turn-off-nightshift_events.png (0.10 MB)
  • turn-off-nightshift_full.png (0.12 MB)

🔗 Download screenshots artifact

@abrichr
abrichr merged commit 787ccfd into main Oct 14, 2026
5 checks passed
@abrichr
abrichr deleted the docs/plain-readme branch October 14, 2026 09:28
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