diff --git a/README.md b/README.md index 26fc06b..2b53765 100644 --- a/README.md +++ b/README.md @@ -1,302 +1,142 @@

- OpenReader reading a PDF + OpenReader

-

OpenReader

+

+ OpenReader +

-

- Privacy-first PDF tools for humans and AI agents — entirely local. -
- Read, search, compare, merge, split, extract, and compress PDFs without uploading documents anywhere. +

+ Private PDF tools for your computer. No uploads. No accounts. No cloud.

- Latest release - License - CI - Microsoft Store - Windows + Microsoft Store +   + Latest release

---- - -## Overview - -OpenReader is a **local-first PDF utility** that works with AI agents. - -Every operation — reading, searching, annotating, compressing, comparing, merging, splitting — runs on your machine. No accounts. No subscriptions. No telemetry. No cloud uploads. - -Use OpenReader directly, from scripts, or through AI agents. - ---- - -## Download - -### Microsoft Store (Recommended) - -OpenReader is **live in the Microsoft Store**. - -**Recommended:** Install [OpenReader by Sparsh on Microsoft Store](https://apps.microsoft.com/detail/9MXDVW2645LL). - -### GitHub Releases (Advanced Users) - -For advanced users, MSIX packages remain available on the [GitHub Releases page](https://github.com/sparshsam/openreader/releases). - -| Platform | Package | Notes | -|---|---|---| -| Windows 10/11 | `OpenReader.msix` | MSIX package. May be unsigned — requires [Developer Mode](https://learn.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development) for sideloading. | -| Windows 10/11 | `OpenReader-Setup.exe` | Legacy installer for manual recovery. Requires administrator rights. | -| Windows 10/11 | `OpenReader-Windows.zip` | Portable ZIP. | -| macOS | `OpenReader-macOS-*.zip` | **Experimental.** See [macOS notes](docs/macos.md). | -| Linux | — | Unsupported. | - -### Platform Support - -| Platform | Status | -|---|---| -| Windows 10/11 | Supported | -| Microsoft Store | Live in Microsoft Store | -| GitHub MSIX | Advanced users | -| macOS Apple Silicon | Experimental | -| macOS Intel | Experimental | -| Linux | Unsupported | +

+ Source Code +   + License +   + Downloads +

-### Update Policy +
-OpenReader does not install updates itself. +

+ OpenReader reading a PDF +

-- **Microsoft Store** installations update automatically through the Store. -- **GitHub MSIX** installations: Help → Check for Updates opens the releases page. Download and install manually. -- **Source builds**: `git pull` and rebuild. +
--- -## AI Agent Integration (MCP Server) - -OpenReader ships with a built-in [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server. Any MCP-compatible agent — Claude Code, Claude Desktop, Hermes, or others — can interact with PDFs directly on your machine. - -No cloud, no API keys, no document uploads. - -### What you can do with AI agents +## Why OpenReader -| Workflow | What happens | +| | | |---|---| -| **Ask questions about a PDF** | Agent extracts text from any page and answers. | -| **Search entire PDF libraries** | Agent indexes a folder and searches across all documents (keyword or semantic). | -| **Compare document versions** | Agent runs a side-by-side diff and gives you a structured summary. | -| **Summarize research collections** | Agent reads multiple PDFs and synthesizes findings. | -| **Build automated PDF pipelines** | Write scripts that merge, split, compress, and extract — all local. | - -### Architecture - -``` -┌─────────────────────────────────────────────────────┐ -│ Claude / Hermes / any MCP-compatible agent │ -│ (asks questions, runs searches, compares docs) │ -└──────────┬──────────────────────────────────────────┘ - │ MCP protocol (stdio or SSE) - ▼ -┌─────────────────────────────────────────────────────┐ -│ OpenReader MCP Server │ -│ pdfreader_lib/mcp_server.py │ -│ 14 tools: extract, search, compare, merge, split… │ -└──────────┬──────────────────────────────────────────┘ - │ local file access only - ▼ -┌─────────────────────────────────────────────────────┐ -│ Your PDFs (stored on your machine) │ -└─────────────────────────────────────────────────────┘ -``` - -### Quick setup - -```bash -# Install MCP dependencies -pip install -r requirements-mcp.txt -``` - -Add to your MCP-compatible agent's configuration: - -```json -{ - "mcpServers": { - "openreader": { - "command": "python", - "args": ["-m", "pdfreader_lib.mcp_server"] - } - } -} -``` - -The server runs over stdio by default. For HTTP/SSE transport: - -```bash -python -m pdfreader_lib.mcp_server --transport sse --port 8312 -``` - -All operations are local. No data is uploaded anywhere. +| **Truly private** | Every operation runs on your machine. No accounts, no telemetry, no cloud uploads. | +| **Works offline** | No internet required. Open, read, and annotate PDFs anywhere. | +| **Built for Windows** | A native reading experience with proper Windows 10/11 integration. | +| **AI-ready** | Built-in MCP server lets AI agents interact with your PDFs — entirely local. | --- ## Features -| Category | Capabilities | -|---|---| -| Reading | Open PDFs, one-page view, previous/next navigation, page jump, fit-width, zoom in/out | -| Multi-tab | Open several documents in a single window with movable, closeable tabs. Ctrl+T new tab, Ctrl+W close tab, Ctrl+Shift+W close all | -| Session restore | Remembers open PDFs and page positions across restarts. Auto or manual restore (File menu toggle) | -| Search (keyword) | Full-document text search, match count, next/previous result navigation (PageUp/PageDown). Ctrl+F to focus | -| Search (semantic) | TF-IDF cosine similarity search across indexed library. Toggle "Semantic" in search bar | -| Library search | SQLite FTS5 full-text index over entire folders. Cross-document search ranked by BM25. Ctrl+Shift+F shortcut | -| PDF comparison | Side-by-side diff with color-coded changes (red delete, green insert) and diff summary | -| Copying | Drag-select text from the visible page and copy with `Ctrl+C` or the Copy button | -| OCR fallback | Attempts OCR-assisted selection on scanned/image-based pages when Tesseract OCR data is available | -| Annotations | Highlight, underline, and strikethrough selected text; sticky notes on any page. Saved as native PDF annotations | -| Annotation management | Show/hide annotations toggle (View menu). Delete all annotations on current page or entire document (Tools menu) | -| Save PDF | Explicit File → Save (Ctrl+S) to persist annotation edits immediately | -| PDF tools | Merge PDFs, split every page, extract page ranges like `1-3,5`, save compressed copies | -| Dark mode | System-aware dark theme (Catppuccin Mocha) with Auto/Light/Dark toggle via View → Theme | -| Recent files | Quick access to the last 10 opened PDFs via File → Open Recent | -| Update detection | Help → Check for Updates queries GitHub API and opens the releases page. | +**Read** — Open PDFs, one-page or continuous scroll, fit-width, zoom, page jump. +**Annotate** — Highlight, underline, strikethrough, and sticky notes. Saved as native PDF annotations. +**Search** — Full-document keyword search with match count and navigation. +**Library search** — Index entire folders with SQLite FTS5 for cross-document BM25-ranked search. +**Semantic search** — TF-IDF cosine similarity for meaning-based matching — no external ML dependencies. +**Compare** — Side-by-side diff with color-coded changes (red delete, green insert) and structured summary. +**Multi-tab** — Open several documents in one window with movable, closeable tabs. +**Dark mode** — System-aware dark theme with Auto/Light/Dark toggle. +**PDF tools** — Merge, split, extract page ranges, and save compressed copies. +**OCR fallback** — Automatic OCR on scanned/image-based pages when Tesseract is available. +**Session restore** — Remembers open documents and page positions across restarts. +**AI agent integration** — Built-in MCP server with 14 tools for automated PDF workflows. --- ## Screenshots -| Reader | Sample PDF | -|---|---| -| ![Reader](assets/screenshots/v1.2.2/reader-main.png) | ![Sample PDF](assets/screenshots/v1.2.2/sample-pdf.png) | - | Dark Mode | PDF Tools | |---|---| -| ![Dark Mode](assets/screenshots/v1.2.2/dark-mode.png) | ![PDF Tools](assets/screenshots/v1.2.2/merge-split.png) | +| ![Dark Mode](assets/screenshots/dark-mode.png) | ![PDF Tools: merge, split, compress](assets/screenshots/merge-split.png) | -| Sample PDF 2 | | +| About & Keyboard Shortcuts | Sample Document | |---|---| -| ![Sample PDF 2](assets/screenshots/v1.2.2/sample-pdf-2.png) | | +| ![About dialog with keyboard shortcuts](assets/screenshots/about.png) | ![Sample PDF loaded in OpenReader](assets/screenshots/sample-pdf.png) | --- -## Privacy and Security +## Designed for -OpenReader processes PDFs locally. It does not use network services and does not upload PDFs. - -The app includes lightweight safety checks before opening and rendering documents: - -- Accepts `.pdf` files only. -- Checks for a PDF header before parsing. -- Rejects empty files and files over 500 MB. -- Rejects pages outside the supported page-size limit. -- Caps render pixel allocation to reduce PDF-bomb/OOM risk. -- Limits all-pages search result storage. -- Keeps only a small OCR page cache in memory. -- Runs `pip-audit` and Bandit in CI. - -These checks reduce risk from malformed or oversized PDFs, but PDF parsing still depends on PyMuPDF/MuPDF. Avoid opening PDFs from untrusted sources unless you use OS-level sandboxing, a VM, or another isolation layer. +| Audience | Why OpenReader | +|----------|---------------| +| **Students** | Read textbooks, annotate lecture notes, search across research papers — all offline. | +| **Professionals** | Review contracts, compare document versions, merge reports without uploading to any service. | +| **Researchers** | Index and search across PDF libraries, extract text, build automated PDF pipelines. | +| **Privacy-conscious users** | Full-featured PDF tool that never sends your documents anywhere. | +| **AI adopters** | Connect AI agents to your local documents for automated reading, searching, and processing. | --- -## License +## Design Philosophy -OpenReader is free software under the [GNU AGPLv3](LICENSE). +OpenReader is built around a single idea: **a PDF reader should feel like a well‑made tool, not a web page.** The interface follows native Windows conventions — real menus, keyboard shortcuts, proper window management — with a refined dark theme (Tokyo Night‑inspired) and a clean light option. Every interaction is immediate, every feature discoverable without tutorials. -Copyright © 2026 Sparsh Sam. +The focus is on reading and working with documents, not fighting the interface. Toolbar buttons have clear vector‑drawn icons, tabs are movable, zoom is instant, and the reading view puts your document first. --- -## Build From Source - -### Windows - -```powershell -python -m venv .venv -.\.venv\Scripts\Activate.ps1 -python -m pip install -r requirements.txt -python main.py -``` - -Build the executable: - -```powershell -.\scripts\build_windows.ps1 -``` - -Output: - -```text -dist\OpenReader\ -├── OpenReader.exe -└── _internal\ - ├── python311.dll - ├── PySide6\ - └── ... -``` - -### macOS - -macOS packaged builds are **experimental**. To run from source: +## Technology -```bash -git clone https://github.com/sparshsam/openreader.git -cd openreader -python3 -m venv .venv -source .venv/bin/activate -pip install -r requirements.txt -python main.py -``` - -See [docs/macos.md](docs/macos.md) for macOS setup and OCR notes. - -### OCR Setup - -Text selection works natively on PDFs with embedded text. For scanned/image-only PDFs, the app falls back to OCR via PyMuPDF's Tesseract integration. - -**Windows:** Download Tesseract from [UB-Mannheim/tesseract](https://github.com/UB-Mannheim/tesseract/releases), run the installer, check "Add to PATH", restart the app. +| | | +|---|---| +| **Python 3.11+** — Core application logic | **PySide6 (Qt 6)** — Native Windows UI | +| **PyMuPDF (MuPDF)** — PDF rendering | **SQLite FTS5** — Keyword and full‑text search | +| **scikit‑learn** — Semantic (TF‑IDF) search | **MCP** — AI agent integration protocol | +| **PyInstaller** — Windows packaging | **MSIX** — Microsoft Store distribution | +| **Tesseract** — OCR fallback for scanned pages | | -**macOS:** `brew install tesseract` +--- -**Linux (source builds):** `sudo apt install tesseract-ocr tesseract-ocr-eng` +## Version Journey ---- +| Release | Date | Milestone | +|---------|------|-----------| +| **v1.2.4** | Jun 2026 | Toolbar icon redesign — all buttons use QPainter vector icons | +| **v1.2.3** | Jun 2026 | Reader UX polish — Fit Page on open, Ctrl+Mouse Wheel zoom | +| **v1.2.2** | Jun 2026 | Store submission fix — XML DOM patching, CI validation | +| **v1.2.1** | Jun 2026 | First Microsoft Store release candidate | +| **v1.2.0** | Jun 2026 | MSIX packaging, self‑update removed, App Installer integration | +| **v1.1.0** | Jun 2026 | MCP server — 14 AI agent tools, local document automation | +| **v1.0.6** | Jun 2026 | Single‑instance IPC, icon bundling, Qt file dialog fallback chain | +| **v1.0.0** | Jun 2026 | Stable release — reliability, security audit, regression suite | +| **v0.3.0** | May 2026 | Library search, PDF comparison, semantic search, modular refactor | +| **v0.2.0** | May 2026 | Annotations (highlight, underline, strikethrough, sticky notes) | +| **v0.1.0** | May 2026 | First release — PySide6 PDF reader, text search, merge/split/compress | -## Project Structure - -```text -. -├── .github/ # CI, security checks, Dependabot -├── assets/ # App icon and README screenshots -├── docs/ # Platform notes and known limitations -├── installer/ # Inno Setup installer script (legacy) -├── packaging/ # MSIX packaging -├── scripts/ # Build scripts -├── tests/ # Regression test suite -├── tools/ # Developer utilities and CI test helpers -├── main.py # Main PySide6 application -├── pdfreader_lib/ # Core library (search, comparison, MCP server) -├── requirements.txt # Pinned runtime/build dependencies -├── requirements-mcp.txt # MCP server dependencies (optional) -└── CHANGELOG.md -``` +[Full changelog →](CHANGELOG.md) --- -## Contributing +## License -Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md) before opening issues or pull requests. +OpenReader is free software under the [GNU AGPLv3](LICENSE). -## Tech Stack +Copyright © 2026 Sparsh Sam. -| Layer | Choice | -|---|---| -| Language | Python 3.11+ | -| UI Framework | PySide6 (Qt 6) | -| PDF Rendering | PyMuPDF (MuPDF) | -| Search | SQLite FTS5 (keyword), TF-IDF / scikit-learn (semantic) | -| OCR | PyMuPDF / Tesseract integration | -| Packaging | PyInstaller (onedir), MSIX | -| CI/CD | GitHub Actions (Windows + macOS) | -| Security scanning | Bandit, pip-audit | -| Platform | Windows (primary), macOS (experimental) | +

+ Get it from Microsoft Store +   + Download from GitHub +

--- diff --git a/assets/screenshots/v1.2.2/about.png b/assets/screenshots/v1.2.2/about.png deleted file mode 100644 index 656a5b6..0000000 Binary files a/assets/screenshots/v1.2.2/about.png and /dev/null differ diff --git a/assets/screenshots/v1.2.2/dark-mode.png b/assets/screenshots/v1.2.2/dark-mode.png deleted file mode 100644 index 6a534f7..0000000 Binary files a/assets/screenshots/v1.2.2/dark-mode.png and /dev/null differ diff --git a/assets/screenshots/v1.2.2/merge-split.png b/assets/screenshots/v1.2.2/merge-split.png deleted file mode 100644 index 862ee73..0000000 Binary files a/assets/screenshots/v1.2.2/merge-split.png and /dev/null differ diff --git a/assets/screenshots/v1.2.2/reader-main.png b/assets/screenshots/v1.2.2/reader-main.png deleted file mode 100644 index f9f893d..0000000 Binary files a/assets/screenshots/v1.2.2/reader-main.png and /dev/null differ diff --git a/assets/screenshots/v1.2.2/sample-pdf-2.png b/assets/screenshots/v1.2.2/sample-pdf-2.png deleted file mode 100755 index 3990ef5..0000000 Binary files a/assets/screenshots/v1.2.2/sample-pdf-2.png and /dev/null differ diff --git a/assets/screenshots/v1.2.2/sample-pdf.png b/assets/screenshots/v1.2.2/sample-pdf.png deleted file mode 100644 index 0e2f3a9..0000000 Binary files a/assets/screenshots/v1.2.2/sample-pdf.png and /dev/null differ diff --git a/docs/Development.md b/docs/Development.md new file mode 100644 index 0000000..c6d4d73 --- /dev/null +++ b/docs/Development.md @@ -0,0 +1,247 @@ +# Development + +> Developer documentation for OpenReader. For product information, see the [README](../README.md). + +--- + +## Quick Start + +### Prerequisites + +- Python 3.11+ +- Git +- Windows 10/11 (primary target) + +### Windows + +```powershell +python -m venv .venv +.\.venv\Scripts\Activate.ps1 +pip install -r requirements.txt +python main.py +``` + +### macOS + +macOS is experimental. To run from source: + +```bash +git clone https://github.com/sparshsam/openreader.git +cd openreader +python3 -m venv .venv +source .venv/bin/activate +pip install -r requirements.txt +python3 main.py +``` + +See [Platform Notes](macos.md) for macOS-specific setup and OCR guidance. + +### OCR Setup + +Text selection works natively on PDFs with embedded text. For scanned/image-only PDFs, the app falls back to OCR via PyMuPDF's Tesseract integration. + +| Platform | Command | +|----------|---------| +| Windows | Download Tesseract from [UB-Mannheim/tesseract](https://github.com/UB-Mannheim/tesserage/releases), run the installer, check "Add to PATH", restart the app | +| macOS | `brew install tesseract` | +| Linux | `sudo apt install tesseract-ocr tesseract-ocr-eng` | + +--- + +## Project Structure + +``` +. +├── .github/ # CI, security checks, Dependabot +├── assets/ # App icon and README screenshots +├── docs/ # Platform notes, playbooks, architecture +├── installer/ # Inno Setup installer script (legacy) +├── packaging/ # MSIX packaging +├── scripts/ # Build scripts +├── tests/ # Regression test suite +├── tools/ # Developer utilities and CI test helpers +├── main.py # Main PySide6 application +├── pdfreader_lib/ # Core library (search, comparison, MCP server) +├── requirements.txt # Pinned runtime/build dependencies +├── requirements-mcp.txt # MCP server dependencies (optional) +└── CHANGELOG.md +``` + +--- + +## Building + +### Windows — Packaged Executable + +```powershell +.\scripts\build_windows.ps1 +``` + +Output: + +``` +dist\OpenReader\ +├── OpenReader.exe +└── _internal\ + ├── python311.dll + ├── PySide6\ + └── ... +``` + +### Build Verification + +```bash +python -m py_compile main.py tools/create_icon.py scripts/inject_version.py +``` + +### Testing + +```bash +python -m pytest tests/ -v +``` + +--- + +## Release Assets + +Canonical release asset names: + +| Asset | Description | +|-------|-------------| +| `OpenReader-Windows.zip` | Portable Windows build | +| `OpenReader-macOS-Apple-Silicon.zip` | macOS Apple Silicon build | +| `OpenReader-macOS-Intel.zip` | macOS Intel build | +| `OpenReader.msix` | MSIX package for sideloading | +| `OpenReader-Setup.exe` | Legacy installer | + +### Versioning + +- Tags follow `vMAJOR.MINOR.PATCH`. +- Version is injected from the tag via `scripts/inject_version.py` during CI. +- Source builds always show `-dev`. +- MSIX version uses 4-part `major.minor.patch.build` where build number maps to patch. + +### Frozen Identity + +These values must never change after the first release: + +| Property | Value | +|----------|-------| +| Identity Name | `SparshSam.OpenReader` | +| Publisher | `CN=E6186421-BF8A-47E0-A89C-0F513DFF91C0` | +| PFN | `SparshSam.OpenReader_yh0byntbzd2qw` | +| Store ID | `9MXDVW2645LL` | + +--- + +## Tech Stack + +| Layer | Choice | +|-------|--------| +| Language | Python 3.11+ | +| UI Framework | PySide6 (Qt 6) | +| PDF Rendering | PyMuPDF (MuPDF) | +| Search | SQLite FTS5 (keyword), TF-IDF / scikit-learn (semantic) | +| OCR | PyMuPDF / Tesseract integration | +| Packaging | PyInstaller (onedir), MSIX | +| CI/CD | GitHub Actions (Windows + macOS) | +| Security scanning | Bandit, pip-audit | +| Platform | Windows (primary), macOS (experimental) | + +--- + +## MCP Server + +OpenReader ships a built-in [Model Context Protocol](https://modelcontextprotocol.io) server for AI agent integration. All operations run locally — no cloud, no API keys, no document uploads. + +### Quick Setup + +```bash +pip install -r requirements-mcp.txt +``` + +### Agent Configuration + +Add to your MCP-compatible agent's configuration: + +```json +{ + "mcpServers": { + "openreader": { + "command": "python", + "args": ["-m", "pdfreader_lib.mcp_server"] + } + } +} +``` + +### Standalone Package + +A standalone pip package is also available: + +```bash +pip install openreader-mcp +python -m openreader_mcp +``` + +### Transports + +| Transport | Command | +|-----------|---------| +| stdio (default) | `python -m pdfreader_lib.mcp_server` | +| HTTP/SSE | `python -m pdfreader_lib.mcp_server --transport sse --port 8312` | + +### Available Tools (14) + +| Tool | Purpose | +|------|---------| +| `extract_text` | Extract text from any page range | +| `get_page_text` | Get text from a single page | +| `get_metadata` | Read document metadata | +| `get_page_count` | Get total page count | +| `search_pdf` | Keyword search within a document | +| `search_library` | FTS5 BM25 cross-document search | +| `search_semantic` | TF-IDF cosine similarity search | +| `compare_pdfs` | Page-by-page structured diff | +| `merge_pdfs` | Combine multiple PDFs into one | +| `split_pdf` | Split PDFs by page or range | +| `extract_pages` | Extract specific page ranges | +| `compress_pdf` | Save a compressed copy | +| `index_folder` | Index a folder for library search | +| `list_indexed_docs` | List indexed documents | + +--- + +## Contributing + +Contributions are welcome. Please read [CONTRIBUTING.md](../CONTRIBUTING.md) and [SECURITY.md](../SECURITY.md) before opening issues or pull requests. + +### Design Principles + +- **Local-first.** No cloud dependency. No network calls beyond the optional GitHub release update check. +- **Privacy by design.** Treat PDFs as private user data. Never upload or transmit document content. +- **Windows primary.** macOS experimental. Linux unsupported. + +### Security + +- Accepts `.pdf` files only +- Checks for PDF header before parsing +- Rejects empty files and files over 500 MB +- Caps render pixel allocation to reduce OOM risk +- Runs `pip-audit` and Bandit in CI + +These checks reduce risk from malformed or oversized PDFs, but PDF parsing still depends on PyMuPDF/MuPDF. Avoid opening PDFs from untrusted sources unless using OS-level sandboxing. + +### Update Policy + +OpenReader does not install updates itself: + +- **Microsoft Store** installations update automatically through the Store. +- **GitHub MSIX** installations: Help → Check for Updates opens the releases page. Download and install manually. +- **Source builds**: `git pull` and rebuild. + +--- + +## Architecture Reference + +See [Product Architecture Playbook](playbooks/PRODUCT_ARCHITECTURE_PLAYBOOK.md) and [Design Playbook](playbooks/DESIGN_PLAYBOOK.md) for the full design and architecture documentation.