# CLI

femforge installs two commands. `femforge` ships with the library: it starts a project, browses the artifact store, purges run bundles, reads the telemetry store, manages the Elmer Docker image and checks the machine. `femforge-workbench` ships with the `workbench` extra and opens the browser workbench. The help text on this page is generated from the parsers at build time, so it always matches the installed commands.

## femforge

```text
usage: femforge [-h] {new,artifacts,purge,index,runs,logs,sweeps,telemetry,image,doctor} ...

new starts a project, artifacts browses an artifact store, purge trims run bundles, index, runs,
logs, sweeps and telemetry read the telemetry store, image manages the Docker images, and doctor
checks this machine.

positional arguments:
  {new,artifacts,purge,index,runs,logs,sweeps,telemetry,image,doctor}
    new                 Start a project: one runnable script, its README and a .gitignore.
    artifacts           Browse a local artifact store by name, key, or path.
    purge               Apply a retention policy to run bundles (dry run unless --apply).
    index               Build or refresh the run and artifact indexes.
    runs                List indexed runs.
    logs                Query the stored log records or tail the live ones.
    sweeps              List sweeps or show one sweep's progress.
    telemetry           Maintain the telemetry store.
    image               Print, tag, pull, build, or version the Docker images femforge runs.
    doctor              Check that this machine can mesh and solve, and name the fixes.

options:
  -h, --help            show this help message and exit
```

Every subcommand prints its own help with `-h`.

## New

Use `femforge new` to start a project: a folder with one runnable script, its README and a `.gitignore`. `uvx femforge new NAME` runs it without installing femforge first, and it prints `uv run NAME/main.py`, the command that runs the project. It refuses a folder that is not empty unless you pass `--force`. The [Quickstart](<https://docs.femforge.io/overview/quickstart/index.md>) walks through the project.

```text
usage: femforge new [-h] [--force] name

positional arguments:
  name        The project folder to create, such as magnet-plate.

options:
  -h, --help  show this help message and exit
  --force     Write into a folder that is not empty, replacing the three files.
```

## Artifacts

Use `femforge artifacts` to look inside a local artifact store: list what it holds, show one artifact's record and files, print its directory, copy its files out, or put a bundle's store-sourced STEP and mesh back beside it. A reference is a key, a key prefix, a name, an artifact directory or a path inside one. [Artifacts and retention](<https://docs.femforge.io/user-guide/artifacts/#browse-the-store>) covers the store.

```text
usage: femforge artifacts [-h] {ls,show,path,materialize,rehydrate} ...

positional arguments:
  {ls,show,path,materialize,rehydrate}
    ls                  List every committed artifact.
    show                Print an artifact's record, files, spec, and (for a bundle) its inputs.
    path                Print the store directory of an artifact.
    materialize         Copy an artifact's files into a directory.
    rehydrate           Put a bundle's store-sourced inputs (STEP, mesh) back beside it.

options:
  -h, --help            show this help message and exit

usage: femforge artifacts ls [-h] [--root ROOT] [--kind KIND] [--telemetry TELEMETRY]

options:
  -h, --help            show this help message and exit
  --root ROOT           The store root (default: $FEMFORGE_ARTIFACTS, else the store a path
                        argument lies inside).
  --kind KIND           Only this kind directory.
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).

usage: femforge artifacts show [-h] [--spec] [--root ROOT] ref

positional arguments:
  ref          A key, key prefix, name, artifact directory, or a path inside one.

options:
  -h, --help   show this help message and exit
  --spec       Also print the hashed spec payload.
  --root ROOT  The store root (default: $FEMFORGE_ARTIFACTS, else the store a path argument lies
               inside).

usage: femforge artifacts path [-h] [--root ROOT] ref

positional arguments:
  ref          A key, key prefix, name, artifact directory, or a path inside one.

options:
  -h, --help   show this help message and exit
  --root ROOT  The store root (default: $FEMFORGE_ARTIFACTS, else the store a path argument lies
               inside).

usage: femforge artifacts materialize [-h] --into INTO [--verify] [--root ROOT] ref

positional arguments:
  ref          A key, key prefix, name, artifact directory, or a path inside one.

options:
  -h, --help   show this help message and exit
  --into INTO  The directory to write into.
  --verify     Check every file's sha256 while copying.
  --root ROOT  The store root (default: $FEMFORGE_ARTIFACTS, else the store a path argument lies
               inside).

usage: femforge artifacts rehydrate [-h] [--root ROOT] bundle

positional arguments:
  bundle       A run bundle directory.

options:
  -h, --help   show this help message and exit
  --root ROOT  The store root (default: $FEMFORGE_ARTIFACTS, else the store a path argument lies
               inside).
```

## Purge

Use `femforge purge` to apply a retention policy to bundles that already exist, such as after a sweep. It is a dry run unless you pass `--apply`. Start from a `--preset`, override single file classes, and narrow the bundles it touches with `--only-status`, `--older-than` and `--running-grace`. `--only-status abandoned` selects the bundles whose claim went silent before they finished. [Artifacts and retention](<https://docs.femforge.io/user-guide/artifacts/#purge-existing-bundles>) covers the policies.

```text
usage: femforge purge [-h] --runs-dir RUNS_DIR [--preset {default,keep_all,lean,minimal,nuke}]
                      [--geometry {never,on_success,always}]
                      [--gmsh-mesh {never,on_success,always}]
                      [--elmer-mesh {never,on_success,always}]
                      [--partitioning {never,on_success,always}] [--sif {never,on_success,always}]
                      [--fields {never,on_success,always}] [--scalars {never,on_success,always}]
                      [--logs {never,on_success,always}] [--sidecars {never,on_success,always}]
                      [--run-dir {never,on_success,always}]
                      [--cached-inputs {never,on_success,always}]
                      [--only-status [{ok,diverged,error,running,abandoned} ...]]
                      [--older-than DAYS] [--running-grace HOURS] [--dry-run | --apply]

options:
  -h, --help            show this help message and exit
  --runs-dir RUNS_DIR   The runs directory holding the bundles.
  --preset {default,keep_all,lean,minimal,nuke}
                        The policy to start from.
  --geometry {never,on_success,always}
                        Override the geometry rule.
  --gmsh-mesh {never,on_success,always}
                        Override the gmsh_mesh rule.
  --elmer-mesh {never,on_success,always}
                        Override the elmer_mesh rule.
  --partitioning {never,on_success,always}
                        Override the partitioning rule.
  --sif {never,on_success,always}
                        Override the sif rule.
  --fields {never,on_success,always}
                        Override the fields rule.
  --scalars {never,on_success,always}
                        Override the scalars rule.
  --logs {never,on_success,always}
                        Override the logs rule.
  --sidecars {never,on_success,always}
                        Override the sidecars rule.
  --run-dir {never,on_success,always}
                        Override the run_dir rule.
  --cached-inputs {never,on_success,always}
                        Override the cached_inputs rule.
  --only-status [{ok,diverged,error,running,abandoned} ...]
                        Touch only bundles in these statuses.
  --older-than DAYS     Touch only bundles created at least this many days ago.
  --running-grace HOURS
                        Leave running bundles whose manifest is younger than this.
  --dry-run             Report only (the default).
  --apply               Actually delete.
```

## Telemetry

Use `index`, `runs`, `logs`, `sweeps` and `telemetry` to read and maintain a telemetry store: build the run and artifact indexes, list runs, reap runs whose process died, query or tail the logs, follow a sweep's progress, and compact the parquet shards. Each takes `--telemetry`, else `FEMFORGE_TELEMETRY`. [Telemetry](<https://docs.femforge.io/user-guide/telemetry/index.md>) covers the store.

```text
usage: femforge index [-h] {build,update} ...

positional arguments:
  {build,update}
    build         Re-read every bundle.
    update        Read only the bundles whose manifest moved.

options:
  -h, --help      show this help message and exit

usage: femforge index build [-h] [--telemetry TELEMETRY] --runs-dir RUNS_DIR [--store STORE]

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).
  --runs-dir RUNS_DIR   The runs directory holding the bundles.
  --store STORE         Also index the artifact store rooted here.

usage: femforge index update [-h] [--telemetry TELEMETRY] --runs-dir RUNS_DIR [--store STORE]

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).
  --runs-dir RUNS_DIR   The runs directory holding the bundles.
  --store STORE         Also index the artifact store rooted here.

usage: femforge runs [-h] {ls,reap} ...

positional arguments:
  {ls,reap}
    ls        List runs newest first.
    reap      Break the claims of runs whose process died, mark the bundles they left running as
              abandoned, and re-index them.

options:
  -h, --help  show this help message and exit

usage: femforge runs ls [-h] [--telemetry TELEMETRY] [--status [STATUS ...]] [--tag K=V]
                        [--text TEXT] [--since DAYS] [--sweep SWEEP] [--live] [--limit LIMIT]

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).
  --status [STATUS ...]
                        Only runs in these statuses.
  --tag K=V             Only runs carrying this metadata tag (repeatable).
  --text TEXT           Only runs whose id, description or notes contain this.
  --since DAYS          Only runs created within this many days.
  --sweep SWEEP         Only runs solved under this sweep.
  --live                Also show which runs are claimed right now.
  --limit LIMIT         How many rows to print.

usage: femforge runs reap [-h] [--telemetry TELEMETRY] --runs-dir RUNS_DIR

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).
  --runs-dir RUNS_DIR   The runs directory holding the claims.

usage: femforge logs [-h] {query,tail} ...

positional arguments:
  {query,tail}
    query       Search the parquet log store.
    tail        Print the live journals, which hold what parquet has not settled yet.

options:
  -h, --help    show this help message and exit

usage: femforge logs query [-h] [--telemetry TELEMETRY] [--level [LEVEL ...]]
                           [--process [PROCESS ...]] [--run RUN] [--sweep SWEEP] [--since DAYS]
                           [--text TEXT] [--limit LIMIT]

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).
  --level [LEVEL ...]   Only these levels.
  --process [PROCESS ...]
                        Only these process names.
  --run RUN             Only records bound to this run.
  --sweep SWEEP         Only records bound to this sweep.
  --since DAYS          Only records from within this many days.
  --text TEXT           Only records whose message contains this.
  --limit LIMIT         How many rows to print.

usage: femforge logs tail [-h] [--telemetry TELEMETRY] [--follow]

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).
  --follow              Keep reading until interrupted.

usage: femforge sweeps [-h] {ls,show} ...

positional arguments:
  {ls,show}
    ls        List sweeps newest first.
    show      Show one sweep's counts, points and failures.

options:
  -h, --help  show this help message and exit

usage: femforge sweeps ls [-h] [--telemetry TELEMETRY]

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).

usage: femforge sweeps show [-h] [--telemetry TELEMETRY] sweep_id

positional arguments:
  sweep_id              The sweep to show.

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).

usage: femforge telemetry [-h] {compact} ...

positional arguments:
  {compact}
    compact   Fold each table's settled shards into one shard per partition.

options:
  -h, --help  show this help message and exit

usage: femforge telemetry compact [-h] [--telemetry TELEMETRY] [--settle SECONDS]

options:
  -h, --help            show this help message and exit
  --telemetry TELEMETRY
                        The telemetry root (default: $FEMFORGE_TELEMETRY).
  --settle SECONDS      How long a shard must be untouched before it is folded.
```

## Image

Use `femforge image` to manage the Docker image the Docker backend runs Elmer in: print its Dockerfile or tag, pull the released image, build it locally, or raise its version after a recipe change. [Elmer: native and Docker](<https://docs.femforge.io/user-guide/elmer/index.md>) covers the image.

```text
usage: femforge image [-h] {dockerfile,tag,pull,build,bump} ...

positional arguments:
  {dockerfile,tag,pull,build,bump}
    dockerfile          Print the generated Dockerfile.
    tag                 Print the tag this checkout's recipe resolves to.
    pull                Pull the released image from the registry.
    build               Pull or build the image unless Docker already has it.
    bump                Raise the image version if the recipe changed since the last bump.

options:
  -h, --help            show this help message and exit

usage: femforge image dockerfile [-h] [{femforge-elmer}]

positional arguments:
  {femforge-elmer}  The image.

options:
  -h, --help        show this help message and exit

usage: femforge image tag [-h] [{femforge-elmer}]

positional arguments:
  {femforge-elmer}  The image.

options:
  -h, --help        show this help message and exit

usage: femforge image pull [-h] [{femforge-elmer}]

positional arguments:
  {femforge-elmer}  The image.

options:
  -h, --help        show this help message and exit

usage: femforge image build [-h] [--no-pull] [{femforge-elmer}]

positional arguments:
  {femforge-elmer}  The image.

options:
  -h, --help        show this help message and exit
  --no-pull         Build locally without trying the registry first.

usage: femforge image bump [-h] [--part {major,minor,patch}] [{femforge-elmer}]

positional arguments:
  {femforge-elmer}      The image.

options:
  -h, --help            show this help message and exit
  --part {major,minor,patch}
                        The version part to raise.
```

## Doctor

Use `femforge doctor` after an install or on a new machine to check that the machine can mesh and solve. It names the fix for each failed check and exits with code 1 when one fails. [Install](<https://docs.femforge.io/overview/install/#check-the-install>) lists the checks.

```text
usage: femforge doctor [-h] [--json] [--runs-dir RUNS_DIR]

options:
  -h, --help           show this help message and exit
  --json               Print the report as JSON instead of a table.
  --runs-dir RUNS_DIR  The runs directory whose disk is checked (default: runs).
```

## femforge-workbench

Use `femforge-workbench` to open the launcher, a catalogue entry by name, or your own module with `-m`. `--app` and `--webview` open a window instead of a browser tab, and `--dev` restarts the server whenever you save a file in the shell package. [Workbench](<https://docs.femforge.io/user-guide/workbench/index.md>) covers the panels.

```text
usage: femforge-workbench [-h] [-m MODULE] [--app] [--webview] [--dev] [--port PORT] [--watch DIR]
                          [--telemetry DIR] [--persist DIR]
                          [name]

Open a workbench in the trame shell.

positional arguments:
  name                 a catalogue entry, e.g. demo

options:
  -h, --help           show this help message and exit
  -m, --module MODULE  pkg.module[:attr]: attr returns a dock Split or a Renderable; without attr,
                       main() -> Renderable
  --app                open a Chrome/Edge app window and stop the server when it closes
  --webview            open in pywebview (needs the app extra)
  --dev                run the server as a child restarted on every save under the shell package;
                       the page reloads itself
  --port PORT
  --watch DIR          extra directory to watch and purge when a workbench is rebuilt (repeatable)
  --telemetry DIR      the telemetry root the browsers read (default: $FEMFORGE_TELEMETRY)
  --persist DIR        where layouts and choices are saved (default: the per-user config
                       directory)
```
