You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: skills/flashduty/SKILL.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,6 +15,7 @@ hidden: true # internal-only: withheld from skills.sh public discovery (Safari
15
15
-**Auth.** Set your Flashduty app key once — `export FLASHDUTY_APP_KEY=<key>` — or pass `--app-key <key>` per call. Then just call the verb.
16
16
-**No curl for the API.** The CLI is the only supported path to Flashduty — never hand-roll an HTTP call.
17
17
-**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"`.
18
+
-**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.).
18
19
19
20
## Data model — 3 layers
20
21
@@ -24,6 +25,10 @@ hidden: true # internal-only: withheld from skills.sh public discovery (Safari
24
25
25
26
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.
26
27
28
+
**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`.
29
+
30
+
**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.
31
+
27
32
**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.
28
33
29
34
**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.
Copy file name to clipboardExpand all lines: skills/flashduty/reference/alert.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -130,6 +130,8 @@ View alert timeline
130
130
-**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).
131
131
-**`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.
132
132
-**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"))'`
133
+
-**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.
134
+
-**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.
133
135
-**`list` time window cap is 31 days**; `--limit` max is 100. For broader queries use `insight` domain.
134
136
-**`pipeline-upsert` fully replaces** the existing pipeline — always fetch current config with `pipeline-info` first and include unchanged rules in the new body.
135
137
-**Empty `list` result is authoritative** — report "no alerts match" and stop; do not widen filters or retry with alternate keywords.
Copy file name to clipboardExpand all lines: skills/flashduty/reference/incident.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -362,6 +362,8 @@ List war rooms
362
362
-**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`.
363
363
-**`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.
364
364
-**`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.
365
+
-**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.
366
+
-**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`.
365
367
-**`--list` window cap**: `--since`/`--until` window must be < 31 days; `--limit` max 100. Empty result is authoritative — do not widen filters or retry.
366
368
-**`merge` is irreversible**: source incidents are absorbed into target permanently. Always list and confirm both IDs before running.
367
369
-**`remove --force`** bypasses the interactive confirmation prompt — never pass `--force` unless the user has explicitly said so.
-**`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.
328
341
-**`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.
329
342
-**`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.
343
+
-**`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.
344
+
-**"全量规则 / 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.
345
+
-**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.
330
346
-**`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.
331
347
-**`rule-delete-batch` and `datasource-delete` are irreversible.** Confirm IDs with `rule-list-basic` / `datasource-info` first.
332
348
-**`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.
333
349
334
350
## Worked example — inspect a firing rule then batch-disable it
335
351
336
352
```bash
337
-
# 1. find triggered rules in folder 0 (all accessible)
0 commit comments