Skip to content

Add epic hierarchy to Project Planning - #206

Merged
leoncheng57 merged 2 commits into
mainfrom
feat/planning-epic-hierarchy-finish
Aug 26, 2026
Merged

Add epic hierarchy to Project Planning#206
leoncheng57 merged 2 commits into
mainfrom
feat/planning-epic-hierarchy-finish

Conversation

@leoncheng57

Copy link
Copy Markdown
Owner

Summary

  • resolve bounded GitHub sub-issue relationships and expose deterministic parent ownership
  • render collapsed, persistent epic rows with child progress, compact checklist children, and filter-safe breadcrumbs
  • preserve priority promotion, read-only hierarchy, all density modes, and honest truncation warnings
  • add deterministic server, simulator, unit, and Playwright coverage

Verification

  • npm run typecheck - VERIFIED
  • npm test - VERIFIED: 631 tests / 53 files
  • npm run build - VERIFIED
  • CI=1 PORT=3541 MOCK_OPENCODE_PORT=4744 MOCK_PREVIEW_PORT=4745 npm run test:e2e - VERIFIED: 322 passed, 1 screenshot-runner-gated skip
  • npm run test:preview - VERIFIED: 1 passed after one unrelated transient iframe timeout on the first attempt

Human verification

  1. VERIFIED (Playwright): Open /planning; an epic is collapsed by default. Expected: child titles are absent and the parent shows an Epic marker plus progress. Failure: child rows render top-level or expanded.
  2. VERIFIED (Playwright): Activate the epic chevron with Enter. Expected: two thinner child rows appear beneath the parent, including the closed child. Failure: the title dialog opens or children duplicate elsewhere.
  3. VERIFIED (Playwright): Click a child title. Expected: the existing item dialog opens; the external-link control remains separate. Failure: expansion changes or GitHub navigation replaces the dialog.
  4. VERIFIED (Playwright): Inspect the parent progress. Expected: 1/2 closed and a 50% semantic progressbar. Failure: closed children are omitted or counts disagree.
  5. VERIFIED (Playwright): Select Closed and open Low priority. Expected: the filtered child appears top-level with Child of #101. Failure: it silently disappears.
  6. VERIFIED (unit + Playwright): Expand an epic and reload, then test malformed storage. Expected: valid state persists; malformed storage safely collapses all. Failure: reload loses valid state or page errors.
  7. VERIFIED (Playwright): Cycle all five densities and inspect at 390px with the epic expanded. Expected: controls remain usable and body width never exceeds viewport. Failure: horizontal overflow or inaccessible controls.
  8. VERIFIED (Playwright): Simulate epicsTruncated. Expected: warning appears while the planning feed remains visible. Failure: no warning or blank page.
  9. UNVERIFIED: Review the generated desktop/mobile screenshots for subjective visual polish after the screenshot workflow publishes them. Expected: hierarchy is immediately legible. Failure: cramped badges, weak parent/child distinction, or clipped content.

Remote hierarchy mutations

The approved GitHub issue grouping will be applied only after live preflight. A follow-up PR comment will contain the mutation log, final tree, and exact rollback commands.

full:/planning

GitHub's issue list reports sub_issues_summary but never a parent link, and
the only endpoint that names an epic's children is /issues/{n}/sub_issues.
So the snapshot now resolves edges itself, after pagination, with a bounded
fan-out: issues with childCount > 0, sorted by number descending, capped at
PLANNING_LIMITS.epics, at most epicConcurrency requests in flight, at most
epicChildren entries read per epic. It fails open per parent exactly like
the comments fetch in getPlanningItemDetails, so one unlucky epic cannot
blank a backlog that is mostly about other work, and it reports
epicsTruncated rather than implying the hierarchy is complete. Requests run
concurrently but assignments are applied afterwards in parent order, so a
child claimed by two epics always lands on the same one.

groupPlanningItems now returns nodes rather than flat items. A child folds
into its parent and gets no top-level row; a child whose parent is absent
from the filtered input keeps its row with orphanedParentNumber set, since
silently deleting it is the one outcome worse than a missing breadcrumb.
Section placement gains one deliberate exception to "the exact label selects
the section": a node sits at the highest priority anywhere in its epic, so a
priority:high child cannot be buried inside an unlabelled parent. The
parent's own priority conflict still wins outright — it needs triage
whatever its children say — and the tag group still comes from the parent
alone.

planningView.ts persists which epics a device has expanded, defaulting to
none, because folding the backlog down to its parents is the point.

Planning.tsx is touched only enough to keep typecheck honest: it flattens
each node back to parent-then-children rows until the epic UI lands.
@github-actions
github-actions Bot temporarily deployed to pr-preview-206 August 26, 2026 04:58 Destroyed
github-actions Bot added a commit that referenced this pull request Aug 26, 2026
@leoncheng57

Copy link
Copy Markdown
Owner Author

GitHub epic grouping mutation log

Live preflight completed before mutation: only #110 and #132 were parents; every proposed child was unparented; no proposed new parent title existed. PR #116 remained open, so #53 was included. PRs #176 and #178 were merged; closed #91 was omitted, while open #182 and #90 left two eligible sub-agent children. #104 was untouched.

Applied

Post-mutation verification refetched every child parent URL, all ten parent trees, adjusted labels, and the repository-wide parent set. Top-level open issue count: 25.

Exact rollback

GitHub cannot delete created issues. The commands below detach every added edge, restore adjusted labels, and close the eight newly-created empty parents.

gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/132/sub_issue -F sub_issue_id=5252115854
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/110/sub_issue -F sub_issue_id=5219225531
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/207/sub_issue -F sub_issue_id=5252247399
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/207/sub_issue -F sub_issue_id=5251617276
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/207/sub_issue -F sub_issue_id=5224038116
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/207/sub_issue -F sub_issue_id=5241931597
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/207/sub_issue -F sub_issue_id=5235978226
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/207/sub_issue -F sub_issue_id=5224023873
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/208/sub_issue -F sub_issue_id=5251652312
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/208/sub_issue -F sub_issue_id=5223345807
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/209/sub_issue -F sub_issue_id=5221982083
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/209/sub_issue -F sub_issue_id=5228665992
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/209/sub_issue -F sub_issue_id=5249538674
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/209/sub_issue -F sub_issue_id=5219011152
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/210/sub_issue -F sub_issue_id=5220612919
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/210/sub_issue -F sub_issue_id=5220505573
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/211/sub_issue -F sub_issue_id=5225369943
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/211/sub_issue -F sub_issue_id=5247279334
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/211/sub_issue -F sub_issue_id=5225453098
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/211/sub_issue -F sub_issue_id=5249542217
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/211/sub_issue -F sub_issue_id=5225453093
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/211/sub_issue -F sub_issue_id=5252278947
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/212/sub_issue -F sub_issue_id=5227326258
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/212/sub_issue -F sub_issue_id=5248550957
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/212/sub_issue -F sub_issue_id=5251627861
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/213/sub_issue -F sub_issue_id=5224887925
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/213/sub_issue -F sub_issue_id=5230632891
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/213/sub_issue -F sub_issue_id=5219076121
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/214/sub_issue -F sub_issue_id=5248101251
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/214/sub_issue -F sub_issue_id=5248062323
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/214/sub_issue -F sub_issue_id=5248975639
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/132/labels
gh api --method PATCH repos/leoncheng57/custom-dca-opencode/issues/110 -f "labels[]=priority:medium"
gh api --method DELETE repos/leoncheng57/custom-dca-opencode/issues/181/labels
gh issue close 207 --repo leoncheng57/custom-dca-opencode
gh issue close 208 --repo leoncheng57/custom-dca-opencode
gh issue close 209 --repo leoncheng57/custom-dca-opencode
gh issue close 210 --repo leoncheng57/custom-dca-opencode
gh issue close 211 --repo leoncheng57/custom-dca-opencode
gh issue close 212 --repo leoncheng57/custom-dca-opencode
gh issue close 213 --repo leoncheng57/custom-dca-opencode
gh issue close 214 --repo leoncheng57/custom-dca-opencode

@leoncheng57
leoncheng57 marked this pull request as ready for review August 26, 2026 05:03
@leoncheng57
leoncheng57 merged commit ae6d23d into main Aug 26, 2026
6 checks passed
github-actions Bot added a commit that referenced this pull request Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant