feat: Add openspec-sync-specs and openspec-verify-change skills
- Introduced `openspec-sync-specs` skill to sync delta specs to main specs, allowing intelligent merging of requirements. - Added `openspec-verify-change` skill to verify implementation against change artifacts, ensuring completeness, correctness, and coherence before archiving. docs: Create CLAUDE.md for project guidance - Added CLAUDE.md to provide an overview of the PCLI project, including build, test commands, architecture, and resource addition guidelines. chore: Add new change and design documents for project filter in status command - Created `.openspec.yaml`, `design.md`, `proposal.md`, and `tasks.md` for the `add-project-filter-to-status` change. - Updated specs for CLI commands and status command to include project filtering functionality. feat: Expand board included parsing in API client - Added parsing for `labels`, `cardLabels`, and `cardMemberships` in the `GetBoard` response. - Updated `ListCardsByBoard` to enrich card output with label names, enhancing usability in kanban sync workflows.
This commit is contained in:
+8
-2
@@ -43,8 +43,11 @@ func (c *Client) GetBoard(ctx context.Context, id string) (*model.Board, error)
|
||||
var response struct {
|
||||
Item model.Board `json:"item"`
|
||||
Included struct {
|
||||
Lists []model.List `json:"lists"`
|
||||
Cards []model.Card `json:"cards"`
|
||||
Lists []model.List `json:"lists"`
|
||||
Cards []model.Card `json:"cards"`
|
||||
Labels []model.Label `json:"labels"`
|
||||
CardLabels []model.CardLabel `json:"cardLabels"`
|
||||
CardMemberships []model.CardMembership `json:"cardMemberships"`
|
||||
} `json:"included"`
|
||||
}
|
||||
|
||||
@@ -54,6 +57,9 @@ func (c *Client) GetBoard(ctx context.Context, id string) (*model.Board, error)
|
||||
|
||||
response.Item.Lists = response.Included.Lists
|
||||
response.Item.Cards = response.Included.Cards
|
||||
response.Item.Labels = response.Included.Labels
|
||||
response.Item.CardLabels = response.Included.CardLabels
|
||||
response.Item.CardMemberships = response.Included.CardMemberships
|
||||
|
||||
return &response.Item, nil
|
||||
}
|
||||
|
||||
+36
-3
@@ -9,21 +9,31 @@ import (
|
||||
"git.franklin.lab/steve.cliff/pcli/model"
|
||||
)
|
||||
|
||||
func (c *Client) GetCard(ctx context.Context, id string) (*model.Card, error) {
|
||||
func (c *Client) GetCard(ctx context.Context, id string) (*model.CardDetail, error) {
|
||||
data, err := c.DoNoBody(ctx, "GET", fmt.Sprintf("/api/cards/%s", id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Item model.Card `json:"item"`
|
||||
Item model.Card `json:"item"`
|
||||
Included struct {
|
||||
TaskLists []model.TaskList `json:"taskLists"`
|
||||
Tasks []model.Task `json:"tasks"`
|
||||
} `json:"included"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, &response); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal card response: %w", err)
|
||||
}
|
||||
|
||||
return &response.Item, nil
|
||||
result := &model.CardDetail{
|
||||
Card: response.Item,
|
||||
TaskLists: response.Included.TaskLists,
|
||||
Tasks: response.Included.Tasks,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *Client) CreateCard(ctx context.Context, listId string, fields map[string]any) (*model.Card, error) {
|
||||
@@ -195,11 +205,34 @@ func (c *Client) ListCardsByBoard(ctx context.Context, boardId string, limit int
|
||||
listNames[list.ID] = name
|
||||
}
|
||||
|
||||
// Build label ID -> name map
|
||||
labelNames := make(map[string]string)
|
||||
for _, label := range board.Labels {
|
||||
name := ""
|
||||
if label.Name != nil {
|
||||
name = *label.Name
|
||||
}
|
||||
labelNames[label.ID] = name
|
||||
}
|
||||
|
||||
// Build card ID -> label names map
|
||||
cardLabelNames := make(map[string][]string)
|
||||
for _, cl := range board.CardLabels {
|
||||
if name, ok := labelNames[cl.LabelID]; ok {
|
||||
cardLabelNames[cl.CardID] = append(cardLabelNames[cl.CardID], name)
|
||||
}
|
||||
}
|
||||
|
||||
var allCards []model.CardWithList
|
||||
for _, card := range board.Cards {
|
||||
labels := cardLabelNames[card.ID]
|
||||
if labels == nil {
|
||||
labels = []string{}
|
||||
}
|
||||
cardWithList := model.CardWithList{
|
||||
Card: card,
|
||||
ListName: listNames[card.ListID],
|
||||
Labels: labels,
|
||||
}
|
||||
allCards = append(allCards, cardWithList)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user