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:
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.
aglaiais a console script (pip install aglaia); from source useuv run aglaia …. Entry path:aglaia/__main__.py:run→aglaia/cli:run(a Typer app); the commands live inaglaia/cli/commands/. The internal config layer they build (CliConfig, the--ocr/--exportspec parsers) is documented in configuration.md; the implementation plan is subcommand-cli.md.
Shared options
These apply to both gui and run:
| Option | Meaning |
|---|---|
-p, --pipeline NAME|PATH | Pipeline 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 N | Pipeline worker processes (overrides config). 0 = auto. |
--force-proc | Reprocess 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.
| Option | Meaning |
|---|---|
PROJECT | A .agl project to open (optional). |
--camera-id N | Capture camera index. |
--diagnose-memory | tracemalloc snapshots in the GUI process. |
| shared | -p/--pipeline, --workers, --force-proc. |
aglaia gui ~/scans/my-book.aglaglaia gui --camera-id 1 -p book_curved_x2run
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.
| Option | Meaning |
|---|---|
--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 BACKEND | On-device LLM backend for Markdown cleanup, e.g. apple_fm. |
--project-name NAME | Name for a new project (default: from the input filename). |
--parent-dir DIR | Parent folder for a new project. |
--input-dpi [force:]N | Input DPI for imported images; force:N overrides every input. |
--check-ocr | Poll + 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. |
# Open an existing project, run the full pipeline, OCR (FR+EN), export bothaglaia 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 PDFaglaia run ~/scans/book.pdf --project-name book --ocr auto --export pdf:g4
# Poll a previously-submitted Mistral batch and import resultsaglaia run ~/scans/book.agl --check-ocrOption-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.
# OCR a clean PDF straight to a searchable PDF + Markdownaglaia ocr ~/scans/clean.pdf --project-name clean --export pdf:g4+md
# OCR a folder of page images with a specific engine + languageaglaia ocr ~/pages/*.png --ocr surya --ocr-lang fr-FR --export mdWhen 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 setupInteractive 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.
aglaia list pipelinesaglaia list ocraglaia list exportsplugins
aglaia plugins list [--kind KIND]aglaia plugins search TERMaglaia plugins install SLUG_OR_PATH [--kind KIND]aglaia plugins update [SLUG | --all]aglaia plugins toggle SLUG [--on|--off]aglaia plugins remove SLUGaglaia 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.
aglaia plugins install send-to-corpusaglaia plugins config send-to-corpus base_url=https://corpus.example.orgaglaia run ~/scans/book.agl --ocr mistral:batch --export textpack \ --send-to send-to-corpusserver
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.
| Option | Meaning |
|---|---|
--host HOST | Bind address (default 127.0.0.1; use 0.0.0.0 to accept LAN/remote clients). |
--port PORT | Port to listen on (default 4674). |
--public-url URL | Public 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 --versionPrint the Aglaïa version and exit.
skill
aglaia skillPrints 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:
| Old | New |
|---|---|
aglaia <dir> (capture GUI) | aglaia gui <dir> (or just aglaia <dir>) |
aglaia <path> --headless … | aglaia run <path> … |
aglaia --setup | aglaia setup |
aglaia --pipeline-list | aglaia list pipelines |
aglaia --ocr-list | aglaia list ocr |
aglaia --export-list | aglaia list exports |
bare --ocr (default engine) | --ocr auto (the flag now requires a value) |