| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- package cmd
- import (
- "context"
- "encoding/json"
- "fmt"
- "os"
- "strings"
- "gogs.dmsc.dev/arp/arp_cli/client"
- "gogs.dmsc.dev/arp/arp_cli/config"
- "github.com/AlecAivazis/survey/v2"
- "github.com/olekukonko/tablewriter"
- "github.com/urfave/cli/v3"
- )
- // ChannelCommand returns the channel command
- func ChannelCommand() *cli.Command {
- return &cli.Command{
- Name: "channel",
- Usage: "Manage channels",
- Description: `Manage ARP channels. Channels are chat conversations between users/agents.
- Use this command to create, list, update, and delete channels.`,
- Commands: []*cli.Command{
- {
- Name: "list",
- Aliases: []string{"ls"},
- Usage: "List all channels",
- Flags: []cli.Flag{
- &cli.BoolFlag{
- Name: "json",
- Aliases: []string{"j"},
- Usage: "Output as JSON",
- },
- },
- Action: channelList,
- },
- {
- Name: "get",
- Usage: "Get a channel by ID",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "id",
- Aliases: []string{"i"},
- Usage: "Channel ID",
- Required: true,
- },
- &cli.BoolFlag{
- Name: "json",
- Aliases: []string{"j"},
- Usage: "Output as JSON",
- },
- },
- Action: channelGet,
- },
- {
- Name: "create",
- Usage: "Create a new channel",
- Action: channelCreate,
- Flags: []cli.Flag{
- &cli.StringSliceFlag{
- Name: "participants",
- Aliases: []string{"p"},
- Usage: "Participant user IDs",
- },
- },
- },
- {
- Name: "update",
- Usage: "Update a channel",
- Action: channelUpdate,
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "id",
- Aliases: []string{"i"},
- Usage: "Channel ID",
- Required: true,
- },
- &cli.StringSliceFlag{
- Name: "participants",
- Aliases: []string{"p"},
- Usage: "Participant user IDs",
- },
- },
- },
- {
- Name: "delete",
- Usage: "Delete a channel",
- Action: channelDelete,
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "id",
- Aliases: []string{"i"},
- Usage: "Channel ID",
- Required: true,
- },
- &cli.BoolFlag{
- Name: "yes",
- Aliases: []string{"y"},
- Usage: "Skip confirmation",
- },
- },
- },
- },
- }
- }
- type Channel struct {
- ID string `json:"id"`
- Participants []struct {
- ID string `json:"id"`
- Email string `json:"email"`
- } `json:"participants"`
- CreatedAt string `json:"createdAt"`
- UpdatedAt string `json:"updatedAt"`
- }
- func channelList(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- query := "query Channels { channels { id participants { id email } createdAt updatedAt } }"
- resp, err := c.Query(query, nil)
- if err != nil {
- return err
- }
- var result struct {
- Channels []Channel `json:"channels"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if cmd.Bool("json") {
- enc := json.NewEncoder(os.Stdout)
- enc.SetIndent("", " ")
- return enc.Encode(result.Channels)
- }
- if len(result.Channels) == 0 {
- fmt.Println("No channels found.")
- return nil
- }
- table := tablewriter.NewWriter(os.Stdout)
- table.Header([]string{"ID", "Participants", "Created At"})
-
- for _, ch := range result.Channels {
- participants := make([]string, len(ch.Participants))
- for i, p := range ch.Participants {
- participants[i] = p.Email
- }
- table.Append([]string{ch.ID, strings.Join(participants, ", "), ch.CreatedAt})
- }
- table.Render()
- return nil
- }
- func channelGet(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- id := cmd.String("id")
- query := "query Channel($id: ID!) { channel(id: $id) { id participants { id email } createdAt updatedAt } }"
- resp, err := c.Query(query, map[string]interface{}{"id": id})
- if err != nil {
- return err
- }
- var result struct {
- Channel *Channel `json:"channel"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if result.Channel == nil {
- return fmt.Errorf("channel not found")
- }
- if cmd.Bool("json") {
- enc := json.NewEncoder(os.Stdout)
- enc.SetIndent("", " ")
- return enc.Encode(result.Channel)
- }
- ch := result.Channel
- fmt.Printf("ID: %s\n", ch.ID)
- fmt.Printf("Participants:\n")
- for _, p := range ch.Participants {
- fmt.Printf(" - %s (%s)\n", p.Email, p.ID)
- }
- fmt.Printf("Created At: %s\n", ch.CreatedAt)
- fmt.Printf("Updated At: %s\n", ch.UpdatedAt)
- return nil
- }
- func channelCreate(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- participants := cmd.StringSlice("participants")
- if len(participants) == 0 {
- var participantsStr string
- prompt := &survey.Input{Message: "Participant user IDs (comma-separated):"}
- if err := survey.AskOne(prompt, &participantsStr, survey.WithValidator(survey.Required)); err != nil {
- return err
- }
- for _, p := range strings.Split(participantsStr, ",") {
- participants = append(participants, strings.TrimSpace(p))
- }
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- mutation := `mutation CreateChannel($input: NewChannel!) { createChannel(input: $input) { id participants { id email } createdAt updatedAt } }`
- input := map[string]interface{}{
- "participants": participants,
- }
- resp, err := c.Mutation(mutation, map[string]interface{}{"input": input})
- if err != nil {
- return err
- }
- var result struct {
- CreateChannel *Channel `json:"createChannel"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if result.CreateChannel == nil {
- return fmt.Errorf("failed to create channel")
- }
- fmt.Printf("Channel created successfully!\n")
- fmt.Printf("ID: %s\n", result.CreateChannel.ID)
- return nil
- }
- func channelUpdate(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- id := cmd.String("id")
- participants := cmd.StringSlice("participants")
- if len(participants) == 0 {
- fmt.Println("No updates provided. Use flags to specify what to update.")
- return nil
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- input := map[string]interface{}{
- "participants": participants,
- }
- mutation := `mutation UpdateChannel($id: ID!, $input: UpdateChannelInput!) { updateChannel(id: $id, input: $input) { id participants { id email } createdAt updatedAt } }`
- resp, err := c.Mutation(mutation, map[string]interface{}{"id": id, "input": input})
- if err != nil {
- return err
- }
- var result struct {
- UpdateChannel *Channel `json:"updateChannel"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if result.UpdateChannel == nil {
- return fmt.Errorf("channel not found")
- }
- fmt.Printf("Channel updated successfully!\n")
- fmt.Printf("ID: %s\n", result.UpdateChannel.ID)
- return nil
- }
- func channelDelete(ctx context.Context, cmd *cli.Command) error {
- cfg, err := config.Load()
- if err != nil {
- return err
- }
- if err := RequireAuth(cfg); err != nil {
- return err
- }
- id := cmd.String("id")
- skipConfirm := cmd.Bool("yes")
- if !skipConfirm {
- confirm := false
- prompt := &survey.Confirm{
- Message: fmt.Sprintf("Are you sure you want to delete channel %s?", id),
- Default: false,
- }
- if err := survey.AskOne(prompt, &confirm); err != nil {
- return err
- }
- if !confirm {
- fmt.Println("Deletion cancelled.")
- return nil
- }
- }
- c := client.New(cfg.ServerURL)
- c.SetToken(cfg.Token)
- mutation := `mutation DeleteChannel($id: ID!) { deleteChannel(id: $id) }`
- resp, err := c.Mutation(mutation, map[string]interface{}{"id": id})
- if err != nil {
- return err
- }
- var result struct {
- DeleteChannel bool `json:"deleteChannel"`
- }
- if err := json.Unmarshal(resp.Data, &result); err != nil {
- return err
- }
- if result.DeleteChannel {
- fmt.Printf("Channel %s deleted successfully.\n", id)
- } else {
- fmt.Printf("Failed to delete channel %s.\n", id)
- }
- return nil
- }
|