| name | internal-platform-cli |
| description | Use whenever a task touches the internal platform via the `axle` CLI — deploying a service, reading or rotating secrets, tailing logs, running one-off commands or migrations in an environment, or inspecting env config. Reach for this any time you are about to run `axle ...`, or when a command "worked locally" but hung, targeted the wrong environment, or silently hit prod instead of staging. Especially load this before anything destructive (`axle deploy`, `axle db migrate`, `axle secrets set`, `axle exec`) or anything run from CI / a non-interactive shell. |
internal-platform-cli
Overview
axle is the internal platform CLI — the single wrapper engineers use to operate services on the platform: deploys, secrets, logs, one-off command execution, database access, and environment config. Every invocation runs against a context (an auth identity) and a target environment (staging or prod). The two are independent, and the most expensive mistakes come from a command quietly resolving to the wrong one. axle is built for humans at a TTY by default; running it from CI or a script without the right flags is the second-biggest source of failures.
When to Use
Use this skill when you are:
- Deploying or rolling back a service (
axle deploy, axle deploy --rollback).
- Reading, setting, or rotating secrets (
axle secrets get|set|rotate).
- Tailing or querying logs (
axle logs), especially live tail.
- Running a one-off command, shell, or migration inside a running service (
axle exec, axle db).
- Inspecting or diffing environment configuration (
axle env).
- Writing a CI step, cron, or script that shells out to
axle (non-TTY).
- Debugging a command that hung, paged, or hit the wrong environment.
Do NOT use this for: local-only development (use the service's own make/npm scripts), CI pipeline definition syntax (that's the ci.yaml schema, not axle), or cloud-provider console operations that bypass the platform. axle is the platform's front door; if a task is genuinely outside the platform, it won't help.
See references/commands.md for the full subcommand surface, flags, and worked examples. Load it whenever you need exact flag names or output formats.
Context & environment model
Two orthogonal selectors decide what an axle command actually does:
- Context = who you are (auth identity + cluster credentials). Set with
axle context use <name>, shown by axle context current. Stored in ~/.axle/config. A stale or wrong context is why "permission denied" and "service not found" appear for services you know exist.
- Environment = what you target (
staging | prod). Resolved in this order: explicit --env/-e flag → AXLE_ENV var → the context's default env. There is no global default of staging — if a context's default is prod, a bare command hits prod.
Make the target explicit on anything that writes. The safe habit is axle <cmd> -e staging ... / -e prod ... every time, rather than trusting the resolved default.
Typical flow
axle context current
axle deploy api -e staging
axle logs api -e staging --since 5m
axle deploy api -e prod
For machine output (CI, parsing), add --json and --no-pager:
axle logs api -e prod --since 1h --no-pager --json | jq '.[] | select(.level=="error")'
Gotchas
ALWAYS treat these as real, observed failure modes — each has bitten someone operating a live service.
-
A bare command does NOT default to staging — it resolves to the context's default env, which may be prod. New engineers assume "no --env means safe/staging." It doesn't. If your current context's default is prod, axle deploy api deploys to production. Always pass -e staging / -e prod explicitly on any write (deploy, secrets set, db migrate, exec). Run axle context current first to see the default. Treat an unflagged write command in a script as a bug.
-
Context and environment are independent — being "in" staging context does not stop -e prod from working. Context selects credentials; if your identity has prod access, an -e prod flag (or AXLE_ENV=prod left exported in your shell) reaches prod regardless of which context is "current." Check both: axle context current shows context AND resolved default env. A lingering export AXLE_ENV=prod from an earlier session is a classic silent foot-gun — unset AXLE_ENV when in doubt.
-
axle logs (live tail) and other interactive subcommands open a pager and BLOCK under non-TTY. In CI, a cron, or piped output, axle logs without flags will hang forever waiting on a pager / streaming tail that never gets a terminal. From any non-interactive context, always pass --no-pager and a bounded --since/--limit (live --follow tail never returns — don't use it in scripts). axle exec and axle db shell similarly try to allocate a TTY and fail or hang non-interactively; use axle exec -- <cmd> (one-shot, non-interactive) instead of an interactive shell.
-
Destructive subcommands prompt for confirmation, and that prompt is what hangs your automation — don't blindly add --yes. axle deploy -e prod, axle db migrate, axle db reset, and axle secrets rotate require typed confirmation (often re-typing the service or env name for prod). In a script this prompt blocks on stdin forever. The fix is --yes/-y to pre-confirm — but --yes on db reset or -e prod deploy removes the only guardrail, so gate it behind an explicit, reviewed CI condition, never reflexively. There is no undo for db reset.
-
axle secrets get prints the secret value to stdout — it is not masked. Running it in a shared terminal, a logged CI step, or a recorded session leaks the secret into scrollback and logs. Use axle secrets get NAME --copy (to clipboard) for interactive use, and never axle secrets get in a CI step whose logs are retained. To check existence without revealing the value, use axle secrets list (names only).
-
--json changes the contract; default human output is NOT stable to parse. The default tabular/colored output includes ANSI codes and may reflow — scripts that grep/awk it break silently on the next CLI version. Any programmatic consumer must use --json (and --no-pager). If a command lacks --json, that's a signal it isn't meant to be scripted.
-
axle deploy --rollback rolls back to the previous successful release, not "one commit back." If three failed deploys happened since the last good one, rollback jumps over all of them to the last healthy release — which may be older than you expect. Confirm the target with axle deploy <svc> --history before rolling back prod.
Files
references/commands.md — full subcommand reference for deploy, secrets, logs, exec, db, and env: every flag, output format, exit codes, and worked examples (including CI-safe non-TTY invocations).