Skip to main content
Ask questions, pipe in logs, or run production investigations without leaving the terminal.

Quickstart

1

Install

2

Authenticate

Your browser opens for authentication and the CLI selects your default project.
3

Ask

Common workflows

Start a terminal chat with session history and markdown output:

Stay up to date

Stable Annie CLI releases tell you when a newer version is available in an interactive terminal. The TUI keeps the available version in its status bar, and successful human-readable commands may show one reminder every 24 hours. Check synchronously whenever you need the current release status:
The JSON form reports the installed version, latest version, update availability, check time, and release URL. Annie does not download or install the update. Passive checks stay silent for JSON output, pipes, redirected streams, CI, help, version, shell completion, development builds, and prereleases. Network failures do not change command output or exit status. Disable passive checks and reminders without disabling the explicit command:

Investigate cloud changes

Use deterministic graph commands when you need retained AWS, Azure, GCP, or Cloudflare change evidence in a terminal, script, or CI job. List recent events by provider and scope. For GCP, you can also narrow events to one provider operation and inspect the affected inventory:
If a fuzzy topology selector matches several equally authoritative resources, Annie exits 2 with RESOURCE_AMBIGUOUS and lists at most ten stable-ID candidates. JSON keeps the same candidates at .error.details.candidates. Select one id or anyshiftID and retry; Annie never traverses from an arbitrary first match. --operation groups activity by the GCP-native operation identifier. --correlation selects the broader Anyshift event story. They are separate identifiers. Text output keeps the main evidence fields; use JSON when automation needs warnings, availability, before and after values, pagination, or provenance references:
Normal annie graph cloud-events browsing uses bounded page mode. Text output reports the number shown, whether more results exist, and the next cursor without calculating or claiming an exact full-window total. Use --exact-stats only when you need the exact total and event-type breakdown; that opt-in can be slower on large accounts. In page-mode JSON, total is null, byType is empty, and statistics reports { "mode": "none", "exact": false }. An unknown status is not success. Unknown provenance does not mean unmanaged, and unknown freshness does not mean stale. If a response contains nextCursor, pass it back with --cursor to continue that result page.

Repository context

Add an .annie.yaml file to a repository when you want every question from that workspace to use the same Anyshift project, metadata, and runbooks:
.annie.yaml
Annie finds the nearest .annie.yaml by walking up from your current directory. Repository settings apply only to that invocation and do not change your global default project. Use project-scoped personal context when a value should follow you across repositories:
These commands manage your personal context for the selected project. They do not edit the repository’s .annie.yaml. Invocation flags take precedence over TUI session context, repository context, and personal project context:
Files are included only when you name them. Annie blocks files outside the repository, unsafe symlinks, binary and oversized files, common secret filenames, private keys, token-like content, and Kubernetes Secret manifests. The limits are 32 KiB per file and 96 KiB across one request. Run annie context preview to check file status without printing file contents.

Structured output

Pass a local JSON Schema when a script or CI job needs a predictable object instead of prose:
service-risk.schema.json
The CLI validates the schema before sending the request. --schema requires --output json and supports JSON Schema Draft 7 and Draft 2020-12 with an object at the root. Remote schema references are rejected.

Conversation history

Resume a previous investigation with its transcript instead of starting over:
Resume state is scoped to the active project. Annie verifies that the conversation belongs to that project before restoring it. annie conversation delete <id> requires confirmation and may be restricted to administrators.

Reference

The ask timeout covers startup input, login renewal, project selection, submission, and waiting for the answer. With --follow, each question gets a fresh timeout after you enter it; time spent typing is excluded. Login requests also have a 30-second limit, and a failed renewal preserves your saved credentials.
All non-interactive graph commands support --project <name|uuid> and --output text|json. Run annie graph <command> --help for command-specific flags.graph brief and resource-scoped graph check resolve the resource before querying posture. When a name exists in two clusters, qualify the brief or use a stable ID:
From CLI v0.9.0 with Graph API v0.2.96, each compatible brief/check section uses the selected ID. Brief skips sections whose selector contract cannot preserve that identity: deploy impact, service tree, and alerts for non-service resources. It reports RESOURCE_SCOPE_UNSUPPORTED in workflow.warnings and partial completeness. Unavailable headline.activeAlerts and headline.downstreamServices are null, not zero; text displays unknown. These warnings mean evidence was not queried, not that the resource is missing or healthy.Inspect public exposure for a Cloudflare hostname or a Kubernetes service:
Each path may include nullable originReachability for internet-facing ALB or NLB security-group evidence versus pinned Cloudflare IP ranges. That field is not DNS proxied / RESOLVES_DIRECTLY_TO, and text output prints it separately from traffic gaps. See Origin reachability.graph triage is deterministic evidence, not AI. It optionally queries incident_context for the resource (target + since + LIMIT). Returned hops are incident, alerts, service, onCall, responders, and history. Empty hops are omitted from findings. History cites reviewed resolution evidence only (confirmed_fix, explicit_reference, or unknown), never temporal-only association. Raw queries use incident_context; PagerDuty setup is on the PagerDuty integration page.graph show accepts a hashedID or anyshiftID returned by graph discovery. It uses the project-scoped Graph API and never guesses from a display name. Resolve a name first, then inspect the selected identity:
The result includes the resource’s safe properties and bounded incoming and outgoing relationships. Text and JSON make relationship truncation explicit. Historical graph show --at reads are not supported until the Graph API has snapshot semantics; use annie graph history for retained change evidence instead.Discover the query language without authentication:
See the complete Graph Query Language reference.
JSON output uses the annie.cli/v1 envelope. Natural-language answers are returned under .answer.content, while Graph results are returned under .data.From v0.8.60, Graph query validation errors keep the server’s explanation at .error.details.reason, such as an unknown table, the allowed filters, or required time bounds. These errors still return GRAPH_QUERY_INVALID and exit 2. Use the reason to correct the query before retrying. Ambiguous resource errors remain RESOURCE_AMBIGUOUS, with retry choices in .error.details.candidates.Require a schema-validated answer with:
Manage persistent project context:
Essential commands:Use Tab for command completion, Page Up/Down to scroll, and Ctrl+C to cancel.To recover from a network error, API failure, or failed analysis, enter /retry. To change the question first, enter /edit, modify the restored text, and press Enter. Editing alone does not send a request.Both commands also work after a successful answer. Retrying creates a new request in the same conversation once one has been established; it does not replace the earlier turn. /retry keeps the context and files from the original submission, while an edited question uses the current context and files when you send it. RCA and report questions keep their command prefix. Quick prompts such as /alerts expand into editable question text.The last question is available for the current session and project. Clearing the screen keeps it, and switching projects resets it. Wait for the current request to finish before retrying or editing.
IDs accept an eight-character prefix.
For a single command, use --project <name|uuid>.
For local use:
For CI, create an access token in Settings → Access tokens, store it as a secret, and set:
ANNIE_PROJECT_ID is only required when the token can access multiple projects. Use personal tokens locally and shared tokens for team automation. Token authentication cannot perform administrative operations.
In the TUI, use /rate up, /rate down, or /rate hypothesis <n> up|down.
Configuration lives in ~/.annie/config.yaml. Disable anonymous telemetry with:
The CLI also respects NO_COLOR.

Create account

Start using Anyshift

Request a demo

See the CLI in action

Delivery provenance and code owners

Use annie graph delivery to see stored delivery activity, release/commit provenance, and observed code ownership for one resource:
The command resolves one resource and uses its exact graph identity across all three sections. Qualify ambiguous names with --type, --namespace, and --cluster, or select an exact --id. --project selects the project for the whole workflow. --cursor continues only the delivery-event page; retain the same resource, time window, and limit. Provenance and ownership are refreshed bounded snapshots. JSON preserves the section payloads under data.sections, including stored identities, provenance paths, evidence warnings, and the delivery continuation cursor. Code ownership means observed OWNS_CODE team/person relationships. graph owners continues to report GitOps application/repository ownership. Missing commit, actor, release, or owner links remain unknown. A commit, PR, or tag alone does not prove that a customer deployment occurred.

Observed graph coverage

Before interpreting an empty investigation, inspect which source evidence is represented:
Coverage reports observed node, relationship, bridge, and event counts. Supported sources are kubernetes, cloud, github, datadog, tempo, dynatrace, victoria, and grafana; k8s and scm are aliases for Kubernetes and GitHub. PagerDuty and Sentry are not included in this source inventory. These counts do not establish which integrations are configured, whether ingestion is healthy or fully synced, or whether monitoring policies cover every resource. An empty result means the query found no represented evidence within its scope; it does not prove that the underlying resources or events do not exist.

Exact Sentry alert contributors

Discover a retained Sentry firing, then inspect its stored contributor links:
Discovery defaults to seven days and supports a maximum 90-day window, explicit --from/--to, and --cursor pagination. Continue with the same project and filters; the cursor preserves the original window. Results distinguish metric evaluations, source errors and unclassified records. No retained firings does not prove Sentry had no firings. declarationAvailable: false is different from a known empty declaration. The firing ID is the exact, case-sensitive firingId returned by discovery (the graph event’s dedupeId). It is not a Sentry issue number or rule name. The command returns stored contributor identities, available timestamps, event types, and release context. JSON exposes the result under data, including counts, missingProviderEventIds, and page.nextCursor. Use the same firing and project when continuing a page. Declared IDs and observed linked events are counted separately. Missing contributors may be late, expired, or unobserved; the missing-ID list can be a bounded sample. Evaluation coverage remains unknown even when every declared ID is linked. Contributor membership describes alert evaluation, not a proven infrastructure root cause. No temporal match is substituted for a stored link.

Cloudflare resource inventory

Use the same inventory workflow for canonical Cloudflare resources:
Resource IDs retain their cf:// account and zone identity. Cloudflare resources have no fabricated cloud region. Inventory keeps canonical API-scanned resources separate from Terraform or evaluation copies while retaining observed IaC links. Absent observation timestamps and missing provenance remain unknown. Freshness compares each stored resource observation with --max-age, defaulting to 24 hours. Text output shows the threshold, observation timestamp and age; JSON retains filter.freshnessHours and each observedAt. This is not the time of the last completed scan job. Increasing --max-age does not refresh inventory. If observations stop advancing, investigate the connection and extraction pipeline; a partial scan does not by itself prove that OAuth authorization was revoked.

Finding Datadog monitor evidence

The default status is firing. Zero firing alerts can coexist with stored recovered, suppressed or unknown monitors. Empty firing results offer a command that preserves the selected project and filters while switching to --status all. Page counts use the returned canonical items; coverage is independent of that count. not_configured describes missing graph coverage, not a verified credential check. Monitor snapshots are collected hourly. Datadog alert coverage becomes stale after 75 minutes, allowing one collection interval plus 15 minutes for processing. The observation timestamp remains visible. Available coverage means a recent snapshot under this policy, not real-time confirmation of monitor status.

Datadog cloud scope in alert investigations

Datadog monitoring evidence can identify cloud targets directly, including RDS and EC2, without an intermediate APM service. Alert and monitor results preserve target IDs and actual graph types. Cloud targets do not acquire Kubernetes namespace or cluster values. Compare returned scope targets with scopeTargetCount to detect a bounded sample. Multiple legitimate targets remain explicit; monitoring scope does not establish that a target caused the alert. JSON retains scope identities and evidence warnings for automation.

Cross-layer storage, access, and potential impact

Follow stored Kubernetes-to-cloud relationships using exact resource IDs:
storage shows the PVC/PV footprint and cloud resources linked through stored USES_DISK relationships, including graph/native identities and account scope. access shows Kubernetes role evidence and observed ServiceAccount-to-IAM-role associations. An IRSA association does not prove effective permissions or a successful role assumption. Missing identity and relationship evidence stays unknown. Both commands resolve one subject before querying. Qualify ambiguous names with the common resource selectors or use --id; they reject responses for a different resolved identity. Cloud-backing and IRSA sections are bounded snapshots with limit, hasMore, and an explicit evidence boundary. A missing section from an older server means the evidence is unavailable. impact evaluates reviewed propagation directions with a depth of 1–3. Its output keeps exact target IDs, scope, relationship direction and warnings. Continue target pages with --offset <nextOffset>. It excludes identity bridges and IAM role associations; those relationships do not establish impact propagation. Potential impact is not proof of damage or causation, and empty results never establish an exhaustive absence of impact. The existing blast command remains available. Path output includes graph/native IDs and scope. Both path scopes can follow cloud compute, storage, role-association and hosting bridges within five hops; --scope operational also includes observed APM identity and dependency edges. These paths describe connectivity, not causal propagation or effective access.

Exact resource IDs

Ambiguous names list candidates with stable IDs. Copy the chosen ID unchanged, including an initial - or _; quoting preserves it as one shell argument:
A qualified name such as annie graph delivery anyshift-backend --type GITHUB_REPO selects that resource type when it uniquely identifies the intended resource.