Skip to content

CLI reference

Aglaïa is a subcommand CLI:

aglaia [--version] <command> [options] [arguments]

gui is the default command — running aglaia with no command (or with a project path as the first argument) opens the GUI:

Terminal window
aglaia # → aglaia gui (start window)
aglaia ~/book.agl # → aglaia gui ~/book.agl (open that project)

Commands: gui, run, ocr, setup, list, plugins, server, version, and skill (print the agent skill file that documents this CLI). aglaia --help and aglaia <command> --help print the live usage.

aglaia is a console script (pip install aglaia); from source use uv run aglaia …. Entry path: aglaia/__main__.py:run → aglaia/cli:run (a Typer app); the commands live in aglaia/cli/commands/. The internal config layer they build (CliConfig, the --ocr/--export spec parsers) is documented in configuration.md; the implementation plan is subcommand-cli.md.

Shared options

These apply to both gui and run:

OptionMeaning
-p, --pipeline NAME|PATHPipeline name (e.g. book_curved_x2) or a .yaml path. A bare name is looked up in <APP_DATA>/pipelines/ first, then in the bundled aglaia/config/pipelines/. The bundled files are seeded into the first dir so they can be edited, so an edit wins; every name aglaia list pipelines prints resolves.
--workers NPipeline worker processes (overrides config). 0 = auto.
--force-procReprocess every active scan on open (wipe branches/intermediates).

gui

aglaia gui [PROJECT] [options]

Launch the capture GUI (the default command). With no PROJECT it opens the start window; with a .agl / PDF / image it opens or ingests that. Falls back to headless if Qt isn’t installed.

OptionMeaning
PROJECTA .agl project to open (optional).
--camera-id NCapture camera index.
--diagnose-memorytracemalloc snapshots in the GUI process.
shared-p/--pipeline, --workers, --force-proc.
Terminal window
aglaia gui ~/scans/my-book.agl
aglaia gui --camera-id 1 -p book_curved_x2

run

aglaia run PATHS… [options]

Headless batch: ingest → pipeline → (OCR) → (export), no Qt. run is always headless — there is no --headless flag. PATHS is one .agl project to (re)process, or one or more PDFs, or one or more images to ingest into a new project.

OptionMeaning
--ocr ENGINE[:opt…]Run OCR. Requires a value — use --ocr auto for the default (Apple Vision → Surya). e.g. --ocr surya:lang=fr-FR, --ocr mistral:batch.
--ocr-lang CODES+-joined BCP-47 codes (e.g. fr-FR+en-US) or auto.
--export SPECS+-joined export specs, e.g. pdf:g4+md. textpack[:profile][:ocr=ENGINE][:zlib=ID] writes the OCR textpack for corpus (export.md).
--md-refine BACKENDOn-device LLM backend for Markdown cleanup, e.g. apple_fm.
--project-name NAMEName for a new project (default: from the input filename).
--parent-dir DIRParent folder for a new project.
--input-dpi [force:]NInput DPI for imported images; force:N overrides every input.
--check-ocrPoll + import pending Mistral batch OCR jobs for the project (the raw output JSONL is stored in the .agl; jobs imported without it are backfilled), then exit.
--send-to SLUG[+SLUG…]After the exports, hand the written files to these export plugins (aglaia list destinations shows what is installed). Each plugin gets every file whose format it accepts. A plugin that is missing or unconfigured fails the run and names the fix (aglaia plugins install … / aglaia plugins config …): a batch that “succeeded” without sending is the expensive kind of success.
shared-p/--pipeline, --workers, --force-proc.
Terminal window
# Open an existing project, run the full pipeline, OCR (FR+EN), export both
aglaia run ~/scans/book.agl -p full \
--ocr auto --ocr-lang fr-FR+en-US --export pdf:g4+md
# Ingest a PDF into a new project and export a searchable PDF
aglaia run ~/scans/book.pdf --project-name book --ocr auto --export pdf:g4
# Poll a previously-submitted Mistral batch and import results
aglaia run ~/scans/book.agl --check-ocr

Option-spec format

--ocr and --export entries share one option-spec format (parse_spec in aglaia/workers/cli.py): name[:token|key=value][:…]. : and = are reserved (quote a value to use them literally). Positional tokens are flags (e.g. pdf:g4 selects the G4 profile, mistral:batch selects batch mode); key=value pairs are params (e.g. apple:lang=fr-FR). OCR engines receive params via OcrEngine.configure(params); for PDF the profile is the first token (or profile=); md:refine=apple_fm mirrors --md-refine. See ocr.md and export.md.

ocr

aglaia ocr PATHS… [options]

OCR documents that don’t need processing — born-digital PDFs, flat scans — without the geometric pipeline (no dewarp / binarize / page-split). Each page is ingested as the raw colour image and OCR’d directly, then exported. Headless, no Qt, no processing chain. PATHS is one or more PDFs/images to OCR into a new project, or one .agl to re-OCR an existing project (or, with --check-ocr, poll its pending Mistral batch jobs).

Same options as run minus -p/--pipeline, --workers, --force-proc (there is nothing to process): --ocr (defaults to auto if omitted — OCR is the point), --ocr-lang, --export, --md-refine, --project-name, --parent-dir, --input-dpi, --check-ocr, --send-to — plus one of its own, --ocr-dpi, which overrides the DPI each page is downsampled to before inference.

Terminal window
# OCR a clean PDF straight to a searchable PDF + Markdown
aglaia ocr ~/scans/clean.pdf --project-name clean --export pdf:g4+md
# OCR a folder of page images with a specific engine + language
aglaia ocr ~/pages/*.png --ocr surya --ocr-lang fr-FR --export md

When to use ocr vs run: reach for run when the photos need straightening, page-splitting, or binarizing; reach for ocr when the input is already a clean page and you only want text out.

setup

aglaia setup

Interactive first-run setup (CLI-only installs): language, models, defaults.

list

aglaia list {pipelines|ocr|exports|destinations}

List available pipelines, OCR engines, export formats (pdf, md, textpack), or installed export destinations with their state (ready, or the settings each still needs).

list pipelines reads <APP_DATA>/pipelines/ — the same directory -p NAME searches first — so every name it prints can be passed to -p.

Terminal window
aglaia list pipelines
aglaia list ocr
aglaia list exports

plugins

aglaia plugins list [--kind KIND]
aglaia plugins search TERM
aglaia plugins install SLUG_OR_PATH [--kind KIND]
aglaia plugins update [SLUG | --all]
aglaia plugins toggle SLUG [--on|--off]
aglaia plugins remove SLUG
aglaia plugins config SLUG [KEY=VALUE…]

Manage plugins without the GUI, in the three kinds a plugin can have: processors (pipeline steps), ocr (engines) and destinations (where a finished export goes). install takes a registry slug or a local archive; update replaces a plugin in place when the registry has a newer version; config reads and writes its settings, secrets included — the secret goes to the OS keychain, never to a file. Nothing ships inside the app, so a fresh install has no plugins at all. See plugin-store.md and destinations.md.

Terminal window
aglaia plugins install send-to-corpus
aglaia plugins config send-to-corpus base_url=https://corpus.example.org
aglaia run ~/scans/book.agl --ocr mistral:batch --export textpack \
--send-to send-to-corpus

server

aglaia server [--host HOST] [--port 4674] [--public-url URL]

Run the long-running HTTP job server (needs the server extra: pip install "aglaia[server]"). Submit an .aglbundle (from aglaia-bridge) or a PDF and get back a searchable PDF (+ Markdown when OCR is on). Full reference: server.md.

OptionMeaning
--host HOSTBind address (default 127.0.0.1; use 0.0.0.0 to accept LAN/remote clients).
--port PORTPort to listen on (default 4674).
--public-url URLPublic base URL for download links in emails, e.g. https://scan.example.com.

On start it prints the bound URL and the admin-panel URL (with the secret).

version

aglaia version # or: aglaia --version

Print the Aglaïa version and exit.

skill

aglaia skill

Prints the agent skill — aglaia/assets/SKILL.md — to stdout: what each command is for, which to use in which circumstance, the questions to ask a user before running anything, DPI arithmetic, engines, exports, plugins, recipes and gotchas. It is written for an AI agent driving the CLI (Claude Code, etc.), and printing it from the installed binary means the agent gets the version that matches the commands it will run. For this repository’s own Claude Code sessions, .claude/skills/aglaia-cli/SKILL.md is a symlink to the asset — one file, nothing to keep in sync. A test walks the Typer app and fails if any command or long option is missing from the document.

What changed from the old flat CLI

The old single-command form (aglaia <workspace_dir> --headless …) is gone. Mapping:

OldNew
aglaia <dir> (capture GUI)aglaia gui <dir> (or just aglaia <dir>)
aglaia <path> --headless …aglaia run <path> …
aglaia --setupaglaia setup
aglaia --pipeline-listaglaia list pipelines
aglaia --ocr-listaglaia list ocr
aglaia --export-listaglaia list exports
bare --ocr (default engine)--ocr auto (the flag now requires a value)