diff --git a/go.mod b/go.mod index f3d3b98..ba51602 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.14.4 + github.com/flashcatcloud/go-flashduty v0.14.5 github.com/mattn/go-runewidth v0.0.28 github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 diff --git a/go.sum b/go.sum index 29d8cbd..1f423fc 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.14.4 h1:b+Hrkt631lP41o5M4fqxgLZPGd85CHvCnch1qv3Dj+E= -github.com/flashcatcloud/go-flashduty v0.14.4/go.mod h1:YpHiTYXR5NXBI/rGRZfUy537XMkhdCkwA8NW1QoRHwk= +github.com/flashcatcloud/go-flashduty v0.14.5 h1:MNiKJTogpO9MDU50rN5G3OUXpq7O3Tv+l4iNw2SJyGY= +github.com/flashcatcloud/go-flashduty v0.14.5/go.mod h1:YpHiTYXR5NXBI/rGRZfUy537XMkhdCkwA8NW1QoRHwk= 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.28 h1:rPyg2ybwEKPebvpzVWe1gKBkH8EQFkxO4Y0hjBeLaBU= diff --git a/internal/cli/zz_generated_artifacts.go b/internal/cli/zz_generated_artifacts.go new file mode 100644 index 0000000..ca91a7c --- /dev/null +++ b/internal/cli/zz_generated_artifacts.go @@ -0,0 +1,718 @@ +// Code generated by internal/cmd/cligen; DO NOT EDIT. + +package cli + +import ( + "github.com/spf13/cobra" + + flashduty "github.com/flashcatcloud/go-flashduty" +) + +func genArtifactsReadGetCmd() *cobra.Command { + var dataJSON string + var fArtifactID string + cmd := &cobra.Command{ + Use: "artifact-gallery-get ", + Short: "Get artifact detail", + Long: `Get artifact detail. + +Get a single published artifact by ID. + +API: POST /safari/artifact/gallery/get (artifact-read-get) + +Request fields: + --artifact-id string (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - artifact_id (string) (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + - can_edit (boolean) (required) — Whether the caller may manage this artifact (rename, transfer, delete, share): the creator, any member of the owning team, or a manager of the source session. + - content_type (string) (required) — MIME type of the file. + - created_at (string) (required) — Unix timestamp in milliseconds when the artifact was published. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - creator_name (string) (required) — Creator's display name. + - file_id (string) (required) — Presented-file ID ('pf_' prefix) currently holding the artifact's bytes. Changes on every republish. + - is_mine (boolean) (required) — Whether the caller is the creator. + - name (string) (required) — Underlying file name including extension. + - person_id (integer) (required) — Person (member) ID of the creator. + - public_url (string) — Anonymous public link — a console '/share/artifact/' page served entirely from CDN. Present only while shared; anyone with the link can view it, no login required. + - session_id (string) (required) — Source session ID ('sess_' prefix) that produced the file. + - session_title (string) — Source session's title. Omitted when the session has been deleted. + - share_enabled (boolean) — Whether anonymous public sharing is on. Omitted when false. + - share_file_id (string) — Presented-file ID the public snapshot was materialized from. When 'share_enabled' is true and 'file_id' differs from 'share_file_id', the public snapshot is stale — call '/safari/artifact/gallery/share/sync' to refresh it. + - shared_at (string) — Unix timestamp in milliseconds of the last share enable or snapshot sync. Present only while shared. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - shared_by (integer) — Person ID of the member who enabled sharing. Present only while shared. + - size (integer) (required) — File size in bytes. + - team_id (integer) (required) — Owning team ID. '0' means a personal artifact (creator-only management); a positive value means team-owned. + - team_name (string) — Owning team's display name. Omitted for personal artifacts. + - title (string) (required) — Display title in the gallery. + - updated_at (string) (required) — Unix timestamp in milliseconds when the artifact was last updated (rename, transfer, or republish). CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. +`, + Args: requireBodyFieldOrExactArg("artifact_id", "artifact-id"), + Example: ` flashduty safari artifact-gallery-get --data '{"artifact_id":"art_VnfrWic8UbB9q3EfYR4Gmg"}'`, + 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, "artifact_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("artifact-id") { + body["artifact_id"] = fArtifactID + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactIDRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.ReadGet(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fArtifactID, "artifact-id", "", "Artifact ID ('art_' prefix). Also the key of the public-share link. (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 genArtifactsReadGetFileStateCmd() *cobra.Command { + var dataJSON string + var fFileIDs []string + cmd := &cobra.Command{ + Use: "artifact-gallery-file-state [...]", + Short: "Get file publish state", + Long: `Get file publish state. + +Check which presented files already have a live published artifact. + +API: POST /safari/artifact/gallery/file-state (artifact-read-get-file-state) + +Request fields: + --file-ids []string (required) — Presented-file IDs ('pf_' prefix) to probe. At most 50 per call; duplicates and empty strings are ignored. + +Response fields ('data' envelope is unwrapped — rows are nested under items[]; pipe 'jq '.items[]'', NOT '.data.items[]'): + - items (array) (required) — One entry per requested file that has a live published artifact; files without one are omitted. + - artifact_id (string) (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + - file_id (string) (required) — Echoes the requested presented-file ID. + - gallery_path (string) (required) — Console-relative path of the artifact page: '/ai-sre/artifacts/'. + - title (string) (required) — Gallery display title of the published artifact. +`, + Args: requireBodyFieldOrArgs("file_ids", "file-ids"), + Example: ` flashduty safari artifact-gallery-file-state --data '{"file_ids":["pf_SdhEA5fbZJGnHzwrNJMMSB","pf_9kLm2nQpRsTuVwXyZaBcDe"]}'`, + 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, "file_ids", "slice"); err != nil { + return err + } + if cmd.Flags().Changed("file-ids") { + body["file_ids"] = fFileIDs + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactFileStateRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.ReadGetFileState(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringSliceVar(&fFileIDs, "file-ids", nil, "Presented-file IDs ('pf_' prefix) to probe. At most 50 per call; duplicates and empty strings are ignored. (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 genArtifactsReadListCmd() *cobra.Command { + var dataJSON string + var fAsc bool + var fLimit int64 + var fOrderby string + var fPage int64 + var fQuery string + var fScope string + var fTeamIDs []int + cmd := &cobra.Command{ + Use: "artifact-gallery-list", + Short: "List artifacts", + Long: `List artifacts. + +List published artifacts visible to the caller, with pagination and title search. + +API: POST /safari/artifact/gallery/list (artifact-read-list) + +Request fields: + --asc bool — Sort ascending when true, descending when false. Applies only when 'orderby' is set. + --limit int — Page size. Defaults to 20; capped at 100. (max 100) + --orderby string — Sort field: 'created_at' or 'updated_at'. Empty means 'updated_at' descending. [created_at, updated_at] + --page int — Page number, 1-based. (min 1) + --query string — Case-insensitive substring match on the artifact title. + --scope string — Visibility scope. 'all' (default) lists the caller's own personal artifacts plus artifacts of every team the caller belongs to; 'personal' lists only the caller's own; 'team' lists only team-owned artifacts of the caller's teams. [all, personal, team] + --team-ids []int — Restrict to artifacts owned by these team IDs, intersected with the caller's visibility — teams the caller does not belong to silently return nothing. + +Response fields ('data' envelope is unwrapped — rows are nested under items[]; pipe 'jq '.items[]'', NOT '.data.items[]'): + - items (array) — Artifacts on this page. + - artifact_id (string) (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + - can_edit (boolean) (required) — Whether the caller may manage this artifact (rename, transfer, delete, share): the creator, any member of the owning team, or a manager of the source session. + - content_type (string) (required) — MIME type of the file. + - created_at (string) (required) — Unix timestamp in milliseconds when the artifact was published. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - creator_name (string) (required) — Creator's display name. + - file_id (string) (required) — Presented-file ID ('pf_' prefix) currently holding the artifact's bytes. Changes on every republish. + - is_mine (boolean) (required) — Whether the caller is the creator. + - name (string) (required) — Underlying file name including extension. + - person_id (integer) (required) — Person (member) ID of the creator. + - public_url (string) — Anonymous public link — a console '/share/artifact/' page served entirely from CDN. Present only while shared; anyone with the link can view it, no login required. + - session_id (string) (required) — Source session ID ('sess_' prefix) that produced the file. + - session_title (string) — Source session's title. Omitted when the session has been deleted. + - share_enabled (boolean) — Whether anonymous public sharing is on. Omitted when false. + - share_file_id (string) — Presented-file ID the public snapshot was materialized from. When 'share_enabled' is true and 'file_id' differs from 'share_file_id', the public snapshot is stale — call '/safari/artifact/gallery/share/sync' to refresh it. + - shared_at (string) — Unix timestamp in milliseconds of the last share enable or snapshot sync. Present only while shared. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - shared_by (integer) — Person ID of the member who enabled sharing. Present only while shared. + - size (integer) (required) — File size in bytes. + - team_id (integer) (required) — Owning team ID. '0' means a personal artifact (creator-only management); a positive value means team-owned. + - team_name (string) — Owning team's display name. Omitted for personal artifacts. + - title (string) (required) — Display title in the gallery. + - updated_at (string) (required) — Unix timestamp in milliseconds when the artifact was last updated (rename, transfer, or republish). CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - total (integer) — Total number of artifacts matching the filter across all pages. +`, + Example: ` flashduty safari artifact-gallery-list --data '{"limit":20,"page":1,"scope":"all"}'`, + 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("asc") { + body["asc"] = fAsc + } + if cmd.Flags().Changed("limit") { + body["limit"] = fLimit + } + if cmd.Flags().Changed("orderby") { + body["orderby"] = fOrderby + } + if cmd.Flags().Changed("page") { + body["page"] = fPage + } + if cmd.Flags().Changed("query") { + body["query"] = fQuery + } + if cmd.Flags().Changed("scope") { + body["scope"] = fScope + } + if cmd.Flags().Changed("team-ids") { + body["team_ids"] = fTeamIDs + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactListRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.ReadList(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().BoolVar(&fAsc, "asc", false, "Sort ascending when true, descending when false. Applies only when 'orderby' is set.") + cmd.Flags().Int64Var(&fLimit, "limit", 0, "Page size. Defaults to 20; capped at 100. (max 100)") + cmd.Flags().StringVar(&fOrderby, "orderby", "", "Sort field: 'created_at' or 'updated_at'. Empty means 'updated_at' descending. [created_at, updated_at]") + cmd.Flags().Int64Var(&fPage, "page", 0, "Page number, 1-based. (min 1)") + cmd.Flags().StringVar(&fQuery, "query", "", "Case-insensitive substring match on the artifact title.") + cmd.Flags().StringVar(&fScope, "scope", "", "Visibility scope. 'all' (default) lists the caller's own personal artifacts plus artifacts of every team the caller belongs to; 'personal' lists only the caller's own; 'team' lists only team-owned artifacts of the caller's teams. [all, personal, team]") + cmd.Flags().IntSliceVar(&fTeamIDs, "team-ids", nil, "Restrict to artifacts owned by these team IDs, intersected with the caller's visibility — teams the caller does not belong to silently return nothing.") + 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 genArtifactsReadSignCmd() *cobra.Command { + var dataJSON string + var fFileID string + var fShareToken string + cmd := &cobra.Command{ + Use: "artifact-sign ", + Short: "Create signed file URLs", + Long: `Create signed file URLs. + +Create short-lived signed URLs to download or preview a presented file. + +API: POST /safari/artifact/sign (artifact-read-sign) + +Request fields: + --file-id string (required) — Presented-file ID ('pf_' prefix) to sign. + --share-token string — Optional session share-link token. Needed only when the caller reaches the file through a shared session link rather than account membership. + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - content_type (string) (required) — MIME type of the file. + - download_url (string) (required) — Relative URL ('/safari/artifact/stream?...') that serves the file as an attachment. Prepend the API base 'https://api.flashcat.cloud' before use; expires with 'expires_in'. + - expires_in (integer) (required) — Validity of both URLs in seconds (300). + - name (string) (required) — File name including extension. + - preview_url (string) (required) — Same as 'download_url' but served inline for browser preview. + - size (integer) (required) — File size in bytes. +`, + Args: requireBodyFieldOrExactArg("file_id", "file-id"), + Example: ` flashduty safari artifact-sign --data '{"file_id":"pf_SdhEA5fbZJGnHzwrNJMMSB"}'`, + 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, "file_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("file-id") { + body["file_id"] = fFileID + } + if cmd.Flags().Changed("share-token") { + body["share_token"] = fShareToken + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactSignRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.ReadSign(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fFileID, "file-id", "", "Presented-file ID ('pf_' prefix) to sign. (required)") + cmd.Flags().StringVar(&fShareToken, "share-token", "", "Optional session share-link token. Needed only when the caller reaches the file through a shared session link rather than account membership.") + 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 genArtifactsReadStreamCmd() *cobra.Command { + var dataJSON string + var fT string + var fMode string + cmd := &cobra.Command{ + Use: "artifact-stream", + Short: "Download or preview a file", + Long: `Download or preview a file. + +Download or preview a file's bytes using a signed token. + +API: GET /safari/artifact/stream (artifact-read-stream) + +Request fields: + --t string (required) — Signed token issued by 'POST /safari/artifact/sign'. Bound to the calling account and person; valid for 5 minutes. + --mode string — 'download' (default) serves the file as an attachment; 'preview' serves it inline for browser display. Any other value falls back to 'download'. [download, preview] +`, + 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("t") { + body["t"] = fT + } + if cmd.Flags().Changed("mode") { + body["mode"] = fMode + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactsReadStreamRequest) + if err := genBindBody(body, req); err != nil { + return err + } + resp, err := ctx.Client.Artifacts.ReadStream(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + if resp != nil && len(resp.Raw) > 0 { + return ctx.WriteRaw(resp.Raw) + } + ctx.WriteResult("OK: GET /safari/artifact/stream") + return nil + }) + }, + } + cmd.Flags().StringVar(&fT, "t", "", "Signed token issued by 'POST /safari/artifact/sign'. Bound to the calling account and person; valid for 5 minutes. (required)") + cmd.Flags().StringVar(&fMode, "mode", "", "'download' (default) serves the file as an attachment; 'preview' serves it inline for browser display. Any other value falls back to 'download'. [download, preview]") + 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 genArtifactsWriteDeleteCmd() *cobra.Command { + var dataJSON string + var fArtifactID string + cmd := &cobra.Command{ + Use: "artifact-gallery-delete ", + Short: "Remove artifact from gallery", + Long: `Remove artifact from gallery. + +Detach an artifact from the gallery; the source file stays with its session. + +API: POST /safari/artifact/gallery/delete (artifact-write-delete) + +Request fields: + --artifact-id string (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. +`, + Args: requireBodyFieldOrExactArg("artifact_id", "artifact-id"), + Example: ` flashduty safari artifact-gallery-delete --data '{"artifact_id":"art_CWQzDU2PXSRJvKDhQbuMKu"}'`, + 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, "artifact_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("artifact-id") { + body["artifact_id"] = fArtifactID + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactIDRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.WriteDelete(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fArtifactID, "artifact-id", "", "Artifact ID ('art_' prefix). Also the key of the public-share link. (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 genArtifactsWritePublishCmd() *cobra.Command { + var dataJSON string + var fFileID string + var fTitle string + cmd := &cobra.Command{ + Use: "artifact-gallery-publish-from-file ", + Short: "Publish file as artifact", + Long: `Publish file as artifact. + +Publish a session-produced file to the artifact gallery. + +API: POST /safari/artifact/gallery/publish-from-file (artifact-write-publish) + +Request fields: + --file-id string (required) — Presented-file ID ('pf_' prefix) of a file produced in a session, as shown on the file card in chat. + --title string (required) — Gallery display title. Trimmed; must be non-empty. + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - artifact_id (string) (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + - gallery_path (string) (required) — Console-relative path of the artifact page: '/ai-sre/artifacts/'. + - title (string) (required) — Gallery display title. +`, + Args: requireBodyFieldOrExactArg("file_id", "file-id"), + Example: ` flashduty safari artifact-gallery-publish-from-file --data '{"file_id":"pf_SdhEA5fbZJGnHzwrNJMMSB","title":"SK 海力士 2026 Q2 财报深度分析"}'`, + 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, "file_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("file-id") { + body["file_id"] = fFileID + } + if cmd.Flags().Changed("title") { + body["title"] = fTitle + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactPublishFromFileRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.WritePublish(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fFileID, "file-id", "", "Presented-file ID ('pf_' prefix) of a file produced in a session, as shown on the file card in chat. (required)") + cmd.Flags().StringVar(&fTitle, "title", "", "Gallery display title. Trimmed; must be non-empty. (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 genArtifactsWriteShareEnableCmd() *cobra.Command { + var dataJSON string + var fArtifactID string + cmd := &cobra.Command{ + Use: "artifact-gallery-share-enable ", + Short: "Enable public sharing", + Long: `Enable public sharing. + +Turn on anonymous public sharing for an artifact and return its public link. + +API: POST /safari/artifact/gallery/share/enable (artifact-write-share-enable) + +Request fields: + --artifact-id string (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - artifact_id (string) (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + - public_url (string) (required) — Anonymous public link served entirely from CDN. Anyone with the link can view the content, no login required. + - share_enabled (boolean) (required) — Always 'true' in this response. + - shared_at (string) (required) — Unix timestamp in milliseconds of the last share enable or snapshot sync. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - shared_by (integer) (required) — Person ID of the member who enabled sharing. +`, + Args: requireBodyFieldOrExactArg("artifact_id", "artifact-id"), + Example: ` flashduty safari artifact-gallery-share-enable --data '{"artifact_id":"art_VnfrWic8UbB9q3EfYR4Gmg"}'`, + 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, "artifact_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("artifact-id") { + body["artifact_id"] = fArtifactID + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactIDRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.WriteShareEnable(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fArtifactID, "artifact-id", "", "Artifact ID ('art_' prefix). Also the key of the public-share link. (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 genArtifactsWriteShareRevokeCmd() *cobra.Command { + var dataJSON string + var fArtifactID string + cmd := &cobra.Command{ + Use: "artifact-gallery-share-revoke ", + Short: "Revoke public sharing", + Long: `Revoke public sharing. + +Turn off public sharing; the link stops resolving immediately. + +API: POST /safari/artifact/gallery/share/revoke (artifact-write-share-revoke) + +Request fields: + --artifact-id string (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. +`, + Args: requireBodyFieldOrExactArg("artifact_id", "artifact-id"), + Example: ` flashduty safari artifact-gallery-share-revoke --data '{"artifact_id":"art_VnfrWic8UbB9q3EfYR4Gmg"}'`, + 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, "artifact_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("artifact-id") { + body["artifact_id"] = fArtifactID + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactIDRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.WriteShareRevoke(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fArtifactID, "artifact-id", "", "Artifact ID ('art_' prefix). Also the key of the public-share link. (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 genArtifactsWriteShareSyncCmd() *cobra.Command { + var dataJSON string + var fArtifactID string + cmd := &cobra.Command{ + Use: "artifact-gallery-share-sync ", + Short: "Update shared snapshot", + Long: `Update shared snapshot. + +Refresh the public snapshot of a shared artifact with its latest content. + +API: POST /safari/artifact/gallery/share/sync (artifact-write-share-sync) + +Request fields: + --artifact-id string (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - artifact_id (string) (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + - public_url (string) (required) — Anonymous public link served entirely from CDN. Anyone with the link can view the content, no login required. + - share_enabled (boolean) (required) — Always 'true' in this response. + - shared_at (string) (required) — Unix timestamp in milliseconds of the last share enable or snapshot sync. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - shared_by (integer) (required) — Person ID of the member who enabled sharing. +`, + Args: requireBodyFieldOrExactArg("artifact_id", "artifact-id"), + Example: ` flashduty safari artifact-gallery-share-sync --data '{"artifact_id":"art_VnfrWic8UbB9q3EfYR4Gmg"}'`, + 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, "artifact_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("artifact-id") { + body["artifact_id"] = fArtifactID + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactIDRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.WriteShareSync(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fArtifactID, "artifact-id", "", "Artifact ID ('art_' prefix). Also the key of the public-share link. (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 genArtifactsWriteUpdateCmd() *cobra.Command { + var dataJSON string + var fArtifactID string + var fTeamID int64 + var fTitle string + cmd := &cobra.Command{ + Use: "artifact-gallery-update ", + Short: "Update artifact", + Long: `Update artifact. + +Rename an artifact or transfer it between personal and team scope. + +API: POST /safari/artifact/gallery/update (artifact-write-update) + +Request fields: + --artifact-id string (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + --team-id int — Transfer target scope. '0' moves the artifact to personal scope (only the creator can manage it); a positive value moves it to a team the caller must belong to. Omit to leave unchanged. + --title string — New title. Trimmed; must be non-empty when provided. Omit to leave unchanged. + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - artifact_id (string) (required) — Artifact ID ('art_' prefix). Also the key of the public-share link. + - can_edit (boolean) (required) — Whether the caller may manage this artifact (rename, transfer, delete, share): the creator, any member of the owning team, or a manager of the source session. + - content_type (string) (required) — MIME type of the file. + - created_at (string) (required) — Unix timestamp in milliseconds when the artifact was published. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - creator_name (string) (required) — Creator's display name. + - file_id (string) (required) — Presented-file ID ('pf_' prefix) currently holding the artifact's bytes. Changes on every republish. + - is_mine (boolean) (required) — Whether the caller is the creator. + - name (string) (required) — Underlying file name including extension. + - person_id (integer) (required) — Person (member) ID of the creator. + - public_url (string) — Anonymous public link — a console '/share/artifact/' page served entirely from CDN. Present only while shared; anyone with the link can view it, no login required. + - session_id (string) (required) — Source session ID ('sess_' prefix) that produced the file. + - session_title (string) — Source session's title. Omitted when the session has been deleted. + - share_enabled (boolean) — Whether anonymous public sharing is on. Omitted when false. + - share_file_id (string) — Presented-file ID the public snapshot was materialized from. When 'share_enabled' is true and 'file_id' differs from 'share_file_id', the public snapshot is stale — call '/safari/artifact/gallery/share/sync' to refresh it. + - shared_at (string) — Unix timestamp in milliseconds of the last share enable or snapshot sync. Present only while shared. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - shared_by (integer) — Person ID of the member who enabled sharing. Present only while shared. + - size (integer) (required) — File size in bytes. + - team_id (integer) (required) — Owning team ID. '0' means a personal artifact (creator-only management); a positive value means team-owned. + - team_name (string) — Owning team's display name. Omitted for personal artifacts. + - title (string) (required) — Display title in the gallery. + - updated_at (string) (required) — Unix timestamp in milliseconds when the artifact was last updated (rename, transfer, or republish). CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. +`, + Args: requireBodyFieldOrExactArg("artifact_id", "artifact-id"), + Example: ` flashduty safari artifact-gallery-update --data '{"artifact_id":"art_VnfrWic8UbB9q3EfYR4Gmg","title":"SK 海力士 2026 Q2 财报深度分析(终稿)"}'`, + 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, "artifact_id", "string"); err != nil { + return err + } + if cmd.Flags().Changed("artifact-id") { + body["artifact_id"] = fArtifactID + } + if cmd.Flags().Changed("team-id") { + body["team_id"] = fTeamID + } + if cmd.Flags().Changed("title") { + body["title"] = fTitle + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.ArtifactUpdateRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.Artifacts.WriteUpdate(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fArtifactID, "artifact-id", "", "Artifact ID ('art_' prefix). Also the key of the public-share link. (required)") + cmd.Flags().Int64Var(&fTeamID, "team-id", 0, "Transfer target scope. '0' moves the artifact to personal scope (only the creator can manage it); a positive value moves it to a team the caller must belong to. Omit to leave unchanged.") + cmd.Flags().StringVar(&fTitle, "title", "", "New title. Trimmed; must be non-empty when provided. Omit to leave unchanged.") + 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 registerGeneratedArtifacts(root *cobra.Command) { + gSafari := genGroup(root, "safari", "AI SRE API") + genAddLeaf(gSafari, genArtifactsReadGetCmd()) + genAddLeaf(gSafari, genArtifactsReadGetFileStateCmd()) + genAddLeaf(gSafari, genArtifactsReadListCmd()) + genAddLeaf(gSafari, genArtifactsReadSignCmd()) + genAddLeaf(gSafari, genArtifactsReadStreamCmd()) + genAddLeaf(gSafari, genArtifactsWriteDeleteCmd()) + genAddLeaf(gSafari, genArtifactsWritePublishCmd()) + genAddLeaf(gSafari, genArtifactsWriteShareEnableCmd()) + genAddLeaf(gSafari, genArtifactsWriteShareRevokeCmd()) + genAddLeaf(gSafari, genArtifactsWriteShareSyncCmd()) + genAddLeaf(gSafari, genArtifactsWriteUpdateCmd()) +} diff --git a/internal/cli/zz_generated_manifest.go b/internal/cli/zz_generated_manifest.go index 97747f6..faa7b0e 100644 --- a/internal/cli/zz_generated_manifest.go +++ b/internal/cli/zz_generated_manifest.go @@ -16,6 +16,17 @@ var generatedOpIDs = []string{ "alert-read-pipeline-list", "alert-write-merge", "alert-write-pipeline-upsert", + "artifact-read-get", + "artifact-read-get-file-state", + "artifact-read-list", + "artifact-read-sign", + "artifact-read-stream", + "artifact-write-delete", + "artifact-write-publish", + "artifact-write-share-enable", + "artifact-write-share-revoke", + "artifact-write-share-sync", + "artifact-write-update", "audit-read-operation-list", "audit-read-search", "automation-rule-read-get", @@ -310,6 +321,7 @@ var generatedOpIDs = []string{ "statusPageComponentUpsert", "statusPageCreate", "statusPageDelete", + "statusPageDraftCreate", "statusPageInfo", "statusPageMigrateEmailSubscribers", "statusPageMigrateStructure", diff --git a/internal/cli/zz_generated_register.go b/internal/cli/zz_generated_register.go index f9e7ec3..c9c74a3 100644 --- a/internal/cli/zz_generated_register.go +++ b/internal/cli/zz_generated_register.go @@ -8,6 +8,7 @@ import "github.com/spf13/cobra" // from root.go init() after curated commands so curated leaves win on conflict. func registerGenerated(root *cobra.Command) { registerGeneratedA2aAgents(root) + registerGeneratedArtifacts(root) registerGeneratedAutomations(root) registerGeneratedKnowledge(root) registerGeneratedMcpServers(root) diff --git a/internal/cli/zz_generated_response_help.go b/internal/cli/zz_generated_response_help.go index 55bf079..d381e2e 100644 --- a/internal/cli/zz_generated_response_help.go +++ b/internal/cli/zz_generated_response_help.go @@ -55,6 +55,14 @@ var responseHelpBySDKMethod = map[string]string{ "Applications.ReadList": "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.\n - alerting (object) — Alerting configuration of the application.\n - channel_ids (array) — Channel IDs to send alerts to. Used only when `delivery_mode` is `oncall`.\n - delivery_mode (string) — Alert delivery channel: `oncall` routes alert events through Flashduty On-call, `webhook` POSTs them directly to `webhook_url`. An empty value is treated as `oncall`, and on create/update it is persisted as the deployment default (`webhook` on RUM-only on-premises deployments, `oncall` otherwise). Omitted when empty (legacy rows). [oncall, webhook]\n - enabled (boolean) (required) — Whether alerting is enabled.\n - integration_id (integer) — Associated on-call integration ID (read-only, auto-assigned on save when `delivery_mode` is `oncall`).\n - webhook_url (string) — URL that receives alert events when `delivery_mode` is `webhook`; required in that mode, ignored otherwise. Omitted when empty.\n - application_id (string) — Unique application ID.\n - application_name (string) — Application display name.\n - client_token (string) — Token used to initialize the RUM SDK.\n - created_at (string) — Creation timestamp, Unix epoch milliseconds. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - created_by (integer) — Creator member ID.\n - is_private (boolean) — If `true`, the application is only accessible to team members.\n - links (object) — External-link integration configuration.\n - enabled (boolean) (required) — Whether external link integration is enabled.\n - systems (array) — External systems whose URL templates can be opened from matching RUM events.\n - enabled (boolean) (required) — Whether this external system link is enabled.\n - event_types (array) (required) — RUM event types where this external system link is shown; at least one is required. | Value | Meaning | |---|---| | `crash` | Crash events (errors flagged `is_crash`) | | `error` | Error events | | `view` | Page/screen view events | | `action` | User action events | | `resource` | Resource load events | | `session` | Session events | | `all` | All event types | [crash, error, view, action, resource, session, all]\n - icon_color (string) — Display color for the link icon.\n - icon_text (string) — Short text shown in the link icon.\n - id (string) — Stable client-side identifier for this external system.\n - name (string) (required) — Display name of the external system.\n - url (string) (required) — HTTP or HTTPS URL template. `${var}` tokens are resolved from the RUM event context.\n - no_geo (boolean) — If `true`, geographic location is not inferred from IP.\n - no_ip (boolean) — If `true`, IP addresses are not collected.\n - status (string) — Application status. One of `enabled` (active, receiving data), `disabled` (deactivated), `deleted` (soft-delete marker; every query filters it out, so it never actually appears in responses). [enabled, disabled, deleted]\n - team_id (integer) — Owning team ID.\n - tracing (object) — APM tracing integration configuration.\n - enabled (boolean) (required) — Whether tracing integration is enabled.\n - endpoint (string) (required) — Trace endpoint URL (http or https).\n - open_type (string) (required) — How to open the trace link. One of `popup` (open trace details in a popup) or `tab` (open in a new browser tab). [popup, tab]\n - type (string) — Platform identifier: | Value | Meaning | |---|---| | `browser` | Web browser application (JavaScript SDK) | | `ios` | Apple iOS application | | `android` | Android application | | `react-native` | React Native application | | `flutter` | Flutter application | | `kotlin-multiplatform` | Kotlin Multiplatform application | | `roku` | Roku channel application | | `unity` | Unity application | | `miniprogram` | WeChat mini program | | `harmony` | HarmonyOS application | | `electron` | Electron desktop application | [browser, ios, android, react-native, flutter, kotlin-multiplatform, roku, unity, miniprogram, harmony, electron]\n - updated_at (string) — Last update timestamp, Unix epoch milliseconds. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - updated_by (integer) — Last updater member ID.\n", "Applications.WebhookTest": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - message (string) (required) — `ok` on success, otherwise the delivery error message.\n - ok (boolean) (required) — Whether the webhook endpoint accepted the sample event.\n - status_code (integer) (required) — HTTP status code returned by the webhook endpoint. 0 when the request did not receive a response.\n", "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", + "Artifacts.ReadGet": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - artifact_id (string) (required) — Artifact ID (`art_` prefix). Also the key of the public-share link.\n - can_edit (boolean) (required) — Whether the caller may manage this artifact (rename, transfer, delete, share): the creator, any member of the owning team, or a manager of the source session.\n - content_type (string) (required) — MIME type of the file.\n - created_at (string) (required) — Unix timestamp in milliseconds when the artifact was published. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - creator_name (string) (required) — Creator's display name.\n - file_id (string) (required) — Presented-file ID (`pf_` prefix) currently holding the artifact's bytes. Changes on every republish.\n - is_mine (boolean) (required) — Whether the caller is the creator.\n - name (string) (required) — Underlying file name including extension.\n - person_id (integer) (required) — Person (member) ID of the creator.\n - public_url (string) — Anonymous public link — a console `/share/artifact/` page served entirely from CDN. Present only while shared; anyone with the link can view it, no login required.\n - session_id (string) (required) — Source session ID (`sess_` prefix) that produced the file.\n - session_title (string) — Source session's title. Omitted when the session has been deleted.\n - share_enabled (boolean) — Whether anonymous public sharing is on. Omitted when false.\n - share_file_id (string) — Presented-file ID the public snapshot was materialized from. When `share_enabled` is true and `file_id` differs from `share_file_id`, the public snapshot is stale — call `/safari/artifact/gallery/share/sync` to refresh it.\n - shared_at (string) — Unix timestamp in milliseconds of the last share enable or snapshot sync. Present only while shared. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - shared_by (integer) — Person ID of the member who enabled sharing. Present only while shared.\n - size (integer) (required) — File size in bytes.\n - team_id (integer) (required) — Owning team ID. `0` means a personal artifact (creator-only management); a positive value means team-owned.\n - team_name (string) — Owning team's display name. Omitted for personal artifacts.\n - title (string) (required) — Display title in the gallery.\n - updated_at (string) (required) — Unix timestamp in milliseconds when the artifact was last updated (rename, transfer, or republish). CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n", + "Artifacts.ReadGetFileState": "Response fields (this command's `--json` is a TOP-LEVEL array of these row objects — pipe `jq '.[]'`, NOT `.items[]`):\n - artifact_id (string) (required) — Artifact ID (`art_` prefix). Also the key of the public-share link.\n - file_id (string) (required) — Echoes the requested presented-file ID.\n - gallery_path (string) (required) — Console-relative path of the artifact page: `/ai-sre/artifacts/`.\n - title (string) (required) — Gallery display title of the published artifact.\n", + "Artifacts.ReadList": "Response fields (this command's `--json` is a TOP-LEVEL array of these row objects — pipe `jq '.[]'`, NOT `.items[]`):\n - artifact_id (string) (required) — Artifact ID (`art_` prefix). Also the key of the public-share link.\n - can_edit (boolean) (required) — Whether the caller may manage this artifact (rename, transfer, delete, share): the creator, any member of the owning team, or a manager of the source session.\n - content_type (string) (required) — MIME type of the file.\n - created_at (string) (required) — Unix timestamp in milliseconds when the artifact was published. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - creator_name (string) (required) — Creator's display name.\n - file_id (string) (required) — Presented-file ID (`pf_` prefix) currently holding the artifact's bytes. Changes on every republish.\n - is_mine (boolean) (required) — Whether the caller is the creator.\n - name (string) (required) — Underlying file name including extension.\n - person_id (integer) (required) — Person (member) ID of the creator.\n - public_url (string) — Anonymous public link — a console `/share/artifact/` page served entirely from CDN. Present only while shared; anyone with the link can view it, no login required.\n - session_id (string) (required) — Source session ID (`sess_` prefix) that produced the file.\n - session_title (string) — Source session's title. Omitted when the session has been deleted.\n - share_enabled (boolean) — Whether anonymous public sharing is on. Omitted when false.\n - share_file_id (string) — Presented-file ID the public snapshot was materialized from. When `share_enabled` is true and `file_id` differs from `share_file_id`, the public snapshot is stale — call `/safari/artifact/gallery/share/sync` to refresh it.\n - shared_at (string) — Unix timestamp in milliseconds of the last share enable or snapshot sync. Present only while shared. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - shared_by (integer) — Person ID of the member who enabled sharing. Present only while shared.\n - size (integer) (required) — File size in bytes.\n - team_id (integer) (required) — Owning team ID. `0` means a personal artifact (creator-only management); a positive value means team-owned.\n - team_name (string) — Owning team's display name. Omitted for personal artifacts.\n - title (string) (required) — Display title in the gallery.\n - updated_at (string) (required) — Unix timestamp in milliseconds when the artifact was last updated (rename, transfer, or republish). CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n", + "Artifacts.ReadSign": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - content_type (string) (required) — MIME type of the file.\n - download_url (string) (required) — Relative URL (`/safari/artifact/stream?...`) that serves the file as an attachment. Prepend the API base `https://api.flashcat.cloud` before use; expires with `expires_in`.\n - expires_in (integer) (required) — Validity of both URLs in seconds (300).\n - name (string) (required) — File name including extension.\n - preview_url (string) (required) — Same as `download_url` but served inline for browser preview.\n - size (integer) (required) — File size in bytes.\n", + "Artifacts.WritePublish": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - artifact_id (string) (required) — Artifact ID (`art_` prefix). Also the key of the public-share link.\n - gallery_path (string) (required) — Console-relative path of the artifact page: `/ai-sre/artifacts/`.\n - title (string) (required) — Gallery display title.\n", + "Artifacts.WriteShareEnable": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - artifact_id (string) (required) — Artifact ID (`art_` prefix). Also the key of the public-share link.\n - public_url (string) (required) — Anonymous public link served entirely from CDN. Anyone with the link can view the content, no login required.\n - share_enabled (boolean) (required) — Always `true` in this response.\n - shared_at (string) (required) — Unix timestamp in milliseconds of the last share enable or snapshot sync. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - shared_by (integer) (required) — Person ID of the member who enabled sharing.\n", + "Artifacts.WriteShareSync": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - artifact_id (string) (required) — Artifact ID (`art_` prefix). Also the key of the public-share link.\n - public_url (string) (required) — Anonymous public link served entirely from CDN. Anyone with the link can view the content, no login required.\n - share_enabled (boolean) (required) — Always `true` in this response.\n - shared_at (string) (required) — Unix timestamp in milliseconds of the last share enable or snapshot sync. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - shared_by (integer) (required) — Person ID of the member who enabled sharing.\n", + "Artifacts.WriteUpdate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - artifact_id (string) (required) — Artifact ID (`art_` prefix). Also the key of the public-share link.\n - can_edit (boolean) (required) — Whether the caller may manage this artifact (rename, transfer, delete, share): the creator, any member of the owning team, or a manager of the source session.\n - content_type (string) (required) — MIME type of the file.\n - created_at (string) (required) — Unix timestamp in milliseconds when the artifact was published. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - creator_name (string) (required) — Creator's display name.\n - file_id (string) (required) — Presented-file ID (`pf_` prefix) currently holding the artifact's bytes. Changes on every republish.\n - is_mine (boolean) (required) — Whether the caller is the creator.\n - name (string) (required) — Underlying file name including extension.\n - person_id (integer) (required) — Person (member) ID of the creator.\n - public_url (string) — Anonymous public link — a console `/share/artifact/` page served entirely from CDN. Present only while shared; anyone with the link can view it, no login required.\n - session_id (string) (required) — Source session ID (`sess_` prefix) that produced the file.\n - session_title (string) — Source session's title. Omitted when the session has been deleted.\n - share_enabled (boolean) — Whether anonymous public sharing is on. Omitted when false.\n - share_file_id (string) — Presented-file ID the public snapshot was materialized from. When `share_enabled` is true and `file_id` differs from `share_file_id`, the public snapshot is stale — call `/safari/artifact/gallery/share/sync` to refresh it.\n - shared_at (string) — Unix timestamp in milliseconds of the last share enable or snapshot sync. Present only while shared. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - shared_by (integer) — Person ID of the member who enabled sharing. Present only while shared.\n - size (integer) (required) — File size in bytes.\n - team_id (integer) (required) — Owning team ID. `0` means a personal artifact (creator-only management); a positive value means team-owned.\n - team_name (string) — Owning team's display name. Omitted for personal artifacts.\n - title (string) (required) — Display title in the gallery.\n - updated_at (string) (required) — Unix timestamp in milliseconds when the artifact was last updated (rename, transfer, or republish). CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\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. Bodies containing sensitive fields are base64url-encoded instead; bodies over 10 KB are replaced by a truncation placeholder.\n - created_at (string) (required) — Timestamp of the operation in Unix epoch milliseconds. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - credential_id (integer) (required) — ID of the credential (the app key ID) when `credential_type` is `app_key`; 0 otherwise.\n - credential_type (string) (required) — Credential type used for the call. `app_key` when authenticated with an app key; empty string for member sessions.\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. 0 when the action was performed by the account principal itself.\n - member_name (string) (required) — Display name of the member. Empty when `member_id` is 0.\n - operation (string) (required) — Stable machine-readable operation name, e.g. `template:write:create`.\n - operation_name (string) (required) — Human-readable Chinese label of the operation (e.g. `创建模板`).\n - params (array) (required) — URL path parameters as an array of key-value pairs, or an empty array when none.\n - Key (string) — Name of a URL path parameter (the `:xxx` placeholder in the route).\n - Value (string) — The actual value of that path parameter in this request.\n - principal_kind (string) (required) — Kind of the caller. `member` — an interactive member session; `service` — an app key credential. [member, service]\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) — True when the caller can manage this rule: the personal rule owner; for team rules, an account admin or a member of the rule's team.\n - created_at (string) (required) — Creation time, Unix milliseconds. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\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. One of: `cloud` (platform-hosted cloud sandbox), `byoc` (self-hosted BYOC runner in the account); an empty value means automatic selection (prefers an online BYOC runner, falls back to the cloud sandbox). [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. Omitted when the rule has no HTTP POST trigger.\n - http_post_trigger_url (string) — HTTP POST trigger path. Omitted when the rule has no HTTP POST trigger.\n - name (string) (required) — Rule name.\n - oncall_incident_channel_ids (array) — On-call integration IDs to watch. Creating or enabling this trigger requires at least one valid ID. Omitted when no On-call incident trigger is configured.\n - oncall_incident_severities (array) — Incident severities to watch. Supported values are Critical, Warning, and Info; creating or enabling this trigger requires at least one value. Omitted when no On-call incident trigger is configured. [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. Omitted when the rule has no On-call incident trigger.\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. One of: `person` (personal rule, team_id=0, runs as the creator; disabled when the creator leaves the account), `team` (team rule, team_id>0, owned by the team and shared with its members; survives the creator leaving). Derived from the rule's team_id. [person, team]\n - schedule_next_fire_at_ms (string) (required) — Next scheduled fire time, Unix milliseconds. 0 means no future scheduled fire is available. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - schedule_trigger_enabled (boolean) (required) — Whether the schedule trigger is enabled.\n - schedule_trigger_id (string) — Schedule trigger ID. Omitted if the rule has no schedule trigger.\n - team_id (integer) (required) — Scope team ID; 0 means personal rule.\n - timezone (string) (required) — IANA timezone `cron_expr` is evaluated in. Always populated for rules created after this field shipped; empty on legacy rows created before it, which still resolve to UTC when scheduled.\n - updated_at (string) (required) — Last update time, Unix milliseconds. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n", @@ -199,6 +207,7 @@ var responseHelpBySDKMethod = map[string]string{ "StatusPages.ChangeTimelineCreate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - update_id (string) (required) — Newly created update ID.\n", "StatusPages.ComponentUpsert": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - component_ids (array) (required) — IDs of the created or updated components, in the same order as the request.\n", "StatusPages.Create": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - page_id (integer) (required) — Created status page ID.\n - page_name (string) (required) — Created status page name.\n - page_url_name (string) (required) — Final URL-safe slug assigned to the status page.\n", + "StatusPages.DraftCreate": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - created_at (string) (required) — Creation time in Unix epoch seconds. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - draft_id (string) (required) — Draft ID matching `draft_[A-Za-z0-9]{22}`; the console review link carries it.\n", "StatusPages.Info": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - components (array) (required) — Components tracked on the status page.\n - available_since_seconds (string) — Time the component became available, as a Unix timestamp in seconds. Omitted when 0. CLI `--json` renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null.\n - component_id (string) — Component ID. Omitted when empty.\n - description (string) — Component description. Omitted when empty.\n - hide_all (boolean) — When true, the component is hidden entirely from summary endpoints. Omitted when false.\n - hide_uptime (boolean) — When true, uptime data is hidden from summary responses. Omitted when false.\n - name (string) (required) — Component display name.\n - order_id (integer) — Display order within its section. Omitted when 0.\n - section_id (string) — Parent section ID. Omitted when the component sits at the top level.\n - contact_info (string) — Get-in-touch contact, a mailto or website URL. Omitted when not set.\n - custom_domain (string) — Custom domain pointing to the status page. Omitted when not set.\n - custom_links (array) — Custom navigation links shown on the status page. Omitted when not set.\n - dark_logo (string) — Dark-mode logo image of the status page. Omitted when not set.\n - date_view (string) — How the timeline displays change dates. `calendar` uses a calendar view; `list` uses a list view. Omitted when not set. [calendar, list]\n - display_uptime_mode (string) — How uptime is displayed. `chart_and_percentage` shows both the uptime chart and the percentage figure; `chart` shows only the chart; `none` hides uptime entirely. Omitted when not set. [chart_and_percentage, chart, none]\n - favicon (string) — Favicon of the status page. Omitted when not set.\n - logo (string) — Logo image of the status page. Omitted when not set.\n - logo_url (string) — URL opened when the logo is clicked. Omitted when not set.\n - managed_domain_feature_enabled (boolean) (required) — Whether the managed custom-domain feature is enabled for this page. `true` for public pages, always `false` for internal pages.\n - name (string) (required) — Display name of the status page.\n - page_footer (string) — Footer content of the status page. Omitted when not set.\n - page_header (string) — Header content of the status page. Omitted when not set.\n - page_id (integer) (required) — Status page ID.\n - sections (array) (required) — Sections grouping the components.\n - description (string) (required) — Section description.\n - hide_all (boolean) (required) — Whether the section and its components are hidden from summary endpoints.\n - hide_uptime (boolean) (required) — Whether uptime data is hidden from summary responses.\n - name (string) (required) — Section name.\n - order_id (integer) — Display order of the section. Omitted when 0.\n - section_id (string) — Section ID. Omitted when empty.\n - subscription (object) (required) — Subscription channel toggles.\n - email (boolean) (required) — Whether email subscription is enabled.\n - im (boolean) (required) — Whether IM subscription is enabled.\n - template_preference (string) — Preferred event template type: `pre_defined` or `message`. Omitted when never set.\n - type (string) (required) — Page visibility type. `public` pages are accessible to anyone and use email subscriptions; `internal` pages are restricted to account members and use IM subscriptions. [public, internal]\n - url_name (string) (required) — URL-safe slug, unique per account.\n", "StatusPages.MigrateEmailSubscribers": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - job_id (string) (required) — Migration job ID. Use this to poll status or request cancellation.\n", "StatusPages.MigrateStructure": "Response fields (`data` envelope is unwrapped — these fields are at the top level):\n - job_id (string) (required) — Migration job ID. Use this to poll status or request cancellation.\n", diff --git a/internal/cli/zz_generated_status_pages.go b/internal/cli/zz_generated_status_pages.go index 99321d0..38ce8c8 100644 --- a/internal/cli/zz_generated_status_pages.go +++ b/internal/cli/zz_generated_status_pages.go @@ -1114,6 +1114,55 @@ Request fields: return cmd } +func genStatusPagesDraftCreateCmd() *cobra.Command { + var dataJSON string + var fSource string + cmd := &cobra.Command{ + Use: "draft-create", + Short: "Create status page draft", + Long: `Create status page draft. + +Store a status page event draft so a human can review and publish it from the console. + +API: POST /status-page/draft/create (statusPageDraftCreate) + +Request fields: + --source string — Opaque marker of the drafting origin, e.g. 'ai_sre:sess_xxx'. Up to 64 characters. (≤64 chars) + draft (object, via --data) (required) — Draft payload, stored verbatim, up to 64 KB serialized. Validated fields: 'page_id', 'type' ('incident' or 'maintenance'), 'name', 'message'; optional 'change_id' (append an update to an existing event when > 0), 'status', 'affected_components', and 'start_time'/'end_time' (Unix epoch seconds, new maintenance only). + +Response fields ('data' envelope is unwrapped — these fields are at the top level): + - created_at (string) (required) — Creation time in Unix epoch seconds. CLI '--json' renders this as an RFC3339 string in the process's local timezone (NOT UTC, and NOT the wire integer); an unset value renders as null. + - draft_id (string) (required) — Draft ID matching 'draft_[A-Za-z0-9]{22}'; the console review link carries it. +`, + Example: ` flashduty status-page draft-create --data '{"draft":{"affected_components":[{"component_id":"01KC3GAZ6ZJE40H55GM31RPWZE","status":"degraded"}],"message":"We are investigating degraded performance affecting the web console.","name":"Web Console Degraded Performance","page_id":5750613685214,"type":"incident","v":1},"source":"ai_sre:sess_01KC3H2A9ZQ8W7E6R5T4Y3U2I1"}'`, + 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("source") { + body["source"] = fSource + } + return nil + }) + if err != nil { + return err + } + req := new(flashduty.CreateStatusPageDraftRequest) + if err := genBindBody(body, req); err != nil { + return err + } + out, _, err := ctx.Client.StatusPages.DraftCreate(cmdContext(ctx.Cmd), req) + if err != nil { + return err + } + return printGenericResult(ctx, out) + }) + }, + } + cmd.Flags().StringVar(&fSource, "source", "", "Opaque marker of the drafting origin, e.g. 'ai_sre:sess_xxx'. Up to 64 characters. (≤64 chars)") + 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 genStatusPagesInfoCmd() *cobra.Command { var dataJSON string var fPageID int64 @@ -2105,6 +2154,7 @@ func registerGeneratedStatusPages(root *cobra.Command) { genAddLeaf(gStatusPage, genStatusPagesComponentUpsertCmd()) genAddLeaf(gStatusPage, genStatusPagesCreateCmd()) genAddLeaf(gStatusPage, genStatusPagesDeleteCmd()) + genAddLeaf(gStatusPage, genStatusPagesDraftCreateCmd()) genAddLeaf(gStatusPage, genStatusPagesInfoCmd()) genAddLeaf(gStatusPage, genStatusPagesMigrateEmailSubscribersCmd()) genAddLeaf(gStatusPage, genStatusPagesMigrateStructureCmd()) diff --git a/skills/flashduty/reference/safari.md b/skills/flashduty/reference/safari.md index 4601645..5af816b 100644 --- a/skills/flashduty/reference/safari.md +++ b/skills/flashduty/reference/safari.md @@ -105,6 +105,69 @@ Update A2A agent - `--team-id` int64 — Reassign team scope. Omit to leave unchanged. Reassigning requires rights on the destination team; if the team changes without also sending a new environment binding, the existing runner binding must remain selectable by the caller or the update is rejected. - body-only (`--data`): auth_config (object) +### artifact-gallery-delete +Remove artifact from gallery +- `` (positional, required) string — Artifact ID ('art_' prefix). Also the key of the public-share link. + +### artifact-gallery-file-state [...] +Get file publish state +- `` (positional, required) stringSlice — Presented-file IDs ('pf_' prefix) to probe. At most 50 per call; duplicates and empty strings are ignored. +- response: `{items: [...]}` page wrapper — pipe `--json | jq '.items[]'` (NOT top-level `.[]`) — items fields: artifact_id (string); file_id (string); gallery_path (string); title (string) + +### artifact-gallery-get +Get artifact detail +- `` (positional, required) string — Artifact ID ('art_' prefix). Also the key of the public-share link. +- response: single object (`data` unwrapped to the top level) — fields: artifact_id (string); can_edit (boolean); content_type (string); created_at (string); creator_name (string); file_id (string); is_mine (boolean); name (string); person_id (integer); public_url (string); session_id (string); session_title (string); share_enabled (boolean); share_file_id (string); shared_at (string); shared_by (integer); size (integer); team_id (integer); team_name (string); title (string); updated_at (string) + +### artifact-gallery-list +List artifacts +- `--asc` bool — Sort ascending when true, descending when false. Applies only when 'orderby' is set. +- `--limit` int64 — Page size. Defaults to 20; capped at 100. (max 100) +- `--orderby` string — Sort field: 'created_at' or 'updated_at'. Empty means 'updated_at' descending. · enum: created_at | updated_at +- `--page` int64 — Page number, 1-based. (min 1) +- `--query` string — Case-insensitive substring match on the artifact title. +- `--scope` string — Visibility scope. 'all' (default) lists the caller's own personal artifacts plus artifacts of every team the caller belongs to; 'personal' lists only the caller's own; 'team' lists only team-owned artifacts of the caller's teams. · enum: all | personal | team +- `--team-ids` intSlice — Restrict to artifacts owned by these team IDs, intersected with the caller's visibility — teams the caller does not belong to silently return nothing. +- response: `{items: [...], total}` page wrapper — pipe `--json | jq '.items[]'` (NOT top-level `.[]`) — items fields: artifact_id (string); can_edit (boolean); content_type (string); created_at (string); creator_name (string); file_id (string); is_mine (boolean); name (string); person_id (integer); public_url (string); session_id (string); session_title (string); share_enabled (boolean); share_file_id (string); shared_at (string); shared_by (integer); size (integer); team_id (integer); team_name (string); title (string); updated_at (string) + +### artifact-gallery-publish-from-file +Publish file as artifact +- `` (positional, required) string — Presented-file ID ('pf_' prefix) of a file produced in a session, as shown on the file card in chat. +- `--title` string (required) — Gallery display title. Trimmed; must be non-empty. +- response: single object (`data` unwrapped to the top level) — fields: artifact_id (string); gallery_path (string); title (string) + +### artifact-gallery-share-enable +Enable public sharing +- `` (positional, required) string — Artifact ID ('art_' prefix). Also the key of the public-share link. +- response: single object (`data` unwrapped to the top level) — fields: artifact_id (string); public_url (string); share_enabled (boolean); shared_at (string); shared_by (integer) + +### artifact-gallery-share-revoke +Revoke public sharing +- `` (positional, required) string — Artifact ID ('art_' prefix). Also the key of the public-share link. + +### artifact-gallery-share-sync +Update shared snapshot +- `` (positional, required) string — Artifact ID ('art_' prefix). Also the key of the public-share link. +- response: same shape as `artifact-gallery-share-enable ` above + +### artifact-gallery-update +Update artifact +- `` (positional, required) string — Artifact ID ('art_' prefix). Also the key of the public-share link. +- `--team-id` int64 — Transfer target scope. '0' moves the artifact to personal scope (only the creator can manage it); a positive value moves it to a team the caller must belong to. Omit to leave unchanged. +- `--title` string — New title. Trimmed; must be non-empty when provided. Omit to leave unchanged. +- response: same shape as `artifact-gallery-get ` above + +### artifact-sign +Create signed file URLs +- `` (positional, required) string — Presented-file ID ('pf_' prefix) to sign. +- `--share-token` string — Optional session share-link token. Needed only when the caller reaches the file through a shared session link rather than account membership. +- response: single object (`data` unwrapped to the top level) — fields: content_type (string); download_url (string); expires_in (integer); name (string); preview_url (string); size (integer) + +### artifact-stream +Download or preview a file +- `--mode` string — 'download' (default) serves the file as an attachment; 'preview' serves it inline for browser display. Any other value falls back to 'download'. · enum: download | preview +- `--t` string (required) — Signed token issued by 'POST /safari/artifact/sign'. Bound to the calling account and person; valid for 5 minutes. + ### automation-rule-create Create Automation rule - `--cron-expr` string (required) — Run cadence. Supports 4 fields ('hour day month weekday', minute defaults to 0) and 5 fields ('minute hour day month weekday'). The minute must be one fixed integer; 6-field seconds are not supported. A cron that sets both day-of-month and day-of-week is rejected. The create API currently requires this field even for HTTP-POST-only rules; send a valid cron and set 'schedule_trigger_enabled=false'. diff --git a/skills/flashduty/reference/status-page.md b/skills/flashduty/reference/status-page.md index 59846a5..aba1f1d 100644 --- a/skills/flashduty/reference/status-page.md +++ b/skills/flashduty/reference/status-page.md @@ -154,6 +154,12 @@ Create status page Delete status page - `` (positional, required) int64 — Status page ID; obtain it from 'GET /status-page/list'. +### draft-create +Create status page draft +- `--source` string — Opaque marker of the drafting origin, e.g. 'ai_sre:sess_xxx'. Up to 64 characters. (≤64 chars) +- body-only (`--data`): draft (object) (required) +- response: single object (`data` unwrapped to the top level) — fields: created_at (string); draft_id (string) + ### info Get status page detail - `` (positional, required) int64 — Status page ID.