Skip to content

feat(deps): add auto-detected Dependencies tab with status-based grouping#96

Merged
wgordon17 merged 48 commits into
gordon-code:mainfrom
wgordon17:feat/dependencies-tab
May 5, 2026
Merged

feat(deps): add auto-detected Dependencies tab with status-based grouping#96
wgordon17 merged 48 commits into
gordon-code:mainfrom
wgordon17:feat/dependencies-tab

Conversation

@wgordon17
Copy link
Copy Markdown
Member

Summary

  • Add Dependencies tab that auto-detects dependency bot PRs (Dependabot, Renovate, Snyk) via multi-layer detection pipeline (bot login, branch prefix, title pattern, label)
  • Status-based grouping (Needs Review / Waiting / Stale) replaces repo-based grouping for dependency triage
  • Pre-exclusivity ownership ensures dep PRs never leak into Pull Requests tab or custom exclusive tabs
  • Renovate Dashboard abandoned-dependency pill badges with fault-tolerant markdown parsing
  • Settings UI with enabled toggle and configurable rebase label
  • Removes legacy hideDepDashboard toggle (replaced by pre-exclusivity)

Closes #95

wgordon17 added 30 commits May 4, 2026 12:05
- Add e2e/dependencies.spec.ts with 4 tests: tab auto-appears, absent when
  no dep PRs, hidden when settings disabled, status groups render
- Add bot avatar (20px round) before badges in DependenciesTab PR rows
- Gate dependencyPullRequests memo with config.dependencies.enabled check
- Fix aria-controls violation: replace <Show> with CSS hidden class so
  content div stays in DOM when collapsed
- Wire Dependencies settings toggles through saveWithFeedback for saved
  indicator parity with notification toggles
- Add tests: loading skeleton, no-filter-matches empty state,
  resetAbandonedPatternCache cache clearing, equal-version semver edge case
- Update collapse tests to check hidden class instead of DOM absence
- Rename statuses: needs-review→Mergeable, waiting→Needs Action (gordon-code#9)
- Add Pending Rebase status group with first-priority classification (gordon-code#14)
- Remove duplicate All entries from filter popovers (gordon-code#1)
- Restyle status group headers to match RepoGroupHeader patterns (gordon-code#2)
- Add ExpandCollapseButtons for status groups (gordon-code#3)
- Add StatusDot, SizeBadge, ReviewBadge to PR rows (gordon-code#4)
- Persist expand state in viewState.dependencyExpandedGroups (gordon-code#5)
- Structured title display with package name and version arrow (gordon-code#6)
- Wire viewState.globalSort into classifiedPRs with repo tiebreaker (gordon-code#7)
- Remove count badges from status group headers (gordon-code#10)
- Unknown bot detection with one-time info notification (gordon-code#12)
- Filter out dep-tool labels (dependencies, renovate) from PR rows (gordon-code#13)
- Excludes authenticated user from unknown bot flagging
- Handles dependabot vs dependabot[bot] via base-name matching
- Replaces pushNotification with inline banner + Track/Dismiss buttons
- Passes userLogin prop from DashboardPage to DependenciesTab
- Adds repo-header-text class to status group headers for consistent color
- Moves version info into title string (package: from → to) for visibility
- Adds Python requirement pattern (>=A to >=B) to extractVersionInfo
- Default sort clusters by repo first, then updatedAt within each repo
Replaces custom header div+button+ChevronIcon with the existing
RepoGroupHeader component, guaranteeing identical styling.
- Matches PullRequestsTab filter bar: gap-3 compact:gap-2, shrink-0 wrapper
- Strips chore(deps)/fix(deps) prefix from all displayed titles
- Lock file maintenance → Lock file maintenance
- Pin dependencies → Pin dependencies
- Update all major dependencies → Update all major dependencies
expandBotLogins() generates both variants — tracking 'khepri-bot'
now matches PRs from 'khepri-bot[bot]' and vice versa. Applied in
both DashboardPage (isDependencyPr) and DependenciesTab (unknown
bot banner).
- handleTrackBot strips [bot] suffix before storing
- validateGitHubUser strips [bot] from input before API call
- fetchIssuesAndPullRequests runs both base and [bot] variant
  searches for tracked bots (mergeTrackedUserResults deduplicates)
- expandBotLogins still covers local matching in both memos
onRefresh callback fires manualRefresh via the poll coordinator
so newly tracked bot PRs appear immediately.
Tries base login first, then auto-appends [bot] on 404. Entering
'khepri-bot' in Settings now finds the GitHub App bot automatically.
Response login normalized (strips [bot]) for consistent storage.
Every PR gets a DepCategory: major | minor | patch | maintenance |
other. Filter is now exact match — no more unconditional passthrough
for undetected types. Maintenance (pin, lock file) and Other (unknown
bump magnitude) are filterable options.
- Pin dependencies is now its own filterable category
- Lock file maintenance stays as 'maintenance'
- When title parsing can't determine major/minor/patch, checks PR
  labels as fallback (Renovate/Dependabot may label PRs)
- Body parsing for Renovate tables is a future enhancement
wgordon17 added 12 commits May 4, 2026 12:30
- Add parseRenovateBody to parse update type from Renovate PR body table
- Fetch PR bodies on demand for dep PRs where title yields no updateType
- Merge body-derived version info (packageName, from, to, updateType) into
  classifiedPRs for richer display titles and accurate category badges
- Expand VersionInfo.updateType to include pin and digest
- Add needsBodyFallback helper to identify PRs needing body fetch
- Add fetchDepPRBodies GraphQL query in api.ts (nodes batch pattern)
- Ignored dep PRs now stay visible on Dependencies tab (exclusive
  ownership still prevents them from appearing on Pull Requests tab)
- Change empty filter message to 'No dependency PRs match your current
  filters'
- Prefer body-derived versions over imprecise title versions (body has
  full semver, title may only have tag like v9)
- Show category badge for all types including pin and maintenance
  (previously only shown when versionInfo.updateType was set)
- Wire IgnoreBadge into Dependencies tab toolbar for unignoring dep PRs
- Exclude dep PR IDs from Pull Requests tab IgnoreBadge via depPrIds prop
- Restore ignored item filtering in Dependencies tab classifiedPRs
- Detect table schema from header row (Package/Update/Change columns)
- Handle 3-column format (Package | Update | Change) used by some PRs
- Handle tables without Update column (Package | Change | Age | ...)
  by deriving updateType from semver comparison of version change
- Strip markdown links from header cells (e.g. [Age](url))
- Scan all cells for version arrow when no Change column exists
- Add hideAuthor, hideNumber, subtleRepo, titlePrefix props to ItemRow
- Dependencies tab: repo toned down (no pill, just monospace text),
  fixed min-width for vertical alignment of titles across rows
- Type badge moved to titlePrefix slot (between repo and title)
  with fixed min-width for column alignment
- Author name and PR number hidden (noise for dep PRs)
- Bot avatar removed (redundant when author is hidden)
Body fetch effect writes updated PR data (with body field) back to
localStorage after the produce. On next page load, cached dep PRs
already have bodies for immediate version info enrichment.
- Default sort: maintenance→pin→patch→minor→major→other, then repo
  within each category group (major at bottom, easy merges at top)
- Detect Renovate ' - abandoned' title suffix as abandoned signal
  independent of Dashboard issue matching
- Strip ' - abandoned' from title before version parsing and display
- Shortened badge label from 'Abandoned dep' to 'Abandoned'
Body fetch effect now tracks dependencyPullRequests() directly instead
of coordinator lastRefreshAt. This fires on both cache load (page
reload) and poll completion, so body-derived badges appear immediately
from cached data without waiting for a full poll cycle.
carryOverBodies merges body from existing PR objects into fresh API
data during both produce-path and full-replacement-path store updates.
Bodies no longer flash away on each 5-minute poll cycle.
Update type filter options now match the table sort order:
maintenance → pin → patch → minor → major → other (safest first).
Category priority (maintenance→major→other) is now the primary sort
axis regardless of the user-selected globalSort. The dropdown sort
(repo, title, etc.) serves as secondary within each category group.
User-selected sort (repo, title, etc.) is primary. Update type
category (maintenance→major→other) is secondary within each group.
With Repo A-Z: PRs grouped by repo, then sorted by category within.
@wgordon17 wgordon17 force-pushed the feat/dependencies-tab branch from 1d9dd8c to 314dbe6 Compare May 4, 2026 16:42
wgordon17 added 6 commits May 4, 2026 13:41
dependencyPullRequests() returns filtered plain objects that lose
SolidJS store proxy tracking. Mutations via produce() to pr.body
never triggered classifiedPRs recomputation. Replaced with a
separate depBodies signal (Map<id, body>) passed as a prop —
reads in classifiedPRs now trigger reactivity correctly.
Replaces ephemeral depBodies signal (raw body strings) with depMeta
signal (parsed VersionInfo objects) backed by localStorage. Bodies are
parsed immediately on fetch via parseRenovateBody and the result is
cached, eliminating classification jank on page refresh. Stale entries
are pruned against the current dependency PR set.
- Remove dead STATUS_META fields (badgeClass, defaultExpanded)
- Collapse duplicated label-scanning loops in depCategory
- Remove redundant /i regex flags on lowercased strings
- Replace badge class ternary with CATEGORY_BADGE_CLASS lookup
- Pass trackedBotLogins as prop instead of duplicate memo
- Exclude all tracked user logins from unknownBots banner
- Remove dead pr.body guard from needsBodyFallback
- Remove unused updateDependencyConfig export
- Restore hideDepDashboard toggle when dep tab is disabled
- Fix tabCounts badge/content mismatch for hidden dep dashboard issues
- Fix stale E2E comment referencing nonexistent 'Waiting' status
- Add fetchDepPRBodies unit tests (10 tests)
- Add approved+stale classifyDepStatus test
- Add hideDepDashboard filter tests (4 tests)
Synthetic dep PRs from dependabot[bot] and renovate[bot] across
all four status groups: mergeable, pending-rebase, needs-action,
and stale. Seeds dep-meta localStorage for version info display.
The DashboardPage test mock for stores/auth was missing the new
DEP_META_STORAGE_KEY export, causing onAuthCleared callback tests
to fail when accessing the constant at runtime.
The first test in the suite hits Vite's cold-start module compilation,
causing the 5s default assertion timeout to expire before the graphql
response is processed. Waits for tablist first, then uses 10s timeout.
@wgordon17 wgordon17 marked this pull request as ready for review May 5, 2026 17:08
@wgordon17 wgordon17 merged commit c6d1263 into gordon-code:main May 5, 2026
1 check passed
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.

Surface dependency bot PRs in a dedicated Dependencies tab

1 participant