bd603a271c
Lets the model OCR a screenshot, scanned receipt, whiteboard photo, or image-only PDF the user drops into the workspace, without bouncing through `exec_shell` (which would mean an approval prompt plus the model having to remember tesseract's CLI surface). The tool spawns `tesseract <image> -` and returns the recognised text inline — no file is written. Capability is ReadOnly + parallel since OCR is a side-effect-free read. Registration is gated on `crate::dependencies::resolve_tesseract()` via the new `ToolRegistryBuilder::with_image_ocr_tools()` builder, hooked into `with_agent_tools` alongside `pandoc_convert`. When tesseract is missing the tool isn't advertised — same probe-then-decide pattern v0.8.31 introduced for Python. The execute path also late-resolves so a concurrent uninstall surfaces the install-tesseract hint rather than the raw spawn failure. `deepseek doctor`'s "Tool Dependencies" section reports tesseract status next to pandoc / node / python with platform-aware install hints. For non-default language packs or PSM modes the user can still drop into `exec_shell` with the full tesseract CLI surface. Tests check the metadata (ReadOnly + parallel, not WritesFiles), the missing-path rejection, and the happy-path OCR round-trip against `crates/tui/tests/fixtures/ocr_hello.png` — a 2 KB 300×100 grayscale PNG generated with ImageMagick rendering "HELLO OCR" in Helvetica. The happy-path test skips silently on hosts without tesseract (matching the catalog-build behaviour) and on hosts where the fixture isn't checked out (sparse / shallow clones). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>