Added list management commands, board filtering by project name, and enhanced skill documentation with bootstrap workflow and error handling patterns. Also added plumbing in to "pcli" binary for status syncing with Planka

This commit is contained in:
Steve Cliff
2026-02-18 20:06:56 +00:00
parent ad384fe749
commit 46b03e1a22
21 changed files with 1074 additions and 124 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-18
@@ -0,0 +1,71 @@
## Context
The `pcli board list` command currently calls `client.ListBoards()` which returns all boards accessible to the user across all projects. There's no filtering capability at the CLI level. The kanban-sync workflow needs to check if a board exists within a specific project before creating it, but without filtering, it risks creating duplicates.
The Planka API returns boards with a `projectId` field. Projects can be listed via `client.ListProjects()` which returns project objects with `id` and `name` fields. We need to bridge project names (user-friendly) to project IDs (API-level) for filtering.
## Goals / Non-Goals
**Goals:**
- Add `--project <name>` flag to `pcli board list` command
- Filter boards by project name using case-insensitive matching
- Maintain backward compatibility (no flag = list all boards)
- Provide clear error message if project name doesn't match any accessible project
**Non-Goals:**
- Filtering by multiple projects simultaneously
- Fuzzy matching or partial name matching (exact case-insensitive match only)
- Adding project filtering to other board commands (get, actions, etc.)
- Caching project lookups across commands
## Decisions
### Decision 1: Filter client-side, not API-side
**Choice:** Fetch all boards via `ListBoards()`, then filter in CLI code based on `projectId`.
**Rationale:** The Planka API's `ListBoards()` endpoint doesn't support project filtering. Adding API-level filtering would require changes to the Planka server or a different endpoint. Client-side filtering is simpler and keeps changes contained to pcli.
**Alternatives considered:**
- Use a different API endpoint: No suitable endpoint exists in the Planka API
- Modify Planka API: Out of scope for this change
**Trade-off:** Fetches all boards even when filtering, but acceptable given typical board counts.
### Decision 2: Accept project name, not project ID
**Choice:** The `--project` flag accepts a project name string and resolves it to an ID internally.
**Rationale:** Project names are more user-friendly and memorable than UUIDs. Users working with kanban-sync know project names, not IDs.
**Alternatives considered:**
- Accept project ID: Less user-friendly, requires users to look up IDs first
- Accept both name and ID: Adds complexity for minimal benefit
**Trade-off:** Requires an additional API call to `ListProjects()` to resolve the name, but this is a one-time cost per command execution.
### Decision 3: Case-insensitive exact match
**Choice:** Match project name case-insensitively but require exact match (no partial/fuzzy matching).
**Rationale:** Case-insensitive matching improves usability (users don't need to remember exact casing). Exact matching avoids ambiguity when multiple projects have similar names.
**Alternatives considered:**
- Case-sensitive matching: Too strict, poor UX
- Fuzzy/partial matching: Could match multiple projects, requires disambiguation logic
**Trade-off:** Users must know the exact project name, but this is acceptable for the target use case.
### Decision 4: Error on no match
**Choice:** If `--project` is provided but no accessible project matches the name, return an error and exit with code 1.
**Rationale:** Silent failure or empty results could confuse users. Explicit error makes it clear the project name is wrong or inaccessible.
**Alternatives considered:**
- Return empty list: Ambiguous (no boards vs. wrong project name)
- List similar project names: Adds complexity
## Risks / Trade-offs
**[Risk: Performance with many boards]** → Acceptable: Client-side filtering requires fetching all boards. For users with hundreds of boards, this could be slow. However, typical Planka instances have <100 boards, making this acceptable. If performance becomes an issue, we can optimize later with API-level filtering.
**[Risk: Project name collisions]** → Mitigated: If multiple projects have the same name (case-insensitive), the first match wins. This is unlikely in practice since project names are typically unique within an organization. If needed, users can use `pcli project list` to identify the correct project.
**[Risk: Additional API call overhead]** → Acceptable: Resolving project name to ID requires calling `ListProjects()`. This adds ~100-200ms latency but is necessary for the user-friendly interface. The call is made only once per command execution.
@@ -0,0 +1,34 @@
## Why
The `pcli board list` command currently returns all accessible boards across all projects, making it difficult to find boards within a specific project. When working with the kanban-sync workflow, we need to filter boards by project name to avoid creating duplicate boards. This change adds a `--project` flag to enable project-scoped board listing.
## What Changes
- Add `--project <name>` flag to `pcli board list` command
- When `--project` is provided, filter boards to only show those belonging to the specified project
- When `--project` is omitted, maintain current behavior (list all boards)
- The flag accepts a project name (not ID) and performs case-insensitive matching
## Capabilities
### New Capabilities
- `board-list-filtering`: Filter board list results by project name
### Modified Capabilities
- `cli-commands`: Add `--project` flag to the `board list` command specification
## Impact
**Code:**
- `cmd/board.go`: Add `--project` flag to `boardListCmd` and implement filtering logic
- `client/boards.go`: May need to add project name resolution if not already available
**APIs:**
- Uses existing `ListBoards()` and `ListProjects()` client methods
- No new API endpoints required
**Dependencies:**
- No new dependencies
**Workflows:**
- Enables kanban-sync workflow to check for existing boards within a specific project before creating new ones
@@ -0,0 +1,32 @@
## ADDED Requirements
### Requirement: Board list project filtering
The system SHALL provide a `--project <name>` flag for the `board list` command. When the flag is provided, the system SHALL resolve the project name to a project ID by calling `ListProjects()` and performing a case-insensitive exact match on the project name. If no matching project is found, the system SHALL output an error message "project not found: <name>" and exit with code 1. If a matching project is found, the system SHALL filter the board list to include only boards where `projectId` matches the resolved project ID. When the `--project` flag is omitted, the system SHALL list all accessible boards without filtering.
#### Scenario: List boards without project filter
- **WHEN** `pcli board list` is executed without the `--project` flag
- **THEN** the system SHALL output all accessible boards across all projects
#### Scenario: List boards filtered by project name
- **WHEN** `pcli board list --project "project1"` is executed
- **THEN** the system SHALL resolve "project1" to a project ID
- **AND** the system SHALL output only boards belonging to that project
#### Scenario: List boards with case-insensitive project match
- **WHEN** `pcli board list --project "PROJECT1"` is executed and a project named "project1" exists
- **THEN** the system SHALL match the project case-insensitively
- **AND** the system SHALL output boards belonging to the matched project
#### Scenario: Project name not found
- **WHEN** `pcli board list --project "nonexistent"` is executed
- **THEN** the system SHALL output "project not found: nonexistent"
- **AND** the system SHALL exit with code 1
#### Scenario: Project exists but has no boards
- **WHEN** `pcli board list --project "empty-project"` is executed for a project with no boards
- **THEN** the system SHALL output an empty list (or empty JSON array in JSON format)
#### Scenario: User lacks access to project
- **WHEN** `pcli board list --project "restricted"` is executed for a project the user cannot access
- **THEN** the system SHALL output "project not found: restricted"
- **AND** the system SHALL exit with code 1
@@ -0,0 +1,57 @@
## ADDED Requirements
### Requirement: Board list command
The system SHALL provide a `board list` subcommand. `pcli board list` SHALL call the client's ListBoards method and output all accessible boards. The command SHALL accept an optional `--project <name>` flag (string). When `--project` is provided, the system SHALL filter boards to only those belonging to the specified project (see board-list-filtering spec for filtering behavior).
#### Scenario: List all boards
- **WHEN** `pcli board list` is executed without flags
- **THEN** the system SHALL output all accessible boards
#### Scenario: List boards filtered by project
- **WHEN** `pcli board list --project "project1"` is executed
- **THEN** the system SHALL output only boards belonging to the specified project
## MODIFIED Requirements
### Requirement: Board commands
The system SHALL provide a `board` command group with subcommands `list`, `get`, `actions`, `create`, and `delete`. `pcli board list` SHALL list all accessible boards and accept an optional `--project <name>` flag for filtering. `pcli board get <id>` SHALL accept a board ID as a positional argument and output the board details. `pcli board actions <id>` SHALL accept a board ID and an optional `--limit` flag (int, default 0) and output the board's action history. `pcli board create` SHALL create a new board. `pcli board delete <id>` SHALL delete a board.
#### Scenario: Get board
- **WHEN** `pcli board get <id>` is executed
- **THEN** the system SHALL output the board details including its lists
#### Scenario: List board actions
- **WHEN** `pcli board actions <id>` is executed
- **THEN** the system SHALL output the board's action history
#### Scenario: List board actions with limit
- **WHEN** `pcli board actions <id> --limit 10` is executed
- **THEN** the system SHALL output at most 10 action entries
#### Scenario: Create board
- **WHEN** `pcli board create --project <id> --name "Development Board" --position 65536` is executed
- **THEN** the system SHALL create the board and output the created board
#### Scenario: Create board missing required flags
- **WHEN** `pcli board create` is executed without `--project` or `--name`
- **THEN** the system SHALL print an error indicating the required flags and exit with code 1
#### Scenario: Create board with insufficient permissions
- **WHEN** `pcli board create --project <id> --name "Board"` is executed by a user without project manager permissions on the project
- **THEN** the system SHALL output "create board: permission denied (requires project manager role)"
#### Scenario: Create board project not found
- **WHEN** `pcli board create --project <id> --name "Board"` is executed with a project the user cannot access
- **THEN** the system SHALL output "create board: not found — the resource may not exist or you may not have access to it"
#### Scenario: Delete board
- **WHEN** `pcli board delete <id>` is executed with a valid board ID
- **THEN** the system SHALL delete the board and output a success confirmation
#### Scenario: Delete board with insufficient permissions
- **WHEN** `pcli board delete <id>` is executed by a user without project manager permissions
- **THEN** the system SHALL output "delete board: permission denied (requires project manager role)"
#### Scenario: Delete board not found
- **WHEN** `pcli board delete <id>` is executed with a non-existent board ID
- **THEN** the system SHALL output "delete board: not found — the resource may not exist or you may not have access to it"
@@ -0,0 +1,24 @@
## 1. Add project name resolution helper
- [x] 1.1 Add helper function in cmd/board.go to resolve project name to ID by calling ListProjects() and performing case-insensitive match
- [x] 1.2 Add error handling for project not found case with appropriate error message
## 2. Implement board list filtering
- [x] 2.1 Add --project flag to boardListCmd in cmd/board.go
- [x] 2.2 Implement filtering logic: when --project is provided, resolve name to ID and filter boards by projectId
- [x] 2.3 Maintain backward compatibility: when --project is omitted, list all boards
## 3. Update tests and documentation
- [x] 3.1 Add test cases for board list with project filter
- [x] 3.2 Add test cases for project not found error
- [x] 3.3 Add test cases for case-insensitive project matching
- [x] 3.4 Update README or help text if needed
## 4. Verify integration
- [x] 4.1 Test board list without --project flag (should list all boards)
- [x] 4.2 Test board list with valid --project flag (should filter correctly)
- [x] 4.3 Test board list with invalid --project flag (should error appropriately)
- [x] 4.4 Test board list with case variations in project name