B2 — Planner board: group-by pivot (agent | stage | repo) #410
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks#410
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
As an operator,
I want to switch the column axis between agent type, pipeline stage, and repo,
so that I can audit "what is every reviewer doing" or "what does the spec column look like across repos" without leaving the route.
Today
/planner/boardcolumns are always per agent type. A?repo=filter exists but no native pivot. This story adds a Linear-style group-by toggle that re-projects the same card set against three axes.Acceptance criteria
Frontend
Group: [agent | stage | repo], persisted in URL as?group=, defaultagent.group=agent(default) — current column projection, unchanged.group=stage— columns from the pipeline stage enum (triage,spec,impl,review,merged); each card still shows its agent on the card face.group=repo— one column per repo with at least one open card; cards still show their stage badge.repo,milestone,label,unassigned) work identically across pivots. (repochip becomes a no-op whengroup=repo— show it disabled with a tooltip.)Drag semantics per pivot
group=agent— drag triggersassignCard(existing behaviour). Dropping onto a different agent column reassigns; B1 covers the Unassigned target.group=stage— drag triggers a newrestageCardmutation (see backend). Dropping onto a different stage updates the stage label + cancels the running task on the previous stage's agent, mirroring/board/reroutesemantics. Source-and-target-equal drops are no-ops.group=repo— drag is disabled. Cards render withcursor-defaultand no drag handle. Cross-repo move is not a meaningful op.Backend — new endpoint
POST /board/restage{ repo: string, issue_number: number, new_stage: "triage" | "spec" | "impl" | "review" | "merged" }.merged → triage); return400 { error: "illegal_stage_transition", from, to }.stage:*label, add new). Usemcp__forgejo__add_issue_labelsandremove_issue_labelsserver-side helpers inapps/server/src/infrastructure/forge/.Stage moved from @{from} to @{to} by @{actor} via board.{ ok: true, repo, issue_number, new_stage }.Tests
board.test.tsx: pivot toggle updates URL, re-projects columns, preserves card identity (same key → same DOM node where possible).board.test.tsx: drag ingroup=stage→restageCardcall.board.test.tsx: drag ingroup=repois a no-op (nodragstartor visibly suppressed)./board/restage: happy path, illegal transition, running-task cancellation, audit comment.Out of scope
References
docs/specs/board-rework.md§5 B2 + §6.packages/shared/src/pipeline.ts(or wherever the enum lives — checkapps/server/src/domain/views/pipeline.ts).POST /board/rerouteinapps/server/src/domain/views/board.ts.docs/label-routing.md.Dependencies
Suggested first commit
feat(board): group-by pivot — agent | stage | repo