Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions skills/flashduty/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ hidden: true # internal-only: withheld from skills.sh public discovery (Safari
- **Auth.** Set your Flashduty app key once — `export FLASHDUTY_APP_KEY=<key>` — or pass `--app-key <key>` per call. Then just call the verb.
- **No curl for the API.** The CLI is the only supported path to Flashduty — never hand-roll an HTTP call.
- **If `fduty: command not found`** (rare — it is normally on PATH at startup): install from the Flashduty CDN into a user-writable dir (no sudo, no hang), then tell the user — don't work around it: `curl -sSL https://static.flashcat.cloud/flashduty-cli/install.sh | FLASHDUTY_INSTALL_DIR="$HOME/.local/bin" INSTALLED_NAME=fduty sh && export PATH="$HOME/.local/bin:$PATH"`.
- **If `jq` is missing** and you genuinely need JSON filtering, it is fine to install it into a user-writable dir the same way (`$HOME/.local/bin`) and continue. But first ask whether you can avoid `jq` entirely by using `--output-format toon`, `--fields`, a returned `total`, or a server-side aggregation verb (`insight`, `rule-counter-*`, etc.).

## Data model — 3 layers

Expand All @@ -24,6 +25,10 @@ hidden: true # internal-only: withheld from skills.sh public discovery (Safari

Append `--output-format toon` to read commands: it drops the per-row repeated keys that JSON emits, so lists cost far fewer tokens. Use `--json` only to pipe into `jq`. Bare output is a human table — don't parse it.

**Count the cheap way.** If a list response already returns `total`, trust that authoritative server count — do not page N times just to count rows. When the question is "how many by status/progress/severity", issue the narrowest server-side filter per bucket and read each response's `total`; for account-wide trends switch to aggregation verbs such as `insight *`, `rule-counter-status`, `rule-counter-node`, or `rule-counter-total`.

**Shape the payload before you fetch it.** For ID scans, counts, or "find the matching row" tasks, prefer `--fields` projections and compact list verbs over full detail dumps. Huge raw JSON dumps are a last resort, not a default.

**Empty result = authoritative not-found.** A filter returning `[]` means no such entity in scope — report it (optionally the 1–2 closest names) and stop. Do **not** brute-force (no shifted-keyword re-queries, no widening past caps, no full-dump grep). Never infer "feature not enabled" from an empty list, and never fabricate data absent from tool output.

**A result you did not fetch is "unknown", never "empty".** You may report a command's result — including "returned empty" or any count/list/finding — **only if that exact command appears in your tool-call history this turn**. If you did not run it, the honest answer is "未查询 / not queried", followed by the command to run. Writing "`incident similar` 返回空" or "无变更" for a command you never executed is fabrication, not a summary.
Expand Down
2 changes: 2 additions & 0 deletions skills/flashduty/reference/alert.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ View alert timeline
- **All alert verbs are positional except `list` and the two-ID `merge` flag.** Every verb with `<alert-id>` in its `use` form takes that ID as the first bare argument — do NOT pass `--alert-id`. The single exception: `merge` takes the first alert ID positionally AND requires `--incident-id` as a flag (two different IDs, different roles).
- **`alert get` vs `alert info`, `alert events` vs `alert-event list`:** both pairs exist; prefer `get`/`events` (shorter, no extra flag); `info`/`event-list` accept `--alert-id` as a flag override for scripting.
- **No server-side title filter on `list`.** To search by title, use `--json` and pipe to `jq`: `fduty alert list --json | jq '.[] | select(.title | test("disk";"i"))'`
- **If `list` returns a `total`, use it.** Do not paginate page 1/2/3... just to count alerts. Ask the narrowest question (`--active`, `--recovered`, `--severity`, `--channel`, `--since`) and read the server-reported total for that bucket.
- **Use `--fields` when hunting IDs, not full rows.** If the task is "find alert IDs / titles / channels / severities", project only those fields first, then drill into one alert with `get` / `events`. Dumping every field for 100 alerts wastes tokens and hides the one row you need.
- **`list` time window cap is 31 days**; `--limit` max is 100. For broader queries use `insight` domain.
- **`pipeline-upsert` fully replaces** the existing pipeline — always fetch current config with `pipeline-info` first and include unchanged rules in the new body.
- **Empty `list` result is authoritative** — report "no alerts match" and stop; do not widen filters or retry with alternate keywords.
Expand Down
2 changes: 2 additions & 0 deletions skills/flashduty/reference/incident.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ List war rooms
- **24-char `incident_id` vs 6-char `num`**: positional-id verbs (`ack`, `close`, `resolve`, `detail`, `alerts`, `timeline`, `merge`, `reassign`, `comment`, `reset`, …) require the full ObjectID. Passing a 6-char num 400s. Use `incident info --num <num>` to resolve, or `incident list --query <num>` and read `incident_id`.
- **`similar` only works on channel-backed incidents** (those with a real `channel_id`). Manually created incidents with no channel return HTTP 400 "Channel not found" — this is expected, not transient. Fall back to `incident list --query "<keywords>"` for text search.
- **`update` vs `reset`**: `update <id>` edits title/description/severity/custom fields. `reset <incident-id>` additionally supports `--impact`, `--root-cause`, `--resolution` (the AI narrative fields). Use `reset` for post-incident write-back.
- **If `list` returns a `total`, use it instead of page-walking.** For "how many incidents are Triggered / Processing / Closed", run one filtered `incident list --progress <bucket> ...` per bucket and read the returned `total`. Do not fetch page 1/2/3 just to derive counts the server already computed.
- **Use `--fields` to keep list scans compact.** When the goal is to identify matching incidents or collect IDs/numbers/titles, project only the needed columns first, then fetch one target incident with `detail` / `alerts` / `timeline`.
- **`--list` window cap**: `--since`/`--until` window must be < 31 days; `--limit` max 100. Empty result is authoritative — do not widen filters or retry.
- **`merge` is irreversible**: source incidents are absorbed into target permanently. Always list and confirm both IDs before running.
- **`remove --force`** bypasses the interactive confirmation prompt — never pass `--force` unless the user has explicitly said so.
Expand Down
23 changes: 20 additions & 3 deletions skills/flashduty/reference/monit.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ fduty monit tools-invoke --target-locator <hostname-or-ip> --output-format toon
EOF
```

## Hot flow — inventory all monitor alert rules without guessing folders

```bash
# 1. get the distribution first; this is the cheap way to answer "how many rules are where / in what status"
fduty monit rule-counter-status --output-format toon

# 2. list rules only for the concrete folder you care about
fduty monit rule-list-basic --folder-id <folder-id> --output-format toon

# 3. export the exact rules you selected
fduty monit rule-export --ids <id1>,<id2>,<id3> --output-format toon
```

<!-- GENERATED:monit START · 由 fduty __dump-commands 同步 · 勿手改 fence 内 -->

### datasource-create
Expand Down Expand Up @@ -327,16 +340,20 @@ Invoke target tools
- **`query-rows` has no time flags.** There is no `--time-start` / `--time-end` / `--operation`. Embed all time range and bucketing inside `--expr`. Passing those flags is a silent no-op or error.
- **`query-diagnose` time window via `--data`**, not flags. Pass `{"time_range":{"start":<unix>,"end":<unix>},...}`. Window wider than 6 hours is rejected server-side. Omitting `time_range` defaults to the last 15 minutes.
- **`rule_configs` and nested arrays require `--data`.** The queries, thresholds, enabled_times, and labels objects cannot be expressed as flat flags — pass them as inline JSON via `--data '{"rule_configs":{...}}'`. Typed scalar flags (`--name`, `--enabled`, `--cron-pattern`, `--ds-type`) override matching `--data` keys.
- **`folder-id 0` is not a universal "all rules" sentinel.** If the API says "Folder not found", believe it. For global inventory use `rule-counter-status` / `rule-counter-node` first, then run `rule-list-basic` against real folder IDs only.
- **"全量规则 / full rules" means exported monitor alert-rule definitions.** The concrete verb is `rule-export --ids ...`, usually after `rule-list-basic` selected the IDs. It does not mean dumping incidents or alerts.
- **For rule counts, prefer the counter verbs over list pagination.** `rule-counter-status`, `rule-counter-node`, and `rule-counter-total` are the authoritative aggregation surfaces; do not infer counts by walking `rule-list-basic` pages.
- **`tools-catalog` / `tools-invoke` `--target-locator` is required and not guessable.** If the user has not provided a host or IP, ask — do not invent one. Tool names in `invoke` must come from the `tools-catalog` response — never hallucinate them.
- **`rule-delete-batch` and `datasource-delete` are irreversible.** Confirm IDs with `rule-list-basic` / `datasource-info` first.
- **`rule-audit-detail --id` takes the audit record ID**, not the rule ID. Get audit record IDs from `rule-audits --id <rule-id>` first; passing the rule ID returns HTTP 400.

## Worked example — inspect a firing rule then batch-disable it

```bash
# 1. find triggered rules in folder 0 (all accessible)
fduty monit rule-list-basic --folder-id 0 --output-format toon
# look at triggered=true rows; note their ids
# 1. inspect top-level distribution, then choose a real folder id
fduty monit rule-counter-status --output-format toon
fduty monit rule-list-basic --folder-id <folder-id> --output-format toon
# look at the rows you actually care about; note their ids

# 2. get full config of one rule
fduty monit rule-info --id <rule-id> --output-format toon
Expand Down
Loading