Skip to content
dsh.fish
Bundle

dsh-local-ocr

A local OCR library and DeepSeek Harness plugin for macOS and Windows.

Source
littlewrite
License
MIT
Updated
Updated 3 days ago

Readme

# dsh-local-ocr

[English](README.md) | [简体中文](README.zh-CN.md)

An independent local OCR library and DeepSeek Harness tool plugin for macOS and Windows. It does not modify `deepseek-harness`, own a cache, or decide when OCR should run.

The native adapter uses [`@napi-rs/system-ocr`](https://github.com/Brooooooklyn/system-ocr), which exposes macOS system OCR and Windows Media OCR through one Node.js API. Its native work credits [`win-ocr-rs`](https://github.com/JichouP/win-ocr-rs) and [`mac-system-ocr`](https://github.com/DeJeune/mac-system-ocr).

## Install

Requirements: Node.js 20 or newer, `pnpm`, and an installed DeepSeek Harness `dsh` command.

Install the plugin into the Web profile directly from GitHub:

```sh
npx -y github:littlewrite/dsh-local-ocr install
```

The installer adds the bundle to the selected Harness profile. Restart `dsh web` after installation. To select another profile:

```sh
npx -y github:littlewrite/dsh-local-ocr install --profile web
```

To remove it:

```sh
npx -y github:littlewrite/dsh-local-ocr uninstall --profile web
```

For local development, clone the repository and install its dependencies:

```sh
git clone https://github.com/littlewrite/dsh-local-ocr.git
cd dsh-local-ocr
pnpm install
```

The current native dependency supports macOS and Windows. Linux is not supported by this MVP.

## DeepSeek Harness plugin

The bundle loads `dsh-plugin/index.js`. It registers one model-facing tool, `local_ocr_image`, and creates the OCR service without loading the native addon. The addon loads only when the model calls the tool.

Start Harness normally from the Harness repository:

```sh
cd /path/to/deepseek-harness
pnpm dsh web
```

When the plugin is loaded from a source checkout, it expects the Harness checkout to be the current working directory. Set `DSH_HARNESS_ROOT` only when it is loaded from another launcher or packaged installation.

Ask the agent to call `local_ocr_image` with an absolute local image path:

```text
Please call the `local_ocr_image` tool instead of `read_image`.
Read all text from this local image:
/absolute/path/to/image.png
```

## Library API

```js
import { createOcrService } from './src/ocr.js'

const ocr = createOcrService()
const result = await ocr.recognize({
  path: '/tmp/image.png',
  languages: ['zh-cn', 'en-US'],
  mode: 'accurate',
  signal,
})
```

The result contains stable fields only:

```json
{
  "text": "recognized text",
  "confidence": 0.8,
  "engine": "darwin-system-ocr",
  "durationMs": 12
}
```

An image with no detectable text returns an empty `text` value and `confidence: 0`. Set `emptyWhenNoText: false` to preserve the native no-text error.

## Development

```sh
pnpm test
```

Tests inject a fake engine, so they do not require a host OCR runtime. Native smoke tests should run on each supported operating system.

Install

dsh plugin --profile web add github:littlewrite/dsh-local-ocr#c0a91848fae0137ba83a9abb0db51f3657d9e797

Profile: web

Source