Released v1
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
## 1. Project Scaffolding
|
||||
|
||||
- [x] 1.1 Initialize Go module (`go mod init github.com/dcgsteve/pcli`)
|
||||
- [x] 1.2 Create directory structure: `cmd/`, `client/`, `model/`, `output/`, `logging/`
|
||||
- [x] 1.3 Add Cobra dependency (`go get github.com/spf13/cobra`)
|
||||
- [x] 1.4 Create `main.go` entry point that calls `cmd.Execute()`
|
||||
|
||||
## 2. Logging
|
||||
|
||||
- [x] 2.1 Implement `logging/logging.go` — `NewLogger(level string) *slog.Logger` that parses level string, creates JSON handler writing to stderr
|
||||
|
||||
## 3. Model Types
|
||||
|
||||
- [x] 3.1 Define `model/types.go` — Project, Board, List, Card, Comment, TaskList, Task, Label, Action, CardLabel, CardMembership structs with JSON tags and pointer types for nullable fields
|
||||
- [x] 3.2 Define `Envelope` struct (`Data any`, `Error *string`) in `model/types.go`
|
||||
- [x] 3.3 Define `APIError` struct (StatusCode int, Message string) implementing the `error` interface
|
||||
|
||||
## 4. Output Formatting
|
||||
|
||||
- [x] 4.1 Implement `output/output.go` — `Print(data any, format string, w io.Writer)` function that switches on format
|
||||
- [x] 4.2 Implement JSON output mode — marshal `Envelope{Data: data, Error: nil}` to stdout
|
||||
- [x] 4.3 Implement error output — `PrintError(err error, format string, w io.Writer)` that writes `Envelope{Data: nil, Error: msg}` for JSON, or error to stderr for table
|
||||
- [x] 4.4 Implement table output mode — tabwriter-based rendering with per-resource column definitions
|
||||
|
||||
## 5. Base HTTP Client
|
||||
|
||||
- [x] 5.1 Implement `client/client.go` — `Client` struct with BaseURL, Token, HTTPClient, Logger fields
|
||||
- [x] 5.2 Implement `NewClient(baseURL, token string, logger *slog.Logger) *Client`
|
||||
- [x] 5.3 Implement `Do(ctx, method, path string, body any) (json.RawMessage, error)` — URL construction, bearer header, JSON marshal/unmarshal, DEBUG logging with method/path/status/duration
|
||||
- [x] 5.4 Implement `APIError` handling — map 4xx/5xx responses to APIError, WARN logging on errors
|
||||
- [x] 5.5 Implement `DoNoBody(ctx, method, path string) (json.RawMessage, error)` convenience method for GET/DELETE
|
||||
|
||||
## 6. Root Command and Global Flags
|
||||
|
||||
- [x] 6.1 Implement `cmd/root.go` — root Cobra command with `--format`, `--url`, `--token`, `--log-level` persistent flags
|
||||
- [x] 6.2 Implement `PersistentPreRunE` — resolve URL/token from flags or env vars (flag > env), validate both present, initialize logger, create client instance
|
||||
- [x] 6.3 Wire output format into a shared variable accessible by all subcommands
|
||||
|
||||
## 7. Client — Project Operations
|
||||
|
||||
- [x] 7.1 Implement `client/projects.go` — `ListProjects(ctx) ([]model.Project, error)`
|
||||
- [x] 7.2 Implement `GetProject(ctx, id string) (*model.Project, error)`
|
||||
|
||||
## 8. Client — Board Operations
|
||||
|
||||
- [x] 8.1 Implement `client/boards.go` — `GetBoard(ctx, id string) (*model.Board, error)`
|
||||
- [x] 8.2 Implement `ListBoardActions(ctx, boardId string, limit int) ([]model.Action, error)` with cursor-based pagination using `beforeId`
|
||||
|
||||
## 9. Client — Card Operations
|
||||
|
||||
- [x] 9.1 Implement `client/cards.go` — `GetCard(ctx, id string) (*model.Card, error)`
|
||||
- [x] 9.2 Implement `CreateCard(ctx, listId string, fields) (*model.Card, error)`
|
||||
- [x] 9.3 Implement `UpdateCard(ctx, id string, fields) (*model.Card, error)`
|
||||
- [x] 9.4 Implement `DeleteCard(ctx, id string) error`
|
||||
- [x] 9.5 Implement `DuplicateCard(ctx, id string, name *string, position *float64) (*model.Card, error)`
|
||||
- [x] 9.6 Implement `ListCards(ctx, listId string, limit int) ([]model.Card, error)` with cursor-based pagination using `before`
|
||||
- [x] 9.7 Implement `ListCardActions(ctx, cardId string, limit int) ([]model.Action, error)` with cursor-based pagination using `beforeId`
|
||||
- [x] 9.8 Implement `ListCardsByBoard(ctx, boardId string, limit int) ([]model.CardWithList, error)` — multi-call enrichment: get board → get cards per list → inject listName
|
||||
- [x] 9.9 Implement `AddCardLabel(ctx, cardId, labelId string) error`
|
||||
- [x] 9.10 Implement `RemoveCardLabel(ctx, cardId, labelId string) error`
|
||||
- [x] 9.11 Implement `AddCardMember(ctx, cardId, userId string) error`
|
||||
- [x] 9.12 Implement `RemoveCardMember(ctx, cardId, userId string) error`
|
||||
|
||||
## 10. Client — Comment Operations
|
||||
|
||||
- [x] 10.1 Implement `client/comments.go` — `ListComments(ctx, cardId string, limit int) ([]model.Comment, error)` with cursor-based pagination using `beforeId`
|
||||
- [x] 10.2 Implement `CreateComment(ctx, cardId, text string) (*model.Comment, error)`
|
||||
- [x] 10.3 Implement `UpdateComment(ctx, id, text string) (*model.Comment, error)`
|
||||
- [x] 10.4 Implement `DeleteComment(ctx, id string) error`
|
||||
|
||||
## 11. Client — Task List Operations
|
||||
|
||||
- [x] 11.1 Implement `client/task_lists.go` — `CreateTaskList(ctx, cardId string, fields) (*model.TaskList, error)`
|
||||
- [x] 11.2 Implement `GetTaskList(ctx, id string) (*model.TaskList, error)`
|
||||
- [x] 11.3 Implement `UpdateTaskList(ctx, id string, fields) (*model.TaskList, error)`
|
||||
- [x] 11.4 Implement `DeleteTaskList(ctx, id string) error`
|
||||
|
||||
## 12. Client — Task Operations
|
||||
|
||||
- [x] 12.1 Implement `client/tasks.go` — `CreateTask(ctx, taskListId string, fields) (*model.Task, error)`
|
||||
- [x] 12.2 Implement `UpdateTask(ctx, id string, fields) (*model.Task, error)`
|
||||
- [x] 12.3 Implement `DeleteTask(ctx, id string) error`
|
||||
|
||||
## 13. Client — Label Operations
|
||||
|
||||
- [x] 13.1 Implement `client/labels.go` — `CreateLabel(ctx, boardId string, fields) (*model.Label, error)`
|
||||
- [x] 13.2 Implement `UpdateLabel(ctx, id string, fields) (*model.Label, error)`
|
||||
- [x] 13.3 Implement `DeleteLabel(ctx, id string) error`
|
||||
|
||||
## 14. CLI — Project Commands
|
||||
|
||||
- [x] 14.1 Implement `cmd/project.go` — `project` parent command, `project list` subcommand, `project get <id>` subcommand
|
||||
|
||||
## 15. CLI — Board Commands
|
||||
|
||||
- [x] 15.1 Implement `cmd/board.go` — `board` parent command, `board get <id>` subcommand, `board actions <id>` subcommand with `--limit` flag
|
||||
|
||||
## 16. CLI — Card Commands
|
||||
|
||||
- [x] 16.1 Implement `cmd/card.go` — `card` parent command
|
||||
- [x] 16.2 Implement `card list` subcommand with mutually required `--board` / `--list` flags and `--limit`
|
||||
- [x] 16.3 Implement `card get <id>` subcommand
|
||||
- [x] 16.4 Implement `card create` subcommand with `--list`, `--name` (required), `--description`, `--type`, `--position`, `--due-date`, `--due-completed` flags
|
||||
- [x] 16.5 Implement `card update <id>` subcommand with optional update flags
|
||||
- [x] 16.6 Implement `card delete <id>` subcommand
|
||||
- [x] 16.7 Implement `card duplicate <id>` subcommand with optional `--name`, `--position`
|
||||
- [x] 16.8 Implement `card move <id>` subcommand with required `--list` and optional `--position`
|
||||
- [x] 16.9 Implement `card assign <id>` and `card unassign <id>` subcommands with required `--user`
|
||||
- [x] 16.10 Implement `card add-label <id>` and `card remove-label <id>` subcommands with required `--label`
|
||||
- [x] 16.11 Implement `card actions <id>` subcommand with `--limit`
|
||||
|
||||
## 17. CLI — Comment Commands
|
||||
|
||||
- [x] 17.1 Implement `cmd/comment.go` — `comment` parent command, `comment list` with `--card` and `--limit`, `comment create` with `--card` and `--text`, `comment update <id>` with `--text`, `comment delete <id>`
|
||||
|
||||
## 18. CLI — Task List Commands
|
||||
|
||||
- [x] 18.1 Implement `cmd/task_list.go` — `task-list` parent command, `task-list create` with `--card`, `--name`, optional flags, `task-list get <id>`, `task-list update <id>`, `task-list delete <id>`
|
||||
|
||||
## 19. CLI — Task Commands
|
||||
|
||||
- [x] 19.1 Implement `cmd/task.go` — `task` parent command, `task create` with `--task-list`, `--name`, optional flags, `task update <id>` with optional flags, `task delete <id>`
|
||||
|
||||
## 20. CLI — Label Commands
|
||||
|
||||
- [x] 20.1 Implement `cmd/label.go` — `label` parent command, `label create` with `--board`, `--name`, optional `--color`, `--position`, `label update <id>`, `label delete <id>`
|
||||
|
||||
## 21. Build and Verify
|
||||
|
||||
- [x] 21.1 Verify `go build` produces a clean binary
|
||||
- [x] 21.2 Verify `pcli --help` displays all commands and global flags
|
||||
- [x] 21.3 Verify error output when `PLANKA_URL` / `PLANKA_TOKEN` are missing
|
||||
- [x] 21.4 Add README.md with installation, configuration, and usage examples
|
||||
Reference in New Issue
Block a user