Pre-migration backup archive path or directory. Passed through to `apus backup create`.
--no-backup boolean
Skip the pre-apply backup. Requires --force when local Apus state exists.
--force boolean
Required alongside --no-backup when apply would otherwise refuse to skip the backup.
--json boolean
Print the plan or apply result as JSON. With --json and no --yes, apply prints the plan and does not mutate state.
Safety model
apus migrate is preview-first.
Preview before apply
The provider returns an itemized plan before anything changes, including conflicts, skipped items, and sensitive items. JSON plans, apply output, and migration reports redact nested secret-looking keys such as API keys, tokens, authorization headers, cookies, and passwords.
`apus migrate apply <provider>` previews the plan and prompts before changing state unless `--yes` is set. In non-interactive mode, apply requires `--yes`.
Backups
Apply creates and verifies an Apus backup before applying the migration. If no local Apus state exists yet, the backup step is skipped and the migration continues. To skip a backup when state exists, pass both `--no-backup` and `--force`.
Conflicts
Apply refuses to continue when the plan has conflicts. Review the plan, then rerun with `--overwrite` if replacing existing targets is intentional. Providers may still write item-level backups for overwritten files in the migration report directory.
Secrets
Interactive apply asks whether to import detected auth credentials, with yes selected by default. Use `--no-auth-credentials` to skip them, or `--include-secrets` for unattended credential import with `--yes`.
Claude provider
The bundled Claude provider detects Claude Code state at ~/.claude by default. Use --from <path> to import a specific Claude Code home or project root.
What Claude imports
- Claude Code auto-memory Markdown from
~/.claude/projects/*/memory and a
user-configured autoMemoryDirectory, copied under
memory/imports/claude-code/ for indexed recall.
- Project
CLAUDE.md and .claude/CLAUDE.md into the Apus agent workspace (AGENTS.md).
- User
~/.claude/CLAUDE.md appended to workspace USER.md.
- MCP server definitions from project
.mcp.json, Claude Code ~/.claude.json (including its per-project entries), and Claude Desktop claude_desktop_config.json.
- Claude skill directories that include
SKILL.md (user ~/.claude/skills and project .claude/skills).
- Claude command Markdown files (user
~/.claude/commands and project .claude/commands) converted into Apus skills with manual invocation only.
Archive and manual-review state
Claude hooks, permissions, environment defaults, project CLAUDE.local.md, .claude/rules, user and project agents/ directories, and project history (projects, cache, plans under ~/.claude) are preserved in the migration report or reported as manual-review items. Apus does not execute hooks, copy broad allowlists, or import OAuth/Desktop credential state automatically.
Codex provider
The bundled Codex provider detects Codex CLI state at ~/.codex by default, or at CODEX_HOME when that environment variable is set. Use --from <path> to inventory a specific Codex home.
Use this provider when moving to the Apus Codex harness and you want to promote useful personal Codex CLI assets deliberately. Local Codex app-server launches use a per-agent CODEX_HOME, so they do not read your personal ~/.codex by default. The normal process HOME is still inherited, so Codex can see shared $HOME/.agents/* skills/plugin marketplace entries and subprocesses can find user-home config and tokens.
Codex credentials are sensitive migration inputs. Initial credential planning
offers import without inspecting native credential storage. Accepting the
interactive credential prompt or passing --include-secrets allows inspection
and import from Codex's selected storage; macOS may request Keychain access.
Native plugin inventory discovery separately follows Codex's authentication
behavior, including during a dry run. The default
agent-scoped runtime does not consume a copied or mounted auth.json directly.
Import those credentials into the owning agent's Apus auth store explicitly.
Replace <agent-id> with that configured agent's ID:
apus migrate plan codex --from <codex-home> --agent <agent-id> --include-secrets --item auth:openai
apus migrate apply codex --from <codex-home> --agent <agent-id> --include-secrets --item auth:openai --yes
For callers embedding the Codex migration provider, an explicit
providerOptions.allowKeychainPrompt: false disables credential inspection for
auth import, including file-backed imports, even with includeSecrets: true.
Earlier tagged versions could import file credentials with that override. Native
startup can access credential storage before Apus can inspect the selected
store, so the auth-import step does not start its native reader when this override
is false. The normal migration CLI and onboarding consent flows do not set this
override. Plugin discovery is separate and can still request operating-system
credential access.
Running apus migrate codex in an interactive terminal previews the full plan, then opens checkbox selectors before the final apply confirmation. Skill copy items are prompted first. Use Toggle all on or Toggle all off for bulk selection. Press Space to toggle rows, or Enter to activate the highlighted row and continue. Planned skills start checked, conflict skills start unchecked, and Skip for now skips skill copies for this run while still continuing to plugin selection. When source-installed curated Codex plugins are migratable and --plugin was not supplied, migration then prompts for native Codex plugin activation by plugin name. Plugin items start checked unless the target Apus Codex plugin config already has that plugin. Existing target plugins start unchecked and show a conflict hint such as conflict: plugin exists. Choose Toggle all off to migrate no native Codex plugins in that run, or Skip for now to stop before applying.
For scripted or exact runs, select one or more skills or plugins explicitly:
apus migrate codex --dry-run --skill gog-vault77-google-workspace
apus migrate apply codex --yes --skill gog-vault77-google-workspace
apus migrate codex --dry-run --plugin google-calendar
apus migrate apply codex --yes --plugin google-calendar
What Codex imports
- ChatGPT OAuth or OpenAI API-key credentials from Codex's selected native storage,
imported into the agent's Apus auth store only when
--include-secrets
is set.
- Consolidated Codex
MEMORY.md and memory_summary.md from
$CODEX_HOME/memories, copied under memory/imports/codex/ for indexed
recall. Raw rollout memory is not imported.
- Codex CLI skill directories under
$CODEX_HOME/skills, excluding Codex's .system cache.
- Personal AgentSkills under
$HOME/.agents/skills, copied into the current Apus agent workspace for per-agent ownership.
- Source-installed
openai-curated Codex plugins discovered through Codex app-server plugin/installed. Planning reads plugin/read for each enabled installed plugin.
Codex sessions and chat history are not imported. Consolidated memories are not conversation transcripts. Migration does not move or delete your source files.
During onboarding, the migration offer explains this scope before asking whether to continue. Continuing opens the import options; credentials require separate consent, skills and eligible plugins can be selected, and a final confirmation is required before applying.
App-backed plugin migration has extra gates:
- App-backed plugins require the source Codex app-server account to be a ChatGPT subscription account. Non-ChatGPT or missing account responses are skipped with
codex_subscription_required.
- By default, migration does not read the source app inventory. App-backed plugins that pass the account gate are therefore planned without source app-accessibility verification. Account-lookup transport failures skip with
codex_account_unavailable.
- Pass
--verify-plugin-apps to force a fresh source app/installed snapshot, with authorized metadata from batched app/read. That mode requires every owned app to be present, enabled, and accessible before it plans native activation. In that mode, account-lookup transport failures fall through to source app-inventory verification. The snapshot is kept in memory for the current process only. It is never written to migration output or target config.
Disabled plugins, unreadable plugin details, subscription-gated source accounts, and (when --verify-plugin-apps is set) missing, disabled, or inaccessible apps become manual skipped items with typed reasons instead of target config entries. Apply calls app-server plugin/install for each selected eligible plugin, even if the target app-server already reports that plugin as installed and enabled. Migrated Codex plugins are usable only in sessions that select the native Codex harness. They are not exposed to Apus provider runs, ACP conversation bindings, or other harnesses.
Manual-review Codex state
Codex config.toml, native hooks/hooks.json, non-curated marketplaces, cached plugin bundles that are not source-installed curated plugins, and source-installed plugins that fail the source subscription gate are not activated automatically. When --verify-plugin-apps is set, plugins that fail the source app-inventory gate are also skipped. All of these are copied or reported in the migration report for manual review.
For migrated source-installed curated plugins, apply writes:
plugins.entries.codex.enabled: true
plugins.entries.codex.config.codexPlugins.enabled: true
plugins.entries.codex.config.codexPlugins.allow_destructive_actions: true
- one explicit plugin entry with
marketplaceName: "openai-curated" and pluginName for each selected plugin
Migration never writes plugins["*"] and never stores local marketplace cache paths.
Skipped plugins are not written to target config. Source-side subscription failures are reported on manual items with typed reasons: codex_subscription_required, codex_account_unavailable, plugin_disabled, or plugin_read_unavailable. With --verify-plugin-apps, source app-inventory failures can also appear as app_inaccessible, app_disabled, app_missing, or app_inventory_unavailable. Target-side auth-required installs are reported on the affected plugin item with status: "skipped", reason: "auth_required", and sanitized app identifiers. Their explicit config entries are written disabled until you reauthorize and enable them. Other install failures are item-scoped error results.
If Codex app-server plugin inventory is unavailable during planning, migration falls back to cached bundle advisory items instead of failing the whole migration.
Hermes provider
The bundled Hermes provider follows $HERMES_HOME and the active profile, then uses the platform default (~/.hermes or %LOCALAPPDATA%\hermes). Use --from <path> to override discovery.
What Hermes imports
- Default model configuration from
config.yaml. --agent <id> applies the model to the selected agent without changing shared defaults or other agents.
- Configured model providers and custom OpenAI-compatible endpoints from
model, providers, and custom_providers, including supported Hermes transport aliases, camelCase fields, and model list metadata.
- MCP server definitions from
mcp_servers or mcp.servers. Exact Apus mappings cover default Streamable HTTP routing, OAuth scope, boolean TLS verification, separate client certificate/key paths, and Hermes native/resource/prompt tool policy. Unsupported Hermes-only runtime or credential fields are reported for manual review.
SOUL.md and AGENTS.md into the Apus agent workspace.
memories/MEMORY.md and memories/USER.md appended to workspace memory files.
Memory-only surfaces (the onboarding memory page and the Control UI Memory
import page) instead copy these files under memory/imports/hermes/ for
indexed recall without touching existing workspace memory.
- Memory config defaults for Apus file memory, plus archive or manual-review items for external memory providers such as Honcho.
- Skills that include a
SKILL.md file under active directories in skills/. Nested skills are flattened into the workspace skill directory, and organization mirrors follow _org/.active_org.
- Per-skill config values from
skills.config and global disabled state from skills.disabled.
- Current Hermes OpenAI Codex OAuth credentials and OpenCode OpenAI OAuth credentials when interactive credential migration is accepted, or when
--include-secrets is set. Do not keep Hermes and Apus using the same imported refresh grant.
- Supported API keys and tokens from Hermes
.env and OpenCode auth.json when interactive credential migration is accepted, or when --include-secrets is set.
Supported .env keys
AI_GATEWAY_API_KEY, ALIBABA_API_KEY, ALIBABA_CODING_PLAN_API_KEY, ANTHROPIC_API_KEY, ARCEEAI_API_KEY, CEREBRAS_API_KEY, CHUTES_API_KEY, CLOUDFLARE_AI_GATEWAY_API_KEY, COPILOT_GITHUB_TOKEN, DASHSCOPE_API_KEY, DEEPINFRA_API_KEY, DEEPSEEK_API_KEY, FIREWORKS_API_KEY, GEMINI_API_KEY, GLM_API_KEY, GOOGLE_API_KEY, GROQ_API_KEY, HF_TOKEN, HUGGINGFACE_HUB_TOKEN, KILOCODE_API_KEY, KIMICODE_API_KEY, KIMI_API_KEY, KIMI_CN_API_KEY, KIMI_CODING_API_KEY, MINIMAX_API_KEY, MINIMAX_CN_API_KEY, MINIMAX_CODING_API_KEY, MISTRAL_API_KEY, MODELSTUDIO_API_KEY, MOONSHOT_API_KEY, NVIDIA_API_KEY, OPENAI_API_KEY, OPENCODE_API_KEY, OPENCODE_GO_API_KEY, OPENCODE_ZEN_API_KEY, OPENROUTER_API_KEY, QIANFAN_API_KEY, QWEN_API_KEY, TOGETHER_API_KEY, VENICE_API_KEY, XAI_API_KEY, XIAOMI_API_KEY, ZAI_API_KEY, Z_AI_API_KEY.
Archive-only state
Hermes state that Apus cannot safely interpret is copied into the migration report for manual review. It is not loaded into live Apus config or credentials. This includes plugins/, sessions/, logs/, cron/, mcp-tokens/, plans/, workspace/, skins/, kanban/, pairing/platform state, gateway routing/process state, and the detected Hermes SQLite databases.
After applying
apus doctor
Plugin contract
Migration sources are plugins. A plugin declares its provider ids in apus.plugin.json:
{
"contracts": {
"migrationProviders": ["hermes"]
}
}
At runtime the plugin calls api.registerMigrationProvider(...). The provider implements detect, plan, and apply. Core owns CLI orchestration, backup policy, prompts, JSON output, and conflict preflight. Core passes the reviewed plan into apply(ctx, plan), and providers may rebuild the plan only when that argument is absent for compatibility. Migration items may set applyPhase: "after-promotion" for external activation effects that onboarding must defer until staged local data is durably published. Those providers must declare deferredApply: { retrySafe: true } and make each deferred effect safe to replay after an interrupted process. Onboarding rejects undeclared deferred effects. An idempotent no-op should return a non-mutating item with deferredCompletion: true so recovery can record it as complete. Standalone apus migrate still applies the complete plan through its normal backup-backed flow.
Provider plugins can use apus/plugin-sdk/migration for item construction and summary counts, plus apus/plugin-sdk/migration-runtime for conflict-aware file copies, archive-only report copies, cached config-runtime wrappers, and migration reports.
In JSON mode, an apply that finishes with item errors or conflicts writes one complete migration report and exits with code 1. Inspect summary and items to identify partial results.
Onboarding integration
Onboarding can offer migration when a provider detects a known source. Both apus onboard --flow import and apus setup --wizard --import-from hermes use the same plugin migration provider and still show a preview before applying. Unlike standalone migration, the fresh-target onboarding path stages local artifacts and imported credentials. It verifies or repairs imported inference inside staging. It then promotes workspace and agent state before it commits configuration. A mode-0600 promotion journal lets the next run finish or roll back an interrupted publish, including any deferred external activation, without replaying imported local data.
Onboarding imports require a fresh Apus setup. Reset config, credentials, sessions, and the workspace first if you already have local state. Backup-plus-overwrite or merge imports are feature-gated for existing setups.
Related