Released v1

This commit is contained in:
Steve Cliff
2026-02-12 10:37:19 +00:00
commit b07572fed5
77 changed files with 19518 additions and 0 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-11
@@ -0,0 +1,45 @@
## Context
pcli is a Cobra-based CLI for the Planka project management API. Commands follow a `pcli <resource> <action>` pattern (e.g., `pcli board get`, `pcli card list`). The client layer already provides `ListBoards()` (via `/api/projects`) and `GetBoard(id)` (via `/api/boards/:id`), where `GetBoard` returns the board's lists and cards in the `included` block. Output is handled by `output.Print()` which dispatches to JSON envelope or table rendering based on the `--format` flag.
## Goals / Non-Goals
**Goals:**
- Provide a single top-level `pcli status` command that summarizes all boards, their lists, and card counts
- Reuse existing client methods with no new API endpoints
- Support both JSON and table output formats via the existing `--format` flag
- Show open card counts as the primary number, with closed cards noted separately
**Non-Goals:**
- Concurrent/parallel board fetching (sequential is sufficient for expected board counts)
- Filtering by project, board, or list (this is a full overview command)
- Showing card-level detail (names, assignees, due dates) — that's what `card list` is for
- Caching or incremental updates
## Decisions
### 1. Top-level command, not a subcommand
The `status` command will be registered directly on `rootCmd`, not under `board` or any other resource group. It's a cross-cutting summary, not a resource operation.
**Alternative considered:** `pcli board status` — rejected because the command spans all boards and is conceptually similar to `git status` as a quick overview.
### 2. Data aggregation in the command layer
The status command will call `ListBoards()` then `GetBoard(id)` for each board, aggregating card counts per list in the command handler. No new client method is needed.
**Alternative considered:** A dedicated `client.GetStatus()` method — rejected because there's no single Planka API endpoint for this; the aggregation is purely a CLI concern.
### 3. New model types for status data
A `StatusSummary` struct will hold the aggregated data, containing a slice of `BoardSummary` structs (board name + list summaries), each containing a slice of `ListSummary` structs (list name, open count, closed count). This gives both JSON and table formatters a clean data structure to work with.
**Alternative considered:** Reusing existing `Board`/`List` types with card slices — rejected because the status output is a derived summary, not raw API data.
### 4. Table output uses per-board sections
In table format, each board is rendered as a headed section with a list/cards table beneath it. A total board count line appears first. This matches the natural reading pattern for a summary view.
### 5. JSON output uses the standard envelope
JSON output wraps the `StatusSummary` in the existing `{"data": ..., "error": null}` envelope, consistent with all other commands.
## Risks / Trade-offs
- **N+1 API calls** — One `ListBoards` call plus one `GetBoard` per board. For typical usage (< 20 boards) this is fine. If it becomes a problem, concurrent fetching can be added later without changing the interface. → Mitigation: defer optimization until needed.
- **Stale data between calls** — Board state could change between sequential `GetBoard` calls. → Mitigation: acceptable for a summary view; not a transactional operation.
@@ -0,0 +1,30 @@
## Why
There is no quick way to get an overview of the state of all boards in Planka from the CLI. Users currently need to run multiple commands (`board list`, then `board get` per board, then mentally tally cards) to understand what's where. A single `pcli status` command provides an at-a-glance summary — similar in spirit to `git status`.
## What Changes
- Add a new top-level `pcli status` command that:
- Lists the total number of boards
- For each board, displays a table of its lists with card counts
- Card counts show open cards as the primary number, with closed cards in parentheses (e.g., `12 (2 closed)`)
- Empty lists are shown with `0` cards
- Respects the global `--format` flag: JSON by default, table when `--format table` is specified
- Uses existing `ListBoards` and `GetBoard` client methods — no new API endpoints needed
- Sequential board fetching (one `GetBoard` call per board)
## Capabilities
### New Capabilities
- `status-command`: The top-level `pcli status` command, its data aggregation logic, and its output formatting (both JSON and table)
### Modified Capabilities
- `cli-commands`: Adding the new `status` top-level command to the CLI command tree
## Impact
- **New file**: `cmd/status.go` — command definition and aggregation logic
- **Modified file**: `output/output.go` — table rendering for the status summary type
- **Modified file**: `model/types.go` — new types for the status summary data structure
- No new dependencies required
- No breaking changes
@@ -0,0 +1,16 @@
## ADDED Requirements
### Requirement: Status command
The system SHALL provide a top-level `status` command registered directly on the root command (not as a subcommand of any resource group). `pcli status` SHALL take no positional arguments. The command SHALL fetch all boards via `ListBoards`, then fetch each board's details via `GetBoard` sequentially, aggregate card counts per list, and output the result via the standard `output.Print` mechanism respecting the global `--format` flag.
#### Scenario: Run status command
- **WHEN** `pcli status` is executed
- **THEN** the system SHALL output a summary of all boards with their lists and card counts
#### Scenario: Status command respects format flag
- **WHEN** `pcli status --format table` is executed
- **THEN** the output SHALL be in table format
#### Scenario: Status command default format
- **WHEN** `pcli status` is executed without a `--format` flag
- **THEN** the output SHALL be in JSON envelope format
@@ -0,0 +1,53 @@
## ADDED Requirements
### Requirement: Status command summary output
The system SHALL provide a top-level `pcli status` command that outputs a summary of all boards, their lists, and card counts. The summary SHALL include the total number of boards. For each board, the summary SHALL include the board name and a breakdown of each list within that board showing the list name, the number of open cards (where `isClosed` is false), and the number of closed cards (where `isClosed` is true). Empty lists SHALL be included in the output with 0 open and 0 closed cards.
#### Scenario: Status with multiple boards and lists
- **WHEN** `pcli status` is executed and there are boards with lists containing cards
- **THEN** the output SHALL include the total board count
- **AND** each board SHALL list all its lists with open and closed card counts
#### Scenario: Status with empty lists
- **WHEN** a board contains a list with no cards
- **THEN** that list SHALL appear in the output with 0 open cards and 0 closed cards
#### Scenario: Status with no boards
- **WHEN** `pcli status` is executed and there are no boards
- **THEN** the output SHALL indicate 0 boards
#### Scenario: Status with closed cards
- **WHEN** a list contains both open and closed cards
- **THEN** the open card count SHALL exclude closed cards
- **AND** the closed card count SHALL be shown separately
### Requirement: Status command JSON output
The system SHALL output the status summary in the standard JSON envelope format (`{"data": ..., "error": null}`) when `--format json` is used or no format flag is provided. The `data` field SHALL contain an object with `totalBoards` (integer) and `boards` (array). Each board object SHALL contain `id` (string), `name` (string), and `lists` (array). Each list object SHALL contain `id` (string), `name` (string), `openCards` (integer), and `closedCards` (integer).
#### Scenario: JSON output structure
- **WHEN** `pcli status` is executed with `--format json` or no format flag
- **THEN** the output SHALL be a JSON envelope with the status summary as the `data` field
#### Scenario: JSON output field types
- **WHEN** the JSON output is parsed
- **THEN** `totalBoards` SHALL be an integer
- **AND** each list's `openCards` and `closedCards` SHALL be integers
### Requirement: Status command table output
The system SHALL output the status summary in a human-readable table format when `--format table` is specified. The table output SHALL begin with a line showing the total number of boards (e.g., `3 boards`). For each board, the output SHALL display a board header line (e.g., `Board: Sprint Planning`) followed by a table with columns `LIST` and `CARDS`. The `CARDS` column SHALL display the open card count, and if there are closed cards, append ` (<n> closed)` (e.g., `12 (2 closed)`). If there are no closed cards, only the open count SHALL be displayed (e.g., `12`).
#### Scenario: Table output with closed cards
- **WHEN** `pcli status --format table` is executed and a list has 12 open and 2 closed cards
- **THEN** the CARDS column for that list SHALL display `12 (2 closed)`
#### Scenario: Table output with no closed cards
- **WHEN** `pcli status --format table` is executed and a list has 5 open and 0 closed cards
- **THEN** the CARDS column for that list SHALL display `5`
#### Scenario: Table output with empty list
- **WHEN** `pcli status --format table` is executed and a list has 0 open and 0 closed cards
- **THEN** the CARDS column for that list SHALL display `0`
#### Scenario: Table output board count line
- **WHEN** `pcli status --format table` is executed
- **THEN** the first line of output SHALL show the total board count (e.g., `3 boards`)
@@ -0,0 +1,17 @@
## 1. Model Types
- [x] 1.1 Add `StatusSummary`, `BoardSummary`, and `ListSummary` structs to `model/types.go`
## 2. Command Implementation
- [x] 2.1 Create `cmd/status.go` with the top-level `pcli status` command registered on `rootCmd`
- [x] 2.2 Implement the command handler: call `ListBoards`, then `GetBoard` per board, aggregate open/closed card counts per list, build `StatusSummary`, and pass to `output.Print`
## 3. Output Formatting
- [x] 3.1 Add `printStatusTable` function to `output/output.go` rendering the board count header line, per-board sections with LIST/CARDS columns, and closed card counts in parentheses
- [x] 3.2 Register `StatusSummary` in the `printTable` dispatch logic (both direct and pointer cases)
## 4. Verification
- [x] 4.1 Build and manually test `pcli status` with `--format json` (default) and `--format table`