Design pr 3#374
Open
eonist wants to merge 189 commits into
Open
Conversation
) - Collapse System/Actions/ActiveJobs into a single scrollable list - System stats merged into header row (CPU · MEM · DISK inline) - Action rows show inline ↳ job expansion for in-progress groups - Remove standalone "Active Jobs" section (jobs shown under action rows) - Add conditional Local Runners row (hidden when all runners idle/offline) - Add "Load 10 more actions…" pagination button stub - Close button (×) added to header alongside settings gear - All regression-guard frame/padding rules preserved (ref #52 #54 #57)
…h (issue #294) - Extract ActionRowView and InlineJobRowView into file-private structs to bring PopoverMainView under the 400-line file_length limit - Replace all trailing-closure Button{} with explicit Button(action:label:) to satisfy multiple_closures_with_trailing_closure rule
- Fix #1: ActionRowView — expand chevron moved outside outer Button; now composed as HStack(tappable body | expand button) so onToggleExpand fires reliably on macOS SwiftUI without being swallowed by the row tap. - Fix #2: double Divider — removed the unconditional Divider() between headerRow and localRunnerRow; localRunnerRow owns its leading + trailing Divider inside its @ViewBuilder guard, so no adjacent dividers appear. - Fix #3: Phase 4 follow-up — TODO comment added referencing #310 / #182; follow-up issue #310 opened to track the pie-dot radial progress work. - Fix #4: systemStats timer leak — added .onDisappear { systemStats.stop() } so the repeating timer/publisher is torn down when the popover closes.
…ody_length SwiftLint reported two violations on commit f126705: - file_length: 442 > 400 (warning) - type_body_length: PopoverMainView body 202 > 200 (warning) Fix: extract header, local-runner row, action row, and inline job rows into PopoverMainViewSubviews.swift. PopoverMainView.swift now contains only the root struct (~115 lines, body ~40 lines). Subviews file is ~265 lines. No behaviour change; all 4 prior fixes remain intact.
1. loadMoreButton overshoot: clamp visibleCount to store.actions.count so tapping 'Load more' never sets visibleCount beyond the total. 2. authIndicator: restore 'Sign in' caption next to orange dot so unauthenticated state is discoverable without tooltip-only affordance. 3. InlineJobRowsView: add TODO comment above prefix(4) cap noting that a 'load more' affordance is needed when activeJobs.count > 4. 4. expandedGroupIDs stale entries: add .onChange(of: store.actions) to prune IDs of groups that are no longer in the actions list.
Replace runs.allSatisfy { $0.conclusion == "success" } with
group.conclusion == "success" in both statusLabel and dotColor.
group.conclusion is nil while any run is still live (returns nil
unless every run has concluded), so completed groups that arrive
before the API marks all runs done were previously mis-labeled red.
The new check reads the already-computed group-level conclusion
string directly, matching RunnerStore's own priority logic
(failure > cancelled > skipped > success). Empty-runs groups
return "success" vacuously via the allSatisfy base case, which is
consistent with the previous behaviour.
Raise trimGroupCache limit and buildGroupDisplay loop guards from 5 to 30. This makes the UI "Load more" pagination in PopoverMainView reachable in practice (visibleCount starts at 10; store now serves up to 30 groups). The cache trim at 30 keeps memory bounded while covering realistic workloads (many repos with concurrent in-progress + queued + recent runs).
The label said min(10, store.actions.count - visibleCount) but the action clamped with min(visibleCount + 10, store.actions.count). Both now use the same computed nextBatch constant so label and increment are always consistent: shows the exact number of groups that will appear on tap.
- InlineJobRowsView: append "+ N more…" caption below the 4-row cap when activeJobs.count > 4, so users know jobs are hidden. - PopoverLocalRunnerRow: append "+ N more…" caption below the 3-row cap when active.count > 3, so users know runners are hidden.
…ypography parity (#294 / #178) - PieProgressDot: small radial fill view replacing plain colored dot on action rows and inline job rows. Progress fraction from group/job elapsed vs estimated; color semantics unchanged. - RelativeTimeFormatter: Date → short string ("3m ago", "1h ago", "2d ago") used for started-ago label on action rows. - ActionRowView: pie dot replaces circle dot; "Xm ago" compact timestamp added alongside elapsed. Typography parity: status chip font weight raised to .bold, consistent spacing. - InlineJobRowsView: pie dot on job rows; tappable "Load more jobs" affordance added when jobs exceed the 4-row cap. Limit state passed in as binding (inlineJobsLimit) from PopoverMainView. - PopoverMainView: inlineJobsLimit state dictionary added; passed to InlineJobRowsView; pruned alongside expandedGroupIDs on store change. All new types documented with ///. Files stay under SwiftLint file_length 400 / type_body_length 200 limits.
…WithGitHub docs - Always render Divider() after PopoverHeaderView so separator is visible even when store.isRateLimited==false and all runners are offline (#294) - Drop redundant leading Divider inside PopoverLocalRunnerRow.runnerList (parent now always provides one; trailing Divider preserved) - loadMoreButton: @ViewBuilder guard nextBatch > 0 else EmptyView() - Restore multi-line doc comment on signInWithGitHub (refs #221 #246)
…e dot, scrollview cap, simplify expansion 1. Inline job rows always visible for in-progress groups (no expand/collapse) 2. Remove chevron from inline job rows (non-tappable children) 3. PieProgressDot: filled wedge via GeometryReader+Path 4. ScrollView maxHeight: 400 cap 5. InlineJobRowsView: drop jobLimit Binding, fixed cap 4 + passive '+ N more…' 6. PopoverLocalRunnerRow: refresh LocalRunnerStore on appear 7. Reset visibleCount to 10 in onChange(of: store.actions)
…ter (#178) - statChip: add .lineLimit(1) to label and value Text views to prevent fittingSize height changes in AppDelegate.openPopover() (load-bearing) - jobRow: move current step name between job title and step counter, separated by middle-dot ·; falls back gracefully when no in_progress step
… add block-bar chips - Gap 1: remove cosmetic chevron.right from PopoverLocalRunnerRow (no navigation wired) - Gap 2: remove Button wrapper from InlineJobRowsView job rows (read-only per spec) - Gap 3: add blockBar() helper; prepend 3-char block bar to each stat chip value - Gap 4: replace passive '+ N more…' Text with tappable load-more Button (+4 per tap) Fixes #324
InlineJobRowsView no longer accepts onSelectJob (Gap 2 — rows are read-only). Update PopoverMainView.actionsSection accordingly. Fixes #324
…) for load-more - identifier_name: `f` renamed to `filledCount` (>=3 chars) - multiple_closures_with_trailing_closure: Button(action:label:) explicit form used for the Gap 4 load-more button in InlineJobRowsView.body
…ble, resolvingSymlinksInPath, RunnerStoreObservable missing, enrichGroupJobs missing, LocalRunnerScanner dict literal, StepLogView optional)
…uatable, fix onChange
…ix status chip wrapping
…minated string literal)
…nd spacing - Step number badge: width 28 → 18, spacing 8 → 6 Brings left edge visually closer to matching the 12pt right margin. - icon frame unchanged (14pt), name truncation unchanged.
|
CodeAnt AI is running Incremental review |
|
CodeAnt AI Incremental review completed. |
- Repo label → https://github.com/{owner}/{repo} - Branch label → https://github.com/{owner}/{repo}/tree/{branch} - SHA/PR origin label → PR URL (https://github.com/{owner}/{repo}/pull/{N}) or commit URL (https://github.com/{owner}/{repo}/commit/{sha}) derived from ActionGroup.label ("#1270" → PR, else short-sha → commit) - All three use Button(.plain) + .help() tooltip - ActionGroup passed as new `group` prop; all call sites must supply it
detailViewFromAction(job:group:) and detailView(job:) now supply the required `group` parameter to JobDetailView so the metadata row (repo / branch / SHA-origin chips) has the data it needs. detailView(job:) constructs a minimal ActionGroup from the job's htmlUrl so the chips still render correctly on the Jobs (non-Actions) navigation path.
…jump on menu bar hide ResizeAndRepositionPanel() was recomputing Y from the live statusItemRect.minY on every KVO fire. When macOS auto-hides the menu bar, that rect shifts down (or to 0) — pulling the panel under the camera notch. Fix: capture panelOriginY once in openPanel() from the initial statusItemRect, and use that stored Y in every subsequent resizeAndRepositionPanel() call. Only X is re-derived live (to keep horizontal centering correct on width changes). Y is immutable for the lifetime of the panel session. Reset panelOriginY to nil in closePanel().
… correctly Previous fix locked panelOriginY = statusItemRect.minY - initH - gap (bottom-left corner), but resizeAndRepositionPanel() sets totalH from the real content size — growing the panel downward from a stale bottom coord broke alignment entirely. Fix: store panelTopY = statusItemRect.minY - gap (the top edge, just below the status bar). resizeAndRepositionPanel() then computes y = panelTopY - totalH on every resize, so the panel always grows downward from the correct top anchor regardless of content height. Y origin never tracks live statusItemRect movement.
|
CodeAnt AI is running Incremental review |
|
CodeAnt AI Incremental review completed. |
… start() Two issues caused blank stats on open: 1. start() called sample() synchronously on main thread. First call always returns CPU=0 (prevTicks all zero → dTotal=0 guard). Real values only appeared after the 2s timer tick. 2. No pre-warm on close: prevTicks reset to zero between opens, so every re-open had the same blank-for-2s problem. Fix: - start() dispatches sample() to background queue immediately so the first real values publish to SwiftUI before the first timer tick. - stop() calls sample() synchronously on whatever queue it is on (background) to capture a fresh prevTicks snapshot. Next start() delta is valid instantly.
…) so pie wedge actually renders
…just non-dimmed groups isDimmed filter was excluding groups whose jobs were still in-progress, meaning only 1-2 jobs from the non-dimmed group were counted while 8+ in-progress jobs in dimmed groups were invisible to the icon progress. Fix: include any group that has at least one incomplete job (conclusion==nil), regardless of isDimmed. Dimmed groups with ALL jobs concluded are still excluded — they are truly done and should not affect progress fraction.
…ceObserver closure
|
This was referenced May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



User description
Closes #294
Re-opening of #309 (which was merged then reverted in #312) so it can be reviewed and merged when ready.
Summary
Redesigns
PopoverMainViewto match the new dynamic layout specified in #178 / #294.Changes
"RunnerBar v0.34 / Authenticated / Sign in with GitHub"; replaced with a compact 7pt dot (green = authenticated, orange = unauthenticated) + inline"Sign in"caption when token is missing. Functionally equivalent; removes version string from popover header.PieProgressDotreplaces plain colored dots on action rows and inline job rows. Shows radial fill fraction (concluded jobs / total jobs for groups; concluded steps / total steps for jobs). Color semantics unchanged."3m ago","1h ago") added to action row trailing meta viaRelativeTimeFormatter."Load more jobs…"button (reveals +4 at a time) or"+ N more…"caption for small overflows. State is per-group viainlineJobsLimitdictionary inPopoverMainView..bold; consistent 6pt horizontal spacing around pie dot.online; hidden when all idle/offline (Phase 6 stub)+ N more…caption shown in runner rows (capped at 3) when entries are hiddennextBatchconstantNSApplication.shared.hide)Self-review fixes (vs original #309)
rowContentButton+expandButtonas independent HStack siblings (no nested Button)Divider().onDisappear { systemStats.stop() }lifecycle cleanup addedPopoverMainView.swift+PopoverMainViewSubviews.swift+PopoverProgressViews.swiftto satisfy SwiftLintfile_length< 400 andtype_body_length< 200Issue #315 fixes (committed on this branch)
SystemStatsViewModel.start()/stop()added; timer no longer auto-starts ininit()(2b97131)group.conclusion == "success"instead ofruns.allSatisfy— fixes mis-labeled red groups (2bd231a)c30b18f)Checks (on previous merged HEAD 4e91c7b)
Note
Not merging on the agent's behalf. Awaiting your explicit approval before merge.
CodeAnt-AI Description
Redesign the popover with a wider layout, richer job details, and clearer controls
What Changed
Impact
✅ Clearer run status at a glance✅ Faster access to GitHub details✅ Fewer permission prompts during runner setup💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.