Install
Install, update, and uninstall the Flywheel CLI.
Choose the environment where you normally launch your AI coding host. WSL and native Windows have separate home directories and host config files, so install Flywheel in the same environment that starts Codex, Claude Code, Cursor, or another host.
The canonical local install for macOS, Linux, and WSL uses the Flywheel installer:
curl -fsSL https://flywheel.paradigma.inc/install | shThe installer places the CLI in the managed user prefix
${FLYWHEEL_INSTALL_PREFIX:-$HOME/.local}, updates PATH when needed, and starts
guided setup.
If guided setup fails, installation remains usable and the installer prints the
installed executable, an exact Retry setup: command, and the uninstall
command. Retry setup after correcting the reported cause; the package, managed
PATH block, and ownership manifest are intentionally retained.
After installation, use flywheel help for the command list, open the
terminal preview with flywheel ui, or browse the
CLI reference for generated command pages.
Platform support
Hosted commands call the Flywheel service. Local repo:* commands run in
the CLI process using Node's built-in SQLite and a bundled filesystem helper.
Use Node ^24.15.0 || >=25.7.0; no Python installation, compiler, or separate
runtime package is required.
| Environment | Install path | Hosted commands | Local repository commands |
|---|---|---|---|
| macOS arm64/x64 | npm or POSIX installer | Supported | Supported with the bundled helper |
| Linux arm64/x64 | npm or POSIX installer | Supported | Supported with glibc or musl, including Alpine |
| WSL arm64/x64 | npm or POSIX installer inside Linux | Supported | Same support as Linux |
| Native Windows | npm from PowerShell | Supported | Not supported; use WSL, macOS, or Linux |
The single package contains six filesystem helpers for the supported operating-system, architecture, and libc combinations. Local commands work with npm installation scripts disabled and optional dependencies omitted. The installed Node executable must itself run on the host; Flywheel no longer imposes the former glibc 2.28 check.
What each step creates
- npm installation creates the package tree, dependencies, and executable
under the selected prefix. POSIX npm uses
bin/flywheel; Windows npm creates command shims such asflywheel.cmdin the prefix and the package undernode_modules. The package includes its native filesystem helpers; npm does not download a separate local-engine package. - The POSIX installer additionally manages a marked PATH block when needed
and writes
<prefix>/.flywheel-install-manifest.v2before guided setup. The manifest records config/cache paths and whether a Flywheel subprocess was observed creating each file. Pre-existing files are never installer-owned, and neither is a file inside a folder reached through a symbolic link (for example a~/.configmanaged by GNU stow or chezmoi), so the uninstaller leaves it in place. The uninstaller also leaves a recorded file in place when it has since become a symbolic link or a folder. - Guided setup writes the selected host's skills or MCP configuration and
Flywheel setup markers. CLI mode for a command-using host also writes the
user TOML configuration and its API key to the separate credential file after
authentication. Direct-copy
universalandantigravitysetup skips authentication, readiness probes, runtime config reads/migration/writes, credential access, and CLI PATH hints. Hosts installed through theskillspackage may haveskills-lock.json; direct-copy hosts do not. - Repository creation happens only through
repo:init,repo:clone, orrepo:restore, never install/setup. Repository data and hosted association live in.flywheel/db.sqlite; there is no.flywheel/config.toml. These commands, and every command that opens an existing repository, also add the repository's folder torepositories.sqlitebeside the credential file, the list of repositories the local app shows. Folders under the system temp folder are skipped, and entries are never removed automatically.
Bootstrap commands retain
<target-parent>/.flywheel-runtime-locks/<sha256(resolved-target-path)>.lock
and report its absolute path in human output and in JSON as
bootstrap_lock: { path, retained: true }. The small sidecar remains so
concurrent attempts keep locking the same file. It is separate from
.flywheel/run/writer.lock and SQLite's db.sqlite-wal/db.sqlite-shm
sidecars. On POSIX, new repository and .flywheel directories are 0700;
existing target modes are preserved. Database and lock files are 0600;
the bootstrap sidecar directory is 0700.
Windows with WSL
Use this path when your normal AI coding workflow starts inside WSL.
From PowerShell, install WSL if needed:
wsl --installRestart Windows if the installer asks you to, then launch your distro from the Start menu or from PowerShell:
wsl -d UbuntuTo inspect or choose a distro:
wsl --list --online
wsl --install -d Ubuntu
wsl -l -v
wsl -d UbuntuInside the WSL distro, install npm and a Node.js version listed under Platform support. Node.js and npm installed only on the Windows side are not available to the WSL installer.
Then run the Linux installer inside WSL:
curl -fsSL https://flywheel.paradigma.inc/install | shCLI-mode setup for a command-using host writes WSL-side runtime configuration
to $XDG_CONFIG_HOME/flywheel/config.toml when XDG is absolute, otherwise
$HOME/.config/flywheel/config.toml. MCP-only and direct-copy skill-only setup
leave it untouched. Launch the coding host from the same WSL environment.
If browser approval for MCP-mode setup or flywheel auth:login does not open,
copy the printed approval URL and setup code into your Windows browser.
Native Windows PowerShell
Use this path when your normal AI coding workflow starts in native PowerShell, Command Prompt, or a native Windows desktop app.
$prefix = "$env:USERPROFILE\.local"
npm install -g --prefix $prefix @paradigma-inc/flywheel@latest
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if (($userPath -split ";") -notcontains $prefix) {
$nextUserPath = if ($userPath) { "$prefix;$userPath" } else { $prefix }
[Environment]::SetEnvironmentVariable("Path", $nextUserPath, "User")
}
if (($env:Path -split ";") -notcontains $prefix) {
$env:Path = "$prefix;$env:Path"
}
# MCP host wiring for native Windows hosts
& "$prefix\flywheel.cmd" setup --mode mcpUse --mode mcp when your native Windows host should call Flywheel tools
directly. Use --mode cli instead when your workflow should call the flywheel
binary directly and you do not want MCP host config written.
Native Windows CLI mode writes %APPDATA%\Flywheel\config.toml and
%APPDATA%\Flywheel\credentials.json.
Do not install in both WSL and native Windows unless you intentionally want two separate Flywheel setups.
MCP mode
curl -fsSL https://flywheel.paradigma.inc/install | sh -s -- --mode mcpUse MCP mode when your host should call Flywheel tools natively. On native
Windows, use the PowerShell command in the section above instead of the POSIX
curl | sh installer.
CLI mode
curl -fsSL https://flywheel.paradigma.inc/install | sh -s -- --mode cliUse CLI mode when your workflow should call the flywheel binary directly.
See flywheel setup for the full setup flag reference.
CLI-mode setup does not open a browser sign-in. If you already signed in with
flywheel auth:login, setup reuses that saved key. If you have not signed in,
setup still installs the skills, and local repository work starts right away.
Run flywheel auth:login when you first need to push, pull, clone, or use
hosted commands. If Flywheel rejects the saved key (for example, it expired or
was revoked), setup stops without installing anything and prints the sign-in
command to run, such as flywheel auth:login --env prod. Run it, then run
setup again.
User configuration and credentials
The non-secret user configuration is TOML, with schema_version = 1. POSIX uses
an absolute $XDG_CONFIG_HOME/flywheel/config.toml, falling back to
$HOME/.config/flywheel/config.toml for absent or relative XDG values.
Native Windows requires a nonempty absolute APPDATA and uses
%APPDATA%\Flywheel\config.toml. Without it, commands return
config_path_unavailable; set FLYWHEEL_CLI_CONFIG_PATH explicitly.
An empty override is ignored; a relative override resolves from the current
directory.
For example, this legacy JSON:
{
"activeProfile": "research",
"baseUrl": "https://example.test/api"
}becomes this TOML:
schema_version = 1
active_profile = "research"
[profiles.research]
base_url = "https://example.test/api"Optional non-secret settings use the same document:
schema_version = 1
active_profile = "research"
[repositories]
personal = "/absolute/path/to/Flywheel"
[profiles.research]
base_url = "https://example.test/api"
default_format = "json"
default_timeout_s = 60Credentials are a separate versioned JSON document with schema_version: 1
and a profiles map. Their location is independent of
FLYWHEEL_CLI_CONFIG_PATH, the current directory, and --repo:
- On macOS, Linux, and WSL, use
$XDG_CONFIG_HOME/flywheel/credentials.jsonwhenXDG_CONFIG_HOMEis absolute; otherwise use$HOME/.config/flywheel/credentials.json. - On native Windows, use
%APPDATA%\Flywheel\credentials.json. APPDATA must be absolute or credential operations returncredential_path_unavailable.
On POSIX the Flywheel credential directory and file are private (0700 and
0600). The API key is stored as plaintext, so other applications running as
the same user can read and reuse it. This does not preserve OS-keychain
per-application access controls. Storage location does not change API-key
permissions, revocation, or expiry; without an explicit expiry_days, the
server default remains 3650 days.
Never put a plaintext API key in TOML. FLYWHEEL_API_KEY, then the selected
profile's api_key_env, take precedence over the matching credential-file
entry. With either environment source selected, auth:status does not open or
validate the credential file and reports
credential_store_readiness: "not_checked". Built-in profile names are
reserved; use a custom name such as research. --env selects a profile for
one call.
To manage a stored key directly, pipe it to
flywheel auth:credentials:set [--profile <name>]. The command reads stdin to
EOF, and an omitted --profile means default, not the active --env profile.
flywheel auth:credentials:clear [--profile <name>] removes only that local
entry without confirmation; it preserves other profiles and does not revoke the
server API key.
Recovering an interrupted credential writer
credential_store_busy means another credential-writing operation owns the
lock. Wait for an active operation to finish. If a writer was interrupted,
stop every credential-writing invocation (flywheel auth:login, CLI-mode
setup, auth:credentials:set, and auth:credentials:clear) and verify that
none remain. Then remove only the stale lock beside the retained credential
file:
rm "$XDG_CONFIG_HOME/flywheel/credentials.json.lock"When XDG is absent or relative, the POSIX lock is
$HOME/.config/flywheel/credentials.json.lock. On native Windows, after the
same verification, remove only %APPDATA%\Flywheel\credentials.json.lock:
Remove-Item -LiteralPath "$env:APPDATA\Flywheel\credentials.json.lock"Rerun the original command. Never delete credentials.json as lock recovery:
it retains the profiles and stored API keys. Flywheel does not remove locks
automatically.
Migration runs only when a command needs config, not for help/version or
skill-only setup. With no config override and no new TOML file, it reads
~/.config/flywheel-cli/config.json and the default legacy profile directory.
A present new config wins. With FLYWHEEL_CLI_CONFIG_PATH, it inspects only
that selected file and converts legacy JSON atomically in place; an explicit
FLYWHEEL_CLI_PROFILES_DIR participates only in that legacy-JSON conversion.
Keep the override pointing at the old JSON through migration. The converted
file contains TOML even if its filename ends in .json. To rename it, stop
CLI processes after successful migration, rename the file, then update the
override. Remove the legacy profiles-directory variable after migration.
Legacy plaintext credentials import into credentials.json before the TOML
replacement is committed; source files are removed only after the replacement
validates. A later TOML failure can therefore leave imported credentials and
legacy sources together. Fix the reported config_migration_failed condition
and reconcile or retry; Flywheel does not roll back the credential file or
discard the legacy inputs automatically.
Login and CLI-mode setup also persist the credential before their non-secret runtime TOML. If that later TOML save fails, the credential remains. Repair the configuration path and reconcile the retained credential before retrying rather than requesting another key.
api_key_keychain = true in an old TOML is removed only as a configuration
migration marker. It does not read, copy, or delete a Keychain/Credential
Manager entry. Profiles with credentials only in an old OS store require one
normal login each: flywheel auth:login for default, or
flywheel auth:login --env <profile> for a named profile. The old entries are
left untouched, and local repository work remains available before login.
Use flywheel repo:init --personal [directory] to initialize or adopt a
personal repository. Existing-repository commands accept --personal or
--repo <root>; without either they discover the nearest ancestor repository.
No personal repository is created or selected implicitly.
If initialization succeeds but writing the personal setting fails, the
repository remains valid at the reported path. Fix the config-write error
and run the exact flywheel repo:init --personal '<path>' retry command
printed by the CLI. It adopts the existing repository without replacing its
database, then saves the personal setting.
Uninstall
curl -fsSL https://flywheel.paradigma.inc/uninstall | shUninstall removes package and host wiring. It removes runtime configuration and
update-cache files only when the install manifest proves that Flywheel created
them; pre-existing and legacy-manifest files are preserved. It retains
credentials.json and its profile entries, and it does not revoke API keys.
It does not delete local repositories, remote account data, graphs, nodes,
artifacts, billing data, GitHub connections, or remote resources.
See flywheel uninstall for the full uninstall flag
reference.