Skip to content

Three first-use fixes: guide image widths, lighter Tesseract, clearer OCR error - #2

Merged
visul merged 3 commits into
dontpayfull:mainfrom
testy-cool:first-use-fixes
Oct 10, 2026
Merged

visul merged 3 commits into
dontpayfull:mainfrom
testy-cool:first-use-fixes

Conversation

@testy-cool

Copy link
Copy Markdown
Contributor

Found while using AInotate on Linux to build a 9-step Microsoft Foundry guide.

1. Narrow screenshots no longer get white strips in guides

Every step image was padded to the widest one. Now each keeps its own size; --width N still pads on request.

Pictures show the guide with #1 applied. This change also works on its own.

Before: the chat screenshot is padded with white strips to match the widest step.

before

After: it keeps its own size.

after

2. Tesseract runs on one core

Each run now gets OMP_THREAD_LIMIT=1, so one OCR pass no longer spreads across every CPU core. Your own environment is untouched. Tested with a mocked subprocess, not measured on a real Tesseract.

3. The missing-OCR error says how to fix it

annotate --privacy auto without an OCR engine still saves nothing, but now says why and gives both ways out:

ERROR: no text reader (OCR engine) is installed, so automatic privacy cannot
read this image to hide secrets. Nothing was saved. Fix it one of two ways:
1. Install a text reader: <the existing per-OS install hint>
2. Or rerun with --privacy off if the image holds nothing sensitive.

When marks use text targets, option 2 tells you to give them rect coordinates too, since --privacy off alone would still fail.

Tests: 593 passed. test_privacy.py::test_dom_fixture fails on Linux on main as well, so it's not from this.

🤖 Generated with Claude Code

testycool and others added 3 commits October 10, 2026 02:30
A guide with one wide screenshot and several narrow ones came out with
white bands on both sides of every narrow step, because each image was
padded to the widest one by default. Most guides mix crop sizes, so the
padding made them look worse, not more consistent.

Each step image now keeps its own size unless `--width N` (or width=N in
the Python API) asks for one canvas width; that path pads and scales
exactly as before, and width=0 still means "as is". The docstrings, the
CLI help and the MCP make_guide description now describe the new default.
The guide test checks the default sizes and runs the padding checks with
an explicit width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tesseract is built with OpenMP and by default starts a thread per core
for a single image. For screenshot-sized OCR that buys little and can
peg the whole machine while a redaction or locate runs.

Each Tesseract call now gets OMP_THREAD_LIMIT=1 in a copy of the
environment passed to the subprocess, so the user's own environment is
not changed. No change was needed to run Tesseract tiles one at a time:
the Tesseract backend has no tile size, so _ocr already sends it the
whole image in a single call and never uses the thread pool. Apple
Vision and Windows OCR keep their tiling and parallel runs.

Testing: a new test mocks the subprocess, runs a 4000x1000 image through
the Tesseract path and checks the env and that no two runs overlap.
Not measured on a real Tesseract; it is not installed on this machine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…stalled

`annotate --privacy auto` on a machine without an OCR engine stopped with
"no OCR engine available. Install one:" and a list of install commands.
It never said that the privacy option was the reason OCR was needed, that
nothing was saved, or that `--privacy off` is the other way out.

When reading the image fails and no OCR engine is installed, an image
spec with privacy on now refuses with a plain message: no text
reader is installed, nothing was saved, then the two fixes (the existing
install hint, or rerun with --privacy off). Exit code stays 4, and the
image is still never saved unredacted. When the spec also has marks with
text targets, --privacy off alone would still fail, because finding those
targets needs OCR too; the second fix then says to give those marks
explicit rect coordinates (read off ainotate grid or zoom) as well.

`shoot` needed no change: its privacy scan reads the page's text from the
DOM, not by OCR, so with no Tesseract on this machine a file:// page shoots
and redacts fine (checked by hand).

Testing: a new CLI test fakes "no engine" and checks the exit code, the
message and that no image was written, with and without a text target.

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

@visul visul left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! All three make sense: per-image widths by default (with --width still available), OCR limited to one thread without touching the caller's environment, and an error that says how to get out of it, with the text-target case handled. Merges cleanly on top of #1 and the suite passes. Merging.

@visul
visul merged commit bc4d20a into dontpayfull:main Oct 10, 2026
visul added a commit that referenced this pull request Oct 10, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants