diff --git a/README.md b/README.md index b80180b..2b2e999 100644 --- a/README.md +++ b/README.md @@ -226,7 +226,12 @@ fopost knowledge list · add · sync · delete · search fopost analytics overview · top-posts · time-series fopost automations list · get · toggle · trigger · runs fopost webhooks list · create · test · delete +<<<<<<< HEAD +fopost ads tree · pause · resume · insights · leads +fopost activity list · audit +======= fopost ads tree · pause · resume · insights · leads · catalogs · library +>>>>>>> origin/main fopost completion bash · zsh · fish · powershell fopost version ``` diff --git a/go.mod b/go.mod index 14cbffb..5780bed 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/fopost/fopost-cli go 1.22 require ( - github.com/fopost/fopost-go v0.2.1-0.20260920143205-156d1c2d360c + github.com/fopost/fopost-go v0.2.1-0.20260920150019-214947b2e852 github.com/spf13/cobra v1.10.2 golang.org/x/term v0.27.0 ) diff --git a/go.sum b/go.sum index cf33d95..bdb02b4 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,8 @@ github.com/fopost/fopost-go v0.2.1-0.20260920141700-633d72b705ca h1:1a7XwNMmGCUh github.com/fopost/fopost-go v0.2.1-0.20260920141700-633d72b705ca/go.mod h1:Qz+7UCYTBnDEeZqB3VMrePxmYLVR9rFvx3+QWcKND8Q= github.com/fopost/fopost-go v0.2.1-0.20260920143205-156d1c2d360c h1:Md2W/Uu8pXDMqJkZ0gRuSb8iNz3/H4zn5FS++Yt+Lf8= github.com/fopost/fopost-go v0.2.1-0.20260920143205-156d1c2d360c/go.mod h1:Qz+7UCYTBnDEeZqB3VMrePxmYLVR9rFvx3+QWcKND8Q= +github.com/fopost/fopost-go v0.2.1-0.20260920150019-214947b2e852 h1:Vn2ObLqhFK01lhS7bqtSOyTlK7/rmEz58Y11Bj83eVE= +github.com/fopost/fopost-go v0.2.1-0.20260920150019-214947b2e852/go.mod h1:Qz+7UCYTBnDEeZqB3VMrePxmYLVR9rFvx3+QWcKND8Q= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/internal/cmd/activity.go b/internal/cmd/activity.go new file mode 100644 index 0000000..925bbf5 --- /dev/null +++ b/internal/cmd/activity.go @@ -0,0 +1,95 @@ +package cmd + +import ( + fopost "github.com/fopost/fopost-go" + "github.com/spf13/cobra" + + "github.com/fopost/fopost-cli/internal/output" +) + +func init() { register(newActivityCmd) } + +func newActivityCmd(state *State) *cobra.Command { + cmd := &cobra.Command{ + Use: "activity", + Short: "Read what happened in a workspace, including the audit log", + } + cmd.AddCommand(newActivityListCmd(state), newActivityAuditCmd(state)) + return cmd +} + +func listActivity(state *State, cmd *cobra.Command, kind, cursor string, limit int) error { + client, err := state.Client() + if err != nil { + return err + } + resolved, err := state.Resolved() + if err != nil { + return err + } + page, err := client.Activity.List(cmd.Context(), &fopost.ListActivityParams{ + WorkspaceID: resolved.Workspace, + Kind: kind, + Cursor: cursor, + Limit: limit, + }) + if err != nil { + return err + } + printer := state.Printer() + return printer.Value(page, func() { + rows := make([][]string, 0, len(page.Events)) + for _, event := range page.Events { + actor := event.Actor.Name + if actor == "" { + actor = event.Actor.Type + } + rows = append(rows, []string{ + event.Time.String(), + event.Kind, + actor, + output.Truncate(event.Summary, 60), + }) + } + printer.Table([]string{"time", "kind", "actor", "summary"}, rows) + if page.NextCursor != "" { + printer.Success("More to read: pass --cursor %s.", page.NextCursor) + } + }) +} + +func newActivityListCmd(state *State) *cobra.Command { + var kind, cursor string + var limit int + cmd := &cobra.Command{ + Use: "list", + Short: "List activity, newest first", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + return listActivity(state, cmd, kind, cursor, limit) + }, + } + cmd.Flags().StringVar(&kind, "kind", "", "publish, connection, webhook, inbox, automation, billing, or security") + cmd.Flags().StringVar(&cursor, "cursor", "", "next_cursor from the previous page") + cmd.Flags().IntVar(&limit, "limit", 0, "how many to return, 1 to 100") + return cmd +} + +func newActivityAuditCmd(state *State) *cobra.Command { + var cursor string + var limit int + cmd := &cobra.Command{ + Use: "audit", + Short: "The security audit log: who changed access, and when", + Long: "Members joining, leaving, or changing role and access, plus changes to two-step\n" + + "verification, passkeys, single sign-on, and signed-in devices. These rows are\n" + + "append-only and never expire.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + return listActivity(state, cmd, fopost.ActivityKindSecurity, cursor, limit) + }, + } + cmd.Flags().StringVar(&cursor, "cursor", "", "next_cursor from the previous page") + cmd.Flags().IntVar(&limit, "limit", 0, "how many to return, 1 to 100") + return cmd +}