.. _reference-cli: The saggar CLI ============== ``saggar`` (the ``saggar-cli`` crate) is the client: it drives saggar.dev over its REST API. One page, every command. .. code-block:: console $ saggar [flags] .. _cli-connection: Connection settings ------------------- Every subcommand takes the same two connection flags: ``--server `` Base URL of the instance to talk to. Resolution order: this flag, then ``SAGGAR_SERVER``, then ``server`` in the client config file, then the default instance ``https://api.saggar.dev``. ``--token `` API token. Resolution order: this flag, then ``SAGGAR_TOKEN``, then ``token`` in the client config file, then none; a command that needs auth then fails with 401. The client config file is ``~/.config/saggar/cli.toml`` (``$XDG_CONFIG_HOME`` honored; ``$SAGGAR_CONFIG`` points at an explicit file, which must exist): .. code-block:: toml server = "https://build.example.com:7020" token = "sgt-…" Unknown keys in the file are refused: a typo must not silently run against the wrong server. ``saggar login`` (see :doc:`../how-to/login`) writes this file for you. Exit behavior: ``0`` on success, ``1`` on any error, including a failed build followed with ``submit``, and any failed job of a group. saggar submit ------------- .. code-block:: console $ saggar submit [flags] Submit a source and follow the build. ```` A git URL (``https://``, ``http://``, ``ssh://``, ``git://`` or the ``user@host:path`` spelling; remote URLs only), a local directory, or a path to a tarball. Local trees travel as uploads; the service never reads your filesystem. Flags: ``--format `` Explicit format (``deb``, ``docker``, ``native``, ...); auto-detected from the tree by default. ``--name `` Project name override (derived from the tree when absent). ``--project |`` Which project to submit into: a slug you own (created on first submit) or ``owner/slug`` for someone else's (builder standing required). Default: your ``personal`` project. ``--arch `` Target architecture (``amd64``, ``arm64``, ...). Without it the job names no arch; the queue prefers a runner whose arch matches. ``--arches `` Arch fan-out (comma list, e.g. ``amd64,riscv64``): with a formats selector the group runs one job per format × arch. Mutually exclusive with ``--arch``. ``--env `` Build environment: an OCI image ref native/node builds run in, or a fingerprint (``debian:12@amd64/glibc-2.36``) the build machine resolves to an image. ``--ephemeral`` Ephemeral build: the artifact is excluded from the registries and collected after the instance's ephemeral TTL (24 h by default). For check-builds (agents, quick verification) that must not pollute the store. ``--test`` Run the tree's own test suite instead of building (see :doc:`../how-to/test-mode`). ``--test-cmd ""`` Explicit test command; implies ``--test`` and overrides the autodetected suite. ``--formats `` Formats selector (see :doc:`../how-to/fan-out`): ``auto`` fans out to every claimant, or a comma list (``deb,docker``) pins the set. The response carries a group id; the whole group is followed and the command fails if any job does. ``--no-reuse-build`` Disable the build-once hand-off: every job of the group gets its own fresh tree again. ``--cache `` Cross-job reuse: ``incremental`` keeps the build tree between submissions (only what changed rebuilds); ``artifact`` reuses the stored artifact of an identical previous build (instant green). Default: fresh. A memo lookup never hits on runner-backed builds; ``incremental`` is the one that pays there. ``--incremental`` Shorthand for ``--cache incremental``. ``--cached`` Shorthand for ``--cache artifact``. ``--no-wait`` Do not follow the build; exit right after submission. ``--quiet`` Print only the job (or group) id, machine-readable; implies no waiting. While following, the CLI streams the log and prints the verdict. On success it names the artifact route (``saggar download``, the registries); on failure it prints the outcome and the failure class (``infra-retryable``, ``infra-permanent``). saggar download --------------- .. code-block:: console $ saggar download [flags] Download the artifacts of a job (``j-…``) or artifact (``a-…``). ```` A job id (downloads the job's artifact) or an artifact id (downloads every file of that artifact). ``-o, --out `` Output directory. Default: the current directory. ``--extract`` Extract ``.tar.gz`` artifacts into ```` instead of saving them, preserving executable bits (entries that would escape ```` are refused). ``--arch `` Target arch to fetch. Defaults to this machine's arch: job downloads give you what runs here. Arch-independent (``all``) artifacts always come along. Explicit artifact ids are never filtered. ``--group `` Fetch every job of a fan-out group instead of one reference (mutually exclusive with a reference). A group member that produced no artifact (build-check success) is reported and skipped; any real failure exits ``1``. A job that has not succeeded is an error naming its state and outcome. saggar logs ----------- .. code-block:: console $ saggar logs Print a job's full log as plain text. For live streams, the SSE endpoint ``GET /api/v1/jobs/:id/logs`` is the interface (see :doc:`api`); ``submit``'s follow loop already shows the log as the build runs. saggar cancel ------------- .. code-block:: console $ saggar cancel Cancel a job (queued or running). A queued job is cancelled outright; a running build stops at the next command boundary, and host-executed children are killed immediately. The job ends ``cancelled``: terminal, log kept, no failure metadata. saggar login ------------ .. code-block:: console $ saggar login [--server ] [--token ] Sign the CLI in and store the credentials (see :doc:`../how-to/login`). Two modes: - **Browser** (default): starts a device login. The CLI prints and opens the instance's verification page (``https://saggar.dev/device`` on the default instance) where the code is typed, then long-polls until the code is confirmed and stores the minted token. The typed code is normalized server-side: case, dashes and spaces do not matter. - **Headless** (``--token``): validates the token against the server (``GET /auth/me`` must answer) and stores it in ``~/.config/saggar/cli.toml``. A rejected token writes nothing. Both accept ``--server``; without it, the default instance (``https://api.saggar.dev``) is used. saggar whoami ------------- .. code-block:: console $ saggar whoami Show who the current token authenticates as: handle, name, email, provider, storage usage against the account's artifact quota, and the projects the token can see with their roles. The first command to run after wiring a fresh token into the config. saggar token ------------ Manage your API tokens, the long-lived secrets the CLI and CI hold. Mint one per machine; revoke it when the machine dies. .. code-block:: console $ saggar token create [--expires-days ] $ saggar token ls $ saggar token revoke ``token create`` Mint a new token; the secret (``sgt-…``) is shown exactly once. ``--expires-days`` sets an expiry; omit it for a non-expiring token. Minting needs an existing credential: bootstrap happens through ``saggar login`` or the web app, never through the CLI alone. ``token ls`` List your tokens; secrets are never shown again. ``token revoke `` Revoke the token with the listing's id (``t-…``): it stops authenticating immediately. saggar projects --------------- Manage your projects and their git remotes. .. code-block:: console $ saggar projects ls $ saggar projects create $ saggar projects remotes $ saggar projects remote add $ saggar projects remote remove ``ls`` The projects you own or are a member of, with your role. ``create `` Create a project you own. The slug is lowercase letters, digits and dashes. ``remotes `` List the project's remotes: its git mirrors, the URLs git submissions derive their project from. ``remote add `` Register one remote (owner; idempotent). The same URL on two forges is one project with two remotes. Registering a watch adds its URL as a remote too; a remote in use by a watch cannot be removed. ``remote remove `` Forget one remote (owner; refused while a watch of the project polls that URL). ```` is ``owner/slug``, or a bare slug of your own. saggar watch ------------ Register a repo once and every push builds itself (see :doc:`../how-to/ci`). .. code-block:: console $ saggar watch add [flags] [--disabled] $ saggar watch ls $ saggar watch show $ saggar watch edit [flags] $ saggar watch rm $ saggar watch trigger ``add [flags]`` Register a repo: every push to a matching branch or tag builds with the given defaults (and runs the tree's tests, by default). One watch per repo. ``--disabled`` registers dormant: nothing triggers until it is enabled. ``ls`` The watches you can see: id, URL, project, state. ``show `` One watch in full: patterns, settings, interval, enabled, last poll. ``edit [flags]`` Edit a watch: only the flags you pass change. ``rm `` Remove a watch. Its build history stays; re-registering the repo starts from a clean slate and re-triggers the current head. ``trigger `` Poll right now, whatever the interval says; also how you test a fresh registration. Prints what triggered (nothing new → exit 0 with a "no changes" line). The flags shared by ``add`` and ``edit``: ``--branch `` Branch glob pattern, repeatable: ``main``, ``release/*``, or a full ``refs/heads/...`` form. Default: every branch. ``--tag `` Tag glob pattern, repeatable: ``v*``. Default: no tags. ``--formats `` Formats selector for triggered builds. Default: the single-winner build. ``--arch `` Comma list of target arches (``amd64,arm64``): one build per arch. Default: no arch named; the queue prefers a runner whose arch matches. ``--env `` Build environment for triggered builds. ``--cache `` Cross-job reuse for triggered builds: ``incremental`` keeps the build tree between pushes. Default: fresh. (``artifact`` is refused: memoization does not compose with groups.) ``--ephemeral`` / ``--no-ephemeral`` Triggered artifacts are ephemeral / kept permanent. ``--test`` / ``--no-test`` Tests only (pushes run the suite, no artifact builds) / builds only (undoes the build+test default). ``--test-cmd ""`` Run this command as the test suite instead of the autodetected one (implies the test member on pushes). ``--interval `` Poll interval override; five minutes otherwise. ``--project |`` Which project the watch belongs to and its builds are attributed to. Default: your personal project. On ``add``, an absent flag means the server default; on ``edit``, absent means unchanged. There is no credential flag: polling authenticates through the host's git/ssh configuration; the forge credential for commit-status reporting is set through the API (see :doc:`api`). saggar node ----------- Manage the runners of your account: the roster, and retirement. .. code-block:: console $ saggar node ls $ saggar node retire ``ls`` The roster: the runners you own or are shared with, each row carrying node id, arch, engine version, state, declared conduct profile (``network``, ``docker`` capability) and owner. ``retire `` Retire a runner you own: its token stops authenticating immediately. The row stays listed ``retired`` for the record. Not idempotent: an unknown or already-retired node is an error, not a silent no-op. Non-owners are refused. Sharing a runner with another account is a management-API call (``PUT /api/v1/nodes/:id/shares``, see :doc:`worker-api`) or a flip in the web app; the roster shows the sharees' runners beside your own.