Apple on-device Vision tools for text-only dsh models: local OCR (zh-Hans + 30 langs), image classification, face detection, document layout, and a combined describe — 100% offline, no API key, tall-screenshot slicing.
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:Harzva/dsh-maclens
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Apple's on-device Vision framework, bridged into DeepSeek Harness (
dsh) as local tools: OCR, image classification, face detection, document layout, and a combined read — 100% offline, no API key, no daemon.
| 🔒 Privacy | Every pixel stays on your Mac. No network, no upload, no telemetry. |
| ⚡ Speed | Sub-second OCR on typical screenshots (Neural Engine). |
| 🇨🇳 Languages | zh-Hans + 30+ recognition languages out of the box. |
| 🖼️ Tall images | slice splits long screenshots so small text survives Vision's downscale. |
| 🧩 No deps | Swift CLI ships in the npm package — no build step to install. |
👤 For humans — quick start (30 seconds)
# 1. Install into your dsh profile
dsh plugin --profile desktop add dsh-maclens
# 2. Restart DSH. Then just ask the model:
# "OCR this screenshot: /Users/me/Desktop/shot.png"
The five tools the model can call:
| Tool | One-liner |
|---|---|
maclens_ocr |
"Read all the text in this image" — every line + confidence + box |
maclens_classify |
"What kind of image is this?" — document, chart, photo, … |
maclens_faces |
"Are there people in this image?" — face boxes + count |
maclens_document |
"Parse this page" — OCR + left/right column layout |
maclens_describe |
"Give me everything at once" — OCR + classify + faces + layout |
When to pick maclens vs a VLM: maclens is a CV toolkit — it transcribes, classifies, detects but does not narrate "what this image is about". Need open-ended understanding? Pair it with a VLM bridge (e.g. modlens + qwen-vl). Need fast, free, private OCR/detection? maclens.
🤖 For agents — precise contract
TL;DR
Plugin: dsh-maclens (npm), installs with dsh plugin add
Runtime: macOS 14+ with Xcode Command Line Tools (Swift 6+)
Tools: maclens_ocr | maclens_classify | maclens_faces | maclens_document | maclens_describe
Input: absolute local image path (string) — required on every tool
Output: one JSON object on stdout; {"error": "..."} + exit 1 on failure
Binary: bin/maclens in the package (auto-chmod'd), else MACLENS_BIN, else PATH
No network: the CLI makes zero network requests
Install (exact commands)
# From npm — includes the prebuilt binary, no build step:
dsh plugin --profile desktop add dsh-maclens
# From a git checkout — build the Swift bridge first:
cd dsh-maclens && bash scripts/build.sh # produces bin/maclens
dsh plugin --profile desktop add ./dsh-maclens
Binary resolution order: bin/maclens in the package → $MACLENS_BIN → swift/.build/release/MaclensBridge → maclens on PATH. The plugin chmods the found binary to 0755 at resolve time (npm tarballs drop the exec bit).
Tool schemas
All five tools take path (required, string). OCR-family tools additionally accept:
| Field | Type | Default | Meaning |
|---|---|---|---|
languages |
string | zh-Hans,en-US |
Comma-separated recognition languages |
maxLines |
number | — | Cap returned OCR lines (large screenshots) |
slice |
boolean | false | Slice tall images into overlapping strips |
sliceHeight |
number | 4096 | Strip height in px when slicing |
top |
number | 5 | Classify only: how many categories to return |
Output contract
maclens_ocr returns:
{
"task": "ocr",
"language": ["zh-Hans", "en-US"],
"full_text": "跨境增长研究室\n从一个问题,抵达一个决定。",
"lines": [
{
"text": "跨境增长研究室",
"confidence": 1.0,
"bbox": { "x": 0.055, "y": 0.519, "width": 0.517, "height": 0.144 }
}
],
"line_count": 2,
"truncated": false,
"sliced": false
}
bboxis normalized (0–1), origin top-left (converted from Vision's bottom-left so it is intuitive).- With
slice: true, tall images are split into overlapping strips, each strip OCR'd, results stitched back to whole-image coordinates, and duplicate lines in the overlap band de-duplicated. Output adds"sliced": trueand"slice_count": N. maclens_document=ocr+layout.columns(left/right) +layout.image_dimensions.maclens_describe=ocr+classification.observations+faces+layout.maclens_faces→faces[]+face_count;maclens_classify→observations[](identifier,confidence).
Error contract
| Exit | Meaning |
|---|---|
| 0 | Success |
| 1 | Runtime error — stdout is {"error": "..."} (e.g. file does not exist: <path>) |
| 2 | Usage / unknown task — stdout is {"error": "usage: ..."} |
Raw CLI (for testing outside dsh)
bin/maclens ocr --image /path/to/img.png
bin/maclens classify --image /path/to/img.png --top 3
bin/maclens faces --image /path/to/img.png
bin/maclens document --image /path/to/img.png --slice
bin/maclens describe --image /path/to/img.png --slice --top 2
🏗️ How it works
dsh (text-only model)
└─ maclens_* tools (lib/index.js)
└─ bin/maclens (Swift CLI, spawned per call — no daemon, no ports)
└─ Apple Vision: VNRecognizeTextRequest / VNClassifyImageRequest /
VNDetectFaceRectanglesRequest ← on-device, offline
🧪 Development
cd swift && swift build -c release
swift test --package-path swift # 6 behavioral tests
CI (GitHub Actions): Swift release build + smoke tests on macOS, plugin-load + pack-contents check on Ubuntu. All green on main.
📄 Docs
AGENTS.md— the agent-facing quick reference (mirrors this section).CHANGELOG.md— version history.SECURITY.md— security model & reporting.
License
MIT — see LICENSE.
Links
More in this category
liustack/modlens★ 4258
Vision bridge for text-only models: paste an image, get structured JSON evidence (OCR, layout, semantics).
ysr666/dsh-vision-router★ 1152
Free vision for text-only agents: built-in keyless vision chain plus pixel tools (Q&A, grounding, crop, pixel diff, colors, OCR, SVG trace, cutout, screenshots); paste an image to use it.
Anionex/dsh-vision-toolkit★ 895
Vision for text-only models: paste an image and the model switches to a Vision Toolkit variant for image Q&A, multi-image comparison, long-screenshot OCR, screenshot-to-UI reproduction, element grounding, and pixel diff. No API key by default — images are processed by the author-hosted free service, 100 per machine per day; configurable to your own provider.
dickpy/dsh-imagegen★ 115
AI image generation for the DSH Web GUI: text-to-image and image-to-image through a configurable OpenAI-compatible endpoint (gpt-image-2 / gpt-image-1 / dall-e-3), with an api_url/api_key settings card and a sidebar split-pane generation studio.
fandc520/dsh-comfyui★ 114
Drive a local or remote ComfyUI server from DeepSeek Harness: comfyui_run / comfyui_object_info / comfyui_workflow tools generate and edit images and videos, with a workflow library (graph extraction: per component / main flow / all), a load area with resolution auto-match, a live queue, SDXL and Wan 2.1 templates, a companion skill, and a same-origin media proxy.
sunxin-ai/dsh-design-qa★ 44
Design-fidelity QA for text-only models: a `deepseek_vision` tool borrows an eye from any OpenAI-compatible vision route, so the model can judge whether an implementation matches its mock — shipped with the benchmark behind that judgement (four fixtures, 23 injected defects, raw transcripts) and the questioning discipline it depends on.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.