diff --git a/en/ai-sre/agents.mdx b/en/ai-sre/agents.mdx index 4c21e4084..8141034c1 100644 --- a/en/ai-sre/agents.mdx +++ b/en/ai-sre/agents.mdx @@ -22,7 +22,7 @@ sidebarTitle: Agent Delegation doesn't make you wait. After AI SRE delegates a task to a remote agent, the conversation continues immediately. You can keep working or delegate several tasks at once. When the remote agent finishes, its result appears in the conversation as a new message. -Each A2A delegation appears in the conversation stream as a **task card** carrying an `A2A` badge. The card shows the remote agent name, task intent, run status, and usage metrics such as tool call count, tokens, and elapsed time. The run status is one of: initializing, in progress, awaiting input, awaiting authorization, completed, failed (including orphaned), interrupted, or killed. Click the card to view the full delegation trace in the right-hand panel. +Each A2A delegation appears in the conversation stream as one line: a bot glyph, the label "Dispatched [remote agent name]", and the task intent, with the run status and usage metrics such as tool call count, tokens, and elapsed time on the right. The run status is one of: initializing, in progress, awaiting input, awaiting authorization, completed, failed (including orphaned), interrupted, or killed. Click the line to view the full delegation trace in the right-hand panel; the `A2A` badge sits on that panel's header, not on the line. **The instructions decide whether AI SRE picks this agent.** Before delegating, AI SRE sees only one `name: summary` line per agent and uses it to decide. The summary comes from the `summary:` line at the top of the instructions. The body is delivered in full only on the first delegation, so it can be long and detailed. See [Writing Instructions](#writing-instructions). @@ -293,7 +293,7 @@ The platform ships several **bootstrap Subagents** that work out of the box: | `general` | General-purpose worker with full tool access. Use it to offload work whose intermediate steps would otherwise pollute the parent's context (long reports, multi-file edits, end-to-end builds, repeated probing). Dispatch several in parallel for independent units of work | | `explore` | Read-only investigator restricted to `grep` / `glob` / `read`; it cannot write or execute. Returns a compact summary rather than raw search output — ideal for locating evidence inside a codebase or knowledge dump | -**In the conversation**: each dispatch also appears as a **task card** with the same statuses as an A2A delegation. Its badge reads `Agent` instead of `A2A`. The card also shows the **execution environment** of the dispatch (the cloud environment or the BYOC Runner's name) — see "Dispatch target environment" below. +**In the conversation**: each dispatch also appears as one line, with the same statuses as an A2A delegation — a bot glyph, the label "Dispatched [subagent name]" (written `subagent` when the name is a type synonym such as `agent` / `general`), and the task intent, with right-aligned mono meta naming the dispatch's **execution environment** (the cloud environment or the BYOC Runner's name) plus that run's usage and status. Click the line to view the full trace in the right-hand panel; the `Agent` badge (`A2A` for an A2A delegation) sits on that panel's header. See "Dispatch target environment" below. **Runtime limits**: @@ -304,7 +304,7 @@ The platform ships several **bootstrap Subagents** that work out of the box: - **Omitted (the default)**: the subagent runs in the **same** environment as the current session and **shares its filesystem** — it can read your workspace's files directly. Naming the environment the session is *already* in (say, passing `cloud` from a cloud session) has the same result: an inheritance, not a second sandbox. - **`cloud`**: runs in a **fresh cloud environment** — an ephemeral container with its own filesystem and the account's default egress policy. -- **A BYOC Runner's environment_id**: runs on **that Runner**. The selectable targets are **account-scope Runners** plus the Runners of the **team the session is bound to**, and online ones only. Naming an unusable Runner (offline, nonexistent, or belonging to another team) makes the dispatch fail with the reason. It is never re-routed elsewhere. +- **A BYOC Runner's environment_id**: runs on **that Runner**. The candidates are **account-scope Runners** plus the Runners of the **team the session is bound to**. This list does not distinguish whether a Runner is online right now: every Runner that has **connected at least once** is listed (including one that is offline right now), and only a Runner that has **never connected** (`pending`) is left out — whether it is actually reachable is checked at dispatch time. Naming an unusable Runner (offline, nonexistent, or belonging to another team) makes the dispatch fail with the reason. It is never re-routed elsewhere. - **Subagents only**: passing `environment` for an A2A Agent is rejected — a remote agent executes in its own environment and has no placement to choose. To move work to another environment, dispatch a Subagent. **A cross-environment dispatch cannot read the parent's files**: a child session shares the parent's sandbox / workspace only when its execution environment is **exactly the same**. Dispatched to another environment, it gets **its own** sandbox or Runner scratch directory and **cannot see your (the parent's) files**. So put everything the subagent needs **in the prompt**: file contents, paths, parameters, and constraints. Don't write "read file x in the workspace." Results come back as **text** or through an external system such as git or a ticket. See [Environments (BYOC)](/en/ai-sre/environments) for how the environments themselves differ and how to pick one. @@ -313,7 +313,7 @@ The platform ships several **bootstrap Subagents** that work out of the box: - Observe A2A delegation task cards and their sub-session panels within a session. + Observe A2A delegations and their sub-session panels within a session. Connect external tools to agents to expand their capability boundary during tasks. diff --git a/en/ai-sre/automations.mdx b/en/ai-sre/automations.mdx index 022c01c55..908015f8e 100644 --- a/en/ai-sre/automations.mdx +++ b/en/ai-sre/automations.mdx @@ -40,6 +40,8 @@ The page header offers two ways to create a rule. **Create via chat** opens a se Either entry point leads to the same configuration form. +A preset template can also be **opened from another page by link**: a link of the form `/ai-sre/automations/new?template=` opens the create form with that template applied; if the link also carries `oncall_incident_channel_ids=,`, the **On-call incident trigger**'s channels are preselected and the form says the channels already follow the application's alert settings — review it and click **Create**. Such links are shareable and survive a reload; when the template key does not exist or the template fails to load, the form reports an error and opens blank. + ## Configuration fields The configuration form has the following fields: diff --git a/en/ai-sre/environments.mdx b/en/ai-sre/environments.mdx index 361ceceb5..817a38cc3 100644 --- a/en/ai-sre/environments.mdx +++ b/en/ai-sre/environments.mdx @@ -73,6 +73,7 @@ Environment variables are visible in plaintext to everyone who uses this cloud e |---|---| | `FLASHDUTY_APP_KEY` / `FLASHDUTY_BASE_URL` | The Flashduty API credential and endpoint, used by the built-in `flashduty` skill and by the runtime. | | `FLASHDUTY_DOCS_URL` | The static address of the official docs bundle; the built-in `flashduty-docs` skill downloads its copy of the docs from here. | +| `FLASHDUTY_CONSOLE_URL` | The console address. The agent expands it into the clickable absolute links it cites Flashduty resources with (incidents, alerts, channels, schedules, and so on). When no console address is configured the variable is not injected, and the agent cites resources by id in prose instead. It is non-sensitive — unlike `FLASHDUTY_APP_KEY`, the agent can read it. | | `GH_TOKEN`, the `GH_TOKEN_` prefix, `GH_PROMPT_DISABLED`, the `GIT_CONFIG_` prefix | The GitHub-side token and git configuration the platform injects (an account can have more than one GitHub App installation, so names such as `GH_TOKEN_1` and `GH_TOKEN_2` are reserved too). | | `PATH` / `HOME` | The runtime environment's base variables. | | `GITLAB_TOKEN`, `GITLAB_ACCESS_TOKEN`, `OAUTH_TOKEN`, `GITLAB_HOST`, `GL_HOST`, `GITLAB_URI`, `GITLAB_API_HOST`, `GITLAB_SSH_HOST`, `GITLAB_SUBFOLDER`, `CA_CERT`, `SKIP_TLS_VERIFY`, the `GLAB_` prefix | GitLab / `glab` authentication, host and TLS configuration, so sessions cannot bypass the bot identity the platform injects. | diff --git a/en/ai-sre/im.mdx b/en/ai-sre/im.mdx index 692e7666d..390c3a5d5 100644 --- a/en/ai-sre/im.mdx +++ b/en/ai-sre/im.mdx @@ -60,7 +60,7 @@ In a connected IM group with **Allow AI SRE conversations in IM** on, **@mention The platform distinguishes between **group @mentions** and **direct messages**. Once mentioned, AI SRE deduplicates the event, puts a "processing" receipt on that message (see [Processing Receipt](#processing-receipt)), and determines whether the message contains an imperative instruction. - AI SRE locates a session using "account + platform + chat" as the key: multiple @mentions within the same IM chat are routed to the **same agent session**, preserving context. For a new chat, the platform supplies the opening message of that IM thread and any associated incident as initial context. + AI SRE locates a session using "account + platform + chat" as the key: multiple @mentions within the same IM chat are routed to the **same agent session**, preserving context. For a new chat, the platform supplies the opening message of that IM thread and any associated incident as initial context. In a Feishu/Lark group with thread replies enabled, a new Thread session opened by a **top-level @mention** is also seeded with the group's messages from the **last 10 minutes** (up to that @mention) — that is how the error text or screenshot you posted just before the @mention gets into context. A Thread reply reads only its own Thread and never falls back to the group timeline. AI SRE reads the thread / chat history to build context, investigates autonomously, and posts its findings **in-thread**. Other people @mentioned in the original message are carried over into the reply, making it easy for multiple parties to collaborate in the group. @@ -71,6 +71,23 @@ In a connected IM group with **Allow AI SRE conversations in IM** on, **@mention The **reply mode** is configurable (off / first / all), controlling whether AI SRE @mentions the person who asked, and whether it replies **in-thread** or in the main channel. In a busy large group, in-thread replies keep the investigation discussion focused without flooding the channel. +### Attachments and images + +AI SRE downloads the images, documents, and audio it sees in the chat and hands them to the agent as files — not only the attachments on **the message that @mentions the bot**, but also those on **earlier messages in the same thread / session**. This is built for the incident scene: when you post a screenshot of the error in the group and then add "@bot what is this about," the model receives that screenshot instead of unexplained text. + +Each summon has a per-kind attachment budget. **The current message's attachments take it first, and history fills the remainder starting from the newest message**: + +| Kind | Per-summon limit | +| --- | --- | +| Images | 5 | +| Documents | 3 | +| Audio | 3 | + +- **A history message is attached whole or not at all**: if a history message's attachments do not fit the remaining budget, none of them are attached rather than some of them, so the files the model sees always match the message text. +- **Over-limit attachments are rejected**: a single attachment over 20 MiB, or a direct URL that is not HTTPS, is rejected and never handed to the agent. +- **History attachments have a time budget**: one that has not finished downloading in about 5 seconds is shown to the model as "not attached" instead of being promised as a file — an old screenshot never stalls the investigation. +- **Only your current message can stop the investigation**: if every attachment on it fails, AI SRE does not invoke the agent and instead replies "I could not process any of the attachments. Please try again, or send a smaller file." A failed history attachment never stops an investigation. + ### Processing receipt Once the bot has your message, it first puts an emoji reaction on **the message you sent**, as an immediate "received, working on it" signal. The emoji is picked **at random** from that platform's own pool rather than being fixed. The pool keeps only glyphs that read as "received, working on it." The pool leaves out congratulatory, thumbs-up, heart, and smiley reactions. On a message that just arrived, they read as a verdict or as sarcasm: @@ -79,7 +96,7 @@ Once the bot has your message, it first puts an emoji reaction on **the message | --- | --- | | Slack | eyes, thinking_face, hourglass_flowing_sand, mag, zap | | Lark / Feishu | Typing, THINKING, Get, OnIt | -| DingTalk | Platform built-in emotions: 思考, 收到, Get | +| DingTalk | Platform built-in emotions: 思考, 收到 | On Slack this sits alongside a native "is working on it" status, which the bot also shows. diff --git a/en/ai-sre/mcp.mdx b/en/ai-sre/mcp.mdx index 69f7e535d..6ed08b764 100644 --- a/en/ai-sre/mcp.mdx +++ b/en/ai-sre/mcp.mdx @@ -76,10 +76,13 @@ Row names share a namespace with template names: if a system already has a templ ## Adding an MCP server -Go to **Customize → Plugins → MCP**. The list page has two entries in the top-right corner: +Go to **Customize → Plugins → MCP**. The list page has three entries in the top-right corner: -- **Add MCP**: opens a form for defining an MCP server by hand (its fields are listed under "Basic Fields" below). +- **Add from catalog**: jumps to **Customize → Plugins → Overview** (the plugin catalog — see "Installing MCP servers from the marketplace" above), where you pick and install a built-in MCP template; it then shows up in this list. Like the other two buttons, it requires MCP create permission. - **Add in chat**: opens a session with a prefilled prompt. The agent asks whether you want to connect your own service or install an existing one, checks the plugin catalog first, and searches the web for candidates if nothing matches. The button appears only when the target scope is unambiguous (you have account-level permission, or exactly one of your teams is selected). +- **Add MCP**: opens a form for defining an MCP server by hand (its fields are listed under "Basic Fields" below). + +When the list is empty (no servers configured and no active search), the page shows how many built-in MCP templates the plugin catalog holds — "The plugin catalog has N built-in MCP servers. Install one to use it in sessions." — and offers a **Browse built-in MCP servers** button that jumps there (that button appears only with create permission). The plain "No MCP servers configured. Click the button above to add one." message appears only when the catalog itself is empty or a search is active. ### Basic fields @@ -207,7 +210,7 @@ An MCP server may be bound to execution environments **other than the current se - The agent sees the connector's name, purpose and available environments, and asking for it by name gets an explanation rather than "not found". - The agent dispatches a subagent into the target environment to call it (see [Agents](/en/ai-sre/agents)) and brings the result back to the conversation. -- Only **online** account-level Runners, Runners of the team bound to the session, and the bound cloud environment are valid targets. For others the agent explains it cannot use them right now. +- The targets are **account-level Runners**, the Runners of the team bound to the session, and the bound cloud environment. This list does not distinguish whether a Runner is online right now: a Runner that has **connected at least once** (including one that is offline right now) is marked available, and only a Runner that has **never connected** (`pending`) is marked unavailable, with the agent explaining that it cannot be used yet. An offline Runner therefore stays a candidate and only fails at dispatch time with the environment-unavailable reason. - Only the main session can dispatch this way; subagents cannot dispatch further. Conversely, to make a connector directly usable **here**, add the current environment to that server's Execution Environment list (provided the server is reachable from this session). See [Environments (BYOC)](/en/ai-sre/environments) for how the environments themselves differ. diff --git a/en/ai-sre/sessions.mdx b/en/ai-sre/sessions.mdx index 595281687..1e3c1b53b 100644 --- a/en/ai-sre/sessions.mdx +++ b/en/ai-sre/sessions.mdx @@ -171,7 +171,7 @@ Only the console shows the connection card. In IM and API sessions the agent pos ### Subagents -When the agent delegates work, a subagent line appears in the conversation. It shows the type (Agent / A2A), name, execution environment, status, and duration. After the run, it also shows tool calls, token usage, and any failure reason. Click it to open the subagent session side by side; it can be expanded to full screen. +When the agent delegates work, a subagent line appears in the conversation. It shows the name, execution environment, status, and duration; the line itself carries no type badge — the type (Agent / A2A) is labelled on the subagent panel's header. After the run, it also shows tool calls, token usage, and any failure reason. Click it to open the subagent session side by side; it can be expanded to full screen. A subagent may also need you: @@ -180,6 +180,8 @@ A subagent may also need you: Stop subagents from the task panel. A subagent whose executor was lost shows as **Failed**; one terminated by the platform shows as **Killed**. +A subagent can also **report progress to the parent agent** while it runs (a cross-agent `agent_message`). Such a report appears in the main conversation as a **Subagent report** line: collapsed it shows only a bot glyph and that label, and clicking it expands the full text — the expanded block leads with the reporting subagent's name (type names such as `agent` and `general` are dropped) and renders the body as an Output block. While the subagent is still running, the same report first appears as a **Subagent report** line under the subagent reference line for that dispatch; once the durable row lands, that live echo disappears, so the same report never shows twice. After a page reload only the durable rows remain — live echoes are not replayed. + ### Task panel and background tasks Besides subagents, the agent can run long commands in the background (builds, bulk data pulls) or start monitors that watch a condition until it is met or a deadline passes. diff --git a/en/ai-sre/skills.mdx b/en/ai-sre/skills.mdx index f1dde0f4b..732199372 100644 --- a/en/ai-sre/skills.mdx +++ b/en/ai-sre/skills.mdx @@ -134,7 +134,10 @@ Updating a modified skill **overwrites your local changes with the latest Market ## Custom Skills -In addition to installing from the Marketplace, you can upload your own skill packages. On the skill list page, click **Upload Skill** and fill in the form: +In addition to installing from the Marketplace, you can upload your own skill packages. The skill list page's toolbar offers two entries: + +- **Add from catalog**: jumps to the **Skill** category of **Customize → Plugins → Overview** — the plugin catalog described under "Install from marketplace" above (it shares its page with the MCP templates; see [MCP](/en/ai-sre/mcp)) — where you pick and install a built-in skill template, and it then shows up in this list. Like **Upload Skill**, it requires upload permission. +- **Upload Skill**: opens the upload form, where you fill in: | Field | Type | Required | Description | | --- | --- | --- | --- | @@ -143,6 +146,8 @@ In addition to installing from the Marketplace, you can upload your own skill pa At upload time, the system validates the package. The archive must be a valid zip with `SKILL.md` in the root directory and parseable frontmatter. `name` must follow the naming rule: start with a letter, use only letters/digits/`-`/`_`, and be 1–64 characters. All declared tools must be valid, meaning the built-in tools and MCP servers exist. **Skill names must be unique within a team** — a duplicate name within the same team is rejected with a prompt to choose a different name. Different teams may each own a skill with the same name. +When the list is empty (no skills yet and no active search), the page shows how many built-in skill templates the plugin catalog holds — "The plugin catalog has N built-in skills. Install one to use it in sessions." — and offers a **Browse built-in skills** button that jumps there (that button appears only with upload permission). The plain "No skills yet. Click Upload skill to add one." message appears only when the catalog itself is empty or a search is active. + The system reads all metadata other than the skill name from the `SKILL.md` frontmatter, including description, version, tags, author, and tools. You don't enter it in the form. diff --git a/en/changelog/changelog.mdx b/en/changelog/changelog.mdx index 0000b1ec0..b7a88161a 100644 --- a/en/changelog/changelog.mdx +++ b/en/changelog/changelog.mdx @@ -4,6 +4,28 @@ description: "This page documents important updates and feature releases for Fla keywords: ["Changelog", "Product Release", "Feature Updates", "Flashduty", "Version History"] --- + + +### RUM issues: one-click auto-analysis + +The Issue detail page gains an **Auto-analyze** button in its top-right corner, shown when AI SRE is enabled for the account and you can create automation rules: it opens the AI SRE automation create form prefilled with the preset template "RUM Issue Incident Analysis" (`rum_issue_incident_analysis`), with the channels already picked from that application's alert settings — confirm and click **Create**, and the automation analyzes the incidents the application's issue alerts raise from then on. + +The automation is triggered by incidents, so the application has to be able to raise them first. When you click the button, RUM reads the application's alert settings: it jumps straight to the create form only when alerting is on, delivery is set to a **Flashduty channel**, and at least one channel is selected; otherwise it tells you to finish the alert setups first and goes to the application's **Alert Settings** tab. See [Issue overview and details](/en/rum/error-tracking/error-viewing#header-actions). + +### AI SRE reads IM attachments + +AI SRE downloads the images, documents, and audio in the chat and hands them to the agent as files — not only those on **the message that @mentions the bot**, but also those on **earlier messages in the same thread / war room**: post a screenshot of the error and then add "@bot what is this about," and the model receives that screenshot instead of unexplained text. + +Each turn's budget is counted per kind, with the current message's attachments taking it first and history filling the remainder from the newest message back: **5 images, 3 documents, 3 audio**. A single attachment over 20 MiB, or a direct URL that is not HTTPS, is rejected; history attachments also have a download budget of about 5 seconds, and one that has not finished is treated as not attached, so an old screenshot never stalls the investigation. See [IM Integration · Attachments and images](/en/ai-sre/im#attachments-and-images). + +### CLI: global `--fields` projection + +The CLI gains a global `--fields` flag: in `json` / `toon` output it keeps only the named top-level fields (comma-separated), applied to each row of a list or to a single record, and **every command accepts it, the OpenAPI-generated ones included**; where a command declares its own `--fields` (`incident list`, `alert-event list` and the other commands with a default compact projection), that one wins. + +Table output ignores the flag and a stderr note says so; a name that matches no key anywhere in the response is reported on stderr together with the keys the output does carry; output that is neither an object nor a list of objects fails the command. See [CLI](/en/developer/cli). + + + ### Dashboards: built-in time variables and display time zone diff --git a/en/developer/cli.mdx b/en/developer/cli.mdx index 5e08a17a5..7d0d36fb1 100644 --- a/en/developer/cli.mdx +++ b/en/developer/cli.mdx @@ -94,14 +94,16 @@ flashduty config set base_url URL # Override the API endpoint ## Global flags -All subcommands accept these flags: +These flags are registered on the root command; every subcommand accepts them except `--version`: | Flag | Description | |------|-------------| | `--output-format` | Output format: `table` (default), `json`, or `toon` (compact, token-efficient) | | `--json` | Alias for `--output-format json`; emit JSON for parsing with `jq` or similar tools | | `--no-trunc` | Disable column truncation in table output | +| `--fields` | In `json`/`toon` output, keep only the named top-level fields (comma-separated): each row of a list, or the keys of a single record. Table output ignores it and a stderr note says so; a name that matches no key is reported on stderr together with the keys the output does carry, and output that is neither an object nor a list of objects fails the command. See "Field projections for structured output" below | | `--base-url` | Override the API endpoint (for private deployments) | +| `--version` | Print the version — the same single line as `flashduty version`. That meaning exists only on the root command; a command that defines its own `--version` (for example the optimistic-locking version on mutating verbs) follows its own description | ## Command catalog @@ -116,7 +118,7 @@ flashduty incident ack [...] # Acknowledge incidents flashduty incident close [...] # Close (resolve) incidents flashduty incident merge --source # Merge incidents into a target incident flashduty incident timeline # View an incident timeline -flashduty incident alerts # List alerts associated with an incident +flashduty incident alerts # List alerts associated with an incident (--limit default 10, --page) flashduty incident similar # Find similar historical incidents flashduty incident feed [flags] # View an incident's paginated feed (timeline entries) ``` @@ -141,7 +143,7 @@ Common filter flags for `incident list`: | `--is-rare` | Only outlier incidents | `false` | | `--is-snoozed` | Only snoozed incidents | `false` | | `--ever-muted` | Only incidents that were ever silenced | `false` | -| `--since` | Start time (duration, date, datetime, or unix timestamp); the `--since` to `--until` window must be under 31 days | `24h` | +| `--since` | Start time (duration, date, datetime, or unix timestamp); the `--since` to `--until` window must be under 31 days | `24h` (`30d` when `--progress` lists only `Triggered,Processing`) | | `--until` | End time | `now` | | `--asc` | Sort ascending (oldest first) | `false` (newest first) | | `--limit` | Max results (max 100) | `20` | @@ -151,6 +153,8 @@ Time format examples: `5m`, `1h`, `24h`, `168h`, `2026-04-01`, `2026-04-01 10:00 `incident feed ` reads an incident's feed (timeline entries) page by page. `--asc` lists the oldest entries first (the default is newest first). `--types` filters by comma-separated entry types, for example `i_comm,i_assign`; each entry's `type` field gives its actual type. `--limit` (max 100) and `--page` paginate the result. +`incident alerts ` lists the alerts attached to that incident; `--limit` defaults to `10` and `--page` starts at `1`. + #### Create, update, and merge `incident create` requires `--title` (3–200 characters) and `--severity`, and prompts for missing values in a terminal. There are three ways to assign people, which can be combined: `--assign` (member IDs), `--assign-emails` (member emails, comma-separated; emails that match no member are ignored), and `--escalate-rule-id` with `--escalate-layer` (assign the people at that zero-based layer of the escalation rule; `--escalate-layer` requires `--escalate-rule-id`). @@ -685,8 +689,9 @@ This command only reads the value set of one label; to fetch time series from an ### alert — Alert and alert-event queries ```bash -flashduty alert list [flags] # List alerts (default: last 24h) +flashduty alert list [flags] # List alerts (default: last 24h; 30d with --active) flashduty alert get # Get full detail of one alert; detail is an alias +flashduty alert events # List the raw events that make up one alert (--limit, --page) flashduty alert-event list [flags] # List alert events (default: last 1h) ``` @@ -699,6 +704,10 @@ Common filter flags for both `list` commands: `--severity` (`Critical,Warning,In - `--asc`: sort oldest first by start time (the default is newest first). - `--by-updated-at`: apply `--since`/`--until` to the last-updated time instead of the start time. `alert-event list` also supports `--asc` (oldest first; newest first by default), but has no `--by-updated-at` counterpart. +`alert list` also filters by state through `--active` (active alerts only) and `--recovered` (recovered alerts only). They are mutually exclusive — passing both is an error — and passing neither applies no state filter. Active alerts can be older than a day, so with `--active` and no `--since` the window widens to 30 days by default (the window actually sent is reported by the stderr note). + +`alert events ` lists the raw events that make up one alert: leave `--limit` unset to take the server default of 20 (max 100), and `--page` starts at 1. It reads events for a single alert; for a time-window query across alerts use `alert-event list`. + ### automation — AI SRE automation rules The `automation` command group manages AI SRE automation rules — create, query, update, delete, run history, and triggering. See [Automations](/en/ai-sre/automations) for the console workflow. @@ -908,6 +917,14 @@ Table view with no column truncation — useful for copy-paste or wide terminals +### Time-window note + +Commands that query a time range print the window they actually sent to stderr in the local timezone, for example `note: window 2026-10-08T14:00:00+08:00..2026-10-09T14:00:00+08:00 (1d, ended now)`. The parenthesised part carries the span and where the end sits relative to now (`ended 3m ago` / `ends in 2h`); when the window comes from a default rather than from `--since`/`--until` you typed, the note names that default (an `--progress` filter of open states only, or `--active`). + +This covers `incident list`, `alert list`, `alert-event list`, `change list`, `audit search`, `insight`, `oncall`, `monit-query` (when its tool params carry an execution window), and every generated command whose `--start-time`/`--end-time` resolve. A command that leaves one side to `--data` or to the server default prints no note, because the window was never fully resolved by the CLI. A query with a single evaluation timestamp reads `note: instant