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
feat(skill): clean public boundary, merge oncall→schedule, bilingual index, fault-analysis script
Rework the flashduty skill per review feedback:
- SKILL.md is now a clean PUBLIC router: strip Safari-internal behavior
(credential injection, subagent dispatch, the `task` tool). Only the
reference/*.md cards and scripts/ are shared with the Safari embed; each
consumer owns its own SKILL.md.
- Merge the `oncall` domain into `schedule` (one on-call / 值班 domain).
`oncall who` is kept as the deprecated current-on-call lookup; the durable
path is schedule-native `info --start now`. Drop reference/oncall.md.
- Add reference/change.md (the `change` group was previously uncovered).
- Make the domain index bilingual (Chinese + English routing terms per row).
- Add scripts/incident-summary.sh: one call fetches all six fault-analysis
aspects (detail/alerts/timeline/similar/post-mortem/changes) so a compound
summary is written from real output instead of fabricated piecemeal.
Copy file name to clipboardExpand all lines: skills/flashduty/SKILL.md
+32-24Lines changed: 32 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
name: flashduty
3
3
version: "3.0"
4
4
description: "USE FIRST for Flashduty tasks — status pages, incidents, alerts, on-call, monitors, RUM, members. `fduty` CLI = the whole API. ALWAYS load this skill + read reference/<domain>.md for exact verbs & flags BEFORE running fduty. Don't guess or --help-dance."
5
-
allowed-tools: bash, read, task
5
+
allowed-tools: bash, read
6
6
---
7
7
8
8
# Flashduty CLI
@@ -11,7 +11,7 @@ allowed-tools: bash, read, task
11
11
12
12
## Auth & availability
13
13
14
-
-**Auth is automatic.**Safari injects the credential into each `fduty` subprocess. You never handle it and *cannot* read it — commands that reference `FLASHDUTY_APP_KEY` / `$FLASHDUTY_*` by name or dump the environment are rejected. Just call the verb.
14
+
-**Auth.**Set your Flashduty app key once — `export FLASHDUTY_APP_KEY=<key>` — or pass `--app-key <key>` per call. Then just call the verb.
15
15
-**No curl for the API.** The CLI is the only supported path to Flashduty — never hand-roll an HTTP call.
16
16
-**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"`.
17
17
@@ -25,40 +25,48 @@ Append `--output-format toon` to read commands: it drops the per-row repeated ke
25
25
26
26
**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.
27
27
28
+
**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.
29
+
28
30
## Command names — don't guess, read the card
29
31
30
32
The hot path: **read the domain card** (index below) for the exact verb + flags. Command groups are hyphenated (`status-page`, `alert-event`), not concatenated (`statuspage`) — guessing the wrong form costs a failed call. For a command outside the cards, derive it from its API path: **group = first path segment, verb = the rest joined by `-`** (`POST /status-page/change/create` → `fduty status-page change-create`), then confirm with `fduty <group> <verb> --help`. Pass nested-object / array fields as JSON via `--data '{...}'`; typed scalar flags override matching `--data` keys.
31
33
32
34
**Positional arguments.** A card heading like `### change-create <page-id>` means that id is **positional** — pass it as the first bare argument (`change-create 5759… --type incident`), not as `--page-id`. A heading with no `<…>` takes all inputs as flags. Cards mark each positional with a `(positional, required)` row; trust the heading over your instinct to use a flag.
33
35
34
-
## fduty answers directly — don't dispatch or grep
36
+
## fduty answers directly — don't grep or browse
35
37
36
-
Configuration, permission-model, enrichment, monitor, and on-call questions are answered by `fduty` itself (the cards + the live commands). Do **not** grep documentation, browse the web, or dispatch a subagent / product-guide agent for something the CLI covers — that wastes a turn and usually returns staler information than the live API. Read the card, run the verb.
38
+
Configuration, permission-model, enrichment, monitor, and on-call questions are answered by `fduty` itself (the cards + the live commands). Do **not** grep external documentation or browse the webfor something the CLI covers — that usually returns staler information than the live API. Read the card, run the verb.
37
39
38
40
## Safety — confirm before mutating
39
41
40
42
Read verbs (`list`, `get`, `info`, `detail`, `timeline`) are free. Mutating verbs (`create`, `update`, `delete`, `merge`, `ack`, `close`, `assign`, `move`, …) change state — recommend the action and get explicit per-target confirmation first. `merge` / `delete` are **irreversible** — double-check IDs. `create` notifies responders/subscribers. `list` before any bulk mutate to confirm the IDs.
41
43
44
+
## Compound flows — bundled scripts
45
+
46
+
Some asks span several commands. For those the skill ships a script that fetches everything in one call — run it as your **first action** for that ask, rather than hand-picking commands and writing the rest from memory:
47
+
48
+
-**Full incident fault analysis** (详情 + 关联告警 + 变更 + 时间线 + 相似故障 + 复盘 / detail + alerts + changes + timeline + similar + post-mortems): `bash scripts/incident-summary.sh <incident-id>` — runs all six reads and prints them in one block, so the summary is written from real output. See `reference/incident.md`.
49
+
42
50
## Domain index — read the card for the task
43
51
44
-
|意图 / intent| card |
52
+
|intent / 意图 (terms route in either language)| card |
Prereq: `SKILL.md` read. One read-only verb. Change events are the "what changed" signal you correlate against an incident during fault analysis.
4
+
5
+
## Route here when
6
+
7
+
"变更 / 变更事件 / 变更关联 / 发布 / 部署 / change / change event / deployment / release / what changed / correlated change" → **change**. Change events carry `labels`; they correlate to incidents by **shared labels + time proximity** (there is no foreign key). For *status-page* maintenance/incident events use `status-page` instead — that is a different "change".
8
+
9
+
## Intent → verb
10
+
11
+
| want | verb |
12
+
|---|---|
13
+
| list recent change events (filter by window / channel / integration / keyword) |`list`|
14
+
15
+
## Hot flow — find changes around an incident
16
+
17
+
```bash
18
+
# Pull recent changes in the incident's window, then eyeball label/time overlap with the incident.
19
+
fduty change list --since 24h --output-format toon
20
+
21
+
# Narrow by the integration or channel that emitted them, or by a keyword:
-**Correlation is heuristic, not relational.** A change is "related" to an incident when their `labels` overlap and their timestamps are close — there is no `incident_id` on a change. Judge the overlap yourself; do not claim a causal link the data doesn't support.
42
+
-**`--integration` / `--channel`** scope to the source that emitted the change; **`--since` / `--until`** bound the window (relative like `24h`, `-1h`, `now`, or Unix seconds).
43
+
44
+
## Gotchas
45
+
46
+
-**List-only domain.** There is no `change get` / `change detail` verb — `list` (with filters) is the whole surface. Don't guess a detail verb.
47
+
-**Empty result is authoritative** — no changes in that window/scope. Report it; don't widen blindly or invent a change to explain the incident.
48
+
49
+
## Worked example
50
+
51
+
```bash
52
+
# Changes in the last 6h on a specific integration, newest first
53
+
fduty change list --since 6h --integration 5759613685214 --output-format toon
## Hot flow — full fault analysis (read-only summary)
67
+
68
+
When asked to **summarize / analyze** an incident — 详情 + 关联告警 + 变更 + 时间线 + 相似故障 + 复盘 — `incident detail` does **not** contain the alerts / timeline / similar / post-mortem / change data; each is its own command. **Your first action must be the bundled script** — do not hand-pick one or two commands and write the rest from memory. One call fetches all six aspects:
`<skill-dir>` is this skill's base directory — you were given it when the skill loaded (it is also the folder you read this card from). The script runs every command below and prints the results in one block, so each section of your summary is backed by real output and there is nothing to guess. (To tie post-mortems to *this* incident, re-run `incident post-mortem-list --channel-ids <channel-id>` with the `channel_id` from `detail`.)
75
+
76
+
If you fetch the pieces by hand instead, run **all six** — they are cheap reads:
77
+
78
+
```bash
79
+
ID=<incident-id># 24-char id from `incident list`
80
+
fduty incident detail "$ID" --output-format toon # ① 详情 + AI summary + alert counts + channel_id
81
+
fduty incident alerts "$ID" --output-format toon # ② contributing alerts (detail's embedded alerts are empty here)
82
+
fduty incident timeline "$ID" --output-format toon # ④ timeline (or `incident feed "$ID"` for the paginated view)
83
+
fduty incident similar "$ID" --limit 5 --output-format toon # ⑤ similar past incidents (channel-backed; see Gotchas)
84
+
fduty incident post-mortem-list --channel-ids <channel-id> --output-format toon # ⑥ post-mortems for this incident's channel
85
+
fduty change list --since 24h --output-format toon # ③ correlated changes — by shared labels + time; see reference/change.md
86
+
```
87
+
88
+
> **Never report a result you didn't fetch.** Do not write "返回空" / "无" / a count for any aspect whose command is **absent from your tool-call history this turn** — write `未查询 — 可运行 <command>` instead. "Empty" is a claim only a command you actually ran can make; inventing it is the worst failure mode of a fault summary.
89
+
66
90
## Hot flow — resolve, document, and merge duplicates
0 commit comments