Skip to content

Commit 8da199e

Browse files
committed
chore(skills): drop legacy rows guidance from command cards
Skill cards guide new usage, so a deprecated verb earns no card entry: - skilldoc dump now excludes commands with a cobra Deprecated marker (the command stays in the CLI tree with its runtime warning). - cligen reads the spec's deprecated flag and stamps generated commands; monit query-rows carries the 'use monit-query data instead' message. - monit-query / monit cards now teach only data (query_result.v1) and diagnose; the raw rows passthrough remains callable during the migration period but is no longer agent guidance.
1 parent e783925 commit 8da199e

5 files changed

Lines changed: 48 additions & 39 deletions

File tree

internal/cli/zz_generated_diagnostics.go

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/cmd/cligen/main.go

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ type specOp struct {
150150
// envelope. RespTree then holds the ROW (array-element) fields, and help must
151151
// document the output as a TOP-LEVEL array (`jq '.[]'`), not `under data`.
152152
RespArray bool
153+
// Deprecated is the cobra deprecation message when the spec marks the
154+
// operation `deprecated: true`; empty means the operation is current.
155+
Deprecated string
153156
}
154157

155158
// schemaField is one node in a (possibly nested) request/response schema tree.
@@ -244,18 +247,27 @@ func collectServices(paths, schemas map[string]any, sdk map[string]map[string]me
244247
respType = mi.RespType
245248
}
246249
respTree, respArray := walker.responseTree(e.op, respType)
250+
opDeprecated := ""
251+
if ok, _ := e.op["deprecated"].(bool); ok {
252+
if msg := opDeprecationMessages[opID]; msg != "" {
253+
opDeprecated = msg
254+
} else {
255+
opDeprecated = "this API operation is deprecated"
256+
}
257+
}
247258
svc.Ops = append(svc.Ops, specOp{
248-
OpID: opID,
249-
Method: method,
250-
HTTP: e.http,
251-
Path: e.path,
252-
Summary: str(e.op, "summary"),
253-
Desc: str(e.op, "description"),
254-
Example: walker.example(e.op),
255-
Fields: walker.fields(e.op),
256-
ReqTree: walker.requestTree(e.op),
257-
RespTree: respTree,
258-
RespArray: respArray,
259+
OpID: opID,
260+
Method: method,
261+
HTTP: e.http,
262+
Path: e.path,
263+
Summary: str(e.op, "summary"),
264+
Desc: str(e.op, "description"),
265+
Example: walker.example(e.op),
266+
Fields: walker.fields(e.op),
267+
ReqTree: walker.requestTree(e.op),
268+
RespTree: respTree,
269+
RespArray: respArray,
270+
Deprecated: opDeprecated,
259271
})
260272
}
261273
if len(svc.Ops) > 0 {
@@ -972,6 +984,13 @@ var opAliases = map[string][]string{
972984
"channelInfo": {"get", "detail"},
973985
}
974986

987+
// opDeprecationMessages maps a spec-deprecated operationId to its cobra
988+
// deprecation message. Ops without an entry get a generic message when the
989+
// spec marks them deprecated.
990+
var opDeprecationMessages = map[string]string{
991+
"monit-read-query-rows": "use 'monit-query data' instead",
992+
}
993+
975994
// positional describes the positional argument a generated command exposes.
976995
type positional struct {
977996
Wire string // request-body wire key the positional folds into
@@ -1181,6 +1200,9 @@ func emitCmd(fn string, s service, o specOp, mi methodInfo) string {
11811200
fmt.Fprintf(&b, "\tcmd := &cobra.Command{\n")
11821201
fmt.Fprintf(&b, "\t\tUse: %q,\n", use)
11831202
fmt.Fprintf(&b, "\t\tShort: %q,\n", oneLine(o.Summary))
1203+
if o.Deprecated != "" {
1204+
fmt.Fprintf(&b, "\t\tDeprecated: %q,\n", o.Deprecated)
1205+
}
11841206
fmt.Fprintf(&b, "\t\tLong: %s,\n", quoteMultiline(longHelp(o, scalars, complexFields, specByWire)))
11851207
if aliases := opAliases[o.OpID]; len(aliases) > 0 {
11861208
quoted := make([]string, len(aliases))

internal/skilldoc/build.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,12 @@ func walk(c *cobra.Command, parents []string, d *Dump) {
5252
// command gains both real behavior of its own AND subcommands — this
5353
// predicate must change to emit a card for that command's own behavior
5454
// while still not treating its children as absent.
55-
if !c.HasSubCommands() && c.Runnable() && !c.Hidden {
55+
//
56+
// Deprecated commands are excluded: cards guide NEW usage, and a
57+
// deprecated verb's replacement is what the card prose should teach.
58+
// The command stays in the CLI tree (with its runtime deprecation
59+
// warning) for the migration period — it just earns no card entry.
60+
if !c.HasSubCommands() && c.Runnable() && !c.Hidden && c.Deprecated == "" {
5661
d.Commands = append(d.Commands, command(c, path))
5762
}
5863

skills/flashduty/reference/monit-query.md

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Prereq: `SKILL.md` read. Datasource-side RCA: query a monitoring datasource dire
1212
|---|---|
1313
| pre-clustered RCA evidence (log patterns / metric trends) | `diagnose --operation log_patterns\|metric_trends` |
1414
| run a query and get natural structured results (frames / records / samples) | `data --expr "<query>"` |
15-
| legacy flattened rows (migration only) | `rows --expr "<query>"` |
1615

1716
## Hot flow — diagnose a noisy datasource
1817

@@ -50,27 +49,18 @@ Pre-clustered RCA findings (log_patterns or metric_trends)
5049
- `--timeout-seconds` int
5150
- response: single object (`data` unwrapped to the top level) — fields: data_handling (object); ds_name (string); ds_type (string); operation (string); query (string); results (array<object>); schema_version (string); window (object)
5251

53-
### rows
54-
Raw datasource passthrough (returns values/rows as the datasource itself would). Deprecated — prefer 'monit-query data'
55-
- `--args` stringSlice
56-
- `--ds-name` string
57-
- `--ds-type` string
58-
- `--expr` string
59-
- response: TOP-LEVEL array — pipe `--json | jq '.[]'` (NOT `.items[]`) — fields: fields (object); values (object)
60-
6152
<!-- GENERATED:monit-query END -->
6253

6354
## Key concepts
6455

65-
- **`data` = structured query.** Stable `query_result.v1` response: dispatch on `result.kind``frames` (typed tables / time series), `records` (schema-flexible rows, big ints as decimal strings), `samples` (instant samples with labels; non-finite floats as `"NaN"` / `"+Inf"` / `"-Inf"`). Prefer this over `rows`.
66-
- **`rows` = legacy raw passthrough (deprecated).** Numeric fields under `values` (metric canonical key `__value__`); labels/columns under `fields`. Only for callers that still need the flattened shape during migration. **Time belongs in the query expression**, not in flags.
56+
- **`data` = structured query.** Stable `query_result.v1` response: dispatch on `result.kind``frames` (typed tables / time series), `records` (schema-flexible rows, big ints as decimal strings), `samples` (instant samples with labels; non-finite floats as `"NaN"` / `"+Inf"` / `"-Inf"`).
6757
- **`diagnose` = pre-clustered evidence.** Its versioned response echoes the datasource, query, and RFC 3339 analysis window. Each result contains method-specific `pattern_evidence` (logs) or `series_evidence` (metrics), structured window statistics, and observations; log results also declare redaction and untrusted observed-data paths in `data_handling`. Takes `--time-start` / `--time-end` (relative like `-1h`, `now`, or unix seconds).
6858

6959
## Gotchas
7060

7161
- **Discover the datasource name first** (`monit datasource-list`). A wrong/guessed name 400s `can not find datasource` — re-list, don't retry variants.
7262
- **A 5xx or HTML-body error is TRANSIENT** — retry the same call ≤3×. Do NOT fall back to SSH, `monit-agent`, or incident search on a transient datasource error.
73-
- **`data` and `rows` have no time flags** — putting `--time-start` on them is wrong; embed the range in `--expr` (on `data`, `--delay-seconds` shifts the point-in-time lookback).
63+
- **`data` has no time flags** — putting `--time-start` on it is wrong; embed the range in `--expr` (or use `--delay-seconds` for the point-in-time lookback).
7464
- Empty results = the query genuinely matched nothing in that window — report it, don't widen blindly.
7565
- **`diagnose` rejects windows wider than 6 hours outright.** `--time-start`/`--time-end` span is capped at 6h server-side; the default window is the last 15 minutes (`--time-start 15m`, `--time-end now`). Widen within the cap, don't retry past it.
7666
- **`--ds-type` on `diagnose` only accepts `prometheus`, `victorialogs`, `loki`, `mysql`.** `monit datasource-list` can return other types (e.g. `oracle`, `postgres`, `clickhouse`, `elasticsearch`, `sls`) — those are not supported here.

skills/flashduty/reference/monit.md

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Prereq: `SKILL.md` read. **SKILL.md + this card = full competence on monitors
2828
| export / import rules (backup/migrate) | `rule-export` / `rule-import` |
2929
| what datasource types support rules | `rule-dstypes` |
3030
| per-channel / per-node / total counters | `rule-counter-channel` / `rule-counter-node` / `rule-counter-total` |
31-
| run ad-hoc PromQL / SQL / LogQL | `query-rows` |
31+
| run ad-hoc PromQL / SQL / LogQL | `monit-query data` (curated; see the monit-query card) |
3232
| log-pattern / metric-trend RCA evidence | `query-diagnose` |
3333
| list monitored hosts/targets | `targets` |
3434
| what tools a target exposes | `tools-catalog` |
@@ -43,7 +43,8 @@ fduty monit datasource-list --output-format toon
4343
fduty monit datasource-list --type prometheus --output-format toon
4444

4545
# 2a. point-in-time query (PromQL/SQL/LogQL); ALL time range goes INSIDE --expr
46-
fduty monit query-rows --ds-type prometheus --ds-name <ds-name> \
46+
# (the curated 'monit-query data' — see the monit-query card)
47+
fduty monit-query data --ds-type prometheus --ds-name <ds-name> \
4748
--expr 'rate(http_requests_total{job="api"}[5m])' --output-format toon
4849

4950
# 2b. log pattern RCA over last 15 min (time_range via --data; omit = last 15 min default)
@@ -166,16 +167,6 @@ Diagnose data source
166167
- body-only (`--data`): input (object) (required); methods (array<object>); options (object); time_range (object)
167168
- response: single object (`data` unwrapped to the top level) — fields: data_handling (object); ds_name (string); ds_type (string); operation (string); query (string); results (array<object>); schema_version (string); window (object)
168169

169-
### query-rows
170-
Query data source rows
171-
- `--account-id` int64 — Optional consistency check. Must equal the authenticated account when supplied; mismatched values are rejected. Business execution always uses the authenticated account.
172-
- `--delay-seconds` int64 — Look-back offset in seconds applied to point-in-time queries (Prometheus, Loki stats, VictoriaLogs stats). Ignored for raw / detail queries.
173-
- `--ds-name` string (required) — Data source name; must match a configured data source under the tenant.
174-
- `--ds-type` string (required) — Data source type; must match a configured data source under the tenant. Examples: 'prometheus', 'loki', 'victorialogs', 'sls', 'elasticsearch', 'mysql', 'postgres', 'oracle', 'clickhouse'.
175-
- `--expr` string (required) — Query expression. Syntax depends on 'ds_type' and is interpreted by the corresponding monit-edge client (PromQL for Prometheus, LogQL for Loki, SQL for SQL sources, etc.).
176-
- body-only (`--data`): args (object)
177-
- response: TOP-LEVEL array — pipe `--json | jq '.[]'` (NOT `.items[]`) — fields: fields (object); values (object)
178-
179170
### rule-audit-detail
180171
Get rule audit snapshot
181172
- `--id` int64 (required) — Audit record ID — the 'id' of an audit row returned by 'POST /monit/rule/audits', NOT the rule ID. Passing a rule ID returns HTTP 400.
@@ -439,7 +430,7 @@ Invoke target tools
439430

440431
- **Datasource name is not guessable.** A `can not find datasource` 400 means the name is wrong — re-run `datasource-list` and copy the exact `Name`. Never invent variants.
441432
- **`datasource-info` (and the `datasource-create`/`datasource-update` responses) return credentials exactly as configured — nothing is masked.** The `payload` object includes whatever passwords, API keys, tokens, and similar fields were set, in the clear. Treat the response as sensitive: don't dump it into logs or chat, don't echo it back beyond what the task needs, and don't pass it on to another tool.
442-
- **`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.
433+
- **`monit-query data` 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.
443434
- **`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.
444435
- **`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.
445436
- **`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.

0 commit comments

Comments
 (0)