Skip to main content

Agentworks CLI

The operator's command-line interface for managing agentic workloads on Agentworks.

For the product overview and core concepts, see the top-level README. The project's values and design rationale are in the Manifesto. This document covers installing the CLI, the command surface, configuration, and operational details.

Getting Started

Install from PyPI:

uv tool install agentworks-cli
# or:  pipx install agentworks-cli

The everyday command is agw. The longer form agentworks is also installed if you ever want to type it out; examples throughout this document use agw.

Run agw guide for a concise index backed by the reserved packaged _index.md shell. Human and agent modes show the same frontmatter-selected concepts. The static path discovers packaged shells but does not read configuration, live state, or release history.

Use agw guide show concept-assistant-agent for the external assistant's operating posture, agw guide show concept-onboarding for repeatable first setup and current adoption, and agw guide show concept-management for ongoing operation. Prerequisites, VM platforms and sites, Tailscale, the domain model, packaged history, and optional read-only source review have equivalent guide show topics. Selected concepts are Markdown files; small top-level fenced passages can appear only in agent mode. The fence markers and section includes are exact standalone column-zero comment lines; similar comments nested in Markdown containers remain content. Use agw guide list when a completion or tool needs every installed concept and packaged release-note topic name.

Every guide entry point validates the complete installed concept-shell catalog before returning output. An unrelated malformed shell or duplicate global topic therefore blocks the index, list, single-topic show, and dynamic topic completion together instead of exposing a partial catalog.

Raw resource, relationship, schema, and sample facts belong to commands rather than guide topics. Use agw resource show, agw graph show, agw resource kinds, agw resource list, agw resource explain, and agw resource sample for those command-owned facts.

# Initial setup
agw config init                          # creates ~/.config/agentworks/config.toml
agw config edit                          # opens the config in your $EDITOR (or $VISUAL) to fill in required fields
agw doctor                               # sanity-checks installed tools, Tailscale, config validity, and the local DB

# Create a VM, workspace, agent, and session to see how the pieces fit together
agw vm create my-vm
agw workspace create my-workspace --vm my-vm
agw agent create my-agent --vm my-vm
agw session create my-session --workspace my-workspace --agent my-agent

# Attach to the session's tmux session to drive it
agw session attach my-session
# Use tmux's 'detach' command (default Ctrl-b unless overridden by config) to disconnect while
# leaving everything running on the VM.
agw session attach my-session    # You'll pick up right where you left off
agw session stop my-session      # Sessions can be stopped (or can exit on their own)
agw session list                 # Fast local inventory
agw session list --status        # Add bounded, non-activating live status
agw session start my-session
agw session attach my-session
agw session delete my-session    # When you're done with it. Agent and workspace are preserved unless this was their last session (see below).

# Alternatively, you can create ephemeral workspaces and agents along with your sessions
agw session create my-ephemeral-session --vm my-vm --new-workspace --new-agent
agw session attach my-ephemeral-session
agw session delete my-ephemeral-session    # This will prompt you to delete the associated workspace and agent, too

# Deleting a session also checks whether its workspace and agent are now unused
# (whether or not this session created them). A workspace is unused once it has
# no sessions; an agent is unused only once it has no sessions AND no standing
# workspace grant (no explicit grant and grant-all unset; a standing grant
# means you still intend to use the agent, so it is left alone). For each
# resource now unused, session delete offers to delete it interactively.
# Under --yes it auto-deletes only a workspace/agent
# this session created; anything else now unused is reported (naming
# `agw workspace delete <name>` / `agw agent delete <name>`) and left in place
# for you to remove by hand.
# One guard applies: if any agent holds an explicit per-workspace grant on the
# now-unused workspace (deleting it would silently revoke that grant), the
# --yes auto-delete is refused and the workspace is reported (naming the
# granting agents) instead, while the interactive offer discloses whose grants
# a delete would revoke. Grant-all agents don't trigger the guard: blanket
# access is policy, not per-workspace intent.

# Finally, create two sessions and a named console
agw session create s1 --vm my-vm --new-workspace --new-agent
agw session create s2 --vm my-vm --new-workspace --new-agent
agw console create my-console s1 s2+1      # The + syntax gives you extra shells as that agent
agw console attach my-console

# Deleting a session drops it from any console that referenced it (no dangling
# references are left behind). session delete lists the affected consoles, and
# for any console left with no sessions it offers to delete the now-empty
# console (interactively). Under --yes it reports the empty console but leaves
# it for you to remove with `agw console delete <name>`. `console remove-sessions`
# gets the same now-empty treatment when it drops a console's last session.
agw session delete s1                      # Reports that my-console still referenced s1

agw console delete my-console              # Extra shells are lost but sessions are preserved

Automation upgrading from the former session-resume or console-create-on-attach grammar should follow Upgrading to 0.18.

Prerequisites

  • Python 3.12+ (uv will install one for you if needed)
  • uv or pipx for installation
  • Tailscale installed and connected (for VM workspaces)
  • One of: Lima, Azure CLI (az), AWS credentials for EC2, Google Cloud credentials for GCE, Proxmox, or WSL2 (for VM provisioning; Azure, AWS, GCP, and Proxmox also need their system plugin enabled). The optional guest gcloud-cli apt package is not a host prerequisite.

Global Options

Flag Description
--version Print the installed CLI version and exit (equivalent to agw version)
--non-interactive Do not use the TTY for interactions, even if one is present
--debug Print the full traceback on unhandled errors, and show the Azure SDK's own log lines that are otherwise suppressed (also via AGW_DEBUG=1)
--no-deprecations Silence the ambient per-command deprecation banner (agw doctor always reports deprecation health)

--non-interactive is a terminal-input policy: it disables TTY interaction even when a TTY is present. A process without usable terminal input is subject to the same TTY limitation. This flag does not disable color or other presentation, and it does not forbid provider work outside the TTY, such as biometric, app, browser, device, or other out-of-band authentication. Commands that need TTY input fail with a clear error naming the required explicit flag or argument. VM auto-selection still works when exactly one usable VM exists. session create still requires its workspace and mode choices through terminal input because those choices establish the session identity.

Domain errors (SSH timeouts, validation failures, missing resources, etc.) surface as a single clean line: Error: <message>. Truly unexpected failures (internal bugs, OS-level errors, third-party library failures) also get a clean single-line message, plus the full traceback appended to ~/.config/agentworks/logs/error.log for debugging. Pass --debug (or set AGW_DEBUG=1) to print the traceback to stderr instead. Debug mode also restores the Azure SDK's own credential-chain log lines, which are otherwise suppressed so a credential failure renders once as the typed error.

On an interactive terminal, output is colorized by role: a yellow Warning: prefix, a red Error: prefix, bold section headers, a dim-green result line (the closing "VM deleted", "rekeyed", etc.), and dimmed secondary detail. agw doctor colors its per-check status labels the same way (green [ok], yellow [warn], red [FAIL], and unstyled [info]), plus its summary line's fail/warn/ok counts. Color is a presentation aid only, never carried in the message text. It is suppressed automatically when the target stream is not a terminal (pipes, redirects, CI capture). Set the NO_COLOR environment variable (any value, honored by its presence) to opt out of color even on a terminal. --non-interactive does not change this presentation policy.

Pressing Ctrl-C during a long-running operation triggers best-effort cleanup. Where the operation can roll back (e.g. vm create during the provisioning phase, workspace create, agent create, session create) it undoes the partial DB / on-VM state and prints Cancelling X... rolling back.. On every platform the vm create provisioning-phase rollback also deletes the partially created backend state: Azure the cloud resource set (VM, NIC, public IP, NSG, vnet, disk), GCE the provider-ID-owned instance and allow/deny rules, which can take a minute or two; Proxmox the partially cloned VM (cancelling a still-running clone task first); Lima the instance (local, or on the site's placement host for an ssh-placed site); WSL2 the distro plus its install directory. A second Ctrl-C abandons that cleanup, printing what to remove manually: the resource group and name prefix, the node and VMID, or the exact removal command (limactl delete --force <name>, run on the placement host for an ssh-placed site, or wsl --unregister <name> plus deleting the install directory it names). Where rollback isn't possible (vm reinit, agent reinit, the init phase of vm create) it prints a recovery hint: the next command to run (vm reinit, vm delete --force, ...). Every cancellation exits with the conventional SIGINT exit code (130).

Commands

The complete command surface, machine-readable JSON v1 contract, guide behavior, and session/tmux details live in the focused CLI command reference. The VM, workspace, and session list and describe paths project persisted provisioning, initialization, and session-mode values through frozen JSON v1 vocabularies owned by the output contract. On those operational surfaces, valid values retain their existing human bytes and corrupt values render as the stable unknown sentinel without echoing their stored text. Doctor diagnostics are a separate surface. VM, session, and console lists are local inventory reads by default; add --status to any of those three lists for live observation. Their describe commands include the same non-activating live status by default. See Runnable status inspection for the resource-specific states, time bounds, and failure behavior.

Configuration

Configuration splits into two surfaces:

  • Settings live in ~/.config/agentworks/config.toml: your identity, paths, defaults, database safety policy, and the secret source chain. Run agw config init to generate a sample; see sample-config.toml for the full reference.
  • Resources (secrets, templates, git credentials, vm-sites, apt / install-command entries) are declared as YAML manifests under ~/.config/agentworks/resources/, auto-loaded whenever a command needs them. agw resource sample <kind> prints a commented starter (--all for every kind). The classic TOML resource sections are no longer supported: their roots are ordinary unexpected top-level keys (they were previously deprecated with a warning). Rewriting those sections as manifests is a manual step, walked through by docs/guides/upgrading-to-0.14.md.

Settings sections (config.toml, permanent):

  • [operator] -- SSH keys (required), additional authorized keys, SSH config management
  • [paths] -- VM workspace, VS Code workspace file, and backup directories
  • [terminal]: local screen behavior on detach (clear_on_detach: auto / always / never)
  • [defaults]: site, the default vm-site for vm create
  • [database]: automatic pre-migration backup policy (safe default: enabled)
  • [session.config] -- session defaults (history limit)
  • [secret_config] -- active secret source chain; its sources key names secret-source resources
  • [plugins]: the plugin-subsystem namespace; its system key is the opt-in list of enabled system plugins (see System Plugins below)

Resources are declared as YAML manifests. agw resource kinds lists every kind with its category and purpose, agw resource show KIND/NAME shows one complete focused card with list facts, direct relationships, current users, attributable health checks, and the normalized declaration, selectable instance templates also show their fully resolved spec and value provenance, agw resource explain KIND documents what one accepts field by field, and agw graph show KIND/NAME traverses beyond that row through declared and current live relationships.

The table below exists for one thing this repository is otherwise the only record of: which removed legacy TOML section used to declare each kind. Those sections no longer load; the mapping is a reference for reading an old config.toml and for rewriting it as manifests.

Kind Removed TOML section
vm-site [azure] / [proxmox] (flat legacy shape)
vm-template [vm_templates.*]
admin-template [admin.config]
agent-template [agent_templates.*]
session-template [session_templates.*]
workspace-template [workspace_templates.*]
named-console-template [named_console]
git-credential [git_credentials.*]
secret [secrets.*]
secret-source none; introduced as YAML
apt-source, apt-package, system-install-command, user-install-command [apt_sources.*] and siblings

The four capability kinds (vm-platform, harness-integration, git-credential-provider, secret-backend) are read-only rows for registered code, never declared and never in TOML.

Every git-credential provider requires its own structured source. The shipped GitHub provider accepts secret or gh-cli; the Azure DevOps provider accepts secret or az-cli. Secret sources declare the provider input that Agentworks resolves. CLI sources use the target user's active CLI identity at Git-operation time. Enabled credential runup checks that the CLI is installed and its identity is healthy for that admin or agent user, but a warning does not block helper installation. Put credential names on the relevant template and reinitialize the user to rebuild the complete managed Git credential state. See agw resource explain git-credential-provider/NAME for the installed schema.

This is a breaking change from 0.16. The 0.17 upgrade guide covers the paired CLI/resource-directory cutover, per-user reinitialization, and rollback boundary.

Env vars ride their owning resource, as an env map in the template's spec (the removed TOML shape used [<scope>.env] subsections), at vm / workspace / admin / agent / session scope. The lima-local and wsl2 vm-sites ship built in and their names are reserved.

Environment Variables and Secrets

Env tables can be declared at five scopes; for any given session the merged value is computed in this precedence order (highest scope wins; identity vars win over everything):

session > (agent | admin) > workspace > vm           (AGENTWORKS_* identity overrides all)

Admin and agent scopes are mutually exclusive: a shell opened as the admin user (e.g. agw vm shell) sees admin scope; an agent-mode session sees agent scope. Each scope is an env map on the owning resource, mapping env-var name to either a plaintext string or a secret reference:

apiVersion: agentworks/v1
kind: vm-template
metadata:
  name: default
spec:
  env:
    HTTP_PROXY: http://proxy:3128
    NPM_TOKEN: { secret: npm-token }

Every secret reference points to a secret resource declaration, which is auto-declared with a framework description if omitted. [secret_config].sources names secret-source resources in precedence order. Agentworks synthesizes these defaults when the setting is absent:

  • env-var reads the operator process environment. Its default lookup is AW_SECRET_<UPPER_SNAKE_CASE> and a secret's backend_mappings may override that name.
  • prompt requests the value through terminal input and asks at most once per command.

Actual resolution makes one bounded, source-first pass. Each source receives every unresolved candidate in the batch. Ordinary missing values and sources blocked by TTY access fall through; invalid mappings, authentication errors, provider rejection, transport errors, and timeouts are hard failures for that secret and do not fall through. Values remain inside the resolution path and are never part of inspection results. Commands resolve their statically planned secrets before mutation, except deliberately lazy conditional work such as Tailscale repair. A complete batch that is already terminal stops before opening another provider source; other skipped names report the core-only batch-doomed-before-interaction reason. Static viability never predicts from TTY access; the backend receives that exact fact and decides whether it is limiting. Explicit partial reveal continues independent names.

Preflight uses the same provider-aware preview contract as the inspection commands, fixed at no operator impact. It may read a provider and safely discard a value, but it cannot prompt or perform work classified by that backend as requiring operator action. Preflight fails only when the preview proves that the planned secret cannot currently be supplied under those restrictions. Preview does not return values.

Inspect the merged result for any context with agw env show:

agw env show --session my-session              # secrets redacted as <from secret: name>
agw env show --vm my-vm --resolve              # resolves through the active source chain

(The flag was formerly spelled --reveal-secrets; it was renamed to --resolve as a breaking change, the old spelling no longer works.)

Inspect each active source's static mapping for every declared or auto-declared secret with agw secret list:

agw secret list
# 4 secrets (2 operator-declared, 2 auto-declared)
#
# NAME                 DESCRIPTION                                                                env-var                       prompt
# ----                 -----------                                                                -------                       ------
# api-key              OpenAI key for the operator's service                                      OPENAI_API_KEY                candidate
# force-prompt         Always prompted at command time                                            won't attempt                 candidate
# git-token-github     (auto) the GitHub credential input for git-credential:github               AW_SECRET_GIT_TOKEN_GITHUB    candidate
# tailscale-auth-key   (auto) the Tailscale auth key for vm-template:default (and 1 more)          AW_SECRET_TAILSCALE_AUTH_KEY  candidate

Columns are the active sources in [secret_config].sources precedence order. Cells show each source's static lookup identifier (env var name, vault path, op:// URI), won't attempt, candidate, or not ready: <reason>. A candidate is an applicable lookup, not a presence claim. The Description column shows the operator-supplied text for operator-declared secrets, or a framework-synthesized (auto) <usage> for <kind>:<name> (plus (and N more) when more than one source requires the secret) for auto-declared ones. The synthesized text reads as "what this secret is for, and who's asking." The summary line breaks the rows down by origin. Values are never resolved.

For the full per-secret detail view, including the structured origin block, usage list (who requires this secret), source-keyed backend_mappings table, and a resolution preview, use agw secret describe:

agw secret describe tailscale-auth-key
# Secret: tailscale-auth-key
#   Kind: secret
#   Description: (auto) the Tailscale auth key for vm-template:default (and 1 more)
#   Origin: auto-declared (vm-template:default)
#
# Referenced by:
#   - vm-template:default -- the Tailscale auth key
#   - vm-template:heavy -- the Tailscale auth key
#
# Backend mappings:
#   - env-var (env-var, synthesized default): AW_SECRET_TAILSCALE_AUTH_KEY
#   - prompt (prompt, synthesized default): (prompt at resolution time)
#
# Resolution preview:
#   available; source=env-var; identifier=AW_SECRET_TAILSCALE_AUTH_KEY
#   Hint: available under the requested preview impact
#   - env-var: available; identifier=AW_SECRET_TAILSCALE_AUTH_KEY

By default, describe requests a provider-aware preview with no allowed operator impact. It may read an environment variable or provider value and safely discard it. --allow-interaction permits backend-classified operator action and guarantees a definitive answer, although blocked and failed outcomes remain possible. Preview always returns status and safe lookup identity, never the value:

agw secret describe tailscale-auth-key --allow-interaction

Use verify for the same provider-aware preview over one or more named secrets:

agw secret verify tailscale-auth-key deploy-token
# NAME                 STATUS     SOURCE   IDENTIFIER                     REASON  HINT
# ---------------------------------------------------------------------------------------------------------------
# tailscale-auth-key   available  env-var  AW_SECRET_TAILSCALE_AUTH_KEY   -       available under the requested preview impact
# deploy-token         available  work-op  op://Engineering/deploy/token  -       available under the requested preview impact

Verification deduplicates names in first-written order and prints one value-free row per name. Only available is success; missing, indeterminate, blocked, and failed rows make the command exit 1. The default permits no backend-classified operator impact. Opt in explicitly when the strongest available answer may require operator action:

agw secret verify tailscale-auth-key --allow-interaction

--allow-interaction is orthogonal to global --non-interactive. With both flags, providers may request biometric, app, browser, device, or other out-of-band work, while terminal prompts remain disabled. At the maximum impact level a backend must not return indeterminate.

These secret surfaces changed shape in 0.15, including what agw doctor can exit with; docs/guides/upgrading-to-0.15.md covers what an operator or a CI job needs to do about it.

agw doctor keeps three adjacent secret groups. Secret backends reports implementation readiness; Secret sources shows every declared source with its selected backend, active/inactive, enabled/disabled, provenance, and folded readiness; Secrets emits exactly one row per registry secret, operator-declared and auto-declared alike. Doctor keeps these health rows compact; use agw secret list or agw secret describe for descriptions and origin details.

  • OK for available, and for an indeterminate/operator-input-required prompt path that can collect the value when a command needs it.
  • INFO for indeterminate/operator-impact-limited, where doctor deliberately skipped a provider lookup that might require operator action and therefore did not establish availability.
  • WARN for missing or blocked.
  • FAIL for a hard provider or mapping failure.

Source-applicability detail (per-source soft-skip reasons, inactive mappings, per-secret references) lives in agw secret list and agw secret describe. AGENTWORKS_* identity overrides surface in the Configuration group (they're a config-load warning). Broken { secret: ... } references are caught earlier as a hard config-load error before doctor runs. A secret-backed git credential's declared inputs report as ordinary secret rows. CLI-backed credentials declare no secret. Their optional target-user readiness check uses the target user's login/interactive shell during initialization, and final token acquisition remains at Git runtime. That check can precede later install/profile steps, so its result describes only that point in initialization. Doctor uses no-impact provider preview. It may read and discard a value when the backend classifies that work as no-impact, but it cannot ask for operator action and never returns the value. Use agw secret verify NAME... --allow-interaction when you want the strongest provider answer. Secret-backed capability authentication still occurs at the capability runup() stage inside provisioning operations. The Tailscale group checks only workstation connectivity; the auth key is the tailscale-auth-key secret row.

--non-interactive is not a general unattended fail-fast mode. It only disables TTY interaction; out-of-band application authentication may still raise an approval request and wait until the configured source timeout. Truly unattended paths should use env-var or a provider authentication mode known to be unattended, such as supported 1Password service-account or Connect credentials, instead of relying on --non-interactive.

When the config or a resource manifest fails to load, the groups that depend on them (VM sites, Secrets) do not vanish: each renders a single [info] ... skipped (config or manifests unavailable; see the Configuration group) row, so a degraded run keeps the same section skeleton as a healthy one and the Configuration group carries the actual failure. If only database-backed resource publication is unavailable, doctor still runs those groups over the finalized declared-resource graph. The Configuration group marks live-resource coverage as unavailable and reports publication failures, while the Database group separately reports schema and storage health. Doctor neither presents that view as complete nor migrates the database.

Secret Sources and Backends

A source is a declarable secret-source resource that selects one read-only secret-backend implementation in spec.backend. The chain and every backend_mappings key name sources, not implementations. The synthesized env-var and prompt source names remain valid unchanged. For 1Password, enable the plugin, declare a source with backend.name: onepassword, move the old mapping account to that source, optionally set the new source timeout, and map each secret's source key to one scalar op:// reference. A direct configured-backend reference such as onepassword breaks in 0.14 with an exact source declaration and mapping rewrite; no compatibility row is created.

System Plugins

Agentworks ships optional vendor, tool, and installer catalogs as system plugins: separable bundles that are installed but off by default. The shipped build installs apt (five apt sources and their five package sets), install-command (six user install commands), azure (the azure-vm VM platform, the azdo git-credential provider, and the az-cli install-command), proxmox (the proxmox VM platform), aws (the aws-ec2 VM platform), gcp (the gcp-gce VM platform and optional guest gcloud-cli apt package), onepassword (the onepassword secret backend), claude (the claude-code harness integration and the claude CLI install-command), and codex (the codex harness integration and the codex CLI install-command), and grok (the grok-build harness integration and the Grok Build CLI install-command). (This is a different sense of "plugin" from Claude Code Plugins below, which installs marketplace plugins into Claude Code itself.)

Opt in by name in config.toml:

[plugins]
system = ["apt", "install-command", "azure", "aws", "gcp", "proxmox", "onepassword", "claude", "codex", "grok"] # only those you use

A resource that references a not-enabled plugin's contribution (an azure-vm vm-site, a claude-code session-template, a secret mapped to a source selecting onepassword, ...) is not-ready, or refused at use, with an "enable plugin <name>" hint, never an unknown-name error. The default local path (the lima / wsl2 platforms, the shell harness integration, the env-var / prompt secret backends, and the github git-credential provider) is built in, always on, and needs no [plugins] entry.

A not-enabled plugin's rows are hidden from agw resource list by default; pass --include-disabled to reveal them (see the Resource Registry). agw doctor has a System plugins group listing every installed plugin, its description, and whether it is enabled.

See docs/guides/resources.md for the full model (origins, the disabled-resource semantics, config-error deferral) and the upgrade note for configs that relied on Azure, Proxmox, 1Password, or Claude Code before they became opt-in. Cloud platform permissions, credentials, and safe cleanup are covered in Using Amazon EC2, Using Azure Virtual Machines, and Using Google Compute Engine.

Mise (Polyglot Tool Manager)

Agentworks installs mise by default on all VMs for managing CLI tools (terraform, adr-tools, node, etc.) with optional lockfile-based integrity verification. See Using mise for the full guide.

Claude Code Plugins

Agentworks can register Claude Code marketplaces and install plugins automatically per user (admin and per-agent). Configure via claude_marketplaces and claude_plugins on the admin template or any agent template. Requires the claude CLI on PATH (typically installed via user_install_commands). To install nerftools this way:

apiVersion: agentworks/v1
kind: admin-template
metadata:
  name: default
spec:
  claude_marketplaces: ["https://github.com/WayfarerLabs/nerftools#4.1.0"]
  claude_plugins: [nerftools-default@nerftools]

Optional Apt / Install-Command Catalogs

The optional apt plugin owns the shipped apt sources and package sets. The optional install-command plugin owns the shipped user install commands. Both are installed but disabled by default, while core continues to own their kinds, validation, dependency ordering, runners, and executors. Enable the matching plugin in [plugins].system before a template selects an entry. Run agw resource list --kind apt-package,system-install-command,user-install-command,apt-source to see what is available (or filter to any single kind), and add --include-disabled before enablement. Reference entries by name from VM, admin, and agent templates. User-defined entries override a same-named plugin row. A custom apt package that keeps a shipped apt-source dependency still needs apt enabled, or must replace or remove that source dependency too.

An apt-source uses either a release-independent spec.source scalar or a release-keyed spec.sources map. Use the map whenever a Debian codename appears in the stanza. Initialization selects the entry for the VM's verified Debian release and fails before source mutation when that mapping is absent.

Prefer template apt, apt_packages, snap, or mise_packages fields over a custom install command. When an install command is necessary, its command is one logical shell invocation written as a single-line YAML scalar, either plain or quoted, normally one maintained package-manager or vendor entry point. Do not embed a script, block scalar, here-document, multi-step installer, state machine, signature pipeline, or cleanup routine. The invocation must be repeat-safe itself or use test_exec, test_file, or test_dir as reliable completion checks. System install commands run as the VM admin, not root, and explicitly use sudo for privileged work.

VM Initialization

VM creation follows a two-phase lifecycle tracked by separate status columns:

  1. Provisioning (provisioning_status): one-time, platform-specific, over the provisioning transport (Lima shell, SSH, or WSL2 exec): create user, install system packages, add SSH key, install and join Tailscale

  2. Initialization (init_status): repeatable via vm reinit, over Tailscale SSH: configure apt sources, install apt packages, install snap packages, install mise, set shell, reconcile SSH authorized keys, run system install commands, write mise config, configure PATH, configure git credentials, sync dotfiles, fetch mise lockfile, run mise install, run user install commands for the admin user

Initialization is fully declarative. vm create accepts a name, --template, --spec, --admin-template, --admin-spec, and --site. Immutable hardware starts with the VM template and may be refined by --spec; the admin user starts with the selected admin template and may be refined by --admin-spec. vm reinit takes only the VM name and re-runs initialization using the current config and both stored final layers. See Instance specs for the exact create and agent-reinit surface.

Agentworks records the configured SSH identity only after a VM create or reinit proves the admin authorized_keys result. It does not synthesize evidence for VMs created before this tracking was introduced. Such a VM needs one successful agw vm reinit NAME before ordinary canonical SSH commands will use it. If the configured key no longer works, use agw vm shell NAME --platform where the platform offers a usable recovery transport, restore the configured public key, and reinitialize. Some platform transports also depend on the configured key; use provider-native recovery or recreate the VM when that path cannot connect.

Debian distribution upgrades remain operator-led. After following Debian's release notes and verifying provider-native recovery, run agw vm confirm-release <name> to inspect and explicitly adopt the live release, then run the separate agw vm reinit <name> to converge release-aware Agentworks state. See Upgrading a Debian VM.

Passphrase-protected OpenSSH private keys remain supported: Agentworks reads the public identity embedded in the private-key envelope without decrypting it or consulting a sibling public-key file. Recognized encrypted legacy key formats that do not expose a public identity are reported as unverifiable, not mismatched. SSH-agent identity selection is not part of this comparison contract; the configured private-key path remains the identity source.

Non-fatal initialization failures (packages, dotfiles) produce a partial status rather than aborting. Fatal failures prompt for deletion or reinit. Use vm describe to view the full event log, current VM and admin declarations, recorded lifecycle evidence, and structural drift. The hardware evidence is the provisioning request associated with successful creation, not a provider observation of realized hardware. Workspace, agent, and session describe commands show the same current-declaration and stored-instance-layer facts without inventing lifecycle evidence those operations do not record. Human describe keeps the complete current spec compact by omitting per-leaf Value sources; JSON describe and template resource show retain full provenance.

Shell Completion

agw completion install

The shell is autodetected from $SHELL; pass --shell {bash|zsh|powershell} to override (or when autodetection isn't unambiguous, e.g. on Windows). completion install writes the script to the standard location for that shell. For PowerShell it also appends a dot-source line (. "...") to $PROFILE. For bash and zsh, if your rc file is missing the loader (bash-completion for bash, fpath=(~/.zfunc $fpath) for plain zsh without a plugin manager), the installer prints a one-line note telling you what to add.

To print the script without installing, use agw completion show (handy for piping into your own config-management flow). To remove completions installed here, use agw completion uninstall --shell {bash|zsh|powershell}. For PowerShell, uninstall also strips the dot-source line the installer appended to $PROFILE; user-authored lines around it are left untouched.

Completions include dynamic VM, vm-site, workspace, session, secret, and template name lookups. agw secret verify completes registered secret names at every positional argument.

State

All state is stored in ~/.config/agentworks/agentworks.db (SQLite). Schema migrations are forward-only and run automatically when a normal Agentworks command opens stale state. Before the first migration statement, Agentworks announces the source and target versions on stderr and, by default, completes an online snapshot. An interactive terminal asks Back up the state database before migrating? with yes as the default. Automation uses [database] auto_backup_before_migration = true; set it to false only when deliberately accepting migration without that recovery point. agw doctor uses a WAL-aware read-only inspection and never runs migrations. It reports malformed, orphaned, or newer-release instance records and compares recorded VM SSH identities in one batch when current configuration is available. See the doctor JSON contract for the machine-readable result.

Create a consistent on-demand snapshot, including committed WAL content, with:

agw database backup

The command prints the completed backup path to stdout. Backups live in ~/.config/agentworks/database-backups/ beside the live database. On-demand files use the agentworks-manual-...db prefix and are never removed by automatic retention. Automatic pre-migration files use agentworks-pre-migration-...-vN.db; only that category is pruned, keeping the five newest automatic files. Unrecognized files in the directory are left alone.

If a selected automatic backup fails, migration does not start; the error explains how an interactive retry can explicitly decline or how automation can use the documented opt-out. If a migration itself fails, the error either prints an exact agw database restore ... command for the completed pre-migration snapshot or states explicitly that no snapshot was selected.

Restore a selected snapshot with agw database restore BACKUP_PATH. The command validates the backup, shows the backup and live paths on stderr, and asks before replacing the live database. Pass --yes (or -y) for intentional non-interactive recovery. Restore does not first back up the database it replaces and does not run schema migrations. If the restored snapshot is older, the next ordinary command owns any forward migration. A backup from a newer schema is preserved but must be restored by an Agentworks release that understands that schema. Before downgrading Agentworks, restore a backup whose schema the older release understands; do not open newer state with the older release first.

SQLite may leave user-only -shm and zero-byte -wal coordination files beside a selected backup after validation or restore. This is expected: the backup database remains unchanged, valid, and retryable. Agentworks uses an ordinary read-only open here so committed WAL content is not ignored, and it does not race SQLite by deleting those coordination files.

Environment Variables

Secret values are read from the operator's shell via the env-var backend, which follows the convention AW_SECRET_<UPPER_SNAKE_CASE> derived from the secret's name. The Tailscale auth key (secret tailscale-auth-key) reads from AW_SECRET_TAILSCALE_AUTH_KEY; a secret-backed git credential using its default reference (git-token-<name>) reads from AW_SECRET_GIT_TOKEN_<NAME>; and so on. Override the convention per secret via the secret's backend_mappings (env-var: CUSTOM_NAME).

Use agw secret list to see the exact env var name for each declared or auto-declared secret, and agw secret describe <name> for the full per-secret view (origin, usages, backend mappings, resolution preview).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentworks_cli-0.18.0.tar.gz (2.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentworks_cli-0.18.0-py3-none-any.whl (1.5 MB view details)

Uploaded Python 3

File details

Details for the file agentworks_cli-0.18.0.tar.gz.

File metadata

  • Download URL: agentworks_cli-0.18.0.tar.gz
  • Upload date:
  • Size: 2.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for agentworks_cli-0.18.0.tar.gz
Algorithm Hash digest
SHA256 c1e8af9c3d7c48ae3d6d35b7c26660a5ad8cbbc4ffe4ed8cd1ddfedd63aa8896
MD5 583bcd4925217ed4b3b0d0891fe48da7
BLAKE2b-256 feb81a9f07a448102d32ae7da0144b4b708435016a85319c46cabe9005d1ed37

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentworks_cli-0.18.0.tar.gz:

Publisher: release.yml on WayfarerLabs/agentworks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agentworks_cli-0.18.0-py3-none-any.whl.

File metadata

File hashes

Hashes for agentworks_cli-0.18.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2accd10fcb03492a2805107870764c5354d39e2135b8abc27a2737b66e472b94
MD5 e2c3269218f81b3b4df214e95d604410
BLAKE2b-256 fc3ffd43c5a31b23546061a233009be064ed07cdc2e0fb1789c0c19500ae31e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentworks_cli-0.18.0-py3-none-any.whl:

Publisher: release.yml on WayfarerLabs/agentworks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.19.0

2 files

This release

0.18.0 This release

2 files

0.17.0

2 files

0.16.0

2 files

0.15.1

2 files

0.15.0

2 files

0.14.1

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page