fundaia 0.52.1

Command line for the Fundaia deployment platform: projects, services, variables, deployments, logs and metrics
fundaia-0.52.1 is not a library.

fundaia

The command line for the Fundaia deployment platform: projects, services, variables, deployments, logs and metrics, from a terminal. It talks to any instance of the platform — --url and profiles are first-class, so one binary reaches production, staging and a laptop.

What the platform does, and every command grouped by topic, is in the product documentation: infrastructure.fundaia.com/docs/cli. This README covers installing, scripting, updating and working on the crate.

Install

cargo install fundaia

The crate is public on crates.io; that is the route that works for everybody. Each cli-v* release of the repository also carries prebuilt binaries for x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, x86_64-apple-darwin and aarch64-apple-darwin, but the repository is private, so they are fetched authenticated:

gh release download --repo alex28042/fundaia-apps -p '*x86_64-unknown-linux-gnu.tar.gz' -D /tmp
tar -xzf /tmp/fundaia-cli-*.tar.gz -C ~/.local/bin

cli/install.sh downloads the same assets without credentials, so it answers 404 until the repository is public. Nothing here uses sudo or edits a shell profile.

Sign in

fundaia login --url https://infrastructure.fundaia.com

A terminal cannot present a passkey, so the credential is minted in the browser: the command prints a short code, opens the approval page and waits. It works over SSH (--no-browser prints the address). The token lives in ~/.config/fundaia/config.toml (directory 0700, file 0600). logout only forgets it locally; revoke it from Línea de comandos in the web interface.

fundaia status                          # every project, in one screen
fundaia new shop api --repo owner/api --connect-to Postgres
fundaia deploy shop api                 # deploy, and watch the six stages
fundaia logs shop api -f

fundaia attention                       # what is broken, everywhere, worst first
fundaia diagnose shop api               # findings, each with the next step
fundaia grep shop ECONNREFUSED          # a text in every service's log
fundaia fix deployment shop api         # Claude Code fixes the newest failed deployment

Projects and services are named by id, slug or display name; an ambiguous name is an error, not a guess.

Scripting and AI agents

  • --json (or FUNDAIA_JSON=1) prints one compact JSON value on stdout — the server's own DTOs. logs -f and watch print one object per line; deploy --json waits and prints one result. The diagnosis commands (attention, health, diagnose, grep, deps, compare, probe, security…) print the same object the matching MCP tool returns.

  • A failure is one object on stderr: {"error":{"code","message","exit","retryable",…}}, with the server's error code. Colour is off in JSON mode.

  • The exit code is the class, and the numbers never move:

    Exit Meaning Retryable
    0 success —
    1 a bug in the CLI yes
    2 bad arguments (clap) no
    3 not_found no
    4 validation_failed no
    5 unauthorized — run fundaia login no
    6 forbidden no
    7 conflict no
    8 rate_limited yes
    9 external_service_failed yes
    10 the instance is unreachable yes
    11 the deployment failed no
  • fundaia schema --json describes every command, argument and exit code, and whether a command reads, writes, starts, destroys or is local. fundaia guide prints the platform's briefing for agents (AGENT.md, the same truths the instance serves at /agent.md). Both work offline.

  • Completions: fundaia completions bash|zsh|fish.

A Claude Code skill

fundaia skill install writes ~/.claude/skills/fundaia/SKILL.md (--project writes it into .claude/skills/ of the current directory). It is generated from this binary's own commands and the guide, so it lists exactly what the installed version can do; run it again after an upgrade. fundaia skill prints it without writing anything.

CI and profiles

Every global option reads an environment variable (FUNDAIA_URL, FUNDAIA_TOKEN, FUNDAIA_PROFILE):

env:
  FUNDAIA_URL: https://infrastructure.fundaia.com
  FUNDAIA_TOKEN: ${{ secrets.FUNDAIA_TOKEN }}
run: fundaia deploy shop api
fundaia login --url https://staging.example.com --as-profile staging
fundaia --profile staging status

A saved token never travels to another host: --url pointing elsewhere than the profile needs --token too. Plain http:// is refused except on loopback (FUNDAIA_INSECURE_HTTP=1 overrides).

Updates

The tool updates itself. Once a day it asks crates.io for a newer release (alongside the command, never before it), and installs it: the release binary when it can be downloaded — its sha256 is mandatory — and cargo install otherwise, which is what happens today because the assets are private. The swap is a rename, so the running command finishes on the version it started with. Notices go to stderr; nothing here can make a command that worked exit non-zero.

Inside CI (CI set) Notice only, never installs
FUNDAIA_NO_SELF_UPDATE=1 Notice only — your package manager owns the binary
FUNDAIA_NO_UPDATE_CHECK=1 No check at all
fundaia upgrade [--check] Update now, ignoring the daily cache
fundaia changelog [<version>|--since <v>|--all] What each version brought, compiled into the binary
fundaia changelog --history Which versions have run on this machine (~/.config/fundaia/versions.toml)

Working on it

cd cli
cargo build --release
cargo test
cargo clippy --all-targets -- -D warnings
FUNDAIA_PERF_BUDGET_MS=150 cargo test --release -- --include-ignored   # startup and hot-path budgets

cli.yml runs formatting, clippy and the tests on every change under cli/; the performance budgets and the 8 MiB release-binary ceiling run on main, before anything is published.

A new command is finished when it has its --json shape and its row in EFFECT_OF (src/commands/schema.rs); the platform side — service, REST route, MCP tool — is described in .claude/rules/surfaces.md.

Releasing

Nobody edits the version by hand. The repository's post-commit hook raises Cargo.toml from the commit type when a commit touches cli/ (feat minor, ! or BREAKING CHANGE major, anything else a patch) and stamps CHANGELOG.md, whose entries are written by a person.

A push to main that touches cli/** runs .github/workflows/cli.yml: if the tag cli-v<version> does not exist yet, it tags, creates the GitHub release, builds the four binaries with their checksums and publishes the crate. A version already on crates.io is skipped, so a run can be repeated safely; gh workflow run cli.yml --ref cli-v<version> rebuilds a release from its tag.

Publishing uses CARGO_REGISTRY_TOKEN, scoped to publish-new and publish-update on this crate, with no expiry. If it is missing the publish step says so and ends green; mint a replacement under Account settings → API tokens on crates.io and add it to the repository under Settings → Secrets and variables → Actions. When GitHub Actions cannot run at all, bun run ship publishes the crate from a laptop (see deploy/README.md).

Licence

MIT.