> ## Documentation Index
> Fetch the complete documentation index at: https://ekso.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Command reference

> Every ekso migrate command and flag, in one place.

The canonical reference for every `ekso migrate` command. Each per-source page links here for the global flag surface so the source-specific pages can stay focused on the source-specific quirks.

## The four commands

Every source supports the same four verbs:

| Command   | What it does                                                                                                                             |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `list-*`  | Read-only. Enumerate the source containers (`projects`, `teams`, `orgs`) the configured credentials can see. Useful for verifying setup. |
| `collect` | Pull source data into a local SQLite cache. Network: source-only. No Ekso writes.                                                        |
| `apply`   | Walk the cache and write to the Ekso REST API. Network: Ekso-only. Idempotent — re-runs skip already-applied rows.                       |
| `status`  | Read the most recent cache file and print row counts per table, plus IdMap progress. No network.                                         |

The `list-*` verb is named per-source to match the customer's mental model:

* `ekso migrate jira list-projects`
* `ekso migrate linear list-projects`
* `ekso migrate devops list-projects`
* `ekso migrate zendesk list-projects`
* `ekso migrate gemini list-projects`

## Global flags (every migrate command)

These flags work on every `ekso migrate <source> <verb>` invocation, alongside the standard CLI flags from [Configuration](/cli/configuration) (`--url`, `--api-key`, `--format`, `--quiet`, etc.).

| Flag                  | Description                                                           | Default                   |
| --------------------- | --------------------------------------------------------------------- | ------------------------- |
| `--config <FILE>`     | Path to the migration config JSON. Holds source-platform credentials. | `./migration.config.json` |
| `--working-dir <DIR>` | Where to put the SQLite cache.                                        | `~/.ekso/migrate/`        |

## `collect` flags

| Flag                                    | Description                                                                        | Required?                                                                                                                                       |
| --------------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `--project <KEY>`                       | Source container to collect. Repeat for multiple.                                  | Required for Jira / Linear / DevOps / Gemini; optional for Zendesk (omit to collect every organisation under the configured Zendesk subdomain). |
| `--no-attachments`                      | Skip downloading binary attachments. Smaller and faster cache.                     | No                                                                                                                                              |
| `--no-comments`                         | Skip fetching comments.                                                            | No                                                                                                                                              |
| `--exclude-closed`                      | Filter closed items at the source-API layer (Jira, Zendesk, Gemini).               | No                                                                                                                                              |
| `--resume`                              | Resume an interrupted collect. Skips containers already cached.                    | No                                                                                                                                              |
| `--edition <cloud\|datacenter\|server>` | (Jira only) Override Jira edition detection (default: auto-detect via serverInfo). | No                                                                                                                                              |
| `--connection-mode <MODE>`              | (Gemini only) `sql` or `api`. Overrides `gemini.connectionMode` in the config.     | No                                                                                                                                              |

## `apply` flags

| Flag                         | Description                                                                                                     | Required?                                |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `--process <PROCESS_ID>`     | Destination Ekso process. Every migrated item attaches to this process.                                         | **Yes**                                  |
| `--board <BOARD_ID>`         | Destination board. Cycles attach here. Auto-discovered when the tenant has exactly one board.                   | If multiple boards                       |
| `--field-map <FILE>`         | YAML file mapping source custom fields to Ekso process fields. See [Field mapping](/cli/migrate/field-mapping). | No                                       |
| `--user-strategy <STRATEGY>` | Identity resolution: `match-or-create`, `match-only`, `migration-bot`.                                          | No (default: `match-or-create`)          |
| `--fallback-user <USER_ID>`  | User ID used by `match-only` and `migration-bot` when there's no source match.                                  | If using `match-only` or `migration-bot` |
| `--dry-run`                  | Walk the cache and log what would happen without writing to Ekso.                                               | No                                       |
| `--resume`                   | Skip rows that already have an ID-map entry. Picks up where a failed apply left off.                            | No                                       |
| `--cache <FILE>`             | Path to a specific cache file. Default: most recent `<source>-*.sqlite` in the working dir.                     | No                                       |

See [Identity resolution](/cli/migrate/identity-resolution) for what each `--user-strategy` does.

## `status` flags

`status` is read-only and has no source-specific flags. It reads the most recent cache file (or `--cache <FILE>`) and prints:

* Schema version of the cache
* Row counts per `Source*` table (issues, comments, attachments, etc.)
* IdMap progress per entity kind (how many items / users / files have been applied)
* Whether the cache is fresh (collect-only) or partially / fully applied

## A typical run

```bash theme={null}
# 1. Verify credentials work — read-only.
ekso migrate jira list-projects --config migration.config.json --url https://ekso.acme.com

# 2. Collect from the source. Writes ~/.ekso/migrate/jira-2026-04-29T143205.sqlite.
ekso migrate jira collect \
    --config migration.config.json \
    --project ACME \
    --url https://ekso.acme.com

# 3. Dry-run the apply. Walks the cache; no Ekso writes.
ekso migrate jira apply \
    --config migration.config.json \
    --process proc_engineering \
    --url https://ekso.acme.com \
    --dry-run

# 4. Apply for real. Writes to your Ekso tenant.
ekso migrate jira apply \
    --config migration.config.json \
    --process proc_engineering \
    --url https://ekso.acme.com

# 5. (If anything fails) re-run with --resume. Picks up at the last successful row.
ekso migrate jira apply \
    --config migration.config.json \
    --process proc_engineering \
    --url https://ekso.acme.com \
    --resume

# 6. Inspect the cache after the fact.
ekso migrate jira status --config migration.config.json
```

## Idempotency model

Every `apply` writes (source-id → Ekso-id) pairs into an `IdMap` table inside the cache. A re-run reads the IdMap before each write and skips rows that already have an Ekso ID. This means:

* Running `apply` twice in a row is a no-op the second time.
* A killed `apply` (Ctrl-C, network blip, machine reboot) can resume cleanly with `--resume`.
* Running `apply` without `--resume` after a partial run is still safe — it just re-checks every row and skips the applied ones. `--resume` skips the per-row IdMap lookup for speed.

If you want to start from scratch, delete the cache file (or run a fresh `collect` — each `collect` writes a new timestamped file).

## Per-cache schema versioning

Every cache file is stamped with a `schema_version`. If you upgrade the CLI between `collect` and `apply` and the schema version changes, `apply` refuses to run and tells you to re-collect. This is intentional — silent data shape mismatches are worse than an explicit "please re-collect" error.

## Where to next

* **[Identity resolution](/cli/migrate/identity-resolution)** — pick the right `--user-strategy`.
* **[Field mapping](/cli/migrate/field-mapping)** — write `migration.fields.yaml`.
* **[Troubleshooting](/cli/migrate/troubleshooting)** — exit codes and recovery.
* Per-source: [Jira](/cli/migrate/jira) / [Linear](/cli/migrate/linear) / [Azure DevOps](/cli/migrate/devops) / [Zendesk](/cli/migrate/zendesk) / [Gemini](/cli/migrate/gemini).
