Skip to content
udaysinh-gitPublic

About

privacy-first, cross-platform file transformation engine that works entirely offline.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

Rupant - Privacy-First File Conversion Tool

Local-first, cross-platform file transformation engine that works entirely offline.

Project Overview

Rupant is a privacy-first file conversion tool with a layered architecture where the core engine is the single source of truth. All interfaces (CLI, Desktop, Server) must use the core layer.

Architecture Principles

  1. Core-first: Single source of truth (core engine), all interfaces must use it
  2. No duplication: No business logic in CLI or UI layers
  3. Adapter pattern: External tools are wrapped in adapters (see below)
  4. Work pool: Queue + worker pool for conversions
  5. Local privacy: No external uploads, everything runs locally

External tools

Role Tool Notes
Raster images (PNG, JPEG, WebP, GIF, TIFF, ICO, …) ImageMagick Rupant resolves magick (IM7) or convert (IM6) on PATH.
Video & audio FFmpeg (+ ffprobe when available) Progress uses -progress pipe:1 when possible, with stderr time= as fallback if the pipe never reports out_time_ms.
Documents (PDF, DOCX, Markdown, …) Pandoc In-app progress for Pandoc is coarse (stderr activity), not page-accurate.
PDF engine (used by Pandoc) Typst / tectonic / pdflatex / xelatex / lualatex / wkhtmltopdf Rupant auto-detects the first available engine in that order. Typst and tectonic are preferred as they install without a full LaTeX distribution. A bundled engine placed next to the Rupant executable (or in bin/) is also detected automatically.

The desktop Settings → Tools & diagnostics panel probes all of the above and suggests install commands when something is missing. If no PDF engine is found, Markdown-to-PDF conversions will warn before running.

Behaviour notes

  • Pause (desktop queue): Applies between queued jobs. A job that is already running is not frozen mid-encode.
  • Cancel: The per-job context is cancelled; the backend process is stopped via exec.CommandContext (e.g. FFmpeg/ImageMagick/Pandoc).

Layers

┌─────────────────────────────────────────┐
│  CLI    │    Desktop     │   Server    │ (thin wrappers)
├─────────────────────────────────────────┤
│          Core Engine (single source)     │
│  - Job model                            │
│  - Process(Job) function                │
│  - Worker pool                          │
├─────────────────────────────────────────┤
│  Adapters: imagemagick, ffmpeg, pandoc  │
└─────────────────────────────────────────┘

Codebase

Rupant/
├── adapters/
│   ├── ffmpeg/          # Video & audio (not still images)
│   ├── imagemagick/     # Raster images
│   └── pandoc/          # Documents; pdf_engine.go handles auto-detection
├── cmd/rupant/          # CLI entrypoint
├── core/                # Engine, job model, worker pool
├── desktop/             # Wails app (Go + Svelte)
│   ├── scripts/         # Build helpers (e.g. fetch-typst.ps1)
│   └── src/lib/         # Svelte components & stores
├── pkg/
│   ├── cli/             # Cobra commands
│   ├── config/          # Persistent settings
│   └── convertpaths/    # Output path rules (shared with desktop)
└── README.md

Runtime flow

All interfaces route conversion through core.Engine.Process(ctx, job).

  1. CLI: cmd/rupant/main.go → pkg/cli → core.Engine.Process()
  2. Desktop: UI → Wails → desktop/app.go → core.Engine.Process()

Desktop vs CLI feature map

Both interfaces call the same core engine and share output-path rules (pkg/convertpaths). This table is for advanced users choosing between the GUI and rupant on the command line.

Capability Desktop (Wails) CLI (rupant)
Single-file conversion Yes rupant convert <file> --to <fmt>
Many files / queue Staged queue, Run batch rupant batch "<glob>" --to <fmt>
Parallel jobs maxConcurrentJobs (1–8) -j / --workers on batch (1–8)
Re-encode / shrink media (same container) Compress tab rupant compress <file>
Output folder strategies Settings + per-run --out-strategy, --out-dir, --last-used-dir, --naming
Explicit output file Per job in UI -o / --output
Validate readable input (no write) Per-file validate in UI --validate on convert, batch, compress
Per-job progress Progress bars + history Log lines only
Pause queue Yes (between jobs) Not applicable
Conversion history Persisted in app data Not applicable
System tray / notifications Optional Not applicable
Dependency diagnostics Settings → Tools & diagnostics Install tools; errors at run time
Browse supported formats Format picker rupant formats
Video HW encoder preference Per setting (nvenc, …) --video-hw-encoder
Max video bitrate (compress) UI field --max-video-bitrate
Windows context menu / Send to Optional at install (wails build -nsis) or Settings → Files (per-user, no admin) Not applicable
Scripting / CI Not applicable Natural fit

CLI usage

# Single file (output next to input by default)
rupant convert photo.png --to jpg

# Explicit output path (overrides folder strategy)
rupant convert doc.md --to pdf -o out/paper.pdf

# Dry-run: verify the backend can read the input (no output file)
rupant convert clip.mp4 --to mp3 --validate

# Batch (parallelism via worker pool)
rupant batch "*.wav" --to mp3 --workers 4

CLI flags (cheat sheet)

Shared / path behaviour (same semantics as the desktop app when you do not pass -o):

Flag Purpose
--out-strategy same_as_input (default), desktop_rupant, last_used, custom
--out-dir Required for custom; folder for converted files
--last-used-dir Folder when using last_used (falls back if empty)
--naming On clash: suffix, timestamp, overwrite
--batch-paths Batch only: flatten or preserve (relative paths under a common root; needs absolute paths)
--validate Check readability only; no conversion
--workers / -j Max concurrent conversions in batch (1–8, default 3)
--quality low / medium / high (where the adapter supports it)

Global flags apply to subcommands that define them; run rupant convert -h / rupant batch -h for the full list.

Development commands

# CLI
go run cmd/rupant/main.go convert test.pdf --to docx

# Desktop
cd desktop && wails dev

# Desktop release build
cd desktop && wails build

# Windows installer (NSIS). Requires makensis on PATH.
# Optional component: "Windows shortcut menus" adds * shell → "Convert with Rupant" and a Send to → Rupant shortcut (off by default).
cd desktop && wails build -nsis

Key design patterns

Single entry: Engine.Process

func (e *Engine) Process(ctx context.Context, job Job) (OperationResult, error)

Adapter interface

type Converter interface {
    CanConvert(format string) bool
    Convert(ctx context.Context, job Job) OperationResult
    GetSupportedFormats() []string
}

CLI/UI layers parse input and call Process; they do not embed conversion logic.

Tech stack

  • Core: Go 1.22+
  • CLI: Cobra
  • Desktop: Wails + Svelte + Tailwind
  • Tools: ImageMagick, FFmpeg, Pandoc

Getting started

  1. Install Go, Node.js, Wails CLI, and the external tools above (put magick/convert, ffmpeg, pandoc on PATH where applicable).
  2. For Markdown → PDF, install a PDF engine. Typst is the lightest option:
    • Windows: winget install Typst.Typst (or run desktop/scripts/fetch-typst.ps1)
    • macOS: brew install typst
    • Linux: cargo install typst-cli or your distro's package
  3. Build CLI: go build -o bin/rupant cmd/rupant/main.go
  4. Desktop: cd desktop && npm install && wails dev

Testing

go test ./core/... ./adapters/... ./pkg/...
./bin/rupant convert test.pdf --to docx

Contributing

Keep CLI/UI thin; route everything through the core engine and adapters. Stay local-first.

License

MIT License — see LICENSE for details.

About

privacy-first, cross-platform file transformation engine that works entirely offline.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages