> ## Documentation Index
> Fetch the complete documentation index at: https://test-8ad8522e-feat-ai-sre.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Command-line tool

> Manage incidents, on-call schedules, status pages, and notification templates from your terminal with Flashduty CLI

## Overview

Flashduty CLI (`flashduty`) is a command-line tool for managing the incident lifecycle, querying on-call schedules, publishing status page updates, and debugging notification templates from your terminal. It fits naturally into operations scripts, local troubleshooting, and AI coding-agent workflows.

The tool is open source at [flashcatcloud/flashduty-cli](https://github.com/flashcatcloud/flashduty-cli) and supports macOS, Linux, and Windows.

## Installation

<Tabs>
  <Tab title="macOS / Linux">
    ```bash theme={null}
    curl -sSL https://static.flashcat.cloud/flashduty-cli/install.sh | sh
    ```

    Installs to `/usr/local/bin` by default. Override with the `FLASHDUTY_INSTALL_DIR` environment variable.
  </Tab>

  <Tab title="Windows (PowerShell)">
    ```powershell theme={null}
    irm https://static.flashcat.cloud/flashduty-cli/install.ps1 | iex
    ```

    Installs to `~\.flashduty\bin` by default. Override with the `FLASHDUTY_INSTALL_DIR` environment variable.
  </Tab>

  <Tab title="Manual download">
    Read the latest version from the [CDN latest version pointer](https://static.flashcat.cloud/flashduty-cli/releases/latest), then download the matching asset from `https://static.flashcat.cloud/flashduty-cli/releases/download/<version>/<asset>`, extract it, and place it on your `PATH`.
  </Tab>
</Tabs>

### Installer options

| Variable                    | Description                                                                                         | Default                                                   |
| --------------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `FLASHDUTY_VERSION`         | Install a specific version, e.g. `v0.6.0`                                                           | latest                                                    |
| `FLASHDUTY_INSTALL_DIR`     | Custom install directory                                                                            | `/usr/local/bin` (shell), `~\.flashduty\bin` (PowerShell) |
| `MIRROR_URL`                | Override the release asset download mirror prefix used by the installer script; must use `https://` | `https://static.flashcat.cloud/flashduty-cli`             |
| `FLASHDUTY_UPDATE_BASE_URL` | Override the base URL used by `flashduty update` and the automatic update check                     | `https://static.flashcat.cloud/flashduty-cli`             |

## Authentication

### Log in

```bash theme={null}
flashduty login
```

When prompted, paste your APP Key. To obtain one, sign in to the [Flashduty console](https://console.flashcat.cloud) and copy your APP Key from **Profile > Personal Info**.

### Credential resolution order

The CLI resolves credentials in the following order (highest priority first):

1. `--app-key` command-line flag (hidden, for scripting)
2. `FLASHDUTY_APP_KEY` environment variable
3. Config file `~/.flashduty/config.yaml` (written by `flashduty login`)

### Config file

Stored at `~/.flashduty/config.yaml` with `0600` permissions:

```yaml theme={null}
app_key: your_app_key
base_url: https://api.flashcat.cloud
```

### Config commands

```bash theme={null}
flashduty config show              # Print current config (APP Key masked)
flashduty config set app_key KEY   # Set the APP Key
flashduty config set base_url URL  # Override the API endpoint
```

## Global flags

All subcommands accept these flags:

| 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                                          |
| `--base-url`      | Override the API endpoint (for private deployments)                                |

## Command catalog

### incident — Incident lifecycle

```bash theme={null}
flashduty incident list [flags]          # List incidents (default: last 24h)
flashduty incident get <id> [<id2>...]   # Show incident details (vertical view for a single ID)
flashduty incident create [flags]        # Create an incident (interactive if flags are missing)
flashduty incident update <id> [flags]   # Update incident fields
flashduty incident ack <id> [<id2>...]   # Acknowledge incidents
flashduty incident close <id> [<id2>...] # Close (resolve) incidents
flashduty incident timeline <id>         # View an incident timeline
flashduty incident alerts <id>           # List alerts associated with an incident
flashduty incident similar <id>          # Find similar historical incidents
```

Common filter flags for `incident list`:

| Flag         | Description                                                                                                                                   | Default |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `--progress` | Progress filter: `Triggered`, `Processing`, `Closed`                                                                                          | all     |
| `--severity` | Severity filter: `Critical`, `Warning`, `Info`                                                                                                | all     |
| `--channel`  | Filter by channel ID (comma-separated for multiple). The older `--channel-id` flag is deprecated; it still works but accepts only a single ID | -       |
| `--query`    | Free-text search across title, labels, and content (also resolves a 24-char incident ID or 6-char incident num to a direct lookup)            | -       |
| `--since`    | Start time (duration, date, datetime, or unix timestamp)                                                                                      | `24h`   |
| `--until`    | End time                                                                                                                                      | `now`   |
| `--limit`    | Max results                                                                                                                                   | `20`    |
| `--page`     | Page number                                                                                                                                   | `1`     |

Time format examples: `5m`, `1h`, `24h`, `168h`, `2026-04-01`, `2026-04-01 10:00:00`, `1712000000`.

#### Work items and follow-ups (work-item-\*)

`incident work-item-*` manages work items anchored to an incident or a post-mortem. `--item-type` distinguishes two kinds: `action` (an action item anchored to an active incident) and `follow_up` (a post-mortem follow-up, which must be bound to a post-mortem ID).

```bash theme={null}
flashduty incident work-item-create <incident-id> [flags]        # Create an action item / follow-up
flashduty incident work-item-list [flags]                        # List work items
flashduty incident work-item-update <work-item-id> [flags]       # Update title/description/status/priority
flashduty incident work-item-complete <work-item-id> [flags]     # Mark complete
flashduty incident work-item-convert <work-item-id> [flags]      # Convert an action item into a follow-up
flashduty incident work-item-delete <work-item-id> [flags]       # Delete a work item
flashduty incident work-item-assignees-reset <work-item-id>      # Reset the assignee list
flashduty incident work-item-post-mortem-bind [flags]            # Bind converted follow-ups to a post-mortem
```

Key flags for `work-item-create`: `--item-type` (required, `action` or `follow_up`), `--title` (required, up to 512 characters), `--idempotency-key` (required idempotency key, up to 128 characters), `--post-mortem-id` (required for `follow_up`, forbidden for `action`), `--assignee-ids` (initial assignees). Mutating verbs (`update`/`complete`/`convert`/`delete`/`assignees-reset`) require `--version` (optimistic locking — it must match the stored version).

#### Post-mortem reports (post-mortem-\*)

Post-mortem verbs live under the `incident` command group (there is no standalone post-mortem group):

```bash theme={null}
flashduty incident post-mortem-init <incident-id> [<id2>...]        # Initialize a report from 1–10 incidents (--template-id required)
flashduty incident post-mortem-list [flags]                         # List reports (server defaults to published; pass --status drafting for drafts)
flashduty incident post-mortem-info <post-mortem-id>                # Get report detail
flashduty incident post-mortem-title-reset <post-mortem-id>         # Set the title
flashduty incident post-mortem-content-reset <post-mortem-id>       # Replace the Markdown body (--markdown-file)
flashduty incident post-mortem-basics-reset <post-mortem-id>        # Update start/close time, highest severity, responder metadata
flashduty incident post-mortem-follow-ups-reset <post-mortem-id>    # Set follow-ups (--follow-ups)
flashduty incident post-mortem-status-reset <post-mortem-id>        # Publish or revert to draft (--status drafting|published)
flashduty incident post-mortem-delete <post-mortem-id>              # Delete a report (irreversible)
```

Template verbs: `post-mortem-template-list`, `post-mortem-template-info <template-id>`, `post-mortem-template-upsert` (creates when `--template-id` is omitted; `--team-id` is required when creating), `post-mortem-template-delete <template-id>` (irreversible).

#### Comment types (comment-type-\*)

```bash theme={null}
flashduty incident comment-type-create [flags]                # Create (--name ≤40 chars, unique within the account; --color #RRGGBB)
flashduty incident comment-type-list                          # List all comment types
flashduty incident comment-type-update <comment-type-id>      # Update name/color
flashduty incident comment-type-delete <comment-type-id>      # Delete
flashduty incident comment-type-reorder <id> [<id2>...]       # Reorder — pass every comment type ID in the account, in the desired order
```

### change — Change records

```bash theme={null}
flashduty change list [flags]    # List change records (deployments, config changes)
```

Supports `--channel`, `--since`, `--until`, `--type`, `--limit`, `--page`.

### member — Member queries

```bash theme={null}
flashduty member list [flags]       # List members
flashduty member info-reset [flags] # Update a member's profile
flashduty member invite [flags]     # Invite new members (up to 20 per call)
```

`member list` supports `--query` (free-text search by name or email), `--role-id`, `--page`, `--limit`, `--orderby`, `--asc`.

`member info-reset` identifies the member by exactly one of `--member-id`, `--member-name`, `--email`, `--phone`, or `--ref-id`; the fields to change go into the required body via `--data '{"updates":{...}}'`. With `--from api`, an updated email or phone is marked verified directly when the account has member invites disabled.

`member invite` takes the member list via `--data '{"members":[...]}'`. When the account has member invites disabled and `--from api` is set, members are created directly in the enabled state with email/phone marked verified — no invitation is sent.

### team — Team management

```bash theme={null}
flashduty team list [flags]                          # List teams with members
flashduty team info --team-id <id>                   # Get a single team's details
flashduty team upsert --team-name <name> [flags]     # Create or update a team (update when --team-id is set)
flashduty team delete --team-id <id>                 # Delete a team (irreversible)
```

`team list` supports `--query` (team name substring match), `--page`, `--limit`, `--orderby` (`created_at`/`updated_at`/`team_name`), `--asc`, `--person-id` (filter to teams the given member belongs to).

`team info` accepts `--ref-id`, `--team-name`, or `--team-id` to identify the team (exactly one required). When several are provided, the precedence is `--ref-id` > `--team-name` > `--team-id`.

`team upsert` creates or updates a team:

* `--team-name` (required, 1–39 characters)
* `--team-id` (set to update an existing team; omit to create)
* `--description` (up to 500 characters)
* `--person-ids` (member ID list; **replaces the entire member list — run `team info` first to see current members before updating**)
* `--emails` (add existing members by email; addresses that match no existing member are silently ignored — no invitation is sent)
* `--phones` (add existing members by phone number; non-matching numbers are silently ignored, and non-E.164 numbers are parsed with `--country-code`)
* `--country-code` (default country code applied to `--phones` entries that are not in E.164 format)
* `--ref-id` (external reference ID for HR system integration)

<Note>
  `team upsert`'s `--emails` / `--phones` only match and attach **existing** members — no invitation is ever sent. To invite new members into the organization, use `flashduty member invite`.
</Note>

`team delete` accepts `--team-id`, `--team-name`, or `--ref-id` to identify the team. **This action is permanent and cannot be undone.**

### channel — Channel queries

```bash theme={null}
flashduty channel list [flags]   # List channels
```

Supports `--name`.

### channel escalate-rule-list — Escalation rule queries

Escalation rule management has moved into the `channel` command group. Pass the channel ID as a positional argument:

```bash theme={null}
flashduty channel escalate-rule-list <channel-id>   # List all escalation rules for a channel
```

Other escalation rule management commands under the `channel` group: `escalate-rule-create`, `escalate-rule-update`, `escalate-rule-delete` (all require `--channel-id`).

### channel silence/inhibit/drop rules — Noise rule management

Channel-level noise rules are managed through the `channel` command group; see [Noise Reduction](/en/on-call/channel/noise-reduction) for rule semantics and configuration. The three families — `silence-rule-*` (silence), `inhibit-rule-*` (inhibit), `unsubscribe-rule-*` (drop) — share the same shape, each with `list`/`create`/`update`/`enable`/`disable`/`delete` verbs:

```bash theme={null}
flashduty channel silence-rule-list <channel-id>                    # List silence rules (channel-id is positional)
flashduty channel silence-rule-create <channel-id> [flags]          # Create (--rule-name required, 1–39 chars; time window and filters go via --data)
flashduty channel silence-rule-update --channel-id <id> --rule-id <id>   # Update
flashduty channel silence-rule-enable --channel-id <id> --rule-id <id>   # Enable
flashduty channel silence-rule-disable --channel-id <id> --rule-id <id>  # Disable
flashduty channel silence-rule-delete --channel-id <id> --rule-id <id>   # Delete
```

`inhibit-rule-*` and `unsubscribe-rule-*` work the same way; `inhibit-rule-create` requires `--equals` (the label keys pairing source and target alerts). Silence and inhibit rules accept `--is-directly-discard` to drop suppressed alerts instead of merging them. Note that `channel-id` is positional on `*-rule-create` and `*-rule-list` but a flag (`--channel-id`) on `*-rule-update`/`delete`/`enable`/`disable`; `--rule-id` is a MongoDB ObjectID string.

### field — Custom field queries

```bash theme={null}
flashduty field list [flags]     # List custom field definitions
```

Supports `--name`.

### status-page — Status page management

```bash theme={null}
flashduty status-page list                                             # List status pages
flashduty status-page change-active-list <page-id>                    # List active status page events
flashduty status-page change-create <page-id> [flags]                 # Create a status page event
flashduty status-page change-timeline-create [flags]                  # Append a timeline update
flashduty status-page draft-create [flags]                            # Create a status page event draft (reviewed by a human, then published from the console)
```

#### Event drafts (draft-create)

`draft-create` stores a status page event draft (incident or maintenance) so a human can review and publish it from the console — the draft itself is never published publicly:

```bash theme={null}
flashduty status-page draft-create \
  --source 'ai_sre:sess_xxx' \
  --data '{"draft":{"page_id":5750613685214,"type":"incident","name":"Web Console Degraded Performance","message":"We are investigating degraded performance affecting the web console.","status":"investigating","affected_components":[{"component_id":"01KC3GAZ6ZJE40H55GM31RPWZE","status":"degraded"}]}}'
```

* `--source`: opaque marker of the drafting origin (e.g. `ai_sre:sess_xxx`), up to 64 characters.
* The `draft` object in `--data` (required, stored verbatim, up to 64 KB serialized). Required fields: `page_id`, `type` (`incident` or `maintenance`), `name`, `message`; optional `change_id` (append an update to an existing event when > 0), `status`, `affected_components`, and `start_time`/`end_time` (Unix epoch seconds, new maintenance only).
* The response returns `draft_id` (matching `draft_[A-Za-z0-9]{22}`) and `created_at`; the console review link carries `draft_id`.

#### Migrate from Atlassian Statuspage

Migration jobs run asynchronously. Poll progress with `migration-status` after kicking off a job:

```bash theme={null}
# 1. Migrate structure and history
flashduty status-page migrate-structure <source-page-id> \
  --from atlassian \
  --api-key $ATLASSIAN_STATUSPAGE_API_KEY

# 2. Check job status
flashduty status-page migration-status <job-id>

# 3. Migrate email subscribers
flashduty status-page migrate-email-subscribers \
  --from atlassian \
  --source-page-id page_123 \
  --target-page-id <target_page_id> \
  --api-key $ATLASSIAN_STATUSPAGE_API_KEY

# 4. Cancel a running job
flashduty status-page migration-cancel <job-id>
```

Other available subcommands: `draft-create`, `change-delete`, `change-info`, `change-list`, `change-timeline-delete`, `change-timeline-update`, `change-update`, `component-upsert`, `component-delete`, `section-upsert`, `section-delete`, `info`, `subscriber-list`, `subscriber-import`, `subscriber-export`, `template-list`, `template-upsert`, `template-delete`.

### rum — RUM applications and session replay

Use these commands to manage RUM applications and export session replay data. The application commands cover detail, batch reads, listing, webhook testing, and create/update/delete operations.

```bash theme={null}
flashduty rum application-info <application-id>            # Get one application's detail
flashduty rum application-infos <id1> [<id2>...]          # Batch get multiple applications
flashduty rum application-list [flags]                    # List accessible applications
flashduty rum application-webhook-test <application-id>   # Send a sample alert to a webhook URL
flashduty rum application-create <team-id> [flags]        # Create an application
flashduty rum application-update <application-id> [flags] # Update an application
flashduty rum application-delete <application-id>         # Delete an application
```

Common flags for `application-list`:

| Flag           | Description                                          |
| -------------- | ---------------------------------------------------- |
| `--query`      | Search by application name                           |
| `--team-id`    | Restrict results to one team                         |
| `--is-my-team` | Return only applications owned by the caller's teams |
| `--orderby`    | Sort field: `created_at` or `updated_at`             |
| `--asc`        | Sort ascending                                       |

Core fields for `application-create` / `application-update`:

| Flag                 | Description                                                                                                                                             |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--application-name` | Application name; required on create, 1-40 characters                                                                                                   |
| `--type`             | Application type: `browser`, `ios`, `android`, `react-native`, `flutter`, `kotlin-multiplatform`, `roku`, `unity`, `miniprogram`, `harmony`, `electron` |
| `--team-id`          | Owning team ID (required on create)                                                                                                                     |
| `--is-private`       | Restrict access to team members only                                                                                                                    |
| `--no-geo`           | Disable geographic inference                                                                                                                            |
| `--no-ip`            | Disable IP collection                                                                                                                                   |
| `--data`             | Add `alerting` and `tracing` objects when you need notification or trace-link configuration                                                             |

<Note>
  `application-webhook-test` returns `ok`, `status_code`, and `message`, which makes it suitable for verifying that a RUM alert webhook really accepts a sample delivery from Flashduty.
</Note>

#### Session replay

```bash theme={null}
flashduty rum session-replay-metadata <session-id> # Get the application, device, session-boundary, and view metadata for a replayable session
flashduty rum session-replay-segments <session-id> # Read session replay segments
```

For `session-replay-metadata`, use `--ts` to supply the session-start Unix timestamp in milliseconds when you need to disambiguate a reused session ID from different time windows.

Common `session-replay-segments` flags:

| Flag                 | Description                                                                                                                                            |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--limit`            | Number of segments to return, from 1 to 99; default: 20.                                                                                               |
| `--search-after-ctx` | Pagination cursor from the previous page. In URL mode, read `search_after_ctx`; in streaming mode, read the `X-Search-After-Ctx` response header.      |
| `--ts`               | Without `--search-after-ctx`, begin at the most recent full-snapshot segment at or before this timestamp.                                              |
| `--url-mode`         | When `true`, return JSON containing presigned download URLs. By default it is `false` and streams segment bytes directly. URLs are valid for one hour. |
| `--view-id`          | Return segments for one view only; omit it to page through the whole session.                                                                          |

#### Error ingestion rules (error-ingestion-rules-\*)

Error ingestion rules filter or rewrite the error events an application reports:

```bash theme={null}
flashduty rum error-ingestion-rules-create <application-id> [flags]       # Create (--rule-name required, 1–128 chars; filters go via --data)
flashduty rum error-ingestion-rules-list <application-id>                 # List rules
flashduty rum error-ingestion-rules-update [flags]                        # Update (--application-id, --rule-id required)
flashduty rum error-ingestion-rules-enable [flags]                        # Enable
flashduty rum error-ingestion-rules-disable [flags]                       # Disable
flashduty rum error-ingestion-rules-delete [flags]                        # Delete
flashduty rum error-ingestion-rules-history-list <application-id>         # View change history (--orderby updated_at|version)
flashduty rum error-ingestion-rules-history-revert <application-id> --version <v>  # Revert to a history version
```

`--description` is capped at 512 characters. `create`/`list`/`history-list`/`history-revert` take `application-id` as a positional argument; `update`/`enable`/`disable`/`delete` target rules via the `--application-id` and `--rule-id` flags.

#### Preset severity rules (issue-preset-severity-rules-\*)

Preset severity rules assign a preset severity to errors matching a condition, used for issue grading:

```bash theme={null}
flashduty rum issue-preset-severity-rules-create <application-id> [flags]  # Create (--rule-name required; --severity Critical|Warning|Info required)
flashduty rum issue-preset-severity-rules-list <application-id>            # List rules
flashduty rum issue-preset-severity-rules-update [flags]                   # Update
flashduty rum issue-preset-severity-rules-enable [flags]                   # Enable
flashduty rum issue-preset-severity-rules-disable [flags]                  # Disable
flashduty rum issue-preset-severity-rules-delete [flags]                   # Delete
flashduty rum issue-preset-severity-rules-reorder [flags]                  # Reorder priority (--drag-rule-id, --target-rule-id)
flashduty rum issue-preset-severity-rules-history-list <application-id>    # Change history
flashduty rum issue-preset-severity-rules-history-revert <application-id> --version <v>  # Revert
```

#### Resource info (resource-info)

```bash theme={null}
flashduty rum resource-info [--no-cache]   # View the RUM plan version, quotas, and usage (--no-cache bypasses the short-lived cache)
```

### oncall — On-call licenses

```bash theme={null}
flashduty oncall license-list # List people with active On-call licenses in the current account
```

This read-only command returns each person's ID, name, and license type: `fixed` is explicitly assigned, while `temporary` is active for the current temporary-license window.

### template — Notification templates

```bash theme={null}
flashduty template get-preset --channel <channel>             # Get preset template code
flashduty template validate --channel <channel> --file <path> # Validate and preview a template
flashduty template variables [--category <category>]          # List available template variables
flashduty template functions [--type custom|sprig|all]        # List available template functions
```

Supported channels: `dingtalk`, `dingtalk_app`, `feishu`, `feishu_app`, `wecom`, `wecom_app`, `slack`, `slack_app`, `telegram`, `teams_app`, `email`, `sms`, `zoom`.

### session — AI SRE sessions

Inspect AI SRE (and other Flashduty agent) sessions: `session list` lists the sessions visible to the caller, and `session export` streams a single session's full event log for offline analysis.

```bash theme={null}
flashduty session list [flags]            # List agent sessions (sorted by updated_at desc, newest first)
flashduty session export <session_id>     # Stream a single session's full events as NDJSON
```

Common flags for `session list`:

| Flag              | Description                                                                                                                                                                               | Default  |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `--app`           | Which agent app's sessions to list                                                                                                                                                        | `ai-sre` |
| `--scope`         | Visibility: `all` (your own + your teams, default), `personal`, `team`                                                                                                                    | `all`    |
| `--status`        | Archive status: `active` (default), `archived`, `all`                                                                                                                                     | `active` |
| `--team-id`       | Keep only sessions for the given team ID                                                                                                                                                  | -        |
| `--since`         | Keep only sessions updated within the window (client-side filter), e.g. `30d`, `24h`, `2026-05-01`                                                                                        | -        |
| `--limit`         | Max sessions to fetch                                                                                                                                                                     | `200`    |
| `--page`          | Start page (1-based)                                                                                                                                                                      | `1`      |
| `--output-format` | Output format: `jsonl` (default, one session object per line, pipe straight to `jq`), `json` (full envelope; subject to the 16 KiB output bound — see "Output formats"), `toon` (compact) | `jsonl`  |

<Note>
  The server endpoint `/safari/session/list` caps each page at 100 rows; when `--limit` exceeds that, the CLI paginates automatically — no manual paging required. The API has no time-window filter, so `--since` is applied client-side against each session's `updated_at` after fetching.
</Note>

`session export` streams session events as newline-delimited JSON (NDJSON) to stdout: the first line is always a `session_meta` envelope, and each subsequent line is one event (`user_message`, `llm_call`, `tool_call`, `subagent_dispatch`, `final_answer`, `agent_text`, `error`). Exports can be large, so redirect to a file instead of printing to the terminal:

```bash theme={null}
flashduty session export <session_id> > session.ndjson
flashduty session export <session_id> --include-subagents > session.ndjson
```

| Flag                  | Description                                                                              |
| --------------------- | ---------------------------------------------------------------------------------------- |
| `--include-subagents` | After each `subagent_dispatch`, recursively inline that subagent's own full event stream |

### monit-query — Unified datasource tool invocation

`monit-query` executes **a single named tool** against a configured datasource — the unified entry for both query tools (`<type>.query`, covering `prometheus`, `mysql`, `postgres`, `oracle`, `clickhouse`, `elasticsearch`, `loki`, `victorialogs`, `sls`, `tencent_cls`) and diagnostic tools (e.g. `mysql.overview`, `redis_node.slowlog`), bypassing the alert-rule layer. The legacy `monit-query data` subcommand is retired. Get the datasource ID from the `id` field of `monit datasource-list`:

```bash theme={null}
flashduty monit datasource-list --type prometheus --json | jq '.[] | {id, name, type_ident, address}'
flashduty monit-query <datasource-id> --tool 'prometheus.query' \
  --params '{"expr":"sum(rate(http_requests_total[5m]))","execution":{"kind":"instant","to_ms":1789000000000}}'
flashduty monit-query <datasource-id> --tool 'redis_node.slowlog' --params '{}'
```

| Flag              | Description                                                                                                                               |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `<datasource-id>` | Datasource ID (positional, required, from `monit datasource-list`, min 1)                                                                 |
| `--tool`          | Tool name (required), prefixed by the datasource type, e.g. `prometheus.query`, `mysql.overview`, `redis_node.slowlog`; 1–128 chars       |
| `--params`        | Tool parameters JSON (may be omitted, meaning `{}`; pass `-` to read a larger payload from standard input; an explicit `null` is invalid) |

Query tools return a complete `explore_result.v1` structured result: `format` is always `explore_result.v1`, and `result.kind` is one of `samples` (instant samples with complete label sets), `frames` (typed table/time-series frames), or `logs` (raw logs with `applied_limit` and `has_more`). For the diagnostic tool response shape, see `monit datasource-tools-invoke` below.

### monit datasource-tools-invoke — Datasource diagnostics

`monit datasource-tools-invoke` executes **one deterministic read-only tool** against a configured datasource — the current path for structured datasource diagnostics (replacing `monit-query diagnose`). It is equivalent to the `monit-query` command above, which is the recommended path. Get the datasource ID from the `id` field of `monit datasource-list`:

```bash theme={null}
flashduty monit datasource-list --type redis_node --json | jq '.[] | {id, name, type_ident, address}'
flashduty monit datasource-tools-invoke <datasource-id> --tool 'redis_node.slowlog' \
  --data '{"params":{}}'
```

| Flag              | Description                                                                                                                                                                                                                                                   |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--datasource-id` | Datasource ID (required, from `monit datasource-list`, min 1)                                                                                                                                                                                                 |
| `--tool`          | Tool name (required), prefixed by the datasource type, e.g. `mysql.overview`, `postgres.activity`, `redis_node.slowlog`, `kafka.consumer_lag`, `elasticsearch.cat`, `prometheus.metric_trends`, `loki.log_patterns`, `victorialogs.log_patterns`; 1–128 chars |
| `--data`          | Tool parameters JSON (`{"params":{...}}`; may be omitted, meaning `{}`; an explicit `null` is invalid)                                                                                                                                                        |
| `--account-id`    | Optional consistency check; must equal the authenticated account                                                                                                                                                                                              |

Semantics and limits:

* **No tool catalog, no auto-replay, no fallback**: one call runs exactly one named tool; fill parameters according to the datasource tool's contract rather than guessing from the command list. Alongside diagnostic tools, the entry also supports `<type>.query` query tools (`prometheus`, `mysql`, `postgres`, `oracle`, `clickhouse`, `elasticsearch`, `loki`, `victorialogs`, `sls`, `tencent_cls`).
* Requires **all** currently online routable Edge sessions in the cluster to support the v0.71.0 base invoke protocol (individual tools may require a newer implementation); normal datasource queries retain their existing version compatibility.
* Request body limit 128 KiB; complete success response limit 10 MiB; tool timeout at most 25 seconds.
* The datasource must have `enabled=true`; `alerting_enabled=false` does not block diagnostics.
* Response: `data` (tool-specific JSON evidence, preserved without conversion, never null, no legacy diagnose envelope), `tool`, `datasource_id`, optional `summary`, and a `truncated` object (with `reason`; its presence indicates truncation).

Errors are returned as-is; common codes: `edge_upgrade_required` (Edge too old), `mixed_edge_versions` (mixed Edge versions in the cluster), `no_active_edge` (no routable online Edge), `tool_not_supported` (tool unavailable), `invalid_request` (fix the parameters), `source_too_large` / `result_too_large` (narrow the request). On Edge version issues, do not rotate Edges or fall back to the legacy diagnose.

### monit — Datasource and alert-expression preview

If you want to validate a datasource expression before saving a rule, use `preview-sync` to execute a synchronous preview request and inspect the raw result.

```bash theme={null}
flashduty monit preview-sync [flags]
```

Common flags:

| Flag              | Description                                                                          |
| ----------------- | ------------------------------------------------------------------------------------ |
| `--ds-name`       | Datasource display name (required, must match the console configuration)             |
| `--ds-type`       | Datasource type (required), such as `prometheus`, `loki`, or `elasticsearch`         |
| `--expr`          | Query expression to preview (required)                                               |
| `--delay-seconds` | Shift the query window backward by a few seconds to compensate for ingestion latency |
| `--data`          | Add datasource-specific parameters such as `args`                                    |

#### Datasource management (datasource-\*)

The `monit datasource-*` command family manages monitoring datasources (provided by the OpenAPI-generated commands):

```bash theme={null}
flashduty monit datasource-list [--type <type-ident>]   # List datasources (--type filters by type; omit for all)
flashduty monit datasource-info --id <datasource-id>    # Get one datasource
flashduty monit datasource-create [flags]               # Create a datasource (payload via --data)
flashduty monit datasource-update [flags]               # Update a datasource (--id required)
flashduty monit datasource-delete --id <datasource-id>  # Delete a datasource (referencing rules are not blocked; the datasource leaves their monitoring scope and their open alerts are closed)
```

Core fields for `datasource-create` / `datasource-update`:

| Flag                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--name`              | Datasource display name (required); the `ds_name` referenced by query APIs                                                                                                                                                                                                                                                                                                                                                                                                           |
| `--type-ident`        | Datasource type identifier (required): `prometheus`, `loki`, `mysql`, `oracle`, `postgres`, `clickhouse`, `elasticsearch`, `sls`, `tencent_cls`, `victorialogs`, plus 5 **diagnostic-only** types: `redis_node`, `redis_sentinel`, `mongodb_mongod`, `mongodb_mongos`, `kafka`                                                                                                                                                                                                       |
| `--address`           | Connection address. Required for every type except `elasticsearch` with `deployment: cloud`. Prometheus/Loki/VictoriaLogs: HTTP URL; MySQL/Oracle/Postgres/ClickHouse: `host:port`; SLS: endpoint without the `http(s)://` prefix. **Redis/MongoDB diagnostic types**: one `host:port`, bracket IPv6; no URI, userinfo or query. **Kafka**: 1–32 unique comma-separated `host:port` bootstrap addresses (no broker list in the payload). At most 4096 characters after normalization |
| `--edge-cluster-name` | Monitors edge cluster name responsible for evaluating rules using this datasource (required)                                                                                                                                                                                                                                                                                                                                                                                         |
| `--note`              | Optional description                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--enabled`           | **Business execution** switch. Omitted on create: `true`; omitted on update: preserve the current value. Explicit `false` disables execution (disabled datasources reject business queries and tools); `null` is invalid. **Does not change `alerting_enabled`**                                                                                                                                                                                                                     |
| `--alerting-enabled`  | Whether this datasource may evaluate alerts. Omitted on create: `true` for alerting types, `false` for diagnostic-only types; omitted on update: preserve the current value; `null` is invalid. The 5 diagnostic types reject `true`; disabling is rejected with a conflict when enabled rules reference the datasource                                                                                                                                                              |
| `--data`              | The `payload` configuration block (required), whose key must match `type_ident`, e.g. `{"payload":{"redis_node":{"database":0,"password":"..."}}}`                                                                                                                                                                                                                                                                                                                                   |

`enabled` and `alerting_enabled` are independent: alert evaluation requires both `enabled=true` and an alerting-capable type; `alerting_enabled=false` does not block non-alerting queries or tools, and `monit datasource-list` always reports `alerting_enabled=false` for diagnostic-only types.

**Diagnostic-type payloads and secret handling**:

* `redis_node`: `database` (Redis database number, default 0), `username` / `password`, `timeout_ms` (default 3000, range 1000–10000).
* `redis_sentinel`: `username` / `password`, `timeout_ms` (default 3000).
* `mongodb_mongod` / `mongodb_mongos`: `auth_source` (authentication database, defaults to `admin`; username and password must be configured together), `username` / `password`, `timeout_ms` (default 3000), TLS fields; client certificates are unsupported.
* `kafka`: `sasl_mechanism` (`none` default / `plain` / `scram-sha-256` / `scram-sha-512`, the latter three require username and password), `username` / `password`, `timeout_ms` (default 5000), TLS fields (`tls_min_version` defaults to 1.2, max 1.3).
* Passwords and `kafka.tls_key` support `${env:NAME}` references (resolved on the edge); literal values are omitted from responses, only `${env:...}` references are echoed. **On update, omit those fields to preserve stored secrets; explicitly send an empty string to clear**.

### alert — Alert and alert-event queries

```bash theme={null}
flashduty alert list [flags]        # List alerts (default: last 24h)
flashduty alert get <alert_id>      # Get full detail of one alert; detail is an alias
flashduty alert-event list [flags]  # List alert events (default: last 1h)
```

Common filter flags for both `list` commands: `--severity` (`Critical,Warning,Info`), `--channel` (comma-separated channel IDs), `--integration` (comma-separated integration IDs), `--since`/`--until`, `--limit` (max 100), `--page`. `alert-event list` also takes `--integration-type`, which filters by comma-separated **plugin keys** (e.g. `AliCloud,Prometheus`) — note these are plugin keys, not integration IDs; use `--integration` to filter by integration ID.

### 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.

```bash theme={null}
flashduty automation create [flags]               # Create a rule
flashduty automation list [flags]                 # List rules visible to the caller
flashduty automation get <rule_id>                # Get one rule by ID
flashduty automation update <rule_id> [flags]     # Update mutable fields on a rule
flashduty automation delete <rule_id> [flags]     # Delete a rule (interactive confirmation; --force skips it)
flashduty automation runs <rule_id> [flags]       # List a rule's run history
flashduty automation templates [--locale zh-CN]   # List preset templates
flashduty automation fire <trigger_id>            # Fire one run through its HTTP POST trigger
```

Common `create` flags:

| Flag                                      | Notes                                                                                                                                                     |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--name`                                  | Rule name (required)                                                                                                                                      |
| `--team-id`                               | Scope team ID; `0` means personal scope (default). The scope is immutable after creation                                                                  |
| `--schedule`                              | Schedule helper: `hourly`, `daily`, `weekly`, or `cron`; defaults to `daily` when omitted                                                                 |
| `--at`                                    | `HH:MM` local time (in the rule's timezone); for `hourly` only the minute is used (default 0), for `daily`/`weekly` both hour and minute (default 09:00)  |
| `--weekday`                               | Weekday for `weekly`: `sun`–`sat` or `0`–`7` (`0` and `7` both mean Sunday; defaults to Monday)                                                           |
| `--cron-expr`                             | Exact 5-field cron expression (interpreted in the rule's timezone); overrides the `--schedule` helpers                                                    |
| `--disabled`                              | Create the rule disabled (enabled by default)                                                                                                             |
| `--schedule-enabled`                      | Whether the schedule trigger is enabled (default `true`)                                                                                                  |
| `--http-post-trigger`                     | Create and enable an HTTP POST trigger; when passed alone without any schedule flags, the CLI writes a placeholder cron and disables the schedule trigger |
| `--prompt` / `--prompt-file`              | Task prompt, exactly one required; `--prompt-file` reads from a file (`-` for stdin)                                                                      |
| `--environment-kind` / `--environment-id` | Runtime environment: `cloud` or `byoc` (`byoc` requires `--environment-id`); empty means automatic                                                        |

`update` accepts `--name`, `--prompt`/`--prompt-file`, `--schedule`/`--at`/`--weekday`/`--cron-expr`, `--enable`/`--disable`, `--enable-schedule`/`--disable-schedule`, `--enable-http-post-trigger`/`--disable-http-post-trigger`, `--rotate-http-post-token`, and `--environment-kind`/`--environment-id`. The personal/team scope is immutable after creation, so `update` exposes no scope flag.

`runs` supports `--status` (`queued`/`running`/`retrying`/`succeeded`/`partial`/`failed`/`skipped`/`abandoned`), `--trigger-kind` (`schedule`/`debug`/`http_post`), `--since`/`--until`, `--page`, and `--limit`. `fire` authenticates with the trigger's token (`--token`, or the `FLASHDUTY_AUTOMATION_TRIGGER_TOKEN` environment variable); `--text` passes context for the run, and `--data` passes a full JSON request body (inline JSON or `-` to read stdin).

<Warning>
  **Timezone semantics**: `--at` and `--cron-expr` are interpreted as local wall-clock time in the **rule's timezone**, which defaults at creation to the caller's member timezone, falling back to the account timezone when the member has none. Pass the user's local time directly — do **not** convert it to UTC. Neither `create` nor `update` has a `--timezone` flag: to pin a different timezone at creation, use the generated command `flashduty safari automation-rule-create --timezone`; a created rule's timezone cannot be changed via `update`.
</Warning>

### insight — Insight queries

The `insight` command family queries aggregated incident metrics over a time window (response times, notification counts, and so on):

```bash theme={null}
flashduty insight incidents [flags]          # List incidents with performance metrics (MTTA, MTTR, notifications)
flashduty insight top-alerts [flags]         # Query top alert sources grouped by a label
flashduty insight incident-export [flags]    # Export the filtered incident list as CSV (redirect to a file)
```

Common flags for `insight incidents`:

| Flag                  | Description                                                                                                                                        | Default                    |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| `--since` / `--until` | Time window (same human-friendly formats as `incident list`)                                                                                       | `7d` / `now`               |
| `--limit`             | Max results (capped at 100)                                                                                                                        | `20`                       |
| `--page`              | Page number                                                                                                                                        | `1`                        |
| `--fields`            | Field projection for `json`/`toon` output (comma-separated, e.g. `incident_id,title,severity`); ignored in table mode; at least one field required | default compact projection |

In `json`/`toon` mode the rows default to the compact fields `incident_id`, `title`, `severity`, `channel_name`, `seconds_to_ack`, `seconds_to_close`, `notifications` (a stderr note announces the default projection and that `--fields` can change it); output is bounded at 16 KiB — overflowing rows are dropped or shortened, with all notes on stderr (see "Field projections for structured output" under "Output formats" below).

`insight top-alerts`: `--label` is required (`check` or `resource`), `--since`/`--until` as above, `--limit` defaults to `10` (top-K), returning the alert count and event count per label value.

`insight incident-export`: writes the filtered incident list as a CSV of header row plus data rows (redirect to a file; `--start-time`/`--end-time` take Unix seconds). The export endpoint returns a one-shot CSV and caps its row count server-side, so the command verifies the CSV data-row count against the `incident-list` total for the same filter after writing: on a shortfall the CSV is still written (a `rows=N` line goes to stderr) and the command exits non-zero stating written vs total — narrow the time window and retry.

### Full command coverage

Beyond the curated commands above, the CLI now provides **full coverage** of the Flashduty OpenAPI through a spec-driven code generator. The current OpenAPI contains **340 API operations**, and the CLI generates resource-organized commands for **337** of them; the remaining operations (e.g. `session-read-export`) are provided by hand-written commands (`session export` / `safari session-export`). In addition to the On-call domain (incident, incident-trigger-subscription, change, channel, field, status-page, template, and more), it also covers:

* **AI SRE (`safari`)**: a2a-agents, artifacts, automations, knowledge, mcp-servers, sessions, skills, and more
* **Alerting & noise reduction**: alert, alert-event, enrichment (alert-rules, rule-sets), route
* **On-call & scheduling**: calendar, schedule
* **Platform administration**: account, member, person, team, role (roles-permissions), audit (audit-logs)
* **Monitoring & RUM**: monit, rum, sourcemap
* **Integrations & webhooks**: datasource (IM integrations), webhook (integrations)

These generated leaf commands use a `resource-action` naming form (e.g. `flashduty safari a2a-agent-get`, `flashduty safari session-list`); their inputs and response fields map directly to the corresponding API. Explore them level by level with `flashduty <resource> --help`:

```bash theme={null}
flashduty --help                 # List all top-level command groups
flashduty safari --help          # AI SRE generated commands
flashduty alert --help           # Alert-related generated commands
```

Time-window parameters on generated commands (`--start-time` / `--end-time`) accept the same human-friendly formats as the curated commands: relative durations (`7d`, `24h` — interpreted as "now minus duration"), `+7d` ("now plus duration", i.e. a future time), `now`, dates and datetimes (such as `2026-05-01` or `2026-05-01 10:00:00`), and unix timestamps in seconds. In addition, `--since` and `--until` are aliases for `--start-time` and `--end-time` respectively and can be used interchangeably; passing both spellings with different values is an error.

#### knowledge — AI SRE knowledge base

The `safari knowledge-*` command family manages AI SRE **Knowledge Packs** — versioned, account/team-scoped file trees (`DUTY.md` plus runbooks, FAQs, service catalogs, and similar files) staged into every AI SRE sandbox at session start. See [Manage Knowledge](/en/ai-sre/knowledge) for the full feature model (`DUTY.md` structure, `@references`, account/team scope, file constraints).

```bash theme={null}
flashduty safari knowledge-get                                  # Get the account knowledge pack (with its file list)
flashduty safari knowledge-pack-list [flags]                    # List knowledge packs
flashduty safari knowledge-pack-ensure --scope <account|team> [--scope-id <team-id>]  # Ensure a knowledge pack exists (create if missing)
flashduty safari knowledge-pack-update <pack-id> [--scope ...]  # Change a pack's scope
flashduty safari knowledge-pack-delete <pack-id>                # Delete a knowledge pack (irreversible)
flashduty safari knowledge-file-list [--pack-id <id>]           # List files within a pack
flashduty safari knowledge-file-get --rel-path <path>           # Read a single knowledge file (content is Base64-encoded)
flashduty safari knowledge-file-put --rel-path <path> --content-b64 <base64>  # Upload or overwrite a knowledge file
flashduty safari knowledge-file-delete --rel-path <path> [--force]  # Delete a knowledge file
```

Common flags:

| Flag         | Description                                                                                        |
| ------------ | -------------------------------------------------------------------------------------------------- |
| `--pack-id`  | Knowledge pack ID; defaults to the caller's account-scope pack when omitted                        |
| `--rel-path` | File path relative to the pack root (required; subdirectories allowed, e.g. `runbooks/api-5xx.md`) |
| `--scope`    | Pack scope: `account` or `team` (required for `knowledge-pack-ensure`)                             |
| `--scope-id` | Team ID; required for `team` scope, ignored for `account` scope                                    |
| `--force`    | On file delete, skip the "still referenced" check; referrers are then returned as warnings         |

`knowledge-file-put` requires `--content-b64` to be the Base64 encoding of valid UTF-8 text; `--content-type` is inferred from the file extension when omitted. `knowledge-file-delete` refuses to remove a file still referenced by other pack files unless `--force` is passed, in which case the referrers are returned as warnings.

#### artifacts — AI SRE artifact gallery

The `safari artifact-*` command family manages **artifacts** produced by AI SRE sessions — publishing to the gallery, sharing, and signed downloads. See [Artifacts](/en/ai-sre/artifacts) for the console workflow:

```bash theme={null}
flashduty safari artifact-gallery-list [flags]                                     # List artifacts (--scope all|personal|team, --query title search, --orderby created_at|updated_at, --limit default 20 cap 100, --page, --team-ids, --asc)
flashduty safari artifact-gallery-get <artifact-id>                                # Get artifact detail (including public-share state)
flashduty safari artifact-gallery-publish-from-file <file-id> --title <t>          # Publish a session-produced file (pf_ prefix) as an artifact
flashduty safari artifact-gallery-file-state <file-id> [<id2>...]                  # Check which files already have a live artifact (at most 50 per call)
flashduty safari artifact-gallery-update <artifact-id> [flags]                     # Rename (--title) or transfer scope (--team-id: 0 = personal, positive = team)
flashduty safari artifact-gallery-delete <artifact-id>                             # Remove from the gallery (the source file stays with its session)
flashduty safari artifact-sign <file-id> [--share-token <t>]                       # Create short-lived signed URLs (download/preview, valid 5 minutes)
flashduty safari artifact-stream --t <token> [--mode download|preview]             # Download or preview file bytes with a signed token (any other --mode falls back to download)
flashduty safari artifact-gallery-share-enable <artifact-id>                       # Enable anonymous public sharing, returns public_url
flashduty safari artifact-gallery-share-revoke <artifact-id>                       # Revoke public sharing (the link stops resolving immediately)
flashduty safari artifact-gallery-share-sync <artifact-id>                         # Refresh the public snapshot with the latest content
```

Public-sharing and signing semantics:

* `public_url` is a console `/share/artifact/<artifact-id>` page served **entirely from the CDN**; it exists only while sharing is on, and anyone with the link can view the content without logging in.
* The public snapshot is materialized from the artifact's current `file_id`: when `share_enabled=true` and the response's `share_file_id` differs from `file_id`, the public snapshot is stale — call `artifact-gallery-share-sync` to refresh it before referencing it externally.
* The `artifact-sign` token is bound to the calling account and person and is valid for 5 minutes (response `expires_in`); `download_url` / `preview_url` are relative paths (`/safari/artifact/stream?...`) — prepend the API base (`https://api.flashcat.cloud`).
* An artifact's initial scope inherits from its source session (personal-session artifacts belong to the creator; team-bound session artifacts belong to the team); `can_edit` tells whether the caller may rename/transfer/delete/share it (the creator, any member of the owning team, or a manager of the source session).

### Utility commands

```bash theme={null}
flashduty login          # Interactive login
flashduty config show    # Show current configuration
flashduty config set     # Set a configuration value
flashduty version        # Print version information
flashduty whoami         # Show the current authenticated identity (account ID, email, role)
flashduty update         # Update to the latest version
flashduty update --check # Check for updates without installing
flashduty completion     # Generate shell completions (bash/zsh/fish/powershell)
```

<Note>
  `flashduty update` downloads and runs the platform installer, replacing the current binary with the latest release. `--check` only prints the available version without modifying any local files. After any non-update command runs in a terminal, if a newer version is available the CLI automatically emits an update notice banner to stderr.
</Note>

Enable shell completion (zsh example):

```bash theme={null}
flashduty completion zsh > "${fpath[1]}/_flashduty"
```

## Output formats

Select the output shape with `--output-format` (`--json` is an alias for `--output-format json`) to fit different consumers:

<Tabs>
  <Tab title="Table (default)">
    Human-readable, aligned columns, long fields truncated.

    ```
    ID           TITLE                    SEVERITY   PROGRESS     CHANNEL       CREATED
    inc_abc123   DB connection timeout    Critical   Triggered    Production    2026-04-10 10:23
    inc_def456   High memory usage        Warning    Processing   Staging       2026-04-10 09:15
    Showing 2 results (page 1, total 2).
    ```
  </Tab>

  <Tab title="JSON (--json / --output-format json)">
    Machine-parseable. Except for the commands with default compact fields listed below, it returns the command's full response data; table-column truncation does not apply to JSON. Ideal for scripts and CI/CD pipelines. Note that generated commands' **list-shaped** responses are bounded at 16 KiB in `json` mode too (see "Generated-command output bound" below).

    ```bash theme={null}
    flashduty incident list --json | jq '.[].title'
    ```
  </Tab>

  <Tab title="TOON (--output-format toon)">
    TOON (Token-Oriented Object Notation) drops the per-row field names that JSON repeats for homogeneous arrays, cutting token usage substantially on list output and making it well suited to AI agents. Commands with default compact fields listed below emit their field projections and are size-bounded; generated commands' list-shaped output is bounded at 16 KiB as well (see "Generated-command output bound" below).

    ```bash theme={null}
    flashduty incident list --output-format toon
    ```

    <Note>
      TOON cannot be parsed directly by `jq`; use `--json` when you need to pipe into `jq`.
    </Note>
  </Tab>

  <Tab title="Full table (--no-trunc)">
    Table view with no column truncation — useful for copy-paste or wide terminals.
  </Tab>
</Tabs>

#### Generated-command output bound

Generated commands (the ones covering the OpenAPI through the code generator, such as `safari session-list`, `monit datasource-list`, `safari a2a-agent-list`) apply the same 16 KiB bound to **list-shaped** responses in `json`/`toon` mode, mirroring the curated commands' behavior, with every note going only to stderr and stdout left untouched:

1. **The whole page overflows**: only the leading rows that fit are emitted, with every value intact, and a stderr note reports how many of the N/M rows were emitted.
2. **A single row alone overflows the budget**: that row's string values are shortened and end with `...`; a stderr note names the clipped fields. Identifier fields (keys ending in `_id` or `_key`) are never shortened.
3. **A row cannot be reduced enough to fit**: the command fails and names the largest fields (up to 3, with their byte sizes); lower `--limit` or reduce the output fields and retry.

**Detail-shaped single objects** (e.g. `safari session-get`) are never bounded or shortened — a shortened id or status would pass for a real value, so these responses print untouched. Generated commands mostly have no `--fields`; for complete JSON lower `--limit` and page through with `--page` (e.g. `flashduty safari session-list --limit 20 --page 2`), or narrow the filter.

### Field projections for structured output

The following commands support `--fields` with `json` or `toon` output. Supply comma-separated top-level response fields; an unknown field fails immediately, and table output ignores this flag.

| Command                                             | Structured output when `--fields` is omitted                                                                                        | Limit                      |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| `flashduty incident list`                           | `incident_id`, `title`, `incident_severity`, `progress`, `start_time`, `channel_id`                                                 | 16 KiB                     |
| `flashduty incident similar <id>`                   | `incident_id`, `title`, `incident_severity`, `progress`, `start_time`, `close_time`, `ack_time`, `alert_cnt`, `root_cause`, `score` | 16 KiB                     |
| `flashduty incident detail <id>`                    | Returns full detail when `--fields` is omitted; otherwise returns only the selected fields                                          | 8 KiB for projections only |
| `flashduty alert-event list`                        | `event_id`, `alert_id`, `event_severity`, `event_status`, `event_time`, `title`                                                     | 16 KiB                     |
| `flashduty channel escalate-rule-list <channel-id>` | `rule_id`, `rule_name`, `status`, `priority`, `filters`                                                                             | 16 KiB                     |
| `flashduty insight incidents`                       | `incident_id`, `title`, `severity`, `channel_name`, `seconds_to_ack`, `seconds_to_close`, `notifications`                           | 16 KiB                     |

For example, export only an incident ID, title, and progress:

```bash theme={null}
flashduty incident list --json --fields incident_id,title,progress
```

When a list projection (`incident list`, `incident similar`, `alert-event list`, `channel escalate-rule-list`, `insight incidents`) exceeds its 16 KiB limit, the CLI handles it in three tiers, with every note going to stderr and stdout left untouched:

1. **Whole page overflows**: only the leading rows that fit are emitted, with every value left intact (no truncation), and a stderr note reports how many of the rows were emitted while the rest were not; narrow `--fields` or lower `--limit` to fit more rows per page.
2. **A single row alone overflows the budget**: that row's string values are shortened and end with `...`, and a stderr note names the clipped fields — matching or filtering on a shortened field will miss, so narrow `--fields` or `--limit` for untruncated values. Identifier fields (keys ending in `_id` or `_key`) are never shortened at any tier.
3. **A row cannot be reduced enough to fit**: the command fails with an error naming the largest fields (up to 3, with their byte sizes); reduce the fields in `--fields` or lower `--limit` and retry.

`incident detail` behaves differently when its projection overflows: the detail is a single object, and a truncated value is indistinguishable from a genuinely short one, so silently shortening it would hand you wrong data. A projection over 8 KiB therefore fails the command outright, and the error names the largest fields (up to 3, with their byte sizes). Reduce the fields in `--fields`, or omit `--fields` entirely to get the full detail, which is not subject to the projection limit.

When `--fields` is omitted and the default compact projection is used, the CLI prints a one-line note to stderr stating which fields the projection uses and that `--fields` can select others. The note goes only to stderr and never touches stdout, so piping into `jq` or similar tools is unaffected.

## Agent skills

Flashduty CLI ships with a single agent skill named `flashduty` that teaches AI coding agents — Claude Code, Cursor, Codex, Gemini CLI, Windsurf, and 40+ others — how to operate Flashduty from your terminal.

Install it to every detected agent on your machine in one shot:

```bash theme={null}
npx skills add flashcatcloud/flashduty-cli -y -g
```

The skill uses a router-plus-reference-card structure: `SKILL.md` carries the shared conventions (authentication, global flags, safety rules) and indexes per-domain reference cards — incidents, alerts, changes, on-call and schedules, channels and escalations, status pages, insights, monitors, RUM and sourcemaps, automations, notification templates, members and teams, and more. Before running a task, the agent reads the card for that domain to get every command, flag, and workflow for it — no `--help` trial-and-error.

## Common workflows

<AccordionGroup>
  <Accordion title="Attach a CLI link to notifications">
    Use `flashduty incident get <id>` to fetch incident details from the terminal. Embed the snippet into notification templates so responders can copy-paste it.
  </Accordion>

  <Accordion title="Bulk acknowledge or close incidents">
    ```bash theme={null}
    flashduty incident ack inc_001 inc_002 inc_003
    flashduty incident close inc_001 inc_002 inc_003
    ```
  </Accordion>

  <Accordion title="Export incident data to BI tools">
    ```bash theme={null}
    flashduty incident list --since 168h --limit 500 --json > incidents.json
    ```

    Then process the file with `jq` or load it into your warehouse.
  </Accordion>

  <Accordion title="Validate notification templates in CI/CD">
    ```bash theme={null}
    flashduty template validate --channel feishu --file templates/feishu.yaml
    ```

    Run this in CI to catch syntax or field errors as soon as a template is committed.
  </Accordion>
</AccordionGroup>

<Tip>
  Full source and issue tracking live on the [GitHub repository](https://github.com/flashcatcloud/flashduty-cli).
</Tip>
