From 97033e2325ee1c009b8c71439f88a9ef770b1a78 Mon Sep 17 00:00:00 2001 From: ysyneu Date: Fri, 3 Jul 2026 00:03:35 -0700 Subject: [PATCH] chore: sync go-flashduty sdk --- go.mod | 2 +- go.sum | 4 +- internal/cli/args.go | 34 +++ internal/cli/gen_positional_test.go | 52 ++++ internal/cli/zz_generated_a2a_agents.go | 10 +- internal/cli/zz_generated_alert_enrichment.go | 34 +-- internal/cli/zz_generated_alerts.go | 16 +- internal/cli/zz_generated_applications.go | 12 +- internal/cli/zz_generated_automations.go | 138 ++++++++++- internal/cli/zz_generated_calendars.go | 10 +- internal/cli/zz_generated_channels.go | 32 +-- internal/cli/zz_generated_incidents.go | 222 +++++++++++++++--- internal/cli/zz_generated_integrations.go | 2 +- internal/cli/zz_generated_issues.go | 4 +- internal/cli/zz_generated_manifest.go | 3 + internal/cli/zz_generated_mcp_servers.go | 10 +- internal/cli/zz_generated_members.go | 10 +- .../zz_generated_notification_templates.go | 6 +- internal/cli/zz_generated_response_help.go | 12 +- .../cli/zz_generated_roles_permissions.go | 12 +- internal/cli/zz_generated_schedules.go | 6 +- internal/cli/zz_generated_sessions.go | 4 +- internal/cli/zz_generated_skills.go | 10 +- internal/cli/zz_generated_status_pages.go | 32 +-- internal/cli/zz_generated_teams.go | 2 +- internal/cmd/cligen/main.go | 14 +- 26 files changed, 533 insertions(+), 160 deletions(-) diff --git a/go.mod b/go.mod index fb3bcf3..5062370 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/flashcatcloud/flashduty-cli go 1.25.1 require ( - github.com/flashcatcloud/go-flashduty v0.5.4 + github.com/flashcatcloud/go-flashduty v0.5.5-0.20260703065853-f90c46dd6441 github.com/mattn/go-runewidth v0.0.24 github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 diff --git a/go.sum b/go.sum index a5006eb..b701961 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/flashcatcloud/go-flashduty v0.5.4 h1:rCVaB88wrBJWYb8B63bZtjcnojiNDuH0d7GuIYnheq0= -github.com/flashcatcloud/go-flashduty v0.5.4/go.mod h1:aA0RtZEs0AYOwwdNKdtVeD8YMOdnmVY1zAlVD+9Ovx8= +github.com/flashcatcloud/go-flashduty v0.5.5-0.20260703065853-f90c46dd6441 h1:N84LGiMMOlKG3Euq0Sp9bAhWkohM0XBpe3ebjAe1+SM= +github.com/flashcatcloud/go-flashduty v0.5.5-0.20260703065853-f90c46dd6441/go.mod h1:aA0RtZEs0AYOwwdNKdtVeD8YMOdnmVY1zAlVD+9Ovx8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/ay2DU= diff --git a/internal/cli/args.go b/internal/cli/args.go index b9fd5b3..e93ddd0 100644 --- a/internal/cli/args.go +++ b/internal/cli/args.go @@ -41,6 +41,40 @@ func requireExactArg(name string) cobra.PositionalArgs { } } +// requireBodyFieldOrArgs validates a required variadic positional that folds +// into a request-body field. The same field can also come from --data or from +// its typed flag, so zero positional args are valid when either source is set. +func requireBodyFieldOrArgs(name, flagName string) cobra.PositionalArgs { + return func(cmd *cobra.Command, args []string) error { + if len(args) > 0 || bodyFieldSourceSet(cmd, flagName) { + return nil + } + return fmt.Errorf("missing %s. Usage: %s", name, cmd.UseLine()) + } +} + +// requireBodyFieldOrExactArg validates a required scalar positional that folds +// into a request-body field. The value may instead come from --data or from the +// typed flag, but extra positionals are still rejected. +func requireBodyFieldOrExactArg(name, flagName string) cobra.PositionalArgs { + return func(cmd *cobra.Command, args []string) error { + switch { + case len(args) == 1: + return nil + case len(args) > 1: + return fmt.Errorf("expects exactly one %s. Usage: %s", name, cmd.UseLine()) + case bodyFieldSourceSet(cmd, flagName): + return nil + default: + return fmt.Errorf("missing %s. Usage: %s", name, cmd.UseLine()) + } + } +} + +func bodyFieldSourceSet(cmd *cobra.Command, flagName string) bool { + return cmd.Flags().Changed("data") || cmd.Flags().Changed(flagName) +} + // optionalArg returns a positional argument validator that accepts zero or one // argument named name. It backs generated commands whose positional folds into // an OPTIONAL body field because the operation also accepts an alternative diff --git a/internal/cli/gen_positional_test.go b/internal/cli/gen_positional_test.go index fb6ca3d..5dca1ec 100644 --- a/internal/cli/gen_positional_test.go +++ b/internal/cli/gen_positional_test.go @@ -164,6 +164,58 @@ func TestGenPositionalFlagOverridesPositional(t *testing.T) { } } +func TestGenPositionalRequiredFieldCanComeFromDataOrFlag(t *testing.T) { + saveAndResetGlobals(t) + stub := newGFStub(t) + + if _, err := execCommand("safari", "automation-rule-run", "--data", `{"rule_id":"auto_1"}`); err != nil { + t.Fatalf("automation-rule-run --data: %v", err) + } + if stub.lastPath != "/safari/automation/rule/run" { + t.Fatalf("path = %q, want /safari/automation/rule/run", stub.lastPath) + } + if got := stub.lastBody["rule_id"]; got != "auto_1" { + t.Errorf("rule_id from --data = %#v, want auto_1", got) + } + + if _, err := execCommand("safari", "automation-rule-run", "--rule-id", "auto_2"); err != nil { + t.Fatalf("automation-rule-run --rule-id: %v", err) + } + if got := stub.lastBody["rule_id"]; got != "auto_2" { + t.Errorf("rule_id from --rule-id = %#v, want auto_2", got) + } + + if _, err := execCommand("incident-trigger-subscription", "upsert", "--data", `{"channel_ids":[2468013579],"consumer":"fc_safari","consumer_ref":"auto_1","severities":["Critical"],"source":"ai_sre_automation"}`); err != nil { + t.Fatalf("incident-trigger-subscription upsert --data: %v", err) + } + if stub.lastPath != "/incident-trigger-subscription/upsert" { + t.Fatalf("path = %q, want /incident-trigger-subscription/upsert", stub.lastPath) + } + raw, ok := stub.lastBody["channel_ids"].([]any) + if !ok || len(raw) != 1 || raw[0] != float64(2468013579) { + t.Errorf("channel_ids from --data = %#v, want [2468013579]", stub.lastBody["channel_ids"]) + } + + if _, err := execCommand("incident-trigger-subscription", "upsert", "--channel-ids", "2468013580", "--consumer", "fc_safari", "--consumer-ref", "auto_2", "--severities", "Warning", "--source", "ai_sre_automation"); err != nil { + t.Fatalf("incident-trigger-subscription upsert --channel-ids: %v", err) + } + raw, ok = stub.lastBody["channel_ids"].([]any) + if !ok || len(raw) != 1 || raw[0] != float64(2468013580) { + t.Errorf("channel_ids from --channel-ids = %#v, want [2468013580]", stub.lastBody["channel_ids"]) + } + + if _, err := execCommand("incident-trigger-subscription", "upsert", "--channel-ids", "2468013581", "--consumer", "fc_safari", "--consumer-ref", "auto_3", "--severities", "Warning", "--source", "ai_sre_automation", "--enabled=false"); err != nil { + t.Fatalf("incident-trigger-subscription upsert --enabled=false: %v", err) + } + if got, ok := stub.lastBody["enabled"].(bool); !ok || got { + t.Errorf("enabled = %#v, want explicit false", stub.lastBody["enabled"]) + } + + if _, err := execCommand("safari", "automation-rule-run"); err == nil || !strings.Contains(err.Error(), "missing rule_id") { + t.Fatalf("automation-rule-run without arg/data/flag error = %v, want missing rule_id", err) + } +} + // TestGenFoldPositional unit-tests the runtime helper across all three kinds. func TestGenFoldPositional(t *testing.T) { // string scalar → args[0] diff --git a/internal/cli/zz_generated_a2a_agents.go b/internal/cli/zz_generated_a2a_agents.go index 6667e48..0a6e25b 100644 --- a/internal/cli/zz_generated_a2a_agents.go +++ b/internal/cli/zz_generated_a2a_agents.go @@ -46,7 +46,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - team_id (integer) (required) — Team scope: 0 = account-wide; >0 = the owning team. - updated_at (integer) (required) — Last update time. Unix timestamp in milliseconds. `, - Args: requireExactArg("agent_id"), + Args: requireBodyFieldOrExactArg("agent_id", "agent-id"), Example: ` flashduty safari a2a-agent-get --data '{"agent_id":"a2a_6mWqZ2pK9nLcR3tY8uVb4D"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -277,7 +277,7 @@ API: POST /safari/a2a-agent/delete (remote-agent-write-delete) Request fields: --agent-id string (required) — Target agent ID. `, - Args: requireExactArg("agent_id"), + Args: requireBodyFieldOrExactArg("agent_id", "agent-id"), Example: ` flashduty safari a2a-agent-delete --data '{"agent_id":"a2a_6mWqZ2pK9nLcR3tY8uVb4D"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -325,7 +325,7 @@ API: POST /safari/a2a-agent/disable (remote-agent-write-disable) Request fields: --agent-id string (required) — Target agent ID. `, - Args: requireExactArg("agent_id"), + Args: requireBodyFieldOrExactArg("agent_id", "agent-id"), Example: ` flashduty safari a2a-agent-disable --data '{"agent_id":"a2a_6mWqZ2pK9nLcR3tY8uVb4D"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -373,7 +373,7 @@ API: POST /safari/a2a-agent/enable (remote-agent-write-enable) Request fields: --agent-id string (required) — Target agent ID. `, - Args: requireExactArg("agent_id"), + Args: requireBodyFieldOrExactArg("agent_id", "agent-id"), Example: ` flashduty safari a2a-agent-enable --data '{"agent_id":"a2a_6mWqZ2pK9nLcR3tY8uVb4D"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -440,7 +440,7 @@ Request fields: --team-id int — Reassign team scope. Omit to leave unchanged. auth_config (object, via --data) — Replace the auth config. Omit to leave unchanged. `, - Args: requireExactArg("agent_id"), + Args: requireBodyFieldOrExactArg("agent_id", "agent-id"), Example: ` flashduty safari a2a-agent-update --data '{"agent_id":"a2a_6mWqZ2pK9nLcR3tY8uVb4D","description":"Inspects deployment pipelines and proposes rollbacks."}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_alert_enrichment.go b/internal/cli/zz_generated_alert_enrichment.go index 4e2ca6e..80fdc77 100644 --- a/internal/cli/zz_generated_alert_enrichment.go +++ b/internal/cli/zz_generated_alert_enrichment.go @@ -38,7 +38,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) (required) — Last update timestamp, Unix seconds. - updated_by (integer) (required) — Last updater member ID. `, - Args: requireExactArg("integration_id"), + Args: requireBodyFieldOrExactArg("integration_id", "integration-id"), Example: ` flashduty enrichment info --data '{"integration_id":5001}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -102,7 +102,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) (required) — Last update timestamp, Unix seconds. - updated_by (integer) (required) — Last updater member ID. `, - Args: requireArgs("integration_ids"), + Args: requireBodyFieldOrArgs("integration_ids", "integration-ids"), Example: ` flashduty enrichment list --data '{"integration_ids":[5001,5002]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -157,7 +157,7 @@ Request fields: - kind (string) (required) — Rule type. 'extraction' extracts a label via regex or GJson. 'composition' builds a label from a template. 'mapping' looks up values from a schema or API. 'drop' removes labels. [extraction, composition, mapping, drop] - settings (any) (required) — Rule-kind–specific settings. The shape depends on 'kind'. `, - Args: requireExactArg("integration_id"), + Args: requireBodyFieldOrExactArg("integration_id", "integration-id"), Example: ` flashduty enrichment upsert --data '{"integration_id":5001,"rules":[{"kind":"extraction","settings":{"override":true,"pattern":"(?P\u003cresult\u003eprod|staging|dev)","result_label":"environment","source_field":"labels.env"}},{"kind":"composition","settings":{"override":false,"result_label":"full_env","template":"{{.labels.region}}-{{.labels.environment}}"}}]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -226,7 +226,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_by (integer) (required) — Last updater member ID. - value_type (string) (required) — Stored value type. 'checkbox' is always 'bool'; 'single_select'/'multi_select'/'text' are always 'string'. [string, bool, float] `, - Args: requireExactArg("field_id"), + Args: requireBodyFieldOrExactArg("field_id", "field-id"), Example: ` flashduty field info --data '{"field_id":"66e9d3a4f7c2b04a1c8a91b3"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -433,7 +433,7 @@ API: POST /field/delete (field-write-delete) Request fields: --field-id string (required) — Field ID — 24-character hex ObjectID. `, - Args: requireExactArg("field_id"), + Args: requireBodyFieldOrExactArg("field_id", "field-id"), Example: ` flashduty field delete --data '{"field_id":"66e9d3a4f7c2b04a1c8a91b3"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -492,7 +492,7 @@ Request fields: --options []string — Replacement options list. Must obey the same per-type rules as create. default_value (any, via --data) — Replacement default value. Type must match the field's existing 'field_type'. `, - Args: requireExactArg("field_id"), + Args: requireBodyFieldOrExactArg("field_id", "field-id"), Example: ` flashduty field update --data '{"default_value":"Medium","description":"Business severity tier.","display_name":"Severity Class","field_id":"66e9d3a4f7c2b04a1c8a91b3","options":["Critical","High","Medium","Low"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -572,7 +572,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_by (integer) (required) — Last updater member ID. - url (string) (required) — Endpoint URL. `, - Args: requireExactArg("api_id"), + Args: requireBodyFieldOrExactArg("api_id", "api-id"), Example: ` flashduty enrichment mapping-api-info --data '{"api_id":"665f1a2b3c4d5e6f7a8b9c02"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -756,7 +756,7 @@ API: POST /enrichment/mapping/api/delete (mapping-api-write-delete) Request fields: --api-id string (required) — Mapping API ID (MongoDB ObjectID hex). `, - Args: requireExactArg("api_id"), + Args: requireBodyFieldOrExactArg("api_id", "api-id"), Example: ` flashduty enrichment mapping-api-delete --data '{"api_id":"665f1a2b3c4d5e6f7a8b9c02"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -823,7 +823,7 @@ Request fields: --url string — New endpoint URL (max 500 chars). (≤500 chars) headers (object, via --data) — New headers map (replaces existing). `, - Args: requireExactArg("api_id"), + Args: requireBodyFieldOrExactArg("api_id", "api-id"), Example: ` flashduty enrichment mapping-api-update --data '{"api_id":"665f1a2b3c4d5e6f7a8b9c02","retry_count":1,"timeout":3}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -903,7 +903,7 @@ API: POST /enrichment/mapping/data/download (mapping-data-read-download) Request fields: --schema-id string (required) — Mapping schema ID (MongoDB ObjectID hex). `, - Args: requireExactArg("schema_id"), + Args: requireBodyFieldOrExactArg("schema_id", "schema-id"), Example: ` flashduty enrichment mapping-data-download --data '{"schema_id":"665f1a2b3c4d5e6f7a8b9c01"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -972,7 +972,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - search_after_ctx (string) — Cursor token for the next page. - total (integer) (required) — Total matching rows. `, - Args: requireExactArg("schema_id"), + Args: requireBodyFieldOrExactArg("schema_id", "schema-id"), Example: ` flashduty enrichment mapping-data-list --data '{"asc":false,"limit":20,"orderby":"updated_at","p":1,"schema_id":"665f1a2b3c4d5e6f7a8b9c01"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1042,7 +1042,7 @@ Request fields: --keys []string (required) — Keys of rows to delete. --schema-id string (required) — Mapping schema ID (MongoDB ObjectID hex). `, - Args: requireExactArg("schema_id"), + Args: requireBodyFieldOrExactArg("schema_id", "schema-id"), Example: ` flashduty enrichment mapping-data-delete --data '{"keys":["server01","server02"],"schema_id":"665f1a2b3c4d5e6f7a8b9c01"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1098,7 +1098,7 @@ API: POST /enrichment/mapping/data/truncate (mapping-data-write-truncate) Request fields: --schema-id string (required) — Mapping schema ID (MongoDB ObjectID hex). `, - Args: requireExactArg("schema_id"), + Args: requireBodyFieldOrExactArg("schema_id", "schema-id"), Example: ` flashduty enrichment mapping-data-truncate --data '{"schema_id":"665f1a2b3c4d5e6f7a8b9c01"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1208,7 +1208,7 @@ Request fields: Response fields ('data' envelope is unwrapped — these fields are at the top level): - keys (array) (required) — Composite keys of upserted rows. `, - Args: requireExactArg("schema_id"), + Args: requireBodyFieldOrExactArg("schema_id", "schema-id"), Example: ` flashduty enrichment mapping-data-upsert --data '{"docs":[{"host":"server01","owner":"alice","service":"api","team":"sre"},{"host":"server02","owner":"bob","service":"gateway","team":"platform"}],"schema_id":"665f1a2b3c4d5e6f7a8b9c01"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1269,7 +1269,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) — Last update timestamp, Unix seconds. - updated_by (integer) (required) — Last updater member ID. `, - Args: requireExactArg("schema_id"), + Args: requireBodyFieldOrExactArg("schema_id", "schema-id"), Example: ` flashduty enrichment mapping-schema-info --data '{"schema_id":"665f1a2b3c4d5e6f7a8b9c01"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1437,7 +1437,7 @@ API: POST /enrichment/mapping/schema/delete (mapping-schema-write-delete) Request fields: --schema-id string (required) — Mapping schema ID (MongoDB ObjectID hex). `, - Args: requireExactArg("schema_id"), + Args: requireBodyFieldOrExactArg("schema_id", "schema-id"), Example: ` flashduty enrichment mapping-schema-delete --data '{"schema_id":"665f1a2b3c4d5e6f7a8b9c01"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1495,7 +1495,7 @@ Request fields: --schema-name string — New schema name (max 39 chars). (≤39 chars) --team-id int — New owning team ID. '0' removes the team association. `, - Args: requireExactArg("schema_id"), + Args: requireBodyFieldOrExactArg("schema_id", "schema-id"), Example: ` flashduty enrichment mapping-schema-update --data '{"description":"Updated description","schema_id":"665f1a2b3c4d5e6f7a8b9c01","schema_name":"CMDB Lookup v2"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_alerts.go b/internal/cli/zz_generated_alerts.go index a7592b9..249c57d 100644 --- a/internal/cli/zz_generated_alerts.go +++ b/internal/cli/zz_generated_alerts.go @@ -199,7 +199,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - search_after_ctx (string) — Cursor to pass as 'search_after_ctx' for the next page. - total (integer) (required) — Total matching event count. `, - Args: requireExactArg("alert_id"), + Args: requireBodyFieldOrExactArg("alert_id", "alert-id"), Example: ` flashduty alert event-list --data '{"alert_id":"663a1b2c3d4e5f6789abcdef","limit":20}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -284,7 +284,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - type (string) (required) — Alert activity feed entry type. Each value identifies one alert lifecycle event; the matching 'detail' payload shape is determined by this field. | Type | Meaning | |---|---| | 'a_new' | Alert triggered. | | 'a_comm' | Comment added on the alert. | | 'a_close' | Alert closed. | [a_new, a_comm, a_close] - updated_at (integer) (required) — Last update timestamp in Unix epoch milliseconds. `, - Args: requireExactArg("alert_id"), + Args: requireBodyFieldOrExactArg("alert_id", "alert-id"), Example: ` flashduty alert feed --data '{"alert_id":"663a1b2c3d4e5f6789abcdef","asc":false,"limit":20}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -414,7 +414,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - title_rule (string) — Title template used to derive 'title' from the event labels (e.g. '$service::$cluster'). - updated_at (integer) — Last update timestamp, Unix epoch seconds. `, - Args: requireExactArg("alert_id"), + Args: requireBodyFieldOrExactArg("alert_id", "alert-id"), Example: ` flashduty alert info --data '{"alert_id":"663a1b2c3d4e5f6789abcdef"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -730,7 +730,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - search_after_ctx (string) — Cursor for the next page. - total (integer) — Total matching alerts. `, - Args: requireArgs("alert_ids"), + Args: requireBodyFieldOrArgs("alert_ids", "alert-ids"), Example: ` flashduty alert list-by-ids --data '{"alert_ids":["663a1b2c3d4e5f6789abcdef"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -790,7 +790,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) — Last update timestamp, Unix epoch seconds. - updated_by (integer) — Member ID who last updated the pipeline. `, - Args: requireExactArg("integration_id"), + Args: requireBodyFieldOrExactArg("integration_id", "integration-id"), Example: ` flashduty alert pipeline-info --data '{"integration_id":10001}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -851,7 +851,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) — Last update timestamp, Unix epoch seconds. - updated_by (integer) — Member ID who last updated the pipeline. `, - Args: requireArgs("integration_ids"), + Args: requireBodyFieldOrArgs("integration_ids", "integration-ids"), Example: ` flashduty alert pipeline-list --data '{"integration_ids":[10001,10002]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -907,7 +907,7 @@ Request fields: --owner-id int — Optional new owner for the target incident. --title string — Optional new title for the target incident. `, - Args: requireArgs("alert_ids"), + Args: requireBodyFieldOrArgs("alert_ids", "alert-ids"), Example: ` flashduty alert merge --data '{"alert_ids":["663a1b2c3d4e5f6789abcdef"],"incident_id":"663a000000000000deadbeef"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -979,7 +979,7 @@ Request fields: - kind (string) — Rule type. [title_reset, description_reset, severity_reset, alert_drop, alert_inhibit] - settings (object) — Kind-specific settings. Shape depends on 'kind': - 'title_reset': '{ "title": "" }' - 'description_reset': '{ "description": "" }' - 'severity_reset': '{ "severity": "Critical"|"Warning"|"Info" }' - 'alert_drop': '{}' (empty object) - 'alert_inhibit': '{ "equals": ["", ...], "source_filters": }' `, - Args: requireExactArg("integration_id"), + Args: requireBodyFieldOrExactArg("integration_id", "integration-id"), Example: ` flashduty alert pipeline-upsert --data '{"integration_id":10001,"rules":[{"if":null,"kind":"severity_reset","settings":{"severity":"Warning"}}]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_applications.go b/internal/cli/zz_generated_applications.go index 316e734..55aaf7f 100644 --- a/internal/cli/zz_generated_applications.go +++ b/internal/cli/zz_generated_applications.go @@ -50,7 +50,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) — Last update timestamp, Unix epoch seconds. - updated_by (integer) — Last updater member ID. `, - Args: requireExactArg("application_id"), + Args: requireBodyFieldOrExactArg("application_id", "application-id"), Example: ` flashduty rum application-info --data '{"application_id":"WoyQQ3BohkdtPivubEvE8o"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -126,7 +126,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) — Last update timestamp, Unix epoch seconds. - updated_by (integer) — Last updater member ID. `, - Args: requireArgs("application_ids"), + Args: requireBodyFieldOrArgs("application_ids", "application-ids"), Example: ` flashduty rum application-infos --data '{"application_ids":["eWbr4xk3ZRnLabRa6unqwD","WoyQQ3BohkdtPivubEvE8o"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -297,7 +297,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - ok (boolean) (required) — Whether the webhook endpoint accepted the sample event. - status_code (integer) (required) — HTTP status code returned by the webhook endpoint. 0 when the request did not receive a response. `, - Args: requireExactArg("application_id"), + Args: requireBodyFieldOrExactArg("application_id", "application-id"), Example: ` flashduty rum application-webhook-test --data '{"application_id":"rum-app-prod","webhook_url":"https://hooks.example.com/rum-alerts"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -375,7 +375,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - application_name (string) — Application display name. - client_token (string) — Token for RUM SDK initialization. `, - Args: requireExactArg("team_id"), + Args: requireBodyFieldOrExactArg("team_id", "team-id"), Example: ` flashduty rum application-create --data '{"application_name":"My Web App","is_private":false,"links":{"enabled":true,"systems":[{"enabled":true,"event_types":["crash","error"],"icon_color":"#0F766E","icon_text":"S3","id":"s3-crash-logs","name":"S3 Crash Logs","url":"https://s3.example.com/logs?app=${application_id}\u0026trace=${trace_id}"}]},"team_id":2477033058131,"type":"browser"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -443,7 +443,7 @@ API: POST /rum/application/delete (rum-application-write-delete) Request fields: --application-id string (required) — RUM application ID. `, - Args: requireExactArg("application_id"), + Args: requireBodyFieldOrExactArg("application_id", "application-id"), Example: ` flashduty rum application-delete --data '{"application_id":"qLpu24Dz4CAzWsESPbJYWA"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -518,7 +518,7 @@ Request fields: - endpoint (string) — Trace endpoint URL (http or https). - open_type (string) — How to open the trace link. [popup, tab] `, - Args: requireExactArg("application_id"), + Args: requireBodyFieldOrExactArg("application_id", "application-id"), Example: ` flashduty rum application-update --data '{"alerting":{"channel_ids":[2490121812131],"enabled":true},"application_id":"WoyQQ3BohkdtPivubEvE8o","application_name":"My Web App v2","links":{"enabled":true,"systems":[{"enabled":true,"event_types":["crash","error"],"icon_color":"#0F766E","icon_text":"S3","id":"s3-crash-logs","name":"S3 Crash Logs","url":"https://s3.example.com/logs?app=${application_id}\u0026trace=${trace_id}"}]}}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_automations.go b/internal/cli/zz_generated_automations.go index e034343..39432b2 100644 --- a/internal/cli/zz_generated_automations.go +++ b/internal/cli/zz_generated_automations.go @@ -36,16 +36,21 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - http_post_trigger_id (string) — HTTP POST trigger ID. - http_post_trigger_url (string) — HTTP POST trigger path. - name (string) (required) — Rule name. + - oncall_incident_channel_ids (array) — On-call channel IDs watched by the incident trigger. + - oncall_incident_severities (array) — Incident severities watched by the trigger. [Critical, Warning, Info] + - oncall_incident_trigger_enabled (boolean) (required) — Whether the on-call incident trigger is enabled. + - oncall_incident_trigger_id (string) — On-call incident trigger ID. - owner_id (integer) (required) — Creator person ID. - prompt (string) (required) — Task prompt. - rule_id (string) (required) — Rule ID. - run_scope (string) (required) — Hidden session run scope. [person, team] + - schedule_next_fire_at_ms (integer) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available. - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled. - schedule_trigger_id (string) — Schedule trigger ID. - team_id (integer) (required) — Scope team ID; 0 means personal rule. - updated_at (integer) (required) — Last update time, Unix milliseconds. `, - Args: requireExactArg("rule_id"), + Args: requireBodyFieldOrExactArg("rule_id", "rule-id"), Example: ` flashduty safari automation-rule-get --data '{"rule_id":"auto_7NnLzY2Qp8xS4kUaV3mR6b"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -121,10 +126,15 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - http_post_trigger_id (string) — HTTP POST trigger ID. - http_post_trigger_url (string) — HTTP POST trigger path. - name (string) (required) — Rule name. + - oncall_incident_channel_ids (array) — On-call channel IDs watched by the incident trigger. + - oncall_incident_severities (array) — Incident severities watched by the trigger. [Critical, Warning, Info] + - oncall_incident_trigger_enabled (boolean) (required) — Whether the on-call incident trigger is enabled. + - oncall_incident_trigger_id (string) — On-call incident trigger ID. - owner_id (integer) (required) — Creator person ID. - prompt (string) (required) — Task prompt. - rule_id (string) (required) — Rule ID. - run_scope (string) (required) — Hidden session run scope. [person, team] + - schedule_next_fire_at_ms (integer) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available. - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled. - schedule_trigger_id (string) — Schedule trigger ID. - team_id (integer) (required) — Scope team ID; 0 means personal rule. @@ -196,6 +206,9 @@ func genAutomationsRuleWriteCreateCmd() *cobra.Command { var fEnvironmentKind string var fHTTPPostTriggerEnabled bool var fName string + var fOncallIncidentChannelIDs []int + var fOncallIncidentSeverities []string + var fOncallIncidentTriggerEnabled bool var fPrompt string var fScheduleTriggerEnabled bool var fTeamID int64 @@ -215,6 +228,9 @@ Request fields: --environment-kind string — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc] --http-post-trigger-enabled bool — Whether to create and enable an HTTP POST trigger. When enabled, the response includes a one-time token. --name string (required) — Rule name. (1-255 chars) + --oncall-incident-channel-ids []int — On-call channel IDs whose new incidents can trigger this rule. + --oncall-incident-severities []string — Incident severities that can trigger this rule. [Critical, Warning, Info] + --oncall-incident-trigger-enabled bool — Whether to create and enable an on-call incident trigger for this rule. --prompt string (required) — Task prompt sent to the AI SRE agent on each run. (≥1 chars) --schedule-trigger-enabled bool — Whether the schedule trigger is enabled. Defaults to true when omitted; HTTP-POST-only rules should send false. --team-id int — Scope team ID. 0 or omitted means a personal rule; >0 means a team in the account. Immutable after creation. (min 0) @@ -232,16 +248,21 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - http_post_trigger_id (string) — HTTP POST trigger ID. - http_post_trigger_url (string) — HTTP POST trigger path. - name (string) (required) — Rule name. + - oncall_incident_channel_ids (array) — On-call channel IDs watched by the incident trigger. + - oncall_incident_severities (array) — Incident severities watched by the trigger. [Critical, Warning, Info] + - oncall_incident_trigger_enabled (boolean) (required) — Whether the on-call incident trigger is enabled. + - oncall_incident_trigger_id (string) — On-call incident trigger ID. - owner_id (integer) (required) — Creator person ID. - prompt (string) (required) — Task prompt. - rule_id (string) (required) — Rule ID. - run_scope (string) (required) — Hidden session run scope. [person, team] + - schedule_next_fire_at_ms (integer) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available. - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled. - schedule_trigger_id (string) — Schedule trigger ID. - team_id (integer) (required) — Scope team ID; 0 means personal rule. - updated_at (integer) (required) — Last update time, Unix milliseconds. `, - Example: ` flashduty safari automation-rule-create --data '{"cron_expr":"0 9 * * 1","enabled":true,"http_post_trigger_enabled":true,"name":"Weekly on-call review","prompt":"Summarize last week'\''s alert noise and escalation load.","schedule_trigger_enabled":true,"team_id":123}'`, + Example: ` flashduty safari automation-rule-create --data '{"cron_expr":"0 9 * * 1","enabled":true,"http_post_trigger_enabled":true,"name":"Weekly on-call review","oncall_incident_channel_ids":[2468013579],"oncall_incident_severities":["Critical","Warning"],"oncall_incident_trigger_enabled":true,"prompt":"Summarize last week'\''s alert noise and escalation load.","schedule_trigger_enabled":true,"team_id":123}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -263,6 +284,15 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le if cmd.Flags().Changed("name") { body["name"] = fName } + if cmd.Flags().Changed("oncall-incident-channel-ids") { + body["oncall_incident_channel_ids"] = fOncallIncidentChannelIDs + } + if cmd.Flags().Changed("oncall-incident-severities") { + body["oncall_incident_severities"] = fOncallIncidentSeverities + } + if cmd.Flags().Changed("oncall-incident-trigger-enabled") { + body["oncall_incident_trigger_enabled"] = fOncallIncidentTriggerEnabled + } if cmd.Flags().Changed("prompt") { body["prompt"] = fPrompt } @@ -295,6 +325,9 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le cmd.Flags().StringVar(&fEnvironmentKind, "environment-kind", "", "Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]") cmd.Flags().BoolVar(&fHTTPPostTriggerEnabled, "http-post-trigger-enabled", false, "Whether to create and enable an HTTP POST trigger. When enabled, the response includes a one-time token.") cmd.Flags().StringVar(&fName, "name", "", "Rule name. (required) (1-255 chars)") + cmd.Flags().IntSliceVar(&fOncallIncidentChannelIDs, "oncall-incident-channel-ids", nil, "On-call channel IDs whose new incidents can trigger this rule.") + cmd.Flags().StringSliceVar(&fOncallIncidentSeverities, "oncall-incident-severities", nil, "Incident severities that can trigger this rule. [Critical, Warning, Info]") + cmd.Flags().BoolVar(&fOncallIncidentTriggerEnabled, "oncall-incident-trigger-enabled", false, "Whether to create and enable an on-call incident trigger for this rule.") cmd.Flags().StringVar(&fPrompt, "prompt", "", "Task prompt sent to the AI SRE agent on each run. (required) (≥1 chars)") cmd.Flags().BoolVar(&fScheduleTriggerEnabled, "schedule-trigger-enabled", false, "Whether the schedule trigger is enabled. Defaults to true when omitted; HTTP-POST-only rules should send false.") cmd.Flags().Int64Var(&fTeamID, "team-id", 0, "Scope team ID. 0 or omitted means a personal rule; >0 means a team in the account. Immutable after creation. (min 0)") @@ -317,7 +350,7 @@ API: POST /safari/automation/rule/delete (automation-rule-write-delete) Request fields: --rule-id string (required) — Rule ID. `, - Args: requireExactArg("rule_id"), + Args: requireBodyFieldOrExactArg("rule_id", "rule-id"), Example: ` flashduty safari automation-rule-delete --data '{"rule_id":"auto_7NnLzY2Qp8xS4kUaV3mR6b"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -350,6 +383,69 @@ Request fields: return cmd } +func genAutomationsRuleWriteRunCmd() *cobra.Command { + var dataJSON string + var fRuleID string + cmd := &cobra.Command{ + Use: "automation-rule-run ", + Short: "Run Automation rule now", + Long: `Run Automation rule now. + +Start a manual run for an Automation rule. + +API: POST /safari/automation/rule/run (automation-rule-write-run) + +Request fields: + --rule-id string (required) — Rule ID. + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - preflight (object) (required) + - app_name (string) (required) — AI SRE app used to execute the rule. + - checks (array) (required) — Preflight checks that were evaluated. + - ok (boolean) (required) — Whether the rule can start a run. + - owner_id (integer) (required) — Owner person ID used for the run context. + - scope (string) (required) — Hidden session scope used for the run. [person, team] + - team_id (integer) (required) — Team ID used for team-scoped runs; 0 for personal runs. + - warnings (array) — Non-blocking preflight warnings. + - rule_id (string) (required) — Rule ID. + - run (object) + - run_id (string) (required) — Created automation run ID. + - session_id (string) — Hidden AI SRE session ID started for this run. + - trigger_kind (string) (required) — Trigger kind for this run. [manual] +`, + Args: requireBodyFieldOrExactArg("rule_id", "rule-id"), + Example: ` flashduty safari automation-rule-run --data '{"rule_id":"auto_7NnLzY2Qp8xS4kUaV3mR6b"}'`, + RunE: func(cmd *cobra.Command, args []string) error { + return runCommand(cmd, args, func(ctx *RunContext) error { + body, err := genAssembleBody(dataJSON, func(body map[string]any) error { + if err := genFoldPositional(args, body, "rule_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("rule-id") { + body["rule_id"] = fRuleID + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.AutomationRuleIDRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Automations.RuleWriteRun(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fRuleID, "rule-id", "", "Rule ID. (required)") + cmd.Flags().StringVar(&dataJSON, "data", "", "Full request body as JSON; positional arguments and typed flags override its fields. Accepts inline JSON, or - to read stdin.") + return cmd +} + func genAutomationsRuleWriteUpdateCmd() *cobra.Command { var dataJSON string var fRuleID string @@ -363,6 +459,9 @@ func genAutomationsRuleWriteUpdateCmd() *cobra.Command { var fEnvironmentID string var fHTTPPostTriggerEnabled bool var fRotateHTTPPostTriggerToken bool + var fOncallIncidentTriggerEnabled bool + var fOncallIncidentChannelIDs []int + var fOncallIncidentSeverities []string cmd := &cobra.Command{ Use: "automation-rule-update ", Short: "Update Automation rule", @@ -384,6 +483,9 @@ Request fields: --environment-id string — BYOC Runner ID. --http-post-trigger-enabled bool — Whether the HTTP POST trigger is enabled. Sending true creates one when missing. --rotate-http-post-trigger-token bool — Whether to rotate the HTTP POST trigger token. The new token is returned only in this response. + --oncall-incident-trigger-enabled bool — Whether the on-call incident trigger is enabled. Sending true creates it when missing and channel/severity filters are provided. + --oncall-incident-channel-ids []int — On-call channel IDs whose new incidents can trigger this rule. + --oncall-incident-severities []string — Incident severities that can trigger this rule. [Critical, Warning, Info] Response fields ('data' envelope is unwrapped — these fields are at the top level): - account_id (integer) (required) — Account ID. @@ -398,17 +500,22 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - http_post_trigger_id (string) — HTTP POST trigger ID. - http_post_trigger_url (string) — HTTP POST trigger path. - name (string) (required) — Rule name. + - oncall_incident_channel_ids (array) — On-call channel IDs watched by the incident trigger. + - oncall_incident_severities (array) — Incident severities watched by the trigger. [Critical, Warning, Info] + - oncall_incident_trigger_enabled (boolean) (required) — Whether the on-call incident trigger is enabled. + - oncall_incident_trigger_id (string) — On-call incident trigger ID. - owner_id (integer) (required) — Creator person ID. - prompt (string) (required) — Task prompt. - rule_id (string) (required) — Rule ID. - run_scope (string) (required) — Hidden session run scope. [person, team] + - schedule_next_fire_at_ms (integer) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available. - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled. - schedule_trigger_id (string) — Schedule trigger ID. - team_id (integer) (required) — Scope team ID; 0 means personal rule. - updated_at (integer) (required) — Last update time, Unix milliseconds. `, - Args: requireExactArg("rule_id"), - Example: ` flashduty safari automation-rule-update --data '{"cron_expr":"15 9 * * 1","enabled":true,"rotate_http_post_trigger_token":true,"rule_id":"auto_7NnLzY2Qp8xS4kUaV3mR6b"}'`, + Args: requireBodyFieldOrExactArg("rule_id", "rule-id"), + Example: ` flashduty safari automation-rule-update --data '{"cron_expr":"15 9 * * 1","enabled":true,"oncall_incident_severities":["Critical"],"oncall_incident_trigger_enabled":true,"rotate_http_post_trigger_token":true,"rule_id":"auto_7NnLzY2Qp8xS4kUaV3mR6b"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -448,6 +555,15 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le if cmd.Flags().Changed("rotate-http-post-trigger-token") { body["rotate_http_post_trigger_token"] = fRotateHTTPPostTriggerToken } + if cmd.Flags().Changed("oncall-incident-trigger-enabled") { + body["oncall_incident_trigger_enabled"] = fOncallIncidentTriggerEnabled + } + if cmd.Flags().Changed("oncall-incident-channel-ids") { + body["oncall_incident_channel_ids"] = fOncallIncidentChannelIDs + } + if cmd.Flags().Changed("oncall-incident-severities") { + body["oncall_incident_severities"] = fOncallIncidentSeverities + } return nil }) if err != nil { @@ -476,6 +592,9 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le cmd.Flags().StringVar(&fEnvironmentID, "environment-id", "", "BYOC Runner ID.") cmd.Flags().BoolVar(&fHTTPPostTriggerEnabled, "http-post-trigger-enabled", false, "Whether the HTTP POST trigger is enabled. Sending true creates one when missing.") cmd.Flags().BoolVar(&fRotateHTTPPostTriggerToken, "rotate-http-post-trigger-token", false, "Whether to rotate the HTTP POST trigger token. The new token is returned only in this response.") + cmd.Flags().BoolVar(&fOncallIncidentTriggerEnabled, "oncall-incident-trigger-enabled", false, "Whether the on-call incident trigger is enabled. Sending true creates it when missing and channel/severity filters are provided.") + cmd.Flags().IntSliceVar(&fOncallIncidentChannelIDs, "oncall-incident-channel-ids", nil, "On-call channel IDs whose new incidents can trigger this rule.") + cmd.Flags().StringSliceVar(&fOncallIncidentSeverities, "oncall-incident-severities", nil, "Incident severities that can trigger this rule. [Critical, Warning, Info]") cmd.Flags().StringVar(&dataJSON, "data", "", "Full request body as JSON; positional arguments and typed flags override its fields. Accepts inline JSON, or - to read stdin.") return cmd } @@ -507,7 +626,7 @@ Request fields: --started-after-ms int — Start-time lower bound, Unix milliseconds. --started-before-ms int — Start-time upper bound, Unix milliseconds. --status string — Run status filter. [queued, running, retrying, succeeded, partial, failed, skipped, abandoned] - --trigger-kind string — Trigger kind filter. [schedule, debug, http_post] + --trigger-kind string — Trigger kind filter. [schedule, debug, manual, http_post, oncall_incident] Response fields ('data' envelope is unwrapped — these fields are at the top level): - runs (array) (required) @@ -526,11 +645,11 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - started_at (integer) (required) — Start time, Unix milliseconds. - stats_json (any) — Run stats JSON. - status (string) (required) — Run status. [queued, running, retrying, succeeded, partial, failed, skipped, abandoned] - - trigger_kind (string) (required) — Trigger kind. [schedule, debug, http_post] + - trigger_kind (string) (required) — Trigger kind. [schedule, debug, manual, http_post, oncall_incident] - updated_at (integer) (required) — Last update time, Unix milliseconds. - total (integer) (required) — Total count. `, - Args: requireExactArg("rule_id"), + Args: requireBodyFieldOrExactArg("rule_id", "rule-id"), Example: ` flashduty safari automation-run-list --data '{"limit":20,"rule_id":"auto_7NnLzY2Qp8xS4kUaV3mR6b","trigger_kind":"schedule"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -586,7 +705,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le cmd.Flags().Int64Var(&fStartedAfterMs, "started-after-ms", 0, "Start-time lower bound, Unix milliseconds.") cmd.Flags().Int64Var(&fStartedBeforeMs, "started-before-ms", 0, "Start-time upper bound, Unix milliseconds.") cmd.Flags().StringVar(&fStatus, "status", "", "Run status filter. [queued, running, retrying, succeeded, partial, failed, skipped, abandoned]") - cmd.Flags().StringVar(&fTriggerKind, "trigger-kind", "", "Trigger kind filter. [schedule, debug, http_post]") + cmd.Flags().StringVar(&fTriggerKind, "trigger-kind", "", "Trigger kind filter. [schedule, debug, manual, http_post, oncall_incident]") cmd.Flags().StringVar(&dataJSON, "data", "", "Full request body as JSON; positional arguments and typed flags override its fields. Accepts inline JSON, or - to read stdin.") return cmd } @@ -649,6 +768,7 @@ func registerGeneratedAutomations(root *cobra.Command) { genAddLeaf(gSafari, genAutomationsRuleReadListCmd()) genAddLeaf(gSafari, genAutomationsRuleWriteCreateCmd()) genAddLeaf(gSafari, genAutomationsRuleWriteDeleteCmd()) + genAddLeaf(gSafari, genAutomationsRuleWriteRunCmd()) genAddLeaf(gSafari, genAutomationsRuleWriteUpdateCmd()) genAddLeaf(gSafari, genAutomationsRunReadListCmd()) genAddLeaf(gSafari, genAutomationsTemplateReadListCmd()) diff --git a/internal/cli/zz_generated_calendars.go b/internal/cli/zz_generated_calendars.go index a4d9219..e3e0a75 100644 --- a/internal/cli/zz_generated_calendars.go +++ b/internal/cli/zz_generated_calendars.go @@ -98,7 +98,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) (required) — Last update timestamp (Unix seconds). - total (integer) (required) — Total number of events returned. `, - Args: requireExactArg("cal_id"), + Args: requireBodyFieldOrExactArg("cal_id", "cal-id"), Example: ` flashduty calendar event-list --data '{"cal_id":"cal.QiNvtdKs4Wj52kZhT3LafM","month":5,"year":2024}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -175,7 +175,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - event_id (string) (required) — Event ID (existing or newly generated). - summary (string) (required) — Event summary. `, - Args: requireExactArg("cal_id"), + Args: requireBodyFieldOrExactArg("cal_id", "cal-id"), Example: ` flashduty calendar event-upsert --data '{"cal_id":"cal.QiNvtdKs4Wj52kZhT3LafM","description":"International Workers Day holiday","end_at":"2024-05-06","is_off":true,"start_at":"2024-05-01","summary":"Labour Day"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -325,7 +325,7 @@ API: POST /calendar/delete (calendarDelete) Request fields: --cal-id string (required) — Calendar ID. `, - Args: requireExactArg("cal_id"), + Args: requireBodyFieldOrExactArg("cal_id", "cal-id"), Example: ` flashduty calendar delete --data '{"cal_id":"cal.QiNvtdKs4Wj52kZhT3LafM"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -393,7 +393,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_by (integer) (required) — Last updater person ID. - workdays (array) — Workday numbers (0 = Sunday, 6 = Saturday). `, - Args: requireExactArg("cal_id"), + Args: requireBodyFieldOrExactArg("cal_id", "cal-id"), Example: ` flashduty calendar info --data '{"cal_id":"cal.eh9gvPtWeH3xXgKeVSRxRg"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -521,7 +521,7 @@ Request fields: --timezone string — New IANA timezone. --workdays []int — Workday numbers (0 = Sunday, 6 = Saturday). `, - Args: requireExactArg("cal_id"), + Args: requireBodyFieldOrExactArg("cal_id", "cal-id"), Example: ` flashduty calendar update --data '{"cal_id":"cal.QiNvtdKs4Wj52kZhT3LafM","cal_name":"Production On-Call Calendar (Updated)","timezone":"America/New_York","workdays":[1,2,3,4,5]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_channels.go b/internal/cli/zz_generated_channels.go index 9c13837..fb7a9c5 100644 --- a/internal/cli/zz_generated_channels.go +++ b/internal/cli/zz_generated_channels.go @@ -164,7 +164,7 @@ API: POST /channel/delete (channelDelete) Request fields: --channel-id int (required) — Channel ID. `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel delete --data '{"channel_id":3521074710131}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -216,7 +216,7 @@ API: POST /channel/disable (channelDisable) Request fields: --channel-id int (required) — Channel ID. `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel disable --data '{"channel_id":3521074710131}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -268,7 +268,7 @@ API: POST /channel/enable (channelEnable) Request fields: --channel-id int (required) — Channel ID. `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel enable --data '{"channel_id":3521074710131}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -712,7 +712,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) (required) — Last update timestamp (unix seconds). - updated_by (integer) (required) — Member ID that last updated the rule. `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel escalate-rule-list --data '{"channel_id":1001}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -973,7 +973,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - team_name (string) — Owning team name (resolved from the team directory; empty when unavailable). - updated_at (integer) — Last update timestamp (unix seconds). `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel info --data '{"channel_id":1001}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1027,7 +1027,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - channel_name (string) (required) — Channel name. - status (string) — Channel status. [enabled, disabled] `, - Args: requireArgs("channel_ids"), + Args: requireBodyFieldOrArgs("channel_ids", "channel-ids"), Example: ` flashduty channel infos --data '{"channel_ids":[1001,1002]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1091,7 +1091,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - rule_id (string) (required) — Newly created rule ID (MongoDB ObjectID). - rule_name (string) (required) — Rule name echoed back from the request. `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel inhibit-rule-create --data '{"channel_id":3521074710131,"description":"When a Critical alert fires, suppress matching Info alerts","equals":["labels.cluster","labels.service"],"is_directly_discard":false,"rule_name":"Suppress Info when Critical fires","source_filters":[[{"key":"severity","oper":"IN","vals":["Critical"]}]],"target_filters":[[{"key":"severity","oper":"IN","vals":["Info"]}]]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1339,7 +1339,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) (required) - updated_by (integer) (required) `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel inhibit-rule-list --data '{"channel_id":1001}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1662,7 +1662,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - rule_id (string) (required) — Newly created rule ID (MongoDB ObjectID). - rule_name (string) (required) — Rule name echoed back from the request. `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel silence-rule-create --data '{"channel_id":3521074710131,"description":"Silence all Info alerts during planned maintenance","filters":[[{"key":"severity","oper":"IN","vals":["Info"]}]],"is_directly_discard":false,"rule_name":"Maintenance window silence","time_filter":{"end_time":1773414000,"start_time":1773388800}}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1924,7 +1924,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) (required) - updated_by (integer) (required) `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel silence-rule-list --data '{"channel_id":1001}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2077,7 +2077,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - rule_id (string) (required) — Newly created rule ID (MongoDB ObjectID). - rule_name (string) (required) — Rule name echoed back from the request. `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel unsubscribe-rule-create --data '{"channel_id":3521074710131,"description":"Discard all alerts from the test environment before they create incidents","filters":[[{"key":"labels.env","oper":"IN","vals":["test","dev"]}]],"rule_name":"Drop test environment alerts"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2314,7 +2314,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) (required) - updated_by (integer) (required) `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel unsubscribe-rule-list --data '{"channel_id":1001}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2474,7 +2474,7 @@ Request fields: Response fields ('data' envelope is unwrapped — these fields are at the top level): - external_report_token (string) — Newly generated token for external reporters. Only returned when 'is_external_report_enabled' is set to 'true' in the request. Callers should store this value; it cannot be retrieved afterwards. `, - Args: requireExactArg("channel_id"), + Args: requireBodyFieldOrExactArg("channel_id", "channel-id"), Example: ` flashduty channel update --data '{"channel_id":1001,"channel_name":"Production Alerts (v2)","description":"Updated description"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2586,7 +2586,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_by (integer) (required) — ID of the person who performed the last update. - version (integer) (required) — Monotonic version number, incremented on each update. Use it for optimistic concurrency control. `, - Args: requireExactArg("integration_id"), + Args: requireBodyFieldOrExactArg("integration_id", "integration-id"), Example: ` flashduty route info --data '{"integration_id":6113996590131}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2659,7 +2659,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_by (integer) (required) — ID of the person who performed the last update. - version (integer) (required) — Monotonic version number, incremented on each update. Use it for optimistic concurrency control. `, - Args: requireArgs("integration_ids"), + Args: requireBodyFieldOrArgs("integration_ids", "integration-ids"), Example: ` flashduty route list --data '{"integration_ids":[6113996590131,6113996590132]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2723,7 +2723,7 @@ Request fields: - name (string) (required) — Section name. Must be unique within the rule. - position (integer) (required) — Index in 'cases' where this section starts. Must be between 0 and the length of 'cases'. `, - Args: requireExactArg("integration_id"), + Args: requireBodyFieldOrExactArg("integration_id", "integration-id"), Example: ` flashduty route upsert --data '{"cases":[{"channel_ids":[3521074710131],"fallthrough":false,"if":[{"key":"severity","oper":"IN","vals":["Critical"]}],"routing_mode":"standard"}],"default":{"channel_ids":[3521074710131]},"integration_id":6113996590131}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_incidents.go b/internal/cli/zz_generated_incidents.go index 4e7a62a..a050b24 100644 --- a/internal/cli/zz_generated_incidents.go +++ b/internal/cli/zz_generated_incidents.go @@ -36,7 +36,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - status (string) — Current status of the person. - time_zone (string) — Time zone of the person. `, - Args: requireExactArg("incident_id"), + Args: requireBodyFieldOrExactArg("incident_id", "incident-id"), Example: ` flashduty incident war-room-default-observers --data '{"incident_id":"664a1b2c3d4e5f6a7b8c9d0e"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -69,6 +69,165 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le return cmd } +func genIncidentsTriggerSubscriptionWriteDeleteCmd() *cobra.Command { + var dataJSON string + var fConsumer string + var fConsumerRef string + var fSource string + cmd := &cobra.Command{ + Use: "delete", + Short: "Delete incident trigger subscription", + Long: `Delete incident trigger subscription. + +Delete an incident trigger subscription for AI SRE automation. + +API: POST /incident-trigger-subscription/delete (incident-trigger-subscription-write-delete) + +Request fields: + --consumer string (required) — Consumer system. + --consumer-ref string (required) — Consumer-owned reference, such as an Automation rule ID. + --source string (required) — Subscription source. +`, + Example: ` flashduty incident-trigger-subscription delete --data '{"consumer":"fc_safari","consumer_ref":"auto_7NnLzY2Qp8xS4kUaV3mR6b","source":"ai_sre_automation"}'`, + RunE: func(cmd *cobra.Command, args []string) error { + return runCommand(cmd, args, func(ctx *RunContext) error { + body, err := genAssembleBody(dataJSON, func(body map[string]any) error { + if cmd.Flags().Changed("consumer") { + body["consumer"] = fConsumer + } + if cmd.Flags().Changed("consumer-ref") { + body["consumer_ref"] = fConsumerRef + } + if cmd.Flags().Changed("source") { + body["source"] = fSource + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.IncidentTriggerSubscriptionDeleteRequest) + if err := genBindBody(body, req); err != nil { + return err + } + resp, err := ctx.Client.Incidents.TriggerSubscriptionWriteDelete(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + if resp != nil && len(resp.Raw) > 0 { + return ctx.WriteRaw(resp.Raw) + } + ctx.WriteResult("OK: POST /incident-trigger-subscription/delete") + return nil + }) + }, + } + cmd.Flags().StringVar(&fConsumer, "consumer", "", "Consumer system. (required)") + cmd.Flags().StringVar(&fConsumerRef, "consumer-ref", "", "Consumer-owned reference, such as an Automation rule ID. (required)") + cmd.Flags().StringVar(&fSource, "source", "", "Subscription source. (required)") + cmd.Flags().StringVar(&dataJSON, "data", "", "Full request body as JSON; positional arguments and typed flags override its fields. Accepts inline JSON, or - to read stdin.") + return cmd +} + +func genIncidentsTriggerSubscriptionWriteUpsertCmd() *cobra.Command { + var dataJSON string + var fChannelIDs []int + var fConsumer string + var fConsumerRef string + var fEnabled bool + var fSeverities []string + var fSource string + var fSubscriptionID string + cmd := &cobra.Command{ + Use: "upsert [...]", + Short: "Create or update incident trigger subscription", + Long: `Create or update incident trigger subscription. + +Create or update an incident trigger subscription for AI SRE automation. + +API: POST /incident-trigger-subscription/upsert (incident-trigger-subscription-write-upsert) + +Request fields: + --channel-ids []int (required) — On-call channel IDs whose new incidents should trigger the consumer. + --consumer string (required) — Consumer system. Use 'fc_safari' for AI SRE automation rules. + --consumer-ref string (required) — Consumer-owned reference, such as an Automation rule ID. + --enabled bool — Whether the subscription is enabled. Defaults to true when omitted. + --severities []string (required) — Incident severities to subscribe to. 'Ok' is not valid. [Critical, Warning, Info] + --source string (required) — Subscription source. Use 'ai_sre_automation' for AI SRE automation rules. + --subscription-id string — Existing subscription ID. Omit to create or upsert by source, consumer, and consumer_ref. + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - account_id (integer) (required) — Account ID. + - channel_ids (array) (required) — Subscribed channel IDs. + - consumer (string) (required) — Consumer system. + - consumer_ref (string) (required) — Consumer-owned reference. + - created_at (integer) (required) — Unix timestamp in seconds when the subscription was created. + - created_by (integer) (required) — Member ID that created the subscription. + - deleted_at (integer) (required) — Unix timestamp in seconds when the subscription was deleted; 0 means active. + - enabled (boolean) (required) — Whether the subscription is enabled. + - severities (array) (required) — Subscribed incident severities. [Critical, Warning, Info] + - source (string) (required) — Subscription source. + - subscription_id (string) (required) — Subscription ID. + - updated_at (integer) (required) — Unix timestamp in seconds when the subscription was last updated. + - updated_by (integer) (required) — Member ID that last updated the subscription. +`, + Args: requireBodyFieldOrArgs("channel_ids", "channel-ids"), + Example: ` flashduty incident-trigger-subscription upsert --data '{"channel_ids":[2468013579],"consumer":"fc_safari","consumer_ref":"auto_7NnLzY2Qp8xS4kUaV3mR6b","enabled":true,"severities":["Critical","Warning"],"source":"ai_sre_automation"}'`, + RunE: func(cmd *cobra.Command, args []string) error { + return runCommand(cmd, args, func(ctx *RunContext) error { + body, err := genAssembleBody(dataJSON, func(body map[string]any) error { + if err := genFoldPositional(args, body, "channel_ids", "intslice"); err != nil { + return err + } + if cmd.Flags().Changed("channel-ids") { + body["channel_ids"] = fChannelIDs + } + if cmd.Flags().Changed("consumer") { + body["consumer"] = fConsumer + } + if cmd.Flags().Changed("consumer-ref") { + body["consumer_ref"] = fConsumerRef + } + if cmd.Flags().Changed("enabled") { + body["enabled"] = fEnabled + } + if cmd.Flags().Changed("severities") { + body["severities"] = fSeverities + } + if cmd.Flags().Changed("source") { + body["source"] = fSource + } + if cmd.Flags().Changed("subscription-id") { + body["subscription_id"] = fSubscriptionID + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.IncidentTriggerSubscriptionUpsertRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Incidents.TriggerSubscriptionWriteUpsert(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().IntSliceVar(&fChannelIDs, "channel-ids", nil, "On-call channel IDs whose new incidents should trigger the consumer. (required)") + cmd.Flags().StringVar(&fConsumer, "consumer", "", "Consumer system. Use 'fc_safari' for AI SRE automation rules. (required)") + cmd.Flags().StringVar(&fConsumerRef, "consumer-ref", "", "Consumer-owned reference, such as an Automation rule ID. (required)") + cmd.Flags().BoolVar(&fEnabled, "enabled", false, "Whether the subscription is enabled. Defaults to true when omitted.") + cmd.Flags().StringSliceVar(&fSeverities, "severities", nil, "Incident severities to subscribe to. 'Ok' is not valid. (required) [Critical, Warning, Info]") + cmd.Flags().StringVar(&fSource, "source", "", "Subscription source. Use 'ai_sre_automation' for AI SRE automation rules. (required)") + cmd.Flags().StringVar(&fSubscriptionID, "subscription-id", "", "Existing subscription ID. Omit to create or upsert by source, consumer, and consumer_ref.") + cmd.Flags().StringVar(&dataJSON, "data", "", "Full request body as JSON; positional arguments and typed flags override its fields. Accepts inline JSON, or - to read stdin.") + return cmd +} + func genIncidentsWriteAddWarRoomMemberCmd() *cobra.Command { var dataJSON string var fChatID string @@ -88,7 +247,7 @@ Request fields: --integration-id int (required) — IM integration that hosts the war room. --member-ids []int (required) — Person IDs to add to the war room. `, - Args: requireExactArg("chat_id"), + Args: requireBodyFieldOrExactArg("chat_id", "chat-id"), Example: ` flashduty incident war-room-add-member --data '{"chat_id":"oc_5ce6d572455d361153b7cb51da133945","integration_id":362,"member_ids":[20001,20002]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -144,7 +303,7 @@ API: POST /incident/ack (incidentAck) Request fields: --incident-ids []string (required) — Incident IDs to acknowledge. At most 100 per call. `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident ack --data '{"incident_ids":["69da451ef77b1b51f40e83ee"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -271,7 +430,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - updated_at (integer) (required) — Last update timestamp (seconds). - total (integer) (required) — Total matching alerts. `, - Args: requireExactArg("incident_id"), + Args: requireBodyFieldOrExactArg("incident_id", "incident-id"), Example: ` flashduty incident alert-list --data '{"incident_id":"69da451ef77b1b51f40e83ee","include_events":true,"is_active":true,"limit":100,"p":1}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -406,7 +565,7 @@ Request fields: --incident-ids []string (required) — Incident IDs to comment on. At most 100 per call. --mute-reply bool — When true, do not trigger webhook reply actions for this comment. `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident comment --data '{"comment":"Identified the root cause. Rolling back the deployment now.","incident_ids":["69da451ef77b1b51f40e83ee"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -595,7 +754,7 @@ API: POST /incident/disable-merge (incidentDisableMerge) Request fields: --incident-ids []string (required) — Incident IDs whose automatic merge should be disabled. `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident disable-merge --data '{"incident_ids":["69da451ef77b1b51f40e83ee"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -669,7 +828,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - type (string) (required) — Incident timeline entry type. Each value identifies one lifecycle event; the matching 'detail' payload shape is determined by this field. Incident types are prefixed with 'i_'. | Type | Meaning | |---|---| | 'i_new' | Incident Created: A new incident was created automatically or manually. | | 'i_assign' | Assigned: Incident was assigned to responders. | | 'i_a_rspd' | Responder Added: Additional responders joined the incident. | | 'i_notify' | Notification dispatched through a channel at a specific escalation level. | | 'i_storm' | Alert storm threshold reached on the incident. | | 'i_snooze' | Notifications snoozed for a given duration. | | 'i_wake' | Snooze cancelled and notifications resumed. | | 'i_ack' | Acknowledged: Responder confirmed they are working on the incident. | | 'i_unack' | Acknowledgement removed. | | 'i_comm' | Comment: Responder logged progress or key information. | | 'i_rslv' | Resolved: Incident was marked as resolved. | | 'i_reopen' | Reopened: Resolved incident was reopened, possibly due to recurrence. | | 'i_merge' | Merged: Multiple related incidents were merged into one. | | 'i_r_title' | Title updated. | | 'i_r_desc' | Description updated. | | 'i_r_impact' | Impact updated. | | 'i_r_rc' | Root cause updated. | | 'i_r_rsltn' | Resolution updated. | | 'i_r_severity' | Severity Changed: Incident severity level was adjusted. | | 'i_r_field' | Custom field value updated. | | 'i_m_flapping' | Incident muted by flapping detection. | | 'i_m_reply' | Mute reply marker on a comment. | | 'i_custom' | Action: Automated action or script was triggered. | | 'i_wr_create' | War Room Created: Chat group was created for collaborative response. | | 'i_wr_delete' | War room chat group deleted. | | 'i_auto_refresh' | Card auto-refresh event posted back to the timeline. | | 'a_merge' | Alert Merged: An alert was merged into an existing incident. | [i_new, i_assign, i_a_rspd, i_notify, i_storm, i_snooze, i_wake, i_ack, i_unack, i_comm, i_rslv, i_reopen, i_merge, i_r_title, i_r_desc, i_r_impact, i_r_rc, i_r_rsltn, i_r_severity, i_r_field, i_m_flapping, i_m_reply, i_custom, i_wr_create, i_wr_delete, i_auto_refresh, a_merge] - updated_at (integer) (required) — Last update timestamp in milliseconds. `, - Args: requireExactArg("incident_id"), + Args: requireBodyFieldOrExactArg("incident_id", "incident-id"), Example: ` flashduty incident feed --data '{"incident_id":"69da451ef77b1b51f40e83ee","limit":20,"p":1}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -740,7 +899,7 @@ Request fields: --incident-id string (required) — Incident ID (MongoDB ObjectID). field_value (any, via --data) — New field value. Type must match the field definition. `, - Args: requireExactArg("incident_id"), + Args: requireBodyFieldOrExactArg("incident_id", "incident-id"), Example: ` flashduty incident field-reset --data '{"field_name":"affected_service","field_value":"payment-service","incident_id":"69da451ef77b1b51f40e83ee"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1498,7 +1657,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - search_after_ctx (string) — Opaque cursor to pass as 'search_after_ctx' on the next request. - total (integer) (required) — Total number of matching incidents. `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident list-by-ids --data '{"incident_ids":["69da451ef77b1b51f40e83ee","69da451ef77b1b51f40e83ef"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1556,7 +1715,7 @@ Request fields: --target-incident-id string (required) — Target incident ID that source incidents will be merged into. --title string — Optional new title for the target incident. (≤512 chars) `, - Args: requireExactArg("target_incident_id"), + Args: requireBodyFieldOrExactArg("target_incident_id", "target-incident-id"), Example: ` flashduty incident merge --data '{"comment":"Merging related database connectivity incidents into one.","source_incident_ids":["69da451ef77b1b51f40e83ef","69da451ef77b1b51f40e83f0"],"target_incident_id":"69da451ef77b1b51f40e83ee"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1785,7 +1944,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - title (string) (required) — Incident title. - updated_at (integer) (required) — Last update timestamp (seconds). `, - Args: requireExactArg("incident_id"), + Args: requireBodyFieldOrExactArg("incident_id", "incident-id"), Example: ` flashduty incident past-list --data '{"incident_id":"69da451ef77b1b51f40e83ee","limit":5}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1837,7 +1996,7 @@ API: POST /incident/post-mortem/delete (incidentPostMortemDelete) Request fields: --post-mortem-id string (required) — Post-mortem ID. `, - Args: requireExactArg("post_mortem_id"), + Args: requireBodyFieldOrExactArg("post_mortem_id", "post-mortem-id"), Example: ` flashduty incident post-mortem-delete --data '{"post_mortem_id":"8104935102bf89dc01ac638a5261fe7e"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1921,7 +2080,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - title (string) (required) — Report title. - updated_at_seconds (integer) (required) — Last update timestamp (seconds). `, - Args: requireExactArg("post_mortem_id"), + Args: requireBodyFieldOrExactArg("post_mortem_id", "post-mortem-id"), RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -2094,7 +2253,7 @@ API: POST /incident/remove (incidentRemove) Request fields: --incident-ids []string (required) — Incident IDs to remove. At most 100 per call. The caller must have access to every channel the incidents belong to. `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident remove --data '{"incident_ids":["69da451ef77b1b51f40e83ee"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2148,7 +2307,7 @@ Request fields: --incident-ids []string (required) — Incident IDs to reopen. At most 100 per call. --reason string — Optional reason recorded on the timeline. (≤1024 chars) `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident reopen --data '{"incident_ids":["69da451ef77b1b51f40e83ee"],"reason":"Monitoring detected the issue recurred after the initial fix."}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2216,7 +2375,7 @@ Request fields: --root-cause string — New root cause analysis. (3-6144 chars) --title string — New incident title. (3-200 chars) `, - Args: requireExactArg("incident_id"), + Args: requireBodyFieldOrExactArg("incident_id", "incident-id"), Example: ` flashduty incident reset --data '{"incident_id":"69da451ef77b1b51f40e83ee","incident_severity":"Critical","title":"Database connection timeout - prod-db-01 primary"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2296,7 +2455,7 @@ Request fields: --resolution string — Optional resolution note applied to every resolved incident. (≤1024 chars) --root-cause string — Optional root cause note applied to every resolved incident. (≤1024 chars) `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident resolve --data '{"incident_ids":["69da451ef77b1b51f40e83ee"],"resolution":"Deployed hotfix v2.3.1 and restarted the affected service.","root_cause":"Memory leak in the connection pool caused by a missing cleanup call."}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2362,7 +2521,7 @@ Request fields: - personal_channels (array) — Channels to use (e.g. 'voice', 'sms', 'email'). - template_id (string) — Notification template ID (MongoDB ObjectID). `, - Args: requireArgs("person_ids"), + Args: requireBodyFieldOrArgs("person_ids", "person-ids"), Example: ` flashduty incident responder-add --data '{"incident_id":"69da451ef77b1b51f40e83ee","person_ids":[2476444212131,2476444212132]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2420,7 +2579,7 @@ Request fields: --incident-ids []string (required) — Incident IDs to snooze. At most 100 per call. --minutes int (required) — Duration in minutes. Must be greater than 0 and at most 1440 (24h). (max 1440) `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident snooze --data '{"incident_ids":["69da451ef77b1b51f40e83ee"],"minutes":60}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2476,7 +2635,7 @@ API: POST /incident/unack (incidentUnack) Request fields: --incident-ids []string (required) — Incident IDs to unacknowledge. At most 100 per call. `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident unack --data '{"incident_ids":["69da451ef77b1b51f40e83ee"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2528,7 +2687,7 @@ API: POST /incident/wake (incidentWake) Request fields: --incident-ids []string (required) — Incident IDs to wake. At most 100 per call. `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident wake --data '{"incident_ids":["69da451ef77b1b51f40e83ee"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2708,7 +2867,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - chat_name (string) (required) — Chat/group display name. - share_link (string) (required) — Join link for the war room, if provided by the IM. `, - Args: requireExactArg("chat_id"), + Args: requireBodyFieldOrExactArg("chat_id", "chat-id"), Example: ` flashduty incident war-room-detail --data '{"chat_id":"oc_a0553eda9014c2de1b3a8f75b4e0c000","integration_id":2490562293131}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2773,7 +2932,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - plugin_type (string) (required) — IM plugin type (e.g. 'feishu', 'dingtalk', 'wecom', 'slack'). - status (string) (required) — War room status. `, - Args: requireExactArg("incident_id"), + Args: requireBodyFieldOrExactArg("incident_id", "incident-id"), Example: ` flashduty incident war-room-list --data '{"incident_id":"69da451ef77b1b51f40e83ee"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -2919,7 +3078,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - template_id (string) (required) — Template ID. Built-in templates use a stable 'post_mortem_default_tmpl_*' ID. - updated_at_seconds (integer) (required) — Unix timestamp in seconds when the template was last updated. `, - Args: requireExactArg("template_id"), + Args: requireBodyFieldOrExactArg("template_id", "template-id"), RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -2966,7 +3125,7 @@ API: POST /incident/post-mortem/template/delete (postmortem-write-delete-templat Request fields: --template-id string (required) — Template ID. `, - Args: requireExactArg("template_id"), + Args: requireBodyFieldOrExactArg("template_id", "template-id"), Example: ` flashduty incident post-mortem-template-delete --data '{"template_id":"post_mortem_custom_tmpl_01"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -3052,7 +3211,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - title (string) (required) — Report title. - updated_at_seconds (integer) (required) — Last update timestamp (seconds). `, - Args: requireArgs("incident_ids"), + Args: requireBodyFieldOrArgs("incident_ids", "incident-ids"), Example: ` flashduty incident post-mortem-init --data '{"incident_ids":["69bb9233331067560c718ecd"],"template_id":"post_mortem_default_tmpl_en-us"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -3114,7 +3273,7 @@ Request fields: --post-mortem-id string (required) — Post-mortem ID. --responder-ids []int — Responder member IDs to store on the report. `, - Args: requireExactArg("post_mortem_id"), + Args: requireBodyFieldOrExactArg("post_mortem_id", "post-mortem-id"), Example: ` flashduty incident post-mortem-basics-reset --data '{"incidents_earliest_start_seconds":1761133512,"incidents_highest_severity":"Warning","incidents_latest_close_seconds":1761133632,"incidents_total_duration_seconds":120,"post_mortem_id":"8104935102bf89dc01ac638a5261fe7e","responder_ids":[3790925372131]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -3196,7 +3355,7 @@ Request fields: --follow-ups string — Follow-up action items as free text. --post-mortem-id string (required) — Post-mortem ID. `, - Args: requireExactArg("post_mortem_id"), + Args: requireBodyFieldOrExactArg("post_mortem_id", "post-mortem-id"), Example: ` flashduty incident post-mortem-follow-ups-reset --data '{"follow_ups":"- Add database saturation alert\n- Review cache TTL rollout","post_mortem_id":"8104935102bf89dc01ac638a5261fe7e"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -3254,7 +3413,7 @@ Request fields: --post-mortem-id string (required) — Post-mortem ID. --status string (required) — Target report status. [drafting, published] `, - Args: requireExactArg("post_mortem_id"), + Args: requireBodyFieldOrExactArg("post_mortem_id", "post-mortem-id"), Example: ` flashduty incident post-mortem-status-reset --data '{"post_mortem_id":"8104935102bf89dc01ac638a5261fe7e","status":"published"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -3312,7 +3471,7 @@ Request fields: --post-mortem-id string (required) — Post-mortem ID. --title string (required) — New report title. `, - Args: requireExactArg("post_mortem_id"), + Args: requireBodyFieldOrExactArg("post_mortem_id", "post-mortem-id"), Example: ` flashduty incident post-mortem-title-reset --data '{"post_mortem_id":"8104935102bf89dc01ac638a5261fe7e","title":"Production API latency incident"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -3441,6 +3600,9 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le func registerGeneratedIncidents(root *cobra.Command) { gIncident := genGroup(root, "incident", "On-call/Incidents API") genAddLeaf(gIncident, genIncidentsReadGetWarRoomDefaultObserversCmd()) + gIncidentTriggerSubscription := genGroup(root, "incident-trigger-subscription", "On-call/Incidents API") + genAddLeaf(gIncidentTriggerSubscription, genIncidentsTriggerSubscriptionWriteDeleteCmd()) + genAddLeaf(gIncidentTriggerSubscription, genIncidentsTriggerSubscriptionWriteUpsertCmd()) genAddLeaf(gIncident, genIncidentsWriteAddWarRoomMemberCmd()) genAddLeaf(gIncident, genIncidentsAckCmd()) genAddLeaf(gIncident, genIncidentsAlertListCmd()) diff --git a/internal/cli/zz_generated_integrations.go b/internal/cli/zz_generated_integrations.go index f970225..9d000eb 100644 --- a/internal/cli/zz_generated_integrations.go +++ b/internal/cli/zz_generated_integrations.go @@ -26,7 +26,7 @@ Request fields: Response fields ('data' envelope is unwrapped — these fields are at the top level): - new_linked_person_ids (array) (required) — Person IDs newly linked during this call. `, - Args: requireExactArg("integration_id"), + Args: requireBodyFieldOrExactArg("integration_id", "integration-id"), Example: ` flashduty datasource im-person-try-link --data '{"integration_id":6113996590131}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_issues.go b/internal/cli/zz_generated_issues.go index 559cdb8..a407dce 100644 --- a/internal/cli/zz_generated_issues.go +++ b/internal/cli/zz_generated_issues.go @@ -59,7 +59,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) - versions (array) `, - Args: requireExactArg("issue_id"), + Args: requireBodyFieldOrExactArg("issue_id", "issue-id"), Example: ` flashduty rum issue-info --data '{"issue_id":"NHEacQHi2DhXqobr9qPQz9"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -278,7 +278,7 @@ Request fields: --status string — New status. [for_review, reviewed, ignored, resolved] --suspected-cause string — Suspected cause. [api.failed_request, network.error, code.exception, code.invalid_object_access, code.invalid_argument, unknown] `, - Args: requireExactArg("issue_id"), + Args: requireBodyFieldOrExactArg("issue_id", "issue-id"), Example: ` flashduty rum issue-update --data '{"issue_id":"NHEacQHi2DhXqobr9qPQz9","status":"resolved"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_manifest.go b/internal/cli/zz_generated_manifest.go index 946d535..5d9c898 100644 --- a/internal/cli/zz_generated_manifest.go +++ b/internal/cli/zz_generated_manifest.go @@ -22,6 +22,7 @@ var generatedOpIDs = []string{ "automation-rule-read-list", "automation-rule-write-create", "automation-rule-write-delete", + "automation-rule-write-run", "automation-rule-write-update", "automation-run-read-list", "automation-template-read-list", @@ -79,6 +80,8 @@ var generatedOpIDs = []string{ "field-write-update", "im-war-room-enabled-list", "incident-read-get-war-room-default-observers", + "incident-trigger-subscription-write-delete", + "incident-trigger-subscription-write-upsert", "incident-write-add-war-room-member", "incidentAck", "incidentAlertList", diff --git a/internal/cli/zz_generated_mcp_servers.go b/internal/cli/zz_generated_mcp_servers.go index e755d5b..9bb50b7 100644 --- a/internal/cli/zz_generated_mcp_servers.go +++ b/internal/cli/zz_generated_mcp_servers.go @@ -55,7 +55,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) (required) — Last update time. Unix timestamp in milliseconds. - url (string) — Server URL (sse / streamable-http transport). `, - Args: requireExactArg("server_id"), + Args: requireBodyFieldOrExactArg("server_id", "server-id"), Example: ` flashduty safari mcp-server-get --data '{"server_id":"mcp_4kP9wQ2nLceRtY7uVb3xA1"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -361,7 +361,7 @@ API: POST /safari/mcp/server/delete (mcp-write-server-delete) Request fields: --server-id string (required) — Target MCP server ID. `, - Args: requireExactArg("server_id"), + Args: requireBodyFieldOrExactArg("server_id", "server-id"), Example: ` flashduty safari mcp-server-delete --data '{"server_id":"mcp_4kP9wQ2nLceRtY7uVb3xA1"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -409,7 +409,7 @@ API: POST /safari/mcp/server/disable (mcp-write-server-disable) Request fields: --server-id string (required) — Target MCP server ID. `, - Args: requireExactArg("server_id"), + Args: requireBodyFieldOrExactArg("server_id", "server-id"), Example: ` flashduty safari mcp-server-disable --data '{"server_id":"mcp_4kP9wQ2nLceRtY7uVb3xA1"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -457,7 +457,7 @@ API: POST /safari/mcp/server/enable (mcp-write-server-enable) Request fields: --server-id string (required) — Target MCP server ID. `, - Args: requireExactArg("server_id"), + Args: requireBodyFieldOrExactArg("server_id", "server-id"), Example: ` flashduty safari mcp-server-enable --data '{"server_id":"mcp_4kP9wQ2nLceRtY7uVb3xA1"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -563,7 +563,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) (required) — Last update time. Unix timestamp in milliseconds. - url (string) — Server URL (sse / streamable-http transport). `, - Args: requireExactArg("server_id"), + Args: requireBodyFieldOrExactArg("server_id", "server-id"), Example: ` flashduty safari mcp-server-update --data '{"description":"Query Prometheus metrics, alerts, and rules.","server_id":"mcp_4kP9wQ2nLceRtY7uVb3xA1"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_members.go b/internal/cli/zz_generated_members.go index a9cfe92..ba456c9 100644 --- a/internal/cli/zz_generated_members.go +++ b/internal/cli/zz_generated_members.go @@ -109,7 +109,7 @@ Request fields: --member-id int (required) — Member ID --role-ids []int (required) — Role IDs to grant; appended to the member's current roles (duplicates are deduplicated). `, - Args: requireArgs("role_ids"), + Args: requireBodyFieldOrArgs("role_ids", "role-ids"), Example: ` flashduty member role-grant --data '{"member_id":5068740052131,"role_ids":[6]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -395,7 +395,7 @@ Request fields: --phone string — Phone number --time-zone string — Time zone `, - Args: requireExactArg("member_id"), + Args: requireBodyFieldOrExactArg("member_id", "member-id"), Example: ` flashduty member info-reset --data '{"locale":"zh-CN","member_id":2476444212131,"member_name":"Alice","time_zone":"Asia/Shanghai"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -477,7 +477,7 @@ Request fields: --member-id int (required) — Member ID --role-ids []int (required) — Role IDs to remove from the member. `, - Args: requireArgs("role_ids"), + Args: requireBodyFieldOrArgs("role_ids", "role-ids"), Example: ` flashduty member role-revoke --data '{"member_id":5068740052131,"role_ids":[6]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -535,7 +535,7 @@ Request fields: --member-id int (required) — Member ID --role-ids []int (required) — New set of role IDs `, - Args: requireArgs("role_ids"), + Args: requireBodyFieldOrArgs("role_ids", "role-ids"), Example: ` flashduty member role-update --data '{"member_id":5068740052131,"role_ids":[2,6]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -606,7 +606,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - status (string) — Person status. 'enabled' — active; 'pending' — invited but not yet accepted; 'deleted' — removed. [enabled, pending, deleted] - time_zone (string) — Time zone `, - Args: requireArgs("person_ids"), + Args: requireBodyFieldOrArgs("person_ids", "person-ids"), Example: ` flashduty person infos --data '{"person_ids":[2476444212131,3790925372131]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_notification_templates.go b/internal/cli/zz_generated_notification_templates.go index 17a9f27..998c8d6 100644 --- a/internal/cli/zz_generated_notification_templates.go +++ b/internal/cli/zz_generated_notification_templates.go @@ -50,7 +50,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - wecom_app (string) (required) — WeCom app message template source. - zoom (string) (required) — Zoom bot message template source. `, - Args: requireExactArg("template_id"), + Args: requireBodyFieldOrExactArg("template_id", "template-id"), Example: ` flashduty template info --data '{"template_id":"6605a1b2c3d4e5f6a7b8c9d0"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -425,7 +425,7 @@ API: POST /template/delete (template-write-delete) Request fields: --template-id string (required) — Target template ID. Pass '000000000000000000000001' to address the built-in preset. `, - Args: requireExactArg("template_id"), + Args: requireBodyFieldOrExactArg("template_id", "template-id"), Example: ` flashduty template delete --data '{"template_id":"6605a1b2c3d4e5f6a7b8c9d0"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -511,7 +511,7 @@ Request fields: --wecom-app string — WeCom app message template source. --zoom string — Zoom bot message template source. `, - Args: requireExactArg("template_id"), + Args: requireBodyFieldOrExactArg("template_id", "template-id"), Example: ` flashduty template update --data '{"description":"Updated description.","email":"Incident {{ .IncidentName }} on {{ .Severity }}","sms":"[Flashduty] {{ .IncidentName }} — {{ .Severity }}","template_id":"6605a1b2c3d4e5f6a7b8c9d0","template_name":"Prod incident default"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_response_help.go b/internal/cli/zz_generated_response_help.go index 5d1282c..18a2514 100644 --- a/internal/cli/zz_generated_response_help.go +++ b/internal/cli/zz_generated_response_help.go @@ -58,11 +58,12 @@ var responseHelpBySDKMethod = map[string]string{ "Applications.WriteCreate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - application_id (string) — Auto-generated unique application ID.\n - application_name (string) — Application display name.\n - client_token (string) — Token for RUM SDK initialization.\n", "AuditLogs.OperationList": "Response fields (this command's `--json` is a TOP-LEVEL array of these row objects — pipe `jq '.[]'`, NOT `.items[]`):\n - name (string) (required) — Stable machine-readable operation name for use as a filter.\n - name_cn (string) (required) — Human-readable Chinese label shown in the console.\n", "AuditLogs.Search": "Response fields (this command's `--json` is a TOP-LEVEL array of these row objects — pipe `jq '.[]'`, NOT `.items[]`):\n - account_id (integer) (required) — ID of the account.\n - body (string) (required) — JSON-encoded request body (may be truncated at 10 KB).\n - created_at (integer) (required) — Timestamp of the operation in Unix epoch milliseconds.\n - ip (string) (required) — Client IP address of the caller.\n - is_dangerous (boolean) (required) — True if this is flagged as a high-risk operation.\n - is_write (boolean) (required) — True for mutating operations; false for read-only ones.\n - member_id (integer) (required) — ID of the member who performed the action.\n - member_name (string) (required) — Display name of the member.\n - operation (string) (required) — Stable machine-readable operation name, e.g. `template:write:create`.\n - operation_name (string) (required) — Human-readable operation label in the account's locale.\n - params (array) (required) — URL path parameters as an array of key-value pairs, or an empty array when none.\n - Key (string)\n - Value (string)\n - request_id (string) (required) — Unique request ID for correlation.\n", - "Automations.RuleReadGet": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - account_id (integer) (required) — Account ID.\n - can_edit (boolean) (required) — Whether the caller can manage this rule.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - cron_expr (string) (required) — Normalized 5-field cron expression.\n - enabled (boolean) (required) — Whether the rule is enabled.\n - environment_id (string) (required) — BYOC Runner ID.\n - environment_kind (string) (required) — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]\n - http_post_token (string) — HTTP POST trigger token. Returned only on create or token rotation; save it immediately.\n - http_post_trigger_enabled (boolean) (required) — Whether the HTTP POST trigger is enabled.\n - http_post_trigger_id (string) — HTTP POST trigger ID.\n - http_post_trigger_url (string) — HTTP POST trigger path.\n - name (string) (required) — Rule name.\n - owner_id (integer) (required) — Creator person ID.\n - prompt (string) (required) — Task prompt.\n - rule_id (string) (required) — Rule ID.\n - run_scope (string) (required) — Hidden session run scope. [person, team]\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n", - "Automations.RuleReadList": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - rules (array) (required)\n - account_id (integer) (required) — Account ID.\n - can_edit (boolean) (required) — Whether the caller can manage this rule.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - cron_expr (string) (required) — Normalized 5-field cron expression.\n - enabled (boolean) (required) — Whether the rule is enabled.\n - environment_id (string) (required) — BYOC Runner ID.\n - environment_kind (string) (required) — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]\n - http_post_token (string) — HTTP POST trigger token. Returned only on create or token rotation; save it immediately.\n - http_post_trigger_enabled (boolean) (required) — Whether the HTTP POST trigger is enabled.\n - http_post_trigger_id (string) — HTTP POST trigger ID.\n - http_post_trigger_url (string) — HTTP POST trigger path.\n - name (string) (required) — Rule name.\n - owner_id (integer) (required) — Creator person ID.\n - prompt (string) (required) — Task prompt.\n - rule_id (string) (required) — Rule ID.\n - run_scope (string) (required) — Hidden session run scope. [person, team]\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n - total (integer) (required) — Total count.\n", - "Automations.RuleWriteCreate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - account_id (integer) (required) — Account ID.\n - can_edit (boolean) (required) — Whether the caller can manage this rule.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - cron_expr (string) (required) — Normalized 5-field cron expression.\n - enabled (boolean) (required) — Whether the rule is enabled.\n - environment_id (string) (required) — BYOC Runner ID.\n - environment_kind (string) (required) — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]\n - http_post_token (string) — HTTP POST trigger token. Returned only on create or token rotation; save it immediately.\n - http_post_trigger_enabled (boolean) (required) — Whether the HTTP POST trigger is enabled.\n - http_post_trigger_id (string) — HTTP POST trigger ID.\n - http_post_trigger_url (string) — HTTP POST trigger path.\n - name (string) (required) — Rule name.\n - owner_id (integer) (required) — Creator person ID.\n - prompt (string) (required) — Task prompt.\n - rule_id (string) (required) — Rule ID.\n - run_scope (string) (required) — Hidden session run scope. [person, team]\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n", - "Automations.RuleWriteUpdate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - account_id (integer) (required) — Account ID.\n - can_edit (boolean) (required) — Whether the caller can manage this rule.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - cron_expr (string) (required) — Normalized 5-field cron expression.\n - enabled (boolean) (required) — Whether the rule is enabled.\n - environment_id (string) (required) — BYOC Runner ID.\n - environment_kind (string) (required) — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]\n - http_post_token (string) — HTTP POST trigger token. Returned only on create or token rotation; save it immediately.\n - http_post_trigger_enabled (boolean) (required) — Whether the HTTP POST trigger is enabled.\n - http_post_trigger_id (string) — HTTP POST trigger ID.\n - http_post_trigger_url (string) — HTTP POST trigger path.\n - name (string) (required) — Rule name.\n - owner_id (integer) (required) — Creator person ID.\n - prompt (string) (required) — Task prompt.\n - rule_id (string) (required) — Rule ID.\n - run_scope (string) (required) — Hidden session run scope. [person, team]\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n", - "Automations.RunReadList": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - runs (array) (required)\n - account_id (integer) (required) — Account ID.\n - attempts (integer) (required) — Attempt count.\n - completed_at (integer) (required) — Completion time, Unix milliseconds. 0 means not completed.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - duration_ms (integer) (required) — Duration in milliseconds.\n - error_code (string) — Error code.\n - error_message (string) — Error message.\n - kind (string) (required) — Run kind.\n - occurrence_key (string) (required) — Idempotency key for this occurrence.\n - result_json (any) — Run result JSON.\n - rule_id (string) (required) — Rule ID.\n - run_id (string) (required) — Run ID.\n - started_at (integer) (required) — Start time, Unix milliseconds.\n - stats_json (any) — Run stats JSON.\n - status (string) (required) — Run status. [queued, running, retrying, succeeded, partial, failed, skipped, abandoned]\n - trigger_kind (string) (required) — Trigger kind. [schedule, debug, http_post]\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n - total (integer) (required) — Total count.\n", + "Automations.RuleReadGet": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - account_id (integer) (required) — Account ID.\n - can_edit (boolean) (required) — Whether the caller can manage this rule.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - cron_expr (string) (required) — Normalized 5-field cron expression.\n - enabled (boolean) (required) — Whether the rule is enabled.\n - environment_id (string) (required) — BYOC Runner ID.\n - environment_kind (string) (required) — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]\n - http_post_token (string) — HTTP POST trigger token. Returned only on create or token rotation; save it immediately.\n - http_post_trigger_enabled (boolean) (required) — Whether the HTTP POST trigger is enabled.\n - http_post_trigger_id (string) — HTTP POST trigger ID.\n - http_post_trigger_url (string) — HTTP POST trigger path.\n - name (string) (required) — Rule name.\n - oncall_incident_channel_ids (array) — On-call channel IDs watched by the incident trigger.\n - oncall_incident_severities (array) — Incident severities watched by the trigger. [Critical, Warning, Info]\n - oncall_incident_trigger_enabled (boolean) (required) — Whether the on-call incident trigger is enabled.\n - oncall_incident_trigger_id (string) — On-call incident trigger ID.\n - owner_id (integer) (required) — Creator person ID.\n - prompt (string) (required) — Task prompt.\n - rule_id (string) (required) — Rule ID.\n - run_scope (string) (required) — Hidden session run scope. [person, team]\n - schedule_next_fire_at_ms (integer) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available.\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n", + "Automations.RuleReadList": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - rules (array) (required)\n - account_id (integer) (required) — Account ID.\n - can_edit (boolean) (required) — Whether the caller can manage this rule.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - cron_expr (string) (required) — Normalized 5-field cron expression.\n - enabled (boolean) (required) — Whether the rule is enabled.\n - environment_id (string) (required) — BYOC Runner ID.\n - environment_kind (string) (required) — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]\n - http_post_token (string) — HTTP POST trigger token. Returned only on create or token rotation; save it immediately.\n - http_post_trigger_enabled (boolean) (required) — Whether the HTTP POST trigger is enabled.\n - http_post_trigger_id (string) — HTTP POST trigger ID.\n - http_post_trigger_url (string) — HTTP POST trigger path.\n - name (string) (required) — Rule name.\n - oncall_incident_channel_ids (array) — On-call channel IDs watched by the incident trigger.\n - oncall_incident_severities (array) — Incident severities watched by the trigger. [Critical, Warning, Info]\n - oncall_incident_trigger_enabled (boolean) (required) — Whether the on-call incident trigger is enabled.\n - oncall_incident_trigger_id (string) — On-call incident trigger ID.\n - owner_id (integer) (required) — Creator person ID.\n - prompt (string) (required) — Task prompt.\n - rule_id (string) (required) — Rule ID.\n - run_scope (string) (required) — Hidden session run scope. [person, team]\n - schedule_next_fire_at_ms (integer) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available.\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n - total (integer) (required) — Total count.\n", + "Automations.RuleWriteCreate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - account_id (integer) (required) — Account ID.\n - can_edit (boolean) (required) — Whether the caller can manage this rule.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - cron_expr (string) (required) — Normalized 5-field cron expression.\n - enabled (boolean) (required) — Whether the rule is enabled.\n - environment_id (string) (required) — BYOC Runner ID.\n - environment_kind (string) (required) — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]\n - http_post_token (string) — HTTP POST trigger token. Returned only on create or token rotation; save it immediately.\n - http_post_trigger_enabled (boolean) (required) — Whether the HTTP POST trigger is enabled.\n - http_post_trigger_id (string) — HTTP POST trigger ID.\n - http_post_trigger_url (string) — HTTP POST trigger path.\n - name (string) (required) — Rule name.\n - oncall_incident_channel_ids (array) — On-call channel IDs watched by the incident trigger.\n - oncall_incident_severities (array) — Incident severities watched by the trigger. [Critical, Warning, Info]\n - oncall_incident_trigger_enabled (boolean) (required) — Whether the on-call incident trigger is enabled.\n - oncall_incident_trigger_id (string) — On-call incident trigger ID.\n - owner_id (integer) (required) — Creator person ID.\n - prompt (string) (required) — Task prompt.\n - rule_id (string) (required) — Rule ID.\n - run_scope (string) (required) — Hidden session run scope. [person, team]\n - schedule_next_fire_at_ms (integer) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available.\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n", + "Automations.RuleWriteRun": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - preflight (object) (required)\n - app_name (string) (required) — AI SRE app used to execute the rule.\n - checks (array) (required) — Preflight checks that were evaluated.\n - ok (boolean) (required) — Whether the rule can start a run.\n - owner_id (integer) (required) — Owner person ID used for the run context.\n - scope (string) (required) — Hidden session scope used for the run. [person, team]\n - team_id (integer) (required) — Team ID used for team-scoped runs; 0 for personal runs.\n - warnings (array) — Non-blocking preflight warnings.\n - rule_id (string) (required) — Rule ID.\n - run (object)\n - run_id (string) (required) — Created automation run ID.\n - session_id (string) — Hidden AI SRE session ID started for this run.\n - trigger_kind (string) (required) — Trigger kind for this run. [manual]\n", + "Automations.RuleWriteUpdate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - account_id (integer) (required) — Account ID.\n - can_edit (boolean) (required) — Whether the caller can manage this rule.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - cron_expr (string) (required) — Normalized 5-field cron expression.\n - enabled (boolean) (required) — Whether the rule is enabled.\n - environment_id (string) (required) — BYOC Runner ID.\n - environment_kind (string) (required) — Runtime environment kind. Omit or send an empty value for automatic selection. [cloud, byoc]\n - http_post_token (string) — HTTP POST trigger token. Returned only on create or token rotation; save it immediately.\n - http_post_trigger_enabled (boolean) (required) — Whether the HTTP POST trigger is enabled.\n - http_post_trigger_id (string) — HTTP POST trigger ID.\n - http_post_trigger_url (string) — HTTP POST trigger path.\n - name (string) (required) — Rule name.\n - oncall_incident_channel_ids (array) — On-call channel IDs watched by the incident trigger.\n - oncall_incident_severities (array) — Incident severities watched by the trigger. [Critical, Warning, Info]\n - oncall_incident_trigger_enabled (boolean) (required) — Whether the on-call incident trigger is enabled.\n - oncall_incident_trigger_id (string) — On-call incident trigger ID.\n - owner_id (integer) (required) — Creator person ID.\n - prompt (string) (required) — Task prompt.\n - rule_id (string) (required) — Rule ID.\n - run_scope (string) (required) — Hidden session run scope. [person, team]\n - schedule_next_fire_at_ms (integer) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available.\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n", + "Automations.RunReadList": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - runs (array) (required)\n - account_id (integer) (required) — Account ID.\n - attempts (integer) (required) — Attempt count.\n - completed_at (integer) (required) — Completion time, Unix milliseconds. 0 means not completed.\n - created_at (integer) (required) — Creation time, Unix milliseconds.\n - duration_ms (integer) (required) — Duration in milliseconds.\n - error_code (string) — Error code.\n - error_message (string) — Error message.\n - kind (string) (required) — Run kind.\n - occurrence_key (string) (required) — Idempotency key for this occurrence.\n - result_json (any) — Run result JSON.\n - rule_id (string) (required) — Rule ID.\n - run_id (string) (required) — Run ID.\n - started_at (integer) (required) — Start time, Unix milliseconds.\n - stats_json (any) — Run stats JSON.\n - status (string) (required) — Run status. [queued, running, retrying, succeeded, partial, failed, skipped, abandoned]\n - trigger_kind (string) (required) — Trigger kind. [schedule, debug, manual, http_post, oncall_incident]\n - updated_at (integer) (required) — Last update time, Unix milliseconds.\n - total (integer) (required) — Total count.\n", "Automations.TemplateReadList": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - templates (array) (required)\n - description (string) (required) — Template description.\n - enabled (boolean) (required) — Whether the template is enabled.\n - icon (string) (required) — Icon identifier.\n - name (string) (required) — Template name.\n - prompt (string) (required) — Template prompt.\n", "Calendars.CalEventList": "Response fields (this command's `--json` is a TOP-LEVEL array of these row objects — pipe `jq '.[]'`, NOT `.items[]`):\n - account_id (integer) — Account ID. Only present for private events.\n - cal_id (string) (required) — Calendar ID. For public events this is a locale key such as zh-cn.china.official.\n - created_at (integer) (required) — Creation timestamp (Unix seconds).\n - creator_id (integer) — Creator person ID. Only present for private events.\n - description (string) (required) — Event description.\n - end_at (string) (required) — Event end date (YYYY-MM-DD, exclusive).\n - event_id (string) (required) — Event ID.\n - is_off (boolean) (required) — Whether the event marks a non-working day.\n - start_at (string) (required) — Event start date (YYYY-MM-DD).\n - summary (string) (required) — Event summary.\n - updated_at (integer) (required) — Last update timestamp (Unix seconds).\n", "Calendars.CalEventUpsert": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - cal_id (string) (required) — Calendar ID.\n - event_id (string) (required) — Event ID (existing or newly generated).\n - summary (string) (required) — Event summary.\n", @@ -115,6 +116,7 @@ var responseHelpBySDKMethod = map[string]string{ "Incidents.PostmortemWriteInit": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - basics (object) (required)\n - incidents_earliest_start_seconds (integer) (required) — Earliest start time among linked incidents (seconds).\n - incidents_highest_severity (string) (required) — Highest severity among linked incidents.\n - incidents_latest_close_seconds (integer) (required) — Latest close time among linked incidents (seconds).\n - incidents_total_duration_seconds (integer) (required) — Cumulative duration in seconds.\n - responders (array) (required) — Responders involved in the incident(s).\n - acknowledged_at (integer) (required) — Unix timestamp (seconds) when the member acknowledged. 0 if not yet acknowledged.\n - as (string) — Role label of this responder.\n - assigned_at (integer) (required) — Unix timestamp (seconds) when the member was assigned.\n - email (string) — Member email, filled by the server.\n - person_id (integer) (required) — Responder member ID.\n - person_name (string) — Member display name, filled by the server.\n - content (object) (required)\n - content (string) (required) — Report body content (BlockNote JSON).\n - follow_ups (string) (required) — Follow-up action items rendered as a single string.\n - meta (object) (required) — Post-mortem metadata (lightweight shape used in lists).\n - account_id (integer) (required) — Account ID.\n - author_ids (array) (required) — Member IDs that contributed to the report.\n - channel_id (integer) (required) — Owning channel ID. 0 if none.\n - channel_name (string) (required) — Channel name, filled by the server.\n - created_at_seconds (integer) (required) — Creation timestamp (seconds).\n - incident_ids (array) (required) — Linked incident IDs.\n - is_private (boolean) (required) — When true, only team members and admins can view.\n - media_count (integer) (required) — Number of uploaded media files.\n - post_mortem_id (string) (required) — Deterministic post-mortem ID derived from account and incident IDs.\n - status (string) (required) — Report status. [drafting, published]\n - team_id (integer) (required) — Owning team ID. 0 if none.\n - template_id (string) (required) — Template used to initialize the report.\n - title (string) (required) — Report title.\n - updated_at_seconds (integer) (required) — Last update timestamp (seconds).\n", "Incidents.PostmortemWriteUpsertTemplate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - account_id (integer) (required) — Account ID that owns the template. 0 for built-in templates.\n - content (string) (required) — BlockNote JSON content used to initialize the report body.\n - content_markdown (string) (required) — Markdown version of the template content, used by AI generation.\n - created_at_seconds (integer) (required) — Unix timestamp in seconds when the template was created.\n - description (string) (required) — Template description.\n - name (string) (required) — Template name shown in the console.\n - team_id (integer) (required) — Managing team ID. Built-in templates use 0.\n - template_id (string) (required) — Template ID. Built-in templates use a stable `post_mortem_default_tmpl_*` ID.\n - updated_at_seconds (integer) (required) — Unix timestamp in seconds when the template was last updated.\n", "Incidents.ReadGetWarRoomDefaultObservers": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - observers (array) — Historical responders suggested as default war-room observers.\n - account_id (integer) — Account this person belongs to.\n - as (string) — Role the person holds in the related context.\n - avatar (string) — URL of the person's avatar image.\n - email (string) — Email address of the person.\n - locale (string) — Preferred language locale of the person.\n - person_id (integer) — Person ID.\n - person_name (string) — Display name of the person.\n - phone (string) — Phone number of the person.\n - status (string) — Current status of the person.\n - time_zone (string) — Time zone of the person.\n", + "Incidents.TriggerSubscriptionWriteUpsert": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - account_id (integer) (required) — Account ID.\n - channel_ids (array) (required) — Subscribed channel IDs.\n - consumer (string) (required) — Consumer system.\n - consumer_ref (string) (required) — Consumer-owned reference.\n - created_at (integer) (required) — Unix timestamp in seconds when the subscription was created.\n - created_by (integer) (required) — Member ID that created the subscription.\n - deleted_at (integer) (required) — Unix timestamp in seconds when the subscription was deleted; 0 means active.\n - enabled (boolean) (required) — Whether the subscription is enabled.\n - severities (array) (required) — Subscribed incident severities. [Critical, Warning, Info]\n - source (string) (required) — Subscription source.\n - subscription_id (string) (required) — Subscription ID.\n - updated_at (integer) (required) — Unix timestamp in seconds when the subscription was last updated.\n - updated_by (integer) (required) — Member ID that last updated the subscription.\n", "Incidents.WarRoomCreate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - chat_id (string) (required) — Chat/group ID on the IM side.\n - chat_name (string) (required) — Chat/group display name.\n - share_link (string) (required) — Join link for the war room, if provided by the IM.\n", "Incidents.WarRoomDetail": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - chat_id (string) (required) — Chat/group ID on the IM side.\n - chat_name (string) (required) — Chat/group display name.\n - share_link (string) (required) — Join link for the war room, if provided by the IM.\n", "Incidents.WarRoomList": "Response fields (this command's `--json` is a TOP-LEVEL array of these row objects — pipe `jq '.[]'`, NOT `.items[]`):\n - account_id (integer) (required) — Account ID.\n - chat_id (string) (required) — Chat/group ID on the IM side.\n - created_at (integer) (required) — Creation timestamp (seconds).\n - created_by (integer) (required) — Member ID that created the war room.\n - incident_id (string) (required) — Associated incident ID (MongoDB ObjectID).\n - integration_id (integer) (required) — IM integration ID.\n - plugin_type (string) (required) — IM plugin type (e.g. `feishu`, `dingtalk`, `wecom`, `slack`).\n - status (string) (required) — War room status.\n", diff --git a/internal/cli/zz_generated_roles_permissions.go b/internal/cli/zz_generated_roles_permissions.go index d4bbc98..8e6ef58 100644 --- a/internal/cli/zz_generated_roles_permissions.go +++ b/internal/cli/zz_generated_roles_permissions.go @@ -33,7 +33,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - status (string) (required) — Role status. [enabled, disabled] - updated_at (integer) (required) — Unix epoch seconds the role was last updated. `, - Args: requireExactArg("role_id"), + Args: requireBodyFieldOrExactArg("role_id", "role-id"), Example: ` flashduty role info --data '{"role_id":2}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -252,7 +252,7 @@ API: POST /role/delete (role-write-delete) Request fields: --role-id int (required) — Role ID. `, - Args: requireExactArg("role_id"), + Args: requireBodyFieldOrExactArg("role_id", "role-id"), Example: ` flashduty role delete --data '{"role_id":150}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -304,7 +304,7 @@ API: POST /role/disable (role-write-disable) Request fields: --role-id int (required) — Role ID. `, - Args: requireExactArg("role_id"), + Args: requireBodyFieldOrExactArg("role_id", "role-id"), Example: ` flashduty role disable --data '{"role_id":150}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -356,7 +356,7 @@ API: POST /role/enable (role-write-enable) Request fields: --role-id int (required) — Role ID. `, - Args: requireExactArg("role_id"), + Args: requireBodyFieldOrExactArg("role_id", "role-id"), Example: ` flashduty role enable --data '{"role_id":150}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -410,7 +410,7 @@ Request fields: --member-ids []int (required) — Member IDs to grant/revoke the role. Max 100. --role-id int (required) — Role ID to grant or revoke. `, - Args: requireArgs("member_ids"), + Args: requireBodyFieldOrArgs("member_ids", "member-ids"), Example: ` flashduty role member-grant --data '{"member_ids":[80011,80012],"role_id":150}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -468,7 +468,7 @@ Request fields: --member-ids []int (required) — Member IDs to grant/revoke the role. Max 100. --role-id int (required) — Role ID to grant or revoke. `, - Args: requireArgs("member_ids"), + Args: requireBodyFieldOrArgs("member_ids", "member-ids"), Example: ` flashduty role member-revoke --data '{"member_ids":[80011],"role_id":150}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_schedules.go b/internal/cli/zz_generated_schedules.go index 2547d36..52ddbf0 100644 --- a/internal/cli/zz_generated_schedules.go +++ b/internal/cli/zz_generated_schedules.go @@ -170,7 +170,7 @@ API: POST /schedule/delete (scheduleDelete) Request fields: --schedule-ids []int (required) — Schedule IDs to operate on. `, - Args: requireArgs("schedule_ids"), + Args: requireBodyFieldOrArgs("schedule_ids", "schedule-ids"), Example: ` flashduty schedule delete --data '{"schedule_ids":[2001]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -371,7 +371,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - update_at (integer) (required) — Last update timestamp (Unix seconds). - update_by (integer) (required) — Last updater person ID. `, - Args: requireExactArg("schedule_id"), + Args: requireBodyFieldOrExactArg("schedule_id", "schedule-id"), Example: ` flashduty schedule info --data '{"end":1712086400,"schedule_id":2001,"start":1712000000}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -554,7 +554,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - update_at (integer) (required) — Last update timestamp (Unix seconds). - update_by (integer) (required) — Last updater person ID. `, - Args: requireArgs("schedule_ids"), + Args: requireBodyFieldOrArgs("schedule_ids", "schedule-ids"), Example: ` flashduty schedule infos --data '{"schedule_ids":[2001,2002,2003]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_sessions.go b/internal/cli/zz_generated_sessions.go index 995e99c..28b78e0 100644 --- a/internal/cli/zz_generated_sessions.go +++ b/internal/cli/zz_generated_sessions.go @@ -88,7 +88,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - reasoning_tokens (integer) — Total reasoning/thinking tokens. - updated_at (integer) — Unix timestamp in milliseconds of the last session update. `, - Args: requireExactArg("session_id"), + Args: requireBodyFieldOrExactArg("session_id", "session-id"), Example: ` flashduty safari session-get --data '{"num_recent_events":50,"session_id":"sess_f8oDvqiG64uur6sBNsTc4u"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -301,7 +301,7 @@ API: POST /safari/session/delete (session-write-delete) Request fields: --session-id string (required) — Target session ID. (≥1 chars) `, - Args: requireExactArg("session_id"), + Args: requireBodyFieldOrExactArg("session_id", "session-id"), Example: ` flashduty safari session-delete --data '{"session_id":"sess_f8oDvqiG64uur6sBNsTc4u"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_skills.go b/internal/cli/zz_generated_skills.go index 17e59c9..e10cf3f 100644 --- a/internal/cli/zz_generated_skills.go +++ b/internal/cli/zz_generated_skills.go @@ -23,7 +23,7 @@ API: POST /safari/skill/enable (skill-read-enable) Request fields: --skill-id string (required) — Target skill ID. `, - Args: requireExactArg("skill_id"), + Args: requireBodyFieldOrExactArg("skill_id", "skill-id"), Example: ` flashduty safari skill-enable --data '{"skill_id":"skill_8s7Hn2kLpQ3xYbVc4Wd2m"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -96,7 +96,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) (required) — Last update time. Unix timestamp in milliseconds. - version (string) — Skill version from the frontmatter. `, - Args: requireExactArg("skill_id"), + Args: requireBodyFieldOrExactArg("skill_id", "skill-id"), Example: ` flashduty safari skill-get --data '{"skill_id":"skill_8s7Hn2kLpQ3xYbVc4Wd2m"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -239,7 +239,7 @@ API: POST /safari/skill/delete (skill-write-delete) Request fields: --skill-id string (required) — Target skill ID. `, - Args: requireExactArg("skill_id"), + Args: requireBodyFieldOrExactArg("skill_id", "skill-id"), Example: ` flashduty safari skill-delete --data '{"skill_id":"skill_8s7Hn2kLpQ3xYbVc4Wd2m"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -287,7 +287,7 @@ API: POST /safari/skill/disable (skill-write-disable) Request fields: --skill-id string (required) — Target skill ID. `, - Args: requireExactArg("skill_id"), + Args: requireBodyFieldOrExactArg("skill_id", "skill-id"), Example: ` flashduty safari skill-disable --data '{"skill_id":"skill_8s7Hn2kLpQ3xYbVc4Wd2m"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -364,7 +364,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - updated_at (integer) (required) — Last update time. Unix timestamp in milliseconds. - version (string) — Skill version from the frontmatter. `, - Args: requireExactArg("skill_id"), + Args: requireBodyFieldOrExactArg("skill_id", "skill-id"), Example: ` flashduty safari skill-update --data '{"description":"Updated triage runbook.","skill_id":"skill_8s7Hn2kLpQ3xYbVc4Wd2m"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_status_pages.go b/internal/cli/zz_generated_status_pages.go index a8c0ffd..9218e8a 100644 --- a/internal/cli/zz_generated_status_pages.go +++ b/internal/cli/zz_generated_status_pages.go @@ -130,7 +130,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - status (string) — Event status after this update. Omitted when the update does not change the overall status. [investigating, identified, monitoring, resolved, scheduled, ongoing, completed] - update_id (string) (required) — Update ID. `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -215,7 +215,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - change_id (integer) (required) — Newly created event ID. - change_name (string) (required) — Event title (echoed from the request). `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), Example: ` flashduty status-page change-create --data '{"description":"We are investigating degraded performance affecting the web console.","notify_subscribers":true,"page_id":5750613685214,"start_at_seconds":1712000000,"status":"investigating","title":"Web Console Degraded Performance","type":"incident","updates":[{"component_changes":[{"component_id":"01KC3GAZ6ZJE40H55GM31RPWZE","status":"degraded"}],"description":"We are currently investigating an issue affecting some users.","status":"investigating"}]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -495,7 +495,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - status (string) — Event status after this update. Omitted when the update does not change the overall status. [investigating, identified, monitoring, resolved, scheduled, ongoing, completed] - update_id (string) (required) — Update ID. `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { vStartAtSeconds, okStartAtSeconds, err := genParseTimeFlag(cmd, "start-at-seconds", fStartAtSeconds) @@ -854,7 +854,7 @@ Request fields: --component-ids []string (required) — IDs of components to delete. --page-id int (required) — Status page ID. `, - Args: requireArgs("component_ids"), + Args: requireBodyFieldOrArgs("component_ids", "component-ids"), Example: ` flashduty status-page component-delete --data '{"component_ids":["01KP032KMN9YFBMPWANJMFZFG1"],"page_id":5750613685214}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -921,7 +921,7 @@ Request fields: Response fields ('data' envelope is unwrapped — these fields are at the top level): - component_ids (array) (required) — IDs of the created or updated components, in the same order as the request. `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), Example: ` flashduty status-page component-upsert --data '{"components":[{"description":"Main web interface","name":"Web Console","order_id":1,"section_id":"01KC3FKKX5TSVG6Z3X1QNGF6V2"}],"page_id":5750613685214}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1043,7 +1043,7 @@ API: GET /status-page/info (statusPageInfo) Request fields: --page-id string (required) — Status page ID `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -1160,7 +1160,7 @@ Request fields: Response fields ('data' envelope is unwrapped — these fields are at the top level): - job_id (string) (required) — Migration job ID. Use this to poll status or request cancellation. `, - Args: requireExactArg("source_page_id"), + Args: requireBodyFieldOrExactArg("source_page_id", "source-page-id"), Example: ` flashduty status-page migrate-structure --data '{"api_key":"sk-stsp-xxxxxxxxxxxxxxxxxxxx","source_page_id":"abcdefghij"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1216,7 +1216,7 @@ API: POST /status-page/migration/cancel (statusPageMigrationCancel) Request fields: --job-id string (required) — Migration job ID. `, - Args: requireExactArg("job_id"), + Args: requireBodyFieldOrExactArg("job_id", "job-id"), Example: ` flashduty status-page migration-cancel --data '{"job_id":"01KP0311872NVYFRRQ82FW0001"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1290,7 +1290,7 @@ Response fields ('data' envelope is unwrapped — these fields are at the top le - target_page_id (integer) (required) — Flashduty target status page ID. Set once the job produces one, or supplied up front for subscriber migration. - updated_at (integer) (required) — Last status update time, unix seconds. `, - Args: requireExactArg("job_id"), + Args: requireBodyFieldOrExactArg("job_id", "job-id"), RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -1339,7 +1339,7 @@ Request fields: --page-id int (required) — Status page ID. --section-ids []string (required) — IDs of sections to delete. `, - Args: requireArgs("section_ids"), + Args: requireBodyFieldOrArgs("section_ids", "section-ids"), Example: ` flashduty status-page section-delete --data '{"page_id":5750613685214,"section_ids":["01KP032J1FV2H8DDGN0QSJ1CAR"]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1405,7 +1405,7 @@ Request fields: Response fields ('data' envelope is unwrapped — these fields are at the top level): - section_ids (array) (required) — IDs of the created or updated sections, in the same order as the request. `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), Example: ` flashduty status-page section-upsert --data '{"page_id":5750613685214,"sections":[{"description":"Our core services","name":"Core Services","order_id":1}]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1455,7 +1455,7 @@ Request fields: --component-ids []string — Optional component IDs to filter subscribers by. --page-id int (required) — Status page ID. `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), Example: ` flashduty status-page subscriber-export --data '{"page_id":5750613685214}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1515,7 +1515,7 @@ Request fields: - locale (string) — Preferred locale for notifications. Defaults to the request locale when omitted. - recipient (string) (required) — Email address (for public pages) or user ID (for internal pages). (≤255 chars) `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), Example: ` flashduty status-page subscriber-import --data '{"method":"email","page_id":5750613685214,"subscribers":[{"all":true,"locale":"en-US","recipient":"alice@example.com"},{"all":false,"component_ids":["01KC3GAZ6ZJE40H55GM31RPWZE"],"locale":"zh-CN","recipient":"bob@example.com"}]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { @@ -1595,7 +1595,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - recipient (string) (required) — Subscriber recipient: email address for public pages, user ID for internal pages. - total (integer) (required) — Total matching subscribers. `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -1716,7 +1716,7 @@ Request fields: --page-id int (required) — Status page ID. --type string (required) — Template category. 'pre_defined' returns predefined event templates; 'message' returns message notification templates. [pre_defined, message] `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { body, err := genAssembleBody(dataJSON, func(body map[string]any) error { @@ -1782,7 +1782,7 @@ Request fields: Response fields ('data' envelope is unwrapped — these fields are at the top level): - template_id (string) (required) — ID of the created or updated template. `, - Args: requireExactArg("page_id"), + Args: requireBodyFieldOrExactArg("page_id", "page-id"), Example: ` flashduty status-page template-upsert --data '{"page_id":5720156736380,"template":{"description":"We are investigating a service disruption affecting some users.","event_type":"incident","status":"investigating","title":"Service Disruption"},"type":"pre_defined"}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cli/zz_generated_teams.go b/internal/cli/zz_generated_teams.go index 1147e42..a1c70f0 100644 --- a/internal/cli/zz_generated_teams.go +++ b/internal/cli/zz_generated_teams.go @@ -100,7 +100,7 @@ Response fields ('data' envelope is unwrapped — rows are nested under items[]; - team_id (integer) - team_name (string) `, - Args: requireArgs("team_ids"), + Args: requireBodyFieldOrArgs("team_ids", "team-ids"), Example: ` flashduty team infos --data '{"team_ids":[1001,1002]}'`, RunE: func(cmd *cobra.Command, args []string) error { return runCommand(cmd, args, func(ctx *RunContext) error { diff --git a/internal/cmd/cligen/main.go b/internal/cmd/cligen/main.go index 2d98bc2..f817e1a 100644 --- a/internal/cmd/cligen/main.go +++ b/internal/cmd/cligen/main.go @@ -945,18 +945,18 @@ func emitCmd(fn string, s service, o specOp, mi methodInfo) string { fmt.Fprintf(&b, "\t\tShort: %q,\n", oneLine(o.Summary)) fmt.Fprintf(&b, "\t\tLong: %s,\n", quoteMultiline(longHelp(o, scalars, complexFields, specByWire))) if hasPos { - // Scalar positionals use requireExactArg so extra arguments (e.g. - // `incident info id1 id2`) are rejected with a clear error instead of - // silently dropping id2. Array positionals use requireArgs (>=1) because - // they are variadic by design. Optional scalar positionals use optionalArg - // (0-or-1) because the op also accepts an alternative lookup flag. + // Required positionals use body-aware validators: the body field can come + // from a positional, its typed flag, or --data. Scalar positionals still + // reject extras rather than silently dropping id2. Optional scalar + // positionals use optionalArg because the op accepts an alternative lookup + // flag. switch { case pos.Array: - fmt.Fprintf(&b, "\t\tArgs: requireArgs(%q),\n", pos.Wire) + fmt.Fprintf(&b, "\t\tArgs: requireBodyFieldOrArgs(%q, %q),\n", pos.Wire, flagName(pos.Wire)) case pos.Optional: fmt.Fprintf(&b, "\t\tArgs: optionalArg(%q),\n", pos.Wire) default: - fmt.Fprintf(&b, "\t\tArgs: requireExactArg(%q),\n", pos.Wire) + fmt.Fprintf(&b, "\t\tArgs: requireBodyFieldOrExactArg(%q, %q),\n", pos.Wire, flagName(pos.Wire)) } } if ex := exampleHelp(o); ex != "" {