fizzy-cli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/.github/workflows/release.yml +29 -0
  2. package/.github/workflows/tests.yml +24 -0
  3. package/AGENTS.md +33 -0
  4. package/CHANGELOG.md +63 -0
  5. package/Makefile +20 -9
  6. package/README.md +88 -1
  7. package/bin/fizzy +0 -0
  8. package/bin/fizzy-darwin-amd64 +0 -0
  9. package/bin/fizzy-darwin-arm64 +0 -0
  10. package/bin/fizzy-linux-amd64 +0 -0
  11. package/bin/fizzy-linux-arm64 +0 -0
  12. package/bin/fizzy-windows-amd64.exe +0 -0
  13. package/cmd/account.go +14 -0
  14. package/cmd/account_list.go +44 -0
  15. package/cmd/account_list_test.go +118 -0
  16. package/cmd/board.go +38 -12
  17. package/cmd/board_create.go +60 -0
  18. package/cmd/board_create_test.go +158 -0
  19. package/cmd/board_list.go +18 -32
  20. package/cmd/board_list_test.go +115 -0
  21. package/cmd/board_test.go +92 -0
  22. package/cmd/card.go +24 -0
  23. package/cmd/card_close.go +46 -0
  24. package/cmd/card_close_test.go +92 -0
  25. package/cmd/card_create.go +73 -0
  26. package/cmd/card_create_test.go +206 -0
  27. package/cmd/card_delete.go +46 -0
  28. package/cmd/card_delete_test.go +92 -0
  29. package/cmd/card_list.go +53 -0
  30. package/cmd/card_list_test.go +148 -0
  31. package/cmd/card_reopen.go +46 -0
  32. package/cmd/card_reopen_test.go +92 -0
  33. package/cmd/card_show.go +46 -0
  34. package/cmd/card_show_test.go +92 -0
  35. package/cmd/card_update.go +74 -0
  36. package/cmd/card_update_test.go +147 -0
  37. package/cmd/column.go +14 -0
  38. package/cmd/column_create.go +80 -0
  39. package/cmd/column_create_test.go +196 -0
  40. package/cmd/column_list.go +44 -0
  41. package/cmd/column_list_test.go +138 -0
  42. package/cmd/login.go +61 -4
  43. package/cmd/login_test.go +98 -0
  44. package/cmd/root.go +15 -4
  45. package/cmd/use.go +85 -0
  46. package/cmd/use_test.go +186 -0
  47. package/docs/API.md +1168 -0
  48. package/go.mod +23 -2
  49. package/go.sum +43 -0
  50. package/internal/api/client.go +463 -0
  51. package/internal/app/app.go +49 -0
  52. package/internal/colors/colors.go +32 -0
  53. package/internal/config/config.go +69 -0
  54. package/internal/testutil/client.go +26 -0
  55. package/internal/ui/account_list.go +14 -0
  56. package/internal/ui/account_selector.go +63 -0
  57. package/internal/ui/board_list.go +14 -0
  58. package/internal/ui/card_list.go +14 -0
  59. package/internal/ui/card_show.go +23 -0
  60. package/internal/ui/column_list.go +28 -0
  61. package/internal/ui/format.go +14 -0
  62. package/main.go +1 -1
  63. package/package.json +1 -1
@@ -0,0 +1,29 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+
7
+ permissions:
8
+ contents: write
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Set up Go
18
+ uses: actions/setup-go@v4
19
+ with:
20
+ go-version: "1.25"
21
+
22
+ - name: Build binaries
23
+ run: make build-all
24
+
25
+ - name: Upload Release Assets
26
+ env:
27
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28
+ run: |
29
+ gh release upload ${{ github.event.release.tag_name }} bin/fizzy-* --clobber
@@ -0,0 +1,24 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-go@v4
17
+ with:
18
+ go-version: "1.25"
19
+
20
+ - name: Install gotestsum
21
+ run: go install gotest.tools/gotestsum@latest
22
+
23
+ - name: Run tests
24
+ run: make test
package/AGENTS.md ADDED
@@ -0,0 +1,33 @@
1
+ # AGENTS.md
2
+
3
+ ## About
4
+
5
+ fizzy-cli is a CLI application built in Go that provides an interface to the
6
+ [Fizzy](https://fizzy.do) API. Fizzy is a kanban-style project management SaaS.
7
+
8
+ ## Dev instructions
9
+
10
+ All the commands for development are available through Makefile, just read that
11
+ file whenever you need to run something because chances are that you will find
12
+ you answer there.
13
+
14
+ You can find the Fizzy API specification at @docs/API.md
15
+
16
+ ## Testing
17
+
18
+ Automated testing is done via `make test`.
19
+
20
+ For manual testing/debugging, you should run `make install` first to install the
21
+ binary and then run the `fizzy` command normally.
22
+
23
+ ## Code quality, standards and style
24
+
25
+ This project is being built in Go because it's supposed to have a strong focus
26
+ on performance. Always prefer performant code and solutions and low memory
27
+ footprint.
28
+
29
+ Don't write obvious code comments. Only use code comments when the code itself
30
+ requires some clarification to be understood.
31
+
32
+ When in doubt, always check similar files or features and reuse the patterns and
33
+ style applied.
package/CHANGELOG.md ADDED
@@ -0,0 +1,63 @@
1
+ # Changelog
2
+
3
+ ## [0.2.0] - 2025-12-20
4
+
5
+ ### Features
6
+
7
+ #### Card Management
8
+
9
+ - `fizzy card update <card_number>` - Update card properties (title, description, status, tags)
10
+ - `fizzy card delete <card_number>` - Delete a card permanently
11
+ - `fizzy card close <card_number>` - Close an existing card (already existed, now documented)
12
+ - `fizzy card reopen <card_number>` - Reopen a closed card (already existed, now documented)
13
+
14
+ #### Account Management
15
+
16
+ - `fizzy account list` - List all accounts you have access to
17
+
18
+ #### Improvements
19
+
20
+ - `fizzy board` without arguments now displays the currently selected board
21
+ - Added `--version` flag to display CLI version
22
+ - Fixed HTTP client leak in API requests
23
+ - Updated API specification to latest version
24
+
25
+ ## [0.1.0] - 2025-12-16
26
+
27
+ ### Initial Release
28
+
29
+ The first stable release of Fizzy CLI with core functionality for managing
30
+ boards, cards, and columns.
31
+
32
+ ### Features
33
+
34
+ #### Authentication
35
+
36
+ - `fizzy login` - Authenticate with Fizzy API using access tokens
37
+
38
+ #### Board Management
39
+
40
+ - `fizzy board list` - List all boards
41
+ - `fizzy board create` - Create a new board
42
+
43
+ #### Card Management
44
+
45
+ - `fizzy card list` - List all cards in the selected board
46
+ - `fizzy card create` - Create a new card
47
+ - `fizzy card show <card_id>` - Display details for a specific card
48
+
49
+ #### Column Management
50
+
51
+ - `fizzy column list` - List all columns in the selected board
52
+ - `fizzy column create` - Create a new column
53
+
54
+ #### Configuration
55
+
56
+ - `fizzy use --board <name>` - Set the active board for subsequent commands
57
+ - `fizzy use --account <slug>` - Set the active account for subsequent commands
58
+
59
+ ### Distribution
60
+
61
+ - Multi-platform support (macOS, Linux, Windows)
62
+ - Multi-architecture binaries (x64, arm64)
63
+ - Distributed via NPM with automatic binary download on install
package/Makefile CHANGED
@@ -1,4 +1,7 @@
1
- .PHONY: help dev-tools run build build-all clean test
1
+ .PHONY: help dev-tools run build build-all clean test install sync-api-spec
2
+
3
+ VERSION := $(shell grep '"version"' package.json | sed 's/.*"version": "\([^"]*\)".*/\1/')
4
+ LDFLAGS := -ldflags="-X 'github.com/rogeriopvl/fizzy/cmd.Version=$(VERSION)'"
2
5
 
3
6
  help:
4
7
  @echo 'Usage: make [target]'
@@ -8,25 +11,33 @@ help:
8
11
 
9
12
  dev-tools:
10
13
  @echo "Installing development tools..."
11
- go install github.com/spf13/cobra@latest
14
+ go install gotest.tools/gotestsum@latest
12
15
 
13
16
  run:
14
17
  go run .
15
18
 
19
+ install:
20
+ go install $(LDFLAGS) .
21
+
16
22
  build:
17
- go build -o bin/fizzy .
23
+ go build $(LDFLAGS) -o bin/fizzy .
18
24
 
19
25
  build-all: clean
20
26
  mkdir -p bin
21
- GOOS=darwin GOARCH=amd64 go build -o bin/fizzy-darwin-amd64 .
22
- GOOS=darwin GOARCH=arm64 go build -o bin/fizzy-darwin-arm64 .
23
- GOOS=linux GOARCH=amd64 go build -o bin/fizzy-linux-amd64 .
24
- GOOS=linux GOARCH=arm64 go build -o bin/fizzy-linux-arm64 .
25
- GOOS=windows GOARCH=amd64 go build -o bin/fizzy-windows-amd64.exe .
27
+ GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o bin/fizzy-darwin-amd64 .
28
+ GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o bin/fizzy-darwin-arm64 .
29
+ GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o bin/fizzy-linux-amd64 .
30
+ GOOS=linux GOARCH=arm64 go build $(LDFLAGS) -o bin/fizzy-linux-arm64 .
31
+ GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o bin/fizzy-windows-amd64.exe .
26
32
  @echo "Binaries built successfully in bin/"
27
33
 
28
34
  clean:
29
35
  rm -rf bin/
30
36
 
31
37
  test:
32
- go test -v ./...
38
+ gotestsum -- -v ./...
39
+
40
+ sync-api-spec:
41
+ @mkdir -p docs
42
+ @curl -s https://raw.githubusercontent.com/basecamp/fizzy/main/docs/API.md -o docs/API.md
43
+ @echo "API spec synced to docs/API.md"
package/README.md CHANGED
@@ -1,7 +1,94 @@
1
1
  # Fizzy CLI
2
2
 
3
+ [![Tests](https://github.com/rogeriopvl/fizzy-cli/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/rogeriopvl/fizzy-cli/actions/workflows/tests.yml)
4
+ [![Commits per month](https://img.shields.io/github/commit-activity/m/rogeriopvl/fizzy-cli)](https://github.com/rogeriopvl/fizzy-cli/commits)
5
+ [![Last commit](https://img.shields.io/github/last-commit/rogeriopvl/fizzy-cli)](https://github.com/rogeriopvl/fizzy-cli/commits)
6
+
3
7
  This is a command-line interface for https://fizzy.do
4
8
 
5
9
  ## Install
6
10
 
7
- Soon...
11
+ You have multiple options to install:
12
+
13
+ ### Homebrew (Mac/Linux)
14
+
15
+ ```bash
16
+ brew tap rogeriopvl/tap
17
+
18
+ brew install fizzy-cli
19
+ ```
20
+
21
+ ### NPM (Mac/Linux/Windows)
22
+
23
+ ```bash
24
+ npm i -g fizzy-cli
25
+ ```
26
+
27
+ Or...
28
+
29
+ ```bash
30
+ npx -y fizzy-cli@latest
31
+ ```
32
+
33
+ ## Setup
34
+
35
+ Before you start using `fizzy-cli`, you need to authenticate it with your Fizzy
36
+ account:
37
+
38
+ ```bash
39
+ fizzy login
40
+ ```
41
+
42
+ The first time you run this command it will print out the instructions for you
43
+ to follow. These instructions will guide you through creating an access token on
44
+ the Fizzy web app.
45
+
46
+ After you get the token, setup your shell to export the `FIZZY_ACCESS_TOKEN`
47
+ environment variable. Edit your `~/.bashrc` or `~/.zshrc` and add the following
48
+ line:
49
+
50
+ ```bash
51
+ export FIZZY_ACCESS_TOKEN=your_access_token
52
+ ```
53
+
54
+ Reload the shell, and run the `fizzy login` command again to confirm that you're
55
+ authenticated. If you have only one Fizzy account, `fizzy-cli` will select it
56
+ automatically. Otherwise you will be able to select which one you want to use.
57
+
58
+ ### Board selection
59
+
60
+ You can choose which board you want to pre-select for all your commands with:
61
+
62
+ ```bash
63
+ fizzy use --board <board_name>
64
+ ```
65
+
66
+ To get the board name just type:
67
+
68
+ ```bash
69
+ fizzy board list
70
+ ```
71
+
72
+ The `use` command also supports selecting a different account:
73
+
74
+ ```bash
75
+ fizzy use --account <account_slug>
76
+ ```
77
+
78
+ ## Development
79
+
80
+ ### Tests
81
+
82
+ ```bash
83
+ make test
84
+ ```
85
+
86
+ ### Run
87
+
88
+ ```bash
89
+ make install
90
+ ```
91
+
92
+ ```bash
93
+ fizzy --help
94
+ ```
package/bin/fizzy CHANGED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/cmd/account.go ADDED
@@ -0,0 +1,14 @@
1
+ // Package cmd
2
+ package cmd
3
+
4
+ import "github.com/spf13/cobra"
5
+
6
+ var accountCmd = &cobra.Command{
7
+ Use: "account",
8
+ Short: "Manage accounts",
9
+ Long: `Manage accounts in Fizzy`,
10
+ }
11
+
12
+ func init() {
13
+ rootCmd.AddCommand(accountCmd)
14
+ }
@@ -0,0 +1,44 @@
1
+ package cmd
2
+
3
+ import (
4
+ "context"
5
+ "fmt"
6
+
7
+ "github.com/rogeriopvl/fizzy/internal/app"
8
+ "github.com/rogeriopvl/fizzy/internal/ui"
9
+ "github.com/spf13/cobra"
10
+ )
11
+
12
+ var accountListCmd = &cobra.Command{
13
+ Use: "list",
14
+ Short: "List all accounts",
15
+ Long: `Retrieve and display all accounts from Fizzy`,
16
+ Run: func(cmd *cobra.Command, args []string) {
17
+ if err := handleListAccounts(cmd); err != nil {
18
+ fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err)
19
+ }
20
+ },
21
+ }
22
+
23
+ func handleListAccounts(cmd *cobra.Command) error {
24
+ a := app.FromContext(cmd.Context())
25
+ if a == nil || a.Client == nil {
26
+ return fmt.Errorf("API client not available")
27
+ }
28
+
29
+ identity, err := a.Client.GetMyIdentity(context.Background())
30
+ if err != nil {
31
+ return fmt.Errorf("fetching accounts: %w", err)
32
+ }
33
+
34
+ if len(identity.Accounts) == 0 {
35
+ fmt.Println("No accounts found")
36
+ return nil
37
+ }
38
+
39
+ return ui.DisplayAccounts(identity.Accounts)
40
+ }
41
+
42
+ func init() {
43
+ accountCmd.AddCommand(accountListCmd)
44
+ }
@@ -0,0 +1,118 @@
1
+ package cmd
2
+
3
+ import (
4
+ "context"
5
+ "encoding/json"
6
+ "net/http"
7
+ "net/http/httptest"
8
+ "testing"
9
+
10
+ "github.com/rogeriopvl/fizzy/internal/api"
11
+ "github.com/rogeriopvl/fizzy/internal/app"
12
+ "github.com/rogeriopvl/fizzy/internal/testutil"
13
+ )
14
+
15
+ func TestAccountListCommand(t *testing.T) {
16
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
17
+ if r.URL.Path != "/my/identity" {
18
+ t.Errorf("expected /my/identity, got %s", r.URL.Path)
19
+ }
20
+ if r.Method != http.MethodGet {
21
+ t.Errorf("expected GET, got %s", r.Method)
22
+ }
23
+
24
+ auth := r.Header.Get("Authorization")
25
+ if auth == "" {
26
+ t.Error("missing Authorization header")
27
+ }
28
+ if auth != "Bearer test-token" {
29
+ t.Errorf("expected Bearer test-token, got %s", auth)
30
+ }
31
+
32
+ w.Header().Set("Content-Type", "application/json")
33
+ response := api.GetMyIdentityResponse{
34
+ Accounts: []api.Account{
35
+ {
36
+ ID: "account-123",
37
+ Name: "Personal",
38
+ Slug: "personal",
39
+ CreatedAt: "2025-01-01T00:00:00Z",
40
+ },
41
+ {
42
+ ID: "account-456",
43
+ Name: "Work",
44
+ Slug: "work",
45
+ CreatedAt: "2025-01-02T00:00:00Z",
46
+ },
47
+ },
48
+ }
49
+ json.NewEncoder(w).Encode(response)
50
+ }))
51
+ defer server.Close()
52
+
53
+ client := testutil.NewTestClient(server.URL, "", "", "test-token")
54
+ testApp := &app.App{Client: client}
55
+
56
+ cmd := accountListCmd
57
+ cmd.SetContext(testApp.ToContext(context.Background()))
58
+
59
+ if err := handleListAccounts(cmd); err != nil {
60
+ t.Fatalf("handleListAccounts failed: %v", err)
61
+ }
62
+ }
63
+
64
+ func TestAccountListCommandNoAccounts(t *testing.T) {
65
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
66
+ w.Header().Set("Content-Type", "application/json")
67
+ response := api.GetMyIdentityResponse{Accounts: []api.Account{}}
68
+ json.NewEncoder(w).Encode(response)
69
+ }))
70
+ defer server.Close()
71
+
72
+ client := testutil.NewTestClient(server.URL, "", "", "test-token")
73
+ testApp := &app.App{Client: client}
74
+
75
+ cmd := accountListCmd
76
+ cmd.SetContext(testApp.ToContext(context.Background()))
77
+
78
+ if err := handleListAccounts(cmd); err != nil {
79
+ t.Fatalf("handleListAccounts failed: %v", err)
80
+ }
81
+ }
82
+
83
+ func TestAccountListCommandAPIError(t *testing.T) {
84
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
85
+ w.WriteHeader(http.StatusInternalServerError)
86
+ w.Write([]byte("Internal Server Error"))
87
+ }))
88
+ defer server.Close()
89
+
90
+ client := testutil.NewTestClient(server.URL, "", "", "test-token")
91
+ testApp := &app.App{Client: client}
92
+
93
+ cmd := accountListCmd
94
+ cmd.SetContext(testApp.ToContext(context.Background()))
95
+
96
+ err := handleListAccounts(cmd)
97
+ if err == nil {
98
+ t.Errorf("expected error for API failure")
99
+ }
100
+ if err.Error() != "fetching accounts: unexpected status code 500: Internal Server Error" {
101
+ t.Errorf("expected API error, got %v", err)
102
+ }
103
+ }
104
+
105
+ func TestAccountListCommandNoClient(t *testing.T) {
106
+ testApp := &app.App{}
107
+
108
+ cmd := accountListCmd
109
+ cmd.SetContext(testApp.ToContext(context.Background()))
110
+
111
+ err := handleListAccounts(cmd)
112
+ if err == nil {
113
+ t.Errorf("expected error when client not available")
114
+ }
115
+ if err.Error() != "API client not available" {
116
+ t.Errorf("expected 'client not available' error, got %v", err)
117
+ }
118
+ }
package/cmd/board.go CHANGED
@@ -1,23 +1,49 @@
1
+ // Package cmd
1
2
  package cmd
2
3
 
3
- import "github.com/spf13/cobra"
4
+ import (
5
+ "context"
6
+ "fmt"
7
+
8
+ "github.com/rogeriopvl/fizzy/internal/app"
9
+ "github.com/rogeriopvl/fizzy/internal/ui"
10
+ "github.com/spf13/cobra"
11
+ )
4
12
 
5
13
  var boardCmd = &cobra.Command{
6
14
  Use: "board",
7
- Short: "Manage boards",
8
- Long: `Manage boards in Fizzy`,
15
+ Short: "Show the currently selected board",
16
+ Long: `Display the name and ID of the currently selected board.
17
+
18
+ Use subcommands to list, create, or manage boards:
19
+ fizzy board list List all boards
20
+ fizzy board create Create a new board`,
21
+ Run: func(cmd *cobra.Command, args []string) {
22
+ if err := handleShowBoard(cmd); err != nil {
23
+ fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err)
24
+ }
25
+ },
9
26
  }
10
27
 
11
- func init() {
12
- rootCmd.AddCommand(boardCmd)
28
+ func handleShowBoard(cmd *cobra.Command) error {
29
+ a := app.FromContext(cmd.Context())
30
+ if a == nil || a.Client == nil {
31
+ return fmt.Errorf("API client not available")
32
+ }
13
33
 
14
- // Here you will define your flags and configuration settings.
34
+ if a.Config.SelectedBoard == "" {
35
+ return fmt.Errorf("no board selected")
36
+ }
15
37
 
16
- // Cobra supports Persistent Flags which will work for this command
17
- // and all subcommands, e.g.:
18
- // boardCmd.PersistentFlags().String("foo", "", "A help for foo")
38
+ board, err := a.Client.GetBoard(context.Background(), a.Config.SelectedBoard)
39
+ if err != nil {
40
+ return fmt.Errorf("fetching board: %w", err)
41
+ }
19
42
 
20
- // Cobra supports local flags which will only run when this command
21
- // is called directly, e.g.:
22
- // boardCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
43
+ fmt.Printf("%s (%s)\n", board.Name, ui.DisplayID(board.ID))
44
+ return nil
45
+ }
46
+
47
+ func init() {
48
+ rootCmd.AddCommand(boardCmd)
23
49
  }
@@ -0,0 +1,60 @@
1
+ package cmd
2
+
3
+ import (
4
+ "context"
5
+ "fmt"
6
+
7
+ "github.com/rogeriopvl/fizzy/internal/api"
8
+ "github.com/rogeriopvl/fizzy/internal/app"
9
+ "github.com/spf13/cobra"
10
+ )
11
+
12
+ var (
13
+ boardName string
14
+ boardAllAccess bool
15
+ boardAutoPostponePeriod int
16
+ boardPublicDescription string
17
+ )
18
+
19
+ var boardCreateCmd = &cobra.Command{
20
+ Use: "create",
21
+ Short: "Create a new board",
22
+ Long: `Create a new board in Fizzy`,
23
+ Run: func(cmd *cobra.Command, args []string) {
24
+ if err := handleCreateBoard(cmd); err != nil {
25
+ fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err)
26
+ }
27
+ },
28
+ }
29
+
30
+ func handleCreateBoard(cmd *cobra.Command) error {
31
+ a := app.FromContext(cmd.Context())
32
+ if a == nil || a.Client == nil {
33
+ return fmt.Errorf("API client not available")
34
+ }
35
+
36
+ payload := api.CreateBoardPayload{
37
+ Name: boardName,
38
+ AllAccess: boardAllAccess,
39
+ AutoPostponePeriod: boardAutoPostponePeriod,
40
+ PublicDescription: boardPublicDescription,
41
+ }
42
+
43
+ _, err := a.Client.PostBoards(context.Background(), payload)
44
+ if err != nil {
45
+ return fmt.Errorf("creating board: %w", err)
46
+ }
47
+
48
+ fmt.Printf("✓ Board '%s' created successfully\n", boardName)
49
+ return nil
50
+ }
51
+
52
+ func init() {
53
+ boardCreateCmd.Flags().StringVarP(&boardName, "name", "n", "", "Board name (required)")
54
+ boardCreateCmd.MarkFlagRequired("name")
55
+ boardCreateCmd.Flags().BoolVar(&boardAllAccess, "all-access", false, "Allow all access to the board")
56
+ boardCreateCmd.Flags().IntVar(&boardAutoPostponePeriod, "auto-postpone-period", 0, "Auto postpone period in days")
57
+ boardCreateCmd.Flags().StringVar(&boardPublicDescription, "description", "", "Public description of the board")
58
+
59
+ boardCmd.AddCommand(boardCreateCmd)
60
+ }