Skip to content

Commit bf538e2

Browse files
committed
feat(prs): add repository overview and reading panel for v0.3.0
1 parent e2efa27 commit bf538e2

15 files changed

Lines changed: 936 additions & 93 deletions

‎CHANGELOG.md‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,32 @@ All notable changes are documented here. The format follows
66

77
## [Unreleased]
88

9+
## [0.3.0] - 2026-10-08
10+
11+
### Added
12+
13+
- Pull request reading panel with descriptions, changed files, review and check details, branches,
14+
and linked local worktrees. Details load on selection, with shared requests, caching, and retry.
15+
- Searchable organization and repository picker, with PR totals and attention counts.
16+
- Direct GitHub links from every pull request row and the reading panel.
17+
18+
### Changed
19+
20+
- Replaced the wide pull request table with a repository overview and a separate sticky reader.
21+
The list follows normal page scrolling; phones open the reader with a Back to pull requests action.
22+
- Compact `organization / repository` headings show counts and latest commit time, including when
23+
collapsed. Organizations and repositories follow the selected activity or name sort.
24+
- Repository previews show two pull requests with a Show more action; search and filters show all
25+
matching results. Repository expansion and the selected PR are remembered for the browser session.
26+
- Consolidated PR status controls into a dropdown alongside search, filters, and sorting.
27+
- Refreshed the README, design notes, and light, dark, and phone PR screenshots using synthetic data.
28+
29+
### Fixed
30+
31+
- Long check lists no longer stretch pull request rows; details are available in the reader.
32+
- Aligned repository metadata and pull request actions, with wrapping for long titles and paths.
33+
- Dividers stay clear of rounded selected, hovered, and keyboard-focused rows.
34+
935
## [0.2.0] - 2026-10-07
1036

1137
### Added
@@ -55,6 +81,7 @@ First public release.
5581
- Single zero-dependency Go binary (around 20 MB RAM); Homebrew cask, release archives for macOS and
5682
Linux, and `scripts/install.sh`.
5783

58-
[Unreleased]: https://github.com/MilosMosovsky/agentyard/compare/v0.2.0...HEAD
84+
[Unreleased]: https://github.com/MilosMosovsky/agentyard/compare/v0.3.0...HEAD
85+
[0.3.0]: https://github.com/MilosMosovsky/agentyard/releases/tag/v0.3.0
5986
[0.2.0]: https://github.com/MilosMosovsky/agentyard/releases/tag/v0.2.0
6087
[0.1.0]: https://github.com/MilosMosovsky/agentyard/releases/tag/v0.1.0

‎README.md‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ commit, the worktree's index and any uncommitted file. Sizes are `du` logical si
8181
### Pull requests
8282

8383
<picture>
84-
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/prs-dark.png">
85-
<img alt="The Pull requests page: colored status quick views, searchable multi-select filters, and a table where each PR shows the one thing blocking it." src="docs/screenshots/prs-light.png" width="100%">
84+
<source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/prs-dark.jpg">
85+
<img alt="The Pull requests page: compact organization / repository groups with activity and status counts, direct GitHub links, and a sticky reader for the selected PR." src="docs/screenshots/prs-light.jpg" width="100%">
8686
</picture>
8787

8888
Every open PR you authored (`is:pr is:open author:@me archived:false`, as whoever `gh` is logged in
@@ -102,8 +102,18 @@ this order:
102102
| **Blocked** | branch protection is not satisfied | |
103103
| **Ready to merge** | none of the above | who approved it |
104104

105-
Next to the state: check counts, review state, last commit, diff size, and the local worktree that has
106-
the branch checked out. Status quick views give one-click access to needs-action, ready, waiting, draft, and queued PRs. The Filter menu combines multiple statuses, organizations, and repositories with search. Active selections can be removed individually; filters and sort order are remembered for the browser session.
105+
The overview groups PRs under compact `organization / repository` headings. Counts, attention
106+
indicators, and the latest commit time remain visible when a repository is collapsed. Groups follow
107+
your activity or name sort. Expanded repositories preview two PRs; **Show more** opens the rest.
108+
109+
Select a PR to read its description, changed files, checks, reviews, branch, and linked local worktree
110+
in the sticky reader. The list scrolls with the page. **GitHub** links on each row and in the reader
111+
open the PR directly. On a phone, selection opens the reader with a **Back to pull requests** action.
112+
113+
Use the repository heading's picker to find an organization or repository, the status dropdown for
114+
needs-action, ready, waiting, draft, or queued PRs, and **Filter** for multiple selections. Search and
115+
filters show all matching results without the two-PR preview limit. Active selections can be removed
116+
individually; filters, sorting, repository expansion, and the selected PR persist for the browser session.
107117

108118
### Sessions
109119

@@ -135,7 +145,7 @@ every target is thumb-sized.
135145
<p align="center">
136146
<img alt="The Worktrees page on a phone: totals as a two-by-two grid and repositories as cards." src="docs/screenshots/phone-worktrees.png" width="260">
137147
&nbsp;&nbsp;
138-
<img alt="The Pull requests page on a phone: status quick views, a mobile filter panel, and one card per PR with its blocker, checks and review." src="docs/screenshots/phone-prs.png" width="260">
148+
<img alt="The Pull requests page on a phone: repository groups with activity counts, compact PR previews and direct GitHub actions." src="docs/screenshots/phone-prs.jpg" width="260">
139149
</p>
140150

141151
**Sync now** (top right) re-runs the worktree scan, the PR poll and the session index right away and
@@ -379,8 +389,10 @@ manager.
379389

380390
#### JSON
381391

382-
The page's data is also served as JSON: `/api.json` (worktrees), `/api/prs.json` (pull requests) and
383-
`/api/status` (version, last scan times, whether a sync is running).
392+
The page's data is also served as JSON: `/api.json` (worktrees), `/api/prs.json` (pull requests),
393+
`/api/pr-detail?repo=OWNER/REPO&number=123` (description and changed files for a tracked PR), and
394+
`/api/status` (version, last scan times, whether a sync is running). PR details include up to the first
395+
100 changed files and the total changed-file count.
384396

385397
## Privacy and security
386398

@@ -424,7 +436,8 @@ every 5 minutes, or on Sync now
424436
- **GitHub API cost.** One GraphQL query pages through your PRs 20 at a time: about 1 point per 20
425437
PRs per poll, so about 7 points every 5 minutes for 120 PRs, out of the 5,000 an hour GitHub
426438
allows. Failing check names are fetched only for PRs that have failures. Polling pauses while
427-
fewer than 300 points remain.
439+
fewer than 300 points remain. Descriptions and changed files load only when selected; simultaneous
440+
requests share a query, and server results are cached for five minutes or until a new commit.
428441
- **Sessions without reading transcripts.** Each transcript is read as a 128 KB head and a 512 KB
429442
tail, and only again when the file changes. Opening a session reads just enough of its end for the
430443
latest 40 messages.

‎demo.go‎

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,20 @@ func demoPRs(now time.Time) []*TrackedPR {
215215
{Repo: "acme/infra", Number: 214, Title: "Terraform 1.9 and provider upgrades", Branch: "codex/terraform-1.9", IsDraft: true,
216216
CreatedAt: ago(3 * h), LastCommit: ago(2 * h), Additions: 146, Deletions: 139,
217217
ReviewDecision: "REVIEW_REQUIRED", Mergeable: "MERGEABLE", MergeState: "DRAFT",
218-
Checks: CheckSummary{State: "PENDING", Passed: 4, Pending: 2}},
218+
Checks: CheckSummary{State: "FAILURE", Passed: 122, Failed: 12, Failing: []string{
219+
"Terraform validate — shared networking and private endpoints",
220+
"Staging plan — database parameter group compatibility",
221+
"Production plan — application workload identity bindings",
222+
"Provider lock consistency across infrastructure modules",
223+
"Policy checks — encrypted storage and backup retention",
224+
"Module integration tests — object storage lifecycle",
225+
"Module integration tests — managed database failover",
226+
"Container registry access — staging deployment identity",
227+
"Migration lint — resource address replacement detection",
228+
"Documentation — generated module inputs and outputs",
229+
"Dependency audit — provider version constraints",
230+
"Deployment preview — staging service health checks",
231+
}}},
219232
{Repo: "acme/infra", Number: 210, Title: "Pin the AWS provider to 5.x across modules", Branch: "chore/pin-aws-provider",
220233
CreatedAt: ago(8 * d), LastCommit: ago(6 * d), Additions: 27, Deletions: 27,
221234
ReviewDecision: "APPROVED", Approvers: []string{"priya-r"}, Mergeable: "MERGEABLE", MergeState: "BEHIND",
@@ -235,6 +248,43 @@ func demoPRs(now time.Time) []*TrackedPR {
235248
return prs
236249
}
237250

251+
// Descriptions and file paths are synthetic, just like the rest of the demo.
252+
func demoPRDetail(pr *TrackedPR) PRDetail {
253+
bodies := map[int]string{
254+
482: "## Summary\n\nPrevent concurrent refresh requests from rotating the same token twice. Requests for a session share the pending refresh and receive the newly issued token.\n\n## Validation\n\nAdded concurrent refresh coverage and ran the auth suite with the race detector.",
255+
476: "## Summary\n\nWrite payments to both ledgers during migration. Reconciliation compares balances before switching the read path.\n\n## Rollout\n\nKeep the original ledger available for rollback. The PostgreSQL integration test and migration lint check need attention before this can merge.",
256+
479: "Accept an idempotency key when creating a charge. Repeated requests return the original result instead of creating another charge.\n\nKeys expire after 24 hours and are scoped to the account.",
257+
471: "Write CSV rows to the response as they are read from the database, keeping memory use bounded for large exports.\n\nStop reading when the client disconnects. Tested with a million-row export and an interrupted download.",
258+
1291: "Give shipping its own checkout step and validation state. Customers can edit their address without losing their payment information.\n\nThe branch needs a rebase after the recent checkout layout changes.",
259+
1279: "Restore saved cart contents when a customer signs in on another device.\n\nReview feedback asks for explicit behavior when a saved item is no longer available.",
260+
1284: "Load the product carousel when it approaches the viewport. The first product image keeps its eager loading behavior.\n\nReduces initial JavaScript and image requests on product pages.",
261+
214: "Upgrade Terraform and pin provider versions across infrastructure modules.\n\nStill preparing the staging apply and migration notes. This PR is not ready for review.",
262+
210: "Pin the AWS provider to the same supported major version in every module.\n\nUpdate the dependency locks and verify the generated plan.",
263+
88: "Add support for pushing eligible linked assets on HTTP/2 connections.\n\nCover cancellation and cache behavior in the protocol tests. The compatibility checks are still running.",
264+
12: "Initialize Node and Python version managers only when their commands are first used.\n\nProject-specific version selection keeps working while interactive shell startup gets faster.",
265+
}
266+
files := map[string][]string{
267+
"acme/api": {"internal/api/handler.go", "internal/api/handler_test.go", "docs/api.md"},
268+
"acme/web": {"src/checkout/Checkout.tsx", "src/checkout/Checkout.test.tsx"},
269+
"acme/infra": {"infra/versions.tf", "infra/.terraform.lock.hcl"},
270+
"acme-labs/tinyhttp": {"src/http2/server.ts", "tests/http2/server.test.ts"},
271+
"ada/dotfiles": {"zsh/config.zsh", "zsh/lazy-tools.zsh"},
272+
}
273+
detail := PRDetail{Body: bodies[pr.Number], Author: "ada", Files: []PRFile{}}
274+
paths := files[pr.Repo]
275+
for i, path := range paths {
276+
// Keep per-file diff totals consistent with the synthetic PR summary.
277+
added, removed := pr.Additions/len(paths), pr.Deletions/len(paths)
278+
if i == 0 {
279+
added += pr.Additions % len(paths)
280+
removed += pr.Deletions % len(paths)
281+
}
282+
detail.Files = append(detail.Files, PRFile{Path: path, Additions: added, Deletions: removed})
283+
}
284+
detail.ChangedFiles = len(detail.Files)
285+
return detail
286+
}
287+
238288
// ---------------------------------------------------------------- sessions
239289

240290
// convo turns a script into messages ending at end: "> " is the person,

‎docs/design/brief.md‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ Search and multi-select verdict/repository filters update the map, metrics, proj
2222

2323
## Pull requests
2424

25-
Colored status quick views filter by the server's workflow tone. The shared Filter menu combines statuses, organizations, and repositories. Selections use OR within a field and AND between fields; option counts exclude that option's own field. Active selections can be removed individually, and Reset all clears them with search.
25+
A repository workspace header shows the current scope, PR total, attention count, and latest activity. Its searchable picker moves between all repositories, an organization, or a single repository. The status dropdown and shared Filter menu use the same option catalog and selection state. Selections use OR within a field and AND between fields; option counts exclude that option's own field. Active selections can be removed individually, and Reset all clears them with search.
2626

27-
The table keeps blocker, checks, and review evidence distinct. Activity combines last commit and opened time to preserve readable column widths. Status text must wrap at words rather than split words into fragments.
27+
The left overview uses inline `organization / repository` headings with aligned attention, count, and activity columns. Organizations and repositories follow the chosen activity or name sort. Collapsed repositories retain their metadata; expanded groups show two PR previews with a Show more action. Search and filtering lift this preview limit. A GitHub action is always available on each row.
28+
29+
The overview follows normal document scrolling. A separate sticky reader shows the selected PR's description, changed files, checks, reviews, branch, and local worktree. Long checks use a disclosure in the reader rather than stretching list rows. Below 900px, the reader replaces the list and offers a Back to pull requests action with focus restoration. Below 640px, existing mobile navigation remains unchanged.
30+
31+
Selected, hovered, and keyboard-focused rows have quiet rounded surfaces. A single boundary renderer suppresses separators on both sides of those surfaces, using the actually visible rows so filtering and previews do not leave orphan dividers. Long titles wrap; metadata stays aligned. Descriptions render a small Markdown subset as text and safe elements, never raw HTML.
2832

2933
## Sessions
3034

‎docs/screenshots/phone-prs.jpg‎

32.1 KB
Loading

‎docs/screenshots/phone-prs.png‎

-55.4 KB
Binary file not shown.

‎docs/screenshots/prs-dark.jpg‎

82.5 KB
Loading

‎docs/screenshots/prs-dark.png‎

-218 KB
Binary file not shown.

‎docs/screenshots/prs-light.jpg‎

80.8 KB
Loading

‎docs/screenshots/prs-light.png‎

-216 KB
Binary file not shown.

0 commit comments

Comments
 (0)