Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
88bab33
chore: add .gitkeep file to test-files directory for organization of …
nedanwr Jan 16, 2026
31a053e
chore: update .gitignore to include test files while preserving direc…
nedanwr Jan 16, 2026
a5d1a0b
feat(core): introduce image format utilities for detection and conver…
nedanwr Jan 16, 2026
6db920d
feat(core): add image module for image format utilities
nedanwr Jan 16, 2026
619832f
feat(core): implement `ImageMagick` tool adapter for image processing
nedanwr Jan 16, 2026
720e314
feat(core): add `libvips` tool adapter for efficient image processing
nedanwr Jan 16, 2026
20415f2
feat(core): add `imagemagick` module and re-export tools for image pr…
nedanwr Jan 16, 2026
ae33721
feat(core): implement image processing operations including conversio…
nedanwr Jan 16, 2026
1562af3
feat(core): enhance image processing capabilities with detailed opera…
nedanwr Jan 16, 2026
6c14ee8
feat(cli): add image command module for conversion, resizing, and met…
nedanwr Jan 16, 2026
4fdd50c
feat(cli): register additional image processing tools (ImageMagick an…
nedanwr Jan 16, 2026
60bd7ad
feat(cli): add image module to CLI commands for enhanced image proces…
nedanwr Jan 16, 2026
be1430e
feat(cli): integrate image command into CLI for handling image operat…
nedanwr Jan 16, 2026
98caa38
refactor(core): remove `ImageMagick` tool and streamline image proces…
nedanwr Jan 16, 2026
04c0f66
refactor(cli): remove `ImageMagick` tool from check command to simpli…
nedanwr Jan 16, 2026
de0abda
feat(core): add compression parameter to image conversion function fo…
nedanwr Jan 16, 2026
6b8a71c
docs(core): update image conversion documentation to reflect removal …
nedanwr Jan 16, 2026
4bef7f0
feat(core): enhance `LibvipsTool` with compression parameter for imag…
nedanwr Jan 16, 2026
fc6d931
feat(cli): update image conversion arguments to allow optional output…
nedanwr Jan 16, 2026
f7098ec
feat(cli): make output path optional for image resize and strip comma…
nedanwr Jan 16, 2026
15aa2d5
feat(cli): add image compression command to reduce file size with qua…
nedanwr Jan 16, 2026
f1a65a1
feat(cli): add image info command to display image properties and EXI…
nedanwr Jan 16, 2026
a312237
fix(docs): correct GitHub Releases link in README for ForgeKit binary…
nedanwr Jan 16, 2026
6b84d3a
fix(cli): improve compression range validation in image conversion co…
nedanwr Jan 16, 2026
bf3e1d1
docs(README): streamline installation instructions and enhance usage …
nedanwr Jan 16, 2026
9cecd6f
docs(ROADMAP): update roadmap to reflect completion of image operatio…
nedanwr Jan 16, 2026
e54fa43
chore(deps): bump version to `0.0.6` for `forgekit` and `forgekit-cor…
nedanwr Jan 16, 2026
6baacc7
style(cli): format code for better readability in image command argum…
nedanwr Jan 16, 2026
765cbd0
style(core): improve code readability by formatting function argument…
nedanwr Jan 16, 2026
fae23ee
test(core): add unit tests for image resize and compression descriptions
nedanwr Jan 16, 2026
20f41c5
chore(core): allow clippy warning for too many arguments in convert f…
nedanwr Jan 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ desktop.ini
*.tmp
*.temp


# PDF files
*.pdf
# Test files (but keep directory structure with .gitkeep)
test-files/**/*
!test-files/**/.gitkeep
test-files/output/
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = ["crates/core", "crates/cli"]
resolver = "2"

[workspace.package]
version = "0.0.5"
version = "0.0.6"
edition = "2021"
authors = ["ForgeKit Contributors"]
license = "MIT"
Expand Down
222 changes: 31 additions & 191 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,219 +2,59 @@

Local-first media and PDF toolkit. Fast, lightweight, and privacy-focused.

**Repository**: https://github.com/nedanwar/forgekit

## Quick Start

### Installation

1. Install dependencies (see [Installation](#installation) section below)
2. Download the latest release from GitHub Releases
3. Extract and add to your PATH

### Examples

**PDF Operations:**

```bash
# Merge multiple PDFs
forgekit pdf merge doc1.pdf doc2.pdf --output merged.pdf

# Merge with linearization (fast web view)
forgekit pdf merge *.pdf --output all.pdf --linearize

# Split PDF by pages
forgekit pdf split book.pdf --output-dir pages/ --pages 1-5,10-20

# Extract odd pages
forgekit pdf split book.pdf --output-dir pages/ --pages odd

# See what commands would run (without executing)
forgekit pdf merge a.pdf b.pdf --output c.pdf --plan

# JSON output for scripting
forgekit pdf merge *.pdf --output out.pdf --json | jq -r '.result.output'
```

**Page Specification:**

- Numbers: `1`, `42`
- Ranges: `1-5`, `10-20`, `7-` (7 to end), `-10` (1 to 10)
- Keywords: `odd`, `even`, `first`, `last`
- Exclusions: `!2`, `!5-10`
- Combined: `1-3,5,7-`, `odd`, `even`, `1-10,!2,!5`

## Installation

### Package Manager Installation (Recommended)

Install ForgeKit using your system's package manager. Dependencies are automatically installed alongside ForgeKit - no additional commands needed.

**macOS (Homebrew):**

```bash
brew install forgekit
```

**Windows (winget):**

```powershell
winget install forgekit
```

**Debian/Ubuntu:**

```bash
sudo apt install forgekit
```

**Fedora/RHEL:**

```bash
sudo dnf install forgekit
```

**Arch Linux:**

```bash
# Available via AUR (when published)
yay -S forgekit
# or
pacman -S forgekit
```

### Manual Installation

If package manager installation isn't available, you can install ForgeKit manually and then install dependencies separately.

**1. Install ForgeKit binary:**
**macOS:** `brew install qpdf ghostscript tesseract ffmpeg libvips exiftool && pip3 install ocrmypdf`

Download the latest release from [GitHub Releases](https://github.com/nedanwar/forgekit/releases) and add to your PATH.
**Linux (Debian/Ubuntu):** `sudo apt install qpdf ghostscript tesseract-ocr ffmpeg libvips-tools libimage-exiftool-perl && pip3 install ocrmypdf`

**2. Install dependencies:**
**Windows:** `winget install qpdf.qpdf ArtifexSoftware.GhostScript tesseract-ocr && scoop install libvips exiftool && pip install ocrmypdf`

Check which dependencies are missing:
Then download the latest release from [GitHub Releases](https://github.com/nedanwr/forgekit/releases).

```bash
forgekit check-deps
```

Then install them based on your platform:

**macOS (Homebrew):**

```bash
brew install qpdf ghostscript tesseract ffmpeg libvips exiftool
pip3 install ocrmypdf
```

**Windows (winget/scoop):**

```powershell
winget install qpdf.qpdf ArtifexSoftware.GhostScript tesseract-ocr Gyan.FFmpeg
scoop install libvips exiftool
pip install ocrmypdf
```

**Linux:**
Run `forgekit check-deps` to verify all dependencies are installed.

**Debian/Ubuntu:**
## Usage

```bash
sudo apt install qpdf ghostscript tesseract-ocr ffmpeg libvips-tools libimage-exiftool-perl python3-pip
pip3 install ocrmypdf
```

**Fedora/RHEL:**
### PDF Operations

```bash
sudo dnf install qpdf ghostscript tesseract ffmpeg libvips perl-Image-ExifTool python3-pip
pip3 install ocrmypdf
forgekit pdf merge doc1.pdf doc2.pdf --output merged.pdf
forgekit pdf split book.pdf --output-dir pages/ --pages 1-5
forgekit pdf compress large.pdf --output small.pdf --level high
forgekit pdf ocr scan.pdf --output searchable.pdf --language eng
forgekit pdf metadata doc.pdf --set title="My Doc" --output updated.pdf
```

**Arch Linux:**
### Image Operations

```bash
sudo pacman -S qpdf ghostscript tesseract ffmpeg libvips perl-image-exiftool python-pip
pip3 install ocrmypdf
forgekit image convert photo.jpg -t webp --quality 80 # photo.webp
forgekit image resize photo.jpg --width 800 # photo_800w.jpg
forgekit image strip photo.jpg # photo_stripped.jpg
forgekit image compress photo.jpg --quality 60 # photo_compressed.jpg
forgekit image info photo.jpg --exif # show dimensions + EXIF
```

**Note:** If you have a package manager available, we strongly recommend using package manager installation instead (see above). It automatically handles all dependencies including Python and ocrmypdf.

## Features

### PDF Operations

- **Merge**: Combine multiple PDFs into one
- **Split**: Extract pages by ranges or keywords
- **Linearize**: Optimize for fast web view
- **Compress**: Reduce file size with Ghostscript presets
- **OCR**: Add searchable text layer (coming soon)
- **Metadata**: View/edit PDF metadata (coming soon)

### Image Operations (coming soon)
### Global Options

- Convert formats (WebP, AVIF, JPEG)
- Resize with aspect ratio preservation
- Strip EXIF metadata
- `--plan` - Show commands without executing
- `--json` - Output progress as NDJSON

### Media Operations (coming soon)
## Page Specification

- Video transcoding (H.264)
- Audio conversion and normalization

## Global Flags

- `--json`: Output progress as NDJSON (one event per line)
- `--plan`: Show underlying commands without executing
- `--dry-run`: Validate inputs and show plan, don't execute
- `--log-level <level>`: Set log level (debug|info|warn|error)
- `--force`: Overwrite existing files
- `--tools.<name>=path`: Override tool path (e.g., `--tools.qpdf=/usr/local/bin/qpdf`)
- Numbers: `1`, `42`
- Ranges: `1-5`, `7-` (7 to end), `-10` (1 to 10)
- Keywords: `odd`, `even`
- Exclusions: `!2`, `!5-10`
- Combined: `1-3,5,7-`, `1-10,!2`

## Exit Codes

- `0`: Success
- `1`: General error (processing failed)
- `2`: Missing tool (with install hint)
- `3`: Invalid input (file not found, invalid pages spec, etc.)
- `4`: Permission denied
- `5`: Disk full
- `130`: Cancelled (SIGINT)

## JSON Output

When using `--json`, ForgeKit outputs NDJSON (newline-delimited JSON) events:

```json
{"type":"progress","job_id":"abc123","progress":{"current":1,"total":3,"percent":33},"message":"Merging page 1/3"}
{"type":"progress","job_id":"abc123","progress":{"current":2,"total":3,"percent":67},"message":"Merging page 2/3"}
{"type":"complete","job_id":"abc123","result":{"output":"merged.pdf","size_bytes":123456,"duration_ms":1234}}
```

## Troubleshooting

### Tool not found

If you see "Tool 'qpdf' not found", install the required dependencies (see [Installation](#installation)).

You can also override tool paths:

```bash
forgekit pdf merge a.pdf b.pdf --output c.pdf --tools.qpdf=/custom/path/to/qpdf
```

### Permission denied

Ensure you have read access to input files and write access to output directories.

### Invalid page spec

Page numbers must be >= 1. Ranges must have start <= end. Use `--help` for examples.

## Contributing

Contributions welcome! Please open an issue or pull request on [GitHub](https://github.com/nedanwar/forgekit).
- `0` Success
- `1` General error
- `2` Missing tool (run `check-deps`)
- `3` Invalid input

## License

Expand Down
Loading