Skip to content

feat(web): show my GitHub PRs, review requests and issues - #191

Merged
Bakhomious merged 11 commits into
mainfrom
step/github-page
Oct 30, 2026
Merged

Bakhomious merged 11 commits into
mainfrom
step/github-page

Conversation

@Bakhomious

@Bakhomious Bakhomious commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

The user chose the page of its own at /github (nudge, 2026-10-30), the lead's pick that this PR builds. It lands ahead of the gateway's route in #179, which waits for codedogapp/homelab#43: until then, the gateway's 404 for a path that no service claims makes the page say "GitHub isn't set up.", as the Planner page does (#205).

Brief

Goal: the GitHub app's page shows the github service's three lists: my open PRs, the open PRs that wait for my review or my teams', and the open issues assigned to me (plan §8.2 Phase 4, github-page, decision 207).

Scope

  • apps/web/src/github/: github.ts, the item and snapshot types and the loader for each list; GitHubPage.svelte, three of the shell's PolledSections (decision 205) sharing one row snippet, and "GitHub isn't set up." in the shared status line (decision 206).
  • The shell's page.ts sends /github and the paths below it to the page, titled "GitHub · Bakhyard"; App.svelte shows it.
  • End-to-end: e2e/github.ts (the made-up user's lists and the answer helpers), e2e/github.spec.ts, and the GitHub page in e2e/page-status.spec.ts.
  • Plan: the §0 row, §7's GitHub page, §8.2, decision 207.

Out of scope: the Home's "Needs you" (github-attention, next); the gateway's route (#179); the rollout (codedogapp/homelab#43); when each item was opened or updated, a summary and a refresh button (decision 149).

Acceptance criteria

  • /github and the paths below it show the page, with the head "GitHub" and the title "GitHub · Bakhyard"; the desktop nav marks GitHub, the phone's tab bar marks More.
  • Three sections, "Your PRs", "Review requests" and "Assigned issues", each with its count, a row per item that links to it on GitHub (number, title, repository, and a Draft chip on a draft), its empty and failed texts, and the last search's failure.
  • The lists load at once, each time the page shows, and none waits for another.
  • When every list answers 404: "GitHub isn't set up." in the status line, with no section.
  • A row looks as a PR's row on the PRs page; long texts wrap on a 320 px screen.
  • mise run check is green.

What changed

  • The GitHub app's path shows the GitHub page rather than its "Coming soon" page, so "Your apps" and More lead to it.
  • The page loads GET /api/github/mine, /reviews and /issues as it shows, and each section appears once its own list loads. A row is the PRs page's without the review line, which GitHub's search doesn't give; an item without an https link gets a row that isn't a link (decisions 201 and 203).
  • The made-up user's GitHub lists live in e2e/github.ts rather than e2e/demo.ts, which would pass 200 lines with them.

Screenshots

The made-up user's lists, in the tests' Tokyo time.

Light Dark
Desktop The GitHub page on a desktop, light The GitHub page on a desktop, dark
Phone The GitHub page on a phone, light The GitHub page on a phone, dark

QA

  • Mutants: 42 on GitHubPage.svelte, github.ts and page.ts, covering:

    • the texts, nouns, titles and accents, and which list each section shows
    • the load order and the loading state
    • the row's link, label, title, repository and Draft chip
    • the status line's condition, the URL, the route and the title

    39 died at first. The 3 survivors die to the tests QA added:

    • the row's list-row and list-label classes: the end-to-end test "a draft PR's row looks as one on the PRs page" compares the row's, label's, title's, detail's and chip's computed styles with PR chore(deps): update dependency vite to v8.3.5 #41's on the PRs page
    • every → some in the status line's condition: the unit test "leaves out only the section of a list that answers 404 when the others load"
  • Added: the end-to-end test "the GitHub page loads its lists again each time it shows", as the PRs page's spec has (decision 172), and /github in App.pages.test.ts, so the app's page switch covers the page.

  • Coverage: src/github 100% of lines, statements and functions, 85.71% of branches. The one uncovered branch is the compiler's item.id ?? '' in #{item.id}, as in PullsSection.svelte's #{pull.id}.

  • The empty-text table in GitHubPage.test.ts lost a column that no test read.

Review

No blocking findings. Non-blocking:

  • The row is a second copy of the PRs page's row markup, a dozen lines without the review line, and its look comes from the global row classes (decision 123). Decision 207 rejects a shared row component for now; a third copy would move it to the shell, as decisions 112 and 205 did.
  • The status line's condition, Object.values(lists).every(…), stays in the component, as the PRs page's mine.kind === 'off' && reviews.kind === 'off' does.
  • With this page, every app has a page of its own, so no path shows the "Coming soon" page any more. The page stays, as plan §7 keeps it for an app until it's built, and its own test still renders it (decision 207). Main's test of the page that a path opens on used /github as its "Coming soon" example since feat(web): list the plans on the Planner page #205; it now opens on the GitHub page and waits for its "Your PRs" section, which AppPage doesn't have.

Gates

mise run check, green locally with BAKHYARD_E2E_PORT=8280 on the head with origin/main merged in: Go fmt, gen, lint, actions and compose lint, tests, coverage, govulncheck, the Copilot SDK check; web install, Biome, svelte-check and tsc, Vitest with coverage, knip, pnpm audit, Playwright end-to-end tests in both browsers (438 passed, 8 skipped); Vitest ran 1,341 tests.

The GitHub app's path now shows the github service's three lists, each
in the shell's polled section with one shared row, or "GitHub isn't
set up." when the service answers 404. A page of its own is the lead's
pick until the user chooses where the lists live (decision 207).
QA found that nothing checked a row's look against the PRs page's,
that the lists load again each time the page shows, or that one list
answering 404 leaves out only its section. The app's page tests now
cover the /github path too.
# Conflicts:
#	apps/web/e2e/page-status.spec.ts
#	apps/web/src/App.pages.test.ts
#	apps/web/src/App.svelte
#	apps/web/src/shell/page.test.ts
#	apps/web/src/shell/page.ts
#	docs/plan.md
# Conflicts:
#	apps/web/src/shell/page.ts
The user chose a page of its own at /github (nudge, 2026-10-30). The page lands ahead of the gateway's route, whose 404 makes it say that GitHub isn't set up until then.
@Bakhomious
Bakhomious marked this pull request as ready for review October 30, 2026 08:43
@Bakhomious
Bakhomious merged commit afd65f7 into main Oct 30, 2026
2 checks passed
@Bakhomious
Bakhomious deleted the step/github-page branch October 30, 2026 10:23
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