Skip to content

feat(desktop): add multi-repo work item filters and PR checks - #6201

Merged
Kitenite merged 25 commits into
ParadevAI:mainfrom
Roshvan:agent/work-items-filters-pr-checks
Aug 8, 2026
Merged

Kitenite merged 25 commits into
ParadevAI:mainfrom
Roshvan:agent/work-items-filters-pr-checks

Conversation

@Roshvan

@Roshvan Roshvan commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

What & why

Tasks and Pull requests were limited to one repository at a time, task status filtering exposed only broad buckets, and pull request checks were invisible until leaving Superset.

This change:

  • makes the repository picker multi-select in Tasks and Pull requests, with an empty selection meaning all repositories
  • fans GitHub issue and pull request queries out to the correct serving hosts and aggregates their results
  • adds explicit All tasks, Active, Backlog, Todo, In progress, Done, and Canceled task filters
  • filters pull requests by GitHub author and GitHub review state, including personal and team review requests
  • displays compact check summaries in the PR list and a full checks section in PR detail
  • centers PR detail content in a responsive two-column layout
  • persists repository, source, task-state, issue-state, PR-state, author, review, and view settings with legacy store migrations

How I tested it

  • bun test on the ten original focused test suites: 43 pass, 0 fail, 115 expectations
  • follow-on author/review-filter suites: 30 pass, 0 fail, 123 expectations
  • bun run lint: pass with zero warnings
  • desktop and host-service typechecks: pass
  • root bun run typecheck: pass
  • bun run --cwd apps/desktop compile:app: pass
  • exact isolated Electron journey at http://localhost:3205: selected two repositories through real pointer input, verified both repositories in Tasks and PRs, opened expanded task states, filtered PRs by sanitized author and review status, inspected PR check summaries and detail Checks, navigated detail/back, fully restarted the app, and confirmed the author/review/repository settings persisted
  • verified all eight generated review qualifiers against the live GitHub Search API

All visual fixtures use only acme-*, demo-*, and example.invalid data. No production issues, pull requests, users, or URLs are included.

Pull request list

Before After
PR list before PR list after

Pull request detail

Before After
PR detail before PR detail after

Expanded task states

Expanded task states

Pull request author and review filters

Review menu Combined author and review filters
Review filter menu Author and review filters

Checklist

  • PR title follows conventional commits (type(scope): subject)
  • bun run lint and bun run typecheck pass
  • Allow edits from maintainers is enabled for this fork PR

@coderabbitai

coderabbitai Bot commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The dashboard now supports multiple repository filters for tasks and pull requests. Routes, stores, navigation, and host queries preserve plural project state. Task views support expanded status tabs. Pull-request data includes normalized GitHub checks and update timestamps.

Changes

Dashboard filtering and navigation

Layer / File(s) Summary
Multi-project filter contracts and persistence
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/*/stores/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/*/page.tsx, apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/*
Project filters use normalized string arrays. Stores migrate legacy values, serialize projects, validate persisted state, and preserve filters during navigation.
Task filtering and project fan-out
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/hooks/useProjectQueryTargets/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/hooks/useMultiRepoProjectPagination/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/utils/*
Tasks resolve project-specific host targets, query issues concurrently, merge project-scoped results, preserve project context, and support expanded status filters.
Pull-request filtering and checks display
apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/hooks/useDebouncedSearchNavigation/*
Pull requests query multiple projects, preserve project filters, display project-aware rows, and render check summaries and detail sections.
GitHub result enrichment
packages/host-service/src/trpc/router/pull-requests/*, packages/host-service/src/trpc/router/workspace-creation/procedures/*, packages/host-service/test/integration/*
GitHub responses include nullable update timestamps and normalized pull-request check data across CLI, GraphQL, API, and Octokit paths.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DashboardView
  participant ProjectQueryTargets
  participant GitHubHost
  participant PullRequestChecks
  User->>DashboardView: select multiple projects
  DashboardView->>ProjectQueryTargets: resolve project and host targets
  ProjectQueryTargets->>GitHubHost: query issues or pull requests per target
  GitHubHost->>PullRequestChecks: normalize statusCheckRollup
  PullRequestChecks->>DashboardView: return checks and statuses
  DashboardView->>User: render aggregated results
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title uses conventional commit format and clearly summarizes multi-repository work item filters and pull request checks.
Description check ✅ Passed The description covers the required What & why, How I tested it, and Checklist sections with detailed changes, validation, screenshots, and completed checks.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Roshvan
Roshvan force-pushed the agent/work-items-filters-pr-checks branch from 143e7bf to dded9bb Compare August 5, 2026 18:23
@Roshvan
Roshvan marked this pull request as ready for review August 5, 2026 18:39
@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR expands desktop work-item browsing across multiple repositories, adds detailed task-state filters and pull-request check visibility, and migrates persisted filters to multi-select arrays.

  • Fans issue and pull-request queries out to each selected repository’s serving host and merges results by update time.
  • Adds compact and detailed PR check presentations backed by host-service check-rollup normalization.
  • Preserves multi-repository filters through routes, details, sidebar navigation, and versioned Zustand migrations.
  • Adds explicit workflow-state filtering and responsive PR-detail layout changes.

Confidence Score: 4/5

The pull-request checks enrichment should be fixed before merging because valid CI checks can be silently shown as absent when its independent search page differs from the displayed result page.

Display rows come from GitHub’s search API, while their checks come from a separately paginated gh pr list result; PRs absent from that second page retain an empty check array and render an incorrect “No checks reported” state.

Files Needing Attention: packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts

Important Files Changed

Filename Overview
apps/desktop/src/renderer/routes/_authenticated/_dashboard/hooks/useProjectQueryTargets/useProjectQueryTargets.ts Resolves selected or all repositories to their serving host IDs and URLs using the existing canonical project key.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/components/PullRequestsContent/PullRequestsContent.tsx Replaces single-repository infinite querying with per-repository/page fan-out, merged sorting, and repository-aware actions.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx Adds multi-repository issue fan-out, repository-qualified selection identities, and cross-repository navigation.
packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts Adds updated timestamps and check enrichment, but independently paginating the enrichment query can silently omit checks for displayed PRs.
packages/host-service/src/trpc/router/pull-requests/pull-request-checks.ts Normalizes GitHub CheckRun and StatusContext rollups through existing pull-request mapper utilities.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/stores/tasks-filter-state.ts Migrates the persisted single-repository value to a normalized multi-select array and serializes expanded task filters.

Sequence Diagram

sequenceDiagram
  participant UI as Desktop work-item view
  participant Hosts as Selected host services
  participant Search as GitHub search API
  participant Checks as gh pr list
  UI->>Hosts: Query each selected repository/page
  par Per repository
    Hosts->>Search: Fetch issue/PR result page
    Search-->>Hosts: Results ordered by updated time
    Hosts->>Checks: Fetch PR list with statusCheckRollup
    Checks-->>Hosts: Independently paginated check results
    Hosts-->>UI: Search rows enriched by PR number
  end
  UI->>UI: Merge and sort rows across repositories
Loading
Prompt To Fix All With AI
### Issue 1
packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts:194-197
**Checks use mismatched pagination**

When `gh api search/issues` and `gh pr list --search` return different membership or ordering for a page, this independent positional slice omits checks for displayed pull requests, causing PRs with CI checks to render as “No checks reported.”

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(desktop): stabilize multi-repository..." | Re-trigger Greptile

Comment on lines +194 to +197
return new Map(
ghPrListSchema
.parse(raw)
.slice((page - 1) * perPage, page * perPage)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Checks use mismatched pagination

When gh api search/issues and gh pr list --search return different membership or ordering for a page, this independent positional slice omits checks for displayed pull requests, causing PRs with CI checks to render as “No checks reported.”

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts
Line: 194-197

Comment:
**Checks use mismatched pagination**

When `gh api search/issues` and `gh pr list --search` return different membership or ordering for a page, this independent positional slice omits checks for displayed pull requests, causing PRs with CI checks to render as “No checks reported.”

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/PullRequestsView.tsx (1)

67-79: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Cancel pending search navigation before another filter changes.

The delayed callback retains buildSearch with the previous project and state filters. If a user types a search query and changes the repository or state within 300 ms, the delayed navigation restores the old filters.

Clear debounceRef.current before project and state navigation, or read the latest filters from a ref.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/PullRequestsView.tsx`
around lines 67 - 79, Update the filter navigation handlers in PullRequestsView
so they clear any pending debounceRef timeout before navigating when the project
or state filter changes. Preserve syncSearchToUrl’s debounce behavior while
ensuring delayed search navigation cannot restore stale repository or state
filters.
🧹 Nitpick comments (5)
apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.ts (1)

17-32: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the double cast with an honest partial return type.

migratePullRequestsFilterState declares PullRequestsFilterState but returns only two fields. The as unknown as cast hides that mismatch and removes type checking from this function. Zustand merges the migrated object with the store initializer, so a partial type is accurate and safe.

Declare the partial shape and delete the cast.

As per coding guidelines: "Avoid any unless necessary; preserve type safety across JavaScript/TypeScript code."

♻️ Proposed refactor
+type PersistedPullRequestsFilterState = Pick<
+	PullRequestsFilterState,
+	"projectFilters" | "includeClosed"
+>;
+
 export function migratePullRequestsFilterState(
 	persistedState: unknown,
-): PullRequestsFilterState {
+): PersistedPullRequestsFilterState {
 	const state =
 		persistedState && typeof persistedState === "object"
 			? (persistedState as Record<string, unknown>)
 			: {};
 	const legacyProject =
 		typeof state.projectFilter === "string" ? state.projectFilter : null;
 	return {
 		projectFilters: normalizeProjectFilters(
 			state.projectFilters ?? (legacyProject ? [legacyProject] : []),
 		),
 		includeClosed: state.includeClosed === true,
-	} as unknown as PullRequestsFilterState;
+	};
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.ts`
around lines 17 - 32, Update migratePullRequestsFilterState to return a partial
PullRequestsFilterState matching the two migrated fields, and remove the as
unknown as cast. Preserve the existing normalization and legacy project handling
while allowing Zustand to merge the partial result with the store initializer.

Source: Coding guidelines

apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx (1)

40-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract one helper for the projects parameter with the legacy project fallback. Three task routes repeat the same nested ternary that prefers projects, falls back to a one-element array from project, and otherwise yields an empty result. The shared root cause is a missing helper beside parseProjectFilterParam. Add resolveProjectFilterParams(projects, project) to apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.ts, then call it from each route.

  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx#L40-L46: call the helper for initialProjects, and keep undefined for the empty case so the persisted store value still applies.
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/$taskId/page.tsx#L64-L82: call the helper for projectFilters, and keep [] for the empty case.
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/issue/$issueNumber/page.tsx#L51-L56: call the helper for projectFilters, passing the local projectId as the legacy value.

As per coding guidelines: "promote components used two or more times to the highest shared parent".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx`
around lines 40 - 46, Add the shared resolveProjectFilterParams(projects,
project) helper beside parseProjectFilterParam in
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.ts,
preferring parsed projects, then a one-item legacy project array, and otherwise
returning the caller’s empty-case value. Update initialProjects in
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx#L40-L46
to use it with undefined for empty results; update projectFilters in
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/$taskId/page.tsx#L64-L82
to use [] for empty results; and update projectFilters in
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/issue/$issueNumber/page.tsx#L51-L56
to pass projectId as the legacy value.

Source: Coding guidelines

apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx (1)

114-128: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Memoize issues inside useQueries with combine.

Without combine, useQueries returns a fresh array each render by this installed version, so [queries, queryTargets] changes on every render and recomputes flatMap(...) + sort(...) each time. Return the combined, sorted issues from combine so the sort runs only when query state or project targets change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx`
around lines 114 - 128, The issues aggregation currently memoizes over the
unstable `queries` array, causing repeated flattening and sorting. Update the
`useQueries` configuration to use its `combine` option, merging each query’s
data with the corresponding `queryTargets` entry and returning the sorted issues
there; then consume that combined result directly instead of the separate
`useMemo` around `issues`.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/$prNumber/page.tsx (1)

22-22: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use the renderer path alias.

Replace this relative component import with the existing renderer/... alias.

Proposed change
-import { PullRequestChecksSection } from "../components/PullRequestChecksSection";
+import { PullRequestChecksSection } from "renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSection";

As per coding guidelines, use the path aliases defined in tsconfig.json whenever possible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/`$prNumber/page.tsx
at line 22, Update the PullRequestChecksSection import in the pull-request page
to use the existing renderer/... path alias instead of the relative
../components path, following the aliases defined in tsconfig.json.

Source: Coding guidelines

packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts (1)

179-203: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Do not refetch every prior page for check enrichment.

On page n, this helper requests n * perPage pull requests and then discards all earlier rows. Multi-repository queries repeat that work for every selected repository. This increases GitHub CLI payload size and makes later pages more likely to miss check summaries after the enrichment timeout or failure.

Use a batched check query for only result.items, or paginate check retrieval with the same cursor as the primary search.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts`
around lines 179 - 203, Update the pull-request search flow around execGh and
normalizePullRequestChecks so check enrichment operates only on the current
page’s result.items, rather than fetching page * perPage rows and slicing
earlier pages. Use a batched check query for those items, or advance check
retrieval with the same pagination cursor, while preserving the existing page
results and normalized check fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.ts`:
- Around line 1-16: Update normalizeProjectFilters to trim each string project
ID before checking that it is non-empty and before storing it in the Set, so
parseProjectFilterParam handles comma-separated values with surrounding
whitespace and returns canonical IDs.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSection/PullRequestChecksSection.tsx`:
- Around line 37-44: Update the summaryLabel logic in PullRequestChecksSection
to distinguish skipped or cancelled checks from the “none” state. When check
rows exist but all are skipped or cancelled, display an accurate skipped-check
label while preserving the existing success, failure, pending, and genuinely
empty-state labels.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/components/PullRequestsContent/PullRequestsContent.tsx`:
- Around line 90-92: The error handling in PullRequestsContent must preserve
usable results when only some repository queries fail. Update the
error-rendering branch that consumes error and queries so successful rows remain
visible alongside a partial-failure notice, and render the full error state only
when no query has usable results.
- Around line 102-118: The pullRequests useMemo currently globally re-sorts all
merged rows whenever another repository page loads, changing existing rendered
positions. Update the aggregation around queries, queryTargets, and the
pullRequests mapping to preserve previously emitted rows and append each
deterministic merged batch without reordering existing items, while retaining
correct multi-project pagination and avoiding duplicates or skipped items.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx`:
- Around line 64-112: Update the pagination flow around queryTargets and
pageCount so each target generates pages only through its latest fetched page
and only while that target reports hasNextPage; stop adding pages for exhausted
repositories instead of using the global pageCount cross product. Update the
sentinel/page increment logic to advance only targets whose latest page still
has hasNextPage, while preserving existing fetching and refetch behavior.

In
`@packages/host-service/src/trpc/router/pull-requests/procedures/get-content.ts`:
- Line 30: The pull request check rollup schemas currently reject GitHub’s
nullable statusCheckRollup values. Update both schema fields in
packages/host-service/src/trpc/router/pull-requests/procedures/get-content.ts
(line 30) and
packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts
(lines 55-57) to accept null alongside arrays, while leaving
normalizePullRequestChecks(raw ?? []) and all downstream normalization
unchanged.

---

Outside diff comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/PullRequestsView.tsx`:
- Around line 67-79: Update the filter navigation handlers in PullRequestsView
so they clear any pending debounceRef timeout before navigating when the project
or state filter changes. Preserve syncSearchToUrl’s debounce behavior while
ensuring delayed search navigation cannot restore stale repository or state
filters.

---

Nitpick comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/`$prNumber/page.tsx:
- Line 22: Update the PullRequestChecksSection import in the pull-request page
to use the existing renderer/... path alias instead of the relative
../components path, following the aliases defined in tsconfig.json.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.ts`:
- Around line 17-32: Update migratePullRequestsFilterState to return a partial
PullRequestsFilterState matching the two migrated fields, and remove the as
unknown as cast. Preserve the existing normalization and legacy project handling
while allowing Zustand to merge the partial result with the store initializer.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx`:
- Around line 114-128: The issues aggregation currently memoizes over the
unstable `queries` array, causing repeated flattening and sorting. Update the
`useQueries` configuration to use its `combine` option, merging each query’s
data with the corresponding `queryTargets` entry and returning the sorted issues
there; then consume that combined result directly instead of the separate
`useMemo` around `issues`.

In `@apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx`:
- Around line 40-46: Add the shared resolveProjectFilterParams(projects,
project) helper beside parseProjectFilterParam in
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.ts,
preferring parsed projects, then a one-item legacy project array, and otherwise
returning the caller’s empty-case value. Update initialProjects in
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx#L40-L46
to use it with undefined for empty results; update projectFilters in
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/$taskId/page.tsx#L64-L82
to use [] for empty results; and update projectFilters in
apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/issue/$issueNumber/page.tsx#L51-L56
to pass projectId as the legacy value.

In
`@packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts`:
- Around line 179-203: Update the pull-request search flow around execGh and
normalizePullRequestChecks so check enrichment operates only on the current
page’s result.items, rather than fetching page * perPage rows and slicing
earlier pages. Use a batched check query for those items, or advance check
retrieval with the same pagination cursor, while preserving the existing page
results and normalized check fields.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 91684c7a-e1bf-4d1d-8950-dec1702910c0

📥 Commits

Reviewing files that changed from the base of the PR and between 21db9f5 and c6b74f6.

⛔ Files ignored due to path filters (5)
  • .github/pr-assets/work-items-filters-checks/after-pr-detail.png is excluded by !**/*.png
  • .github/pr-assets/work-items-filters-checks/after-pr-list.png is excluded by !**/*.png
  • .github/pr-assets/work-items-filters-checks/after-task-statuses.png is excluded by !**/*.png
  • .github/pr-assets/work-items-filters-checks/before-pr-detail.png is excluded by !**/*.png
  • .github/pr-assets/work-items-filters-checks/before-pr-list.png is excluded by !**/*.png
📒 Files selected for processing (44)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarHeader/DashboardSidebarHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/ProjectFilter.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/hooks/useProjectQueryTargets/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/hooks/useProjectQueryTargets/useProjectQueryTargets.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/$prNumber/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSection/PullRequestChecksSection.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSection/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSummary/PullRequestChecksSummary.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSummary/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/PullRequestsView.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/components/PullRequestsContent/PullRequestsContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/components/PullRequestsTopBar/PullRequestsTopBar.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/pull-request-checks.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/layout.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/$taskId/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/TasksView.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/TasksTopBar/TasksTopBar.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/TasksTopBar/components/StatusFilter/StatusFilter.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/hooks/useTasksData/useTasksData.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/hooks/useTasksTable/useTasksTable.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/utils/matchesTaskStatusFilter/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/utils/matchesTaskStatusFilter/matchesTaskStatusFilter.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/utils/matchesTaskStatusFilter/matchesTaskStatusFilter.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/issue/$issueNumber/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/layout.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/stores/tasks-filter-state.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/stores/tasks-filter-state.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/utils/getRepositoryMismatchLabel/getRepositoryMismatchLabel.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/utils/getRepositoryMismatchLabel/getRepositoryMismatchLabel.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/utils/getRepositoryMismatchLabel/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/WorkspaceSidebarHeader.tsx
  • packages/host-service/src/trpc/router/pull-requests/procedures/get-content.ts
  • packages/host-service/src/trpc/router/pull-requests/pull-request-checks.test.ts
  • packages/host-service/src/trpc/router/pull-requests/pull-request-checks.ts
  • packages/host-service/src/trpc/router/workspace-creation/procedures/search-github-issues.ts
  • packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts
  • packages/host-service/test/integration/workspace-creation-github.integration.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts (1)

197-230: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Bound the batch size and deduplicate numbers.

ghGetPullRequestChecks builds one aliased pullRequest selection per result, each with contexts(first: 100). The count follows limit, which comes from input.limit ?? 30 and is not capped in this file. A large limit produces a single query that can exceed GitHub GraphQL node and cost limits. The request then fails as a whole, and the caller drops checks for the entire page. Duplicate numbers also emit duplicate aliases.

Chunk the numbers into fixed-size batches and merge the results, so one oversized page does not remove checks for all rows.

♻️ Proposed refactor sketch
+const CHECKS_BATCH_SIZE = 25;
+
 async function ghGetPullRequestChecks(
 	execGh: ExecGh,
 	repo: ResolvedGithubRepo,
 	pullRequestNumbers: number[],
 ): Promise<Map<number, Pick<PullRequestResult, "checks" | "checksStatus">>> {
-	if (pullRequestNumbers.length === 0) return new Map();
-	const selections = pullRequestNumbers
+	const unique = [...new Set(pullRequestNumbers)];
+	if (unique.length === 0) return new Map();
+	if (unique.length > CHECKS_BATCH_SIZE) {
+		const batches: number[][] = [];
+		for (let i = 0; i < unique.length; i += CHECKS_BATCH_SIZE) {
+			batches.push(unique.slice(i, i + CHECKS_BATCH_SIZE));
+		}
+		const results = await Promise.all(
+			batches.map((batch) => ghGetPullRequestChecks(execGh, repo, batch)),
+		);
+		return new Map(results.flatMap((result) => [...result]));
+	}
+	const selections = unique
 		.map(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts`
around lines 197 - 230, Update ghGetPullRequestChecks to deduplicate
pullRequestNumbers, split the unique numbers into fixed-size batches, and
execute the existing GraphQL selection/query flow once per batch. Merge each
batch’s results into one Map while preserving the current empty-input behavior
and ensuring a failed oversized request no longer drops checks for the entire
page.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts`:
- Around line 231-243: Update the GraphQL argument construction in the search
pull-request procedure to use raw string fields for the owner and repository
name variables: replace the `-F` flags associated with `repo.owner` and
`repo.name` with `-f`, while leaving the query and working-directory handling
unchanged.

---

Nitpick comments:
In
`@packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts`:
- Around line 197-230: Update ghGetPullRequestChecks to deduplicate
pullRequestNumbers, split the unique numbers into fixed-size batches, and
execute the existing GraphQL selection/query flow once per batch. Merge each
batch’s results into one Map while preserving the current empty-input behavior
and ensuring a failed oversized request no longer drops checks for the entire
page.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 70b7b042-099a-4263-981e-f5ffde39b7c2

📥 Commits

Reviewing files that changed from the base of the PR and between c6b74f6 and 0e451ee.

📒 Files selected for processing (2)
  • packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts
  • packages/host-service/test/integration/workspace-creation-github.integration.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/host-service/test/integration/workspace-creation-github.integration.test.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 6 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.ts (1)

46-46: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Normalize values at the setter boundary.

setProjectFilters stores raw values without normalizeProjectFilters. A caller can persist blank, whitespace-prefixed, or duplicate IDs. pullRequestsSearchFromFilters can then emit invalid search.projects values.

Proposed fix
-			setProjectFilters: (projectFilters) => set({ projectFilters }),
+			setProjectFilters: (projectFilters) =>
+				set({ projectFilters: normalizeProjectFilters(projectFilters) }),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.ts`
at line 46, Update setProjectFilters in the pull-requests filter store to
normalize the incoming project filters with normalizeProjectFilters before
storing them. Ensure all callers persist trimmed, non-blank, deduplicated
project IDs so pullRequestsSearchFromFilters receives valid values.
🧹 Nitpick comments (1)
apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/pull-request-checks.test.ts (1)

14-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the pending and success summary states directly.

The current case includes both states, but failure takes priority. It does not verify either branch as the final status. Add one pending-only case and one all-success case.

Based on the pull-request-checks.ts contract, pending and success are separate output states.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/pull-request-checks.test.ts`
around lines 14 - 27, Extend the tests around summarizePullRequestChecks with
two independent cases: one containing only pending checks that expects status
"pending", and one containing only successful checks that expects status
"success". Keep the existing failure-priority case unchanged and assert the
corresponding passing, pending, and failing counts for each new summary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.ts`:
- Line 46: Update setProjectFilters in the pull-requests filter store to
normalize the incoming project filters with normalizeProjectFilters before
storing them. Ensure all callers persist trimmed, non-blank, deduplicated
project IDs so pullRequestsSearchFromFilters receives valid values.

---

Nitpick comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/pull-request-checks.test.ts`:
- Around line 14-27: Extend the tests around summarizePullRequestChecks with two
independent cases: one containing only pending checks that expects status
"pending", and one containing only successful checks that expects status
"success". Keep the existing failure-priority case unchanged and assert the
corresponding passing, pending, and failing counts for each new summary.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 129e93a9-64dd-4045-a860-8d6708d80bfc

📥 Commits

Reviewing files that changed from the base of the PR and between 0e451ee and 937fe3e.

📒 Files selected for processing (23)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/$prNumber/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSection/PullRequestChecksSection.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSummary/PullRequestChecksSummary.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/PullRequestsView.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/components/PullRequestsContent/PullRequestsContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/pull-request-checks.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/stores/pullRequestsFilterStore/pullRequestsFilterStore.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/$taskId/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/TasksView.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/issue/$issueNumber/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/stores/tasks-filter-state.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/utils/mergePaginatedProjectRows/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/utils/mergePaginatedProjectRows/mergePaginatedProjectRows.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/utils/mergePaginatedProjectRows/mergePaginatedProjectRows.ts
  • packages/host-service/src/trpc/router/pull-requests/procedures/get-content.ts
  • packages/host-service/src/trpc/router/pull-requests/pull-request-checks.test.ts
  • packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts
  • packages/host-service/test/integration/workspace-creation-github.integration.test.ts
🚧 Files skipped from review as they are similar to previous changes (16)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/ProjectFilter/project-filter-utils.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/issue/$issueNumber/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSection/PullRequestChecksSection.tsx
  • packages/host-service/src/trpc/router/pull-requests/pull-request-checks.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/$taskId/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/PullRequestsView.tsx
  • packages/host-service/src/trpc/router/pull-requests/procedures/get-content.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestChecksSummary/PullRequestChecksSummary.tsx
  • packages/host-service/test/integration/workspace-creation-github.integration.test.ts
  • packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/stores/tasks-filter-state.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/TasksView.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/pull-requests/components/PullRequestsView/components/PullRequestsContent/PullRequestsContent.tsx

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 25 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/TasksView.tsx">

<violation number="1" location="apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/TasksView.tsx:127">
P2: The same `cancelPendingSearchNavigation` helper (cancel + clear a `debounceRef` timeout), the reworked `syncSearchToUrl` that calls it, and the `useEffect(() => cancelPendingSearchNavigation, ...)` unmount cleanup are now duplicated verbatim across TasksView and PullRequestsView, and the helper is invoked in every filter/navigation handler in both. The debounce/cancel logic and its semantics (cancel a pending search push before a filter navigation so the stale debounced URL write can't clobber it) are identical, so keeping them in two places is exactly where behavior tends to drift — e.g. if this view needs a different debounce delay or a flush, it must be changed twice. Consider extracting a small shared hook (e.g. `useDebouncedSearchNavigation`) and using it in both views.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

includeClosedIssues,
],
);
const cancelPendingSearchNavigation = useCallback(() => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The same cancelPendingSearchNavigation helper (cancel + clear a debounceRef timeout), the reworked syncSearchToUrl that calls it, and the useEffect(() => cancelPendingSearchNavigation, ...) unmount cleanup are now duplicated verbatim across TasksView and PullRequestsView, and the helper is invoked in every filter/navigation handler in both. The debounce/cancel logic and its semantics (cancel a pending search push before a filter navigation so the stale debounced URL write can't clobber it) are identical, so keeping them in two places is exactly where behavior tends to drift — e.g. if this view needs a different debounce delay or a flush, it must be changed twice. Consider extracting a small shared hook (e.g. useDebouncedSearchNavigation) and using it in both views.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/TasksView.tsx, line 127:

<comment>The same `cancelPendingSearchNavigation` helper (cancel + clear a `debounceRef` timeout), the reworked `syncSearchToUrl` that calls it, and the `useEffect(() => cancelPendingSearchNavigation, ...)` unmount cleanup are now duplicated verbatim across TasksView and PullRequestsView, and the helper is invoked in every filter/navigation handler in both. The debounce/cancel logic and its semantics (cancel a pending search push before a filter navigation so the stale debounced URL write can't clobber it) are identical, so keeping them in two places is exactly where behavior tends to drift — e.g. if this view needs a different debounce delay or a flush, it must be changed twice. Consider extracting a small shared hook (e.g. `useDebouncedSearchNavigation`) and using it in both views.</comment>

<file context>
@@ -124,26 +124,31 @@ export function TasksView({
 			includeClosedIssues,
 		],
 	);
+	const cancelPendingSearchNavigation = useCallback(() => {
+		if (!debounceRef.current) return;
+		clearTimeout(debounceRef.current);
</file context>

@Roshvan

Roshvan commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 18 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 19 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Roshvan and others added 4 commits August 6, 2026 12:04
…igation

- setProjectFilters bails on equal content; the view sync effect plus an
  always-fresh normalized array was an infinite update loop that crashed
  the Pull Requests page with 'Maximum update depth exceeded'
- search inputs sync only from the URL param, so typing no longer snaps
  back to the stale URL value during the debounced navigation
- detail pages no longer treat the item's own project param as a filter
  fallback, so back from a detail keeps the all-repositories view
- route pages memoize URL-derived project filters (stable identity)
- Run in Workspace blocks mixed-repository issue selections instead of
  silently creating every workspace against one repository
- searchPullRequests/searchGitHubIssues accept projectIds and search all
  of a host's repos in shared queries (repo: qualifiers chunked to
  GitHub's 256-char limit), cutting search-quota usage from one call per
  repo to one per ~7 repos; rows carry projectId for attribution
- direct ParadevAI#123/URL lookups use core-quota calls per repo instead of
  paging the Search API (up to 10 calls) per review-filter check
- rate-limit failures map to TOO_MANY_REQUESTS with a friendly message
  and reset time instead of raw GitHub error text; never auto-retried
- batch requests skip projects that fail to resolve (e.g. no GitHub
  remote) so one misconfigured repo cannot blank the whole list
- Octokit fallback clamps pagination at GitHub's 1000-result search cap
  and enriches real check rollups via octokit.graphql instead of
  reporting 'No checks' when the gh CLI is unavailable
…etching

- group project query targets by serving host and send one batched
  projectIds search per host page instead of one query per repository
- generalize useMultiRepoProjectPagination over host targets; the
  pagination key encodes the project set so filter changes still reset
- placeholderData keeps previous rows for the same target visible while
  a changed search or filter refetches (restores the placeholder
  behavior lost in the multi-repo rewrite)
- issue selection clearing keys off filter content, not array identity
- partial-failure banners get select-text cursor-text so errors can be
  copied into bug reports
@Kitenite

Kitenite commented Aug 7, 2026

Copy link
Copy Markdown
Member

Pushed three maintainer commits addressing the review findings plus a rate-limit fix that surfaced while verifying them.

Review fixes

fix(desktop) — filter state, search, and navigation

  • Opening Pull requests with no repository filter (the default) hit an infinite store-sync loop (setProjectFilters always stored a fresh array; the view effect wrote it back) and crashed the page with Maximum update depth exceeded. Setters now bail on equal content, and route pages memoize URL-derived filters. Regression tests are mutation-verified.
  • Typing in the search box snapped back to the stale URL value until the debounced navigation landed (dropping characters); inputs now sync only from the URL param.
  • Returning from a PR/issue detail rewrote "All repositories" to that item's repo and persisted it; detail back-navigation no longer treats the item's own project param as a filter fallback.
  • Issue selection was wiped by unrelated URL navigations (array-identity effect dep) — now keyed off filter content.
  • Mixed-repository issue selections silently created every workspace against one repo; the Run popover now blocks them with an inline explanation.
  • Partial-failure banners got select-text cursor-text, and lists keep previous rows visible while a changed search/filter refetches (restores the placeholderData behavior the multi-repo rewrite lost).

feat(host-service) — fallback hardening

  • Octokit fallback now clamps pagination at GitHub's 1000-result search cap (the gh path already did) and enriches real check rollups via octokit.graphql instead of reporting "No checks" when the gh CLI is unavailable.
  • Direct #123/URL lookups with a review filter paged the Search API up to 10 times per lookup; they now use per-PR core-quota calls (reviewDecision, reviews, review requests, team membership).

Rate limiting

With "All repositories" selected, every repo issued its own Search API call per page and per keystroke pause — ~28 repos against GitHub's 30-searches/minute quota tripped the limit after two interactions. Searches are now batched per serving host: one projectIds request per host, chunked into multi-repo: qualifier queries under GitHub's 256-char limit (~7 repos per search call). Rate-limit responses map to a typed TOO_MANY_REQUESTS error with the reset time, and a project that fails to resolve (e.g. no GitHub remote) is skipped in batch requests instead of blanking every other repo's results. Single-project callers (new-workspace modal) are unchanged.

Verification

  • 61 host-service + 252 desktop focused tests pass; new batching/loop/clamp tests were proven to fail against the old code. Root typecheck and lint clean.
  • CDP end-to-end on the dev app: the previously-crashing default Pull requests view renders 90 rows across repos with working check summaries; real-input typing keeps every character; detail→back preserves "All repositories"; a fetch-instrumented refresh shows exactly one searchPullRequests request carrying all 28 project ids.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 issues found across 29 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/host-service/src/trpc/router/workspace-creation/shared/github-search.ts">

<violation number="1" location="packages/host-service/src/trpc/router/workspace-creation/shared/github-search.ts:114">
P2: Selecting two local projects that track the same GitHub repository silently drops the results for the later project, so users cannot open those work items in that project. The attribution contract should either deduplicate same-remotes before querying and intentionally expose one project, or preserve all matching project IDs and materialize a row for each selected project.</violation>
</file>

<file name="apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/TasksTopBar/components/RunIssuesInWorkspacePopover/RunIssuesInWorkspacePopover.tsx">

<violation number="1" location="apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/TasksTopBar/components/RunIssuesInWorkspacePopover/RunIssuesInWorkspacePopover.tsx:151">
P2: Selecting issues from two project entries that point at the same GitHub repository is blocked as a mixed-repository batch, even though every issue can safely run against the selected project. Compare canonical repository identity (or include it in `SelectedIssue`) rather than project IDs for this guard.</violation>
</file>

<file name="packages/host-service/src/trpc/router/workspace-creation/procedures/search-github-issues.ts">

<violation number="1" location="packages/host-service/src/trpc/router/workspace-creation/procedures/search-github-issues.ts:213">
P2: Broad issue searches through the Octokit fallback can advertise pages beyond GitHub's 1,000-result search cap, causing infinite scroll to request unavailable pages. Bounding `hasNextPage` by the shared GitHub search result limit would keep the fallback consistent with pull-request search.</violation>

<violation number="2" location="packages/host-service/src/trpc/router/workspace-creation/procedures/search-github-issues.ts:312">
P2: When selected repositories require multiple query chunks, one requested page returns up to `limit` issues per chunk and later pages are appended chunk-by-chunk, so the task list can show more than 30 rows and place newer issues after older ones. A global pagination/merge step would need to fetch enough chunk results to produce one ordered `limit`-sized page (or explicitly expose chunk pagination).</violation>
</file>

<file name="packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts">

<violation number="1" location="packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts:374">
P2: Octokit direct review filters inspect only the first 100 reviews. PRs with older matching reviews or review decisions beyond that page can be incorrectly classified as not reviewed or as the wrong state; paginate review history until the viewer match or final decision is established.</violation>

<violation number="2" location="packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts:773">
P2: One repository's check-enrichment failure removes checks from every other repository in the same page because `Promise.all` rejects the entire batch and the outer catch keeps `merged`. Settling each repository independently would preserve successful check summaries while still allowing the failed repository's rows to render.</violation>

<violation number="3" location="packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts:897">
P1: Multi-repository searches do not return a global page: each query chunk fetches `limit` rows for the same `page`, then all rows are merged without a global slice. Chunked selections can therefore show too many rows on page 1 and omit or duplicate rows as the desktop list loads later pages; the chunk queries need a globally consistent pagination strategy.</violation>
</file>

<file name="apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx">

<violation number="1" location="apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx:109">
P1: The default/all-repositories Tasks view fails for any host serving more than 50 repositories because this call sends the entire host group while the `searchGitHubIssues` input rejects more than 50 `projectIds`; batching within the supported limit or changing the server contract would keep the all-repositories filter usable.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

const chunks = chunkProjectRepos(projectRepos, qualifiers);
const chunkResults = await Promise.all(
chunks.map((chunk) =>
ghApiSearchPullRequests(ctx.execGh, chunk, qualifiers, page, limit),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Multi-repository searches do not return a global page: each query chunk fetches limit rows for the same page, then all rows are merged without a global slice. Chunked selections can therefore show too many rows on page 1 and omit or duplicate rows as the desktop list loads later pages; the chunk queries need a globally consistent pagination strategy.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts, line 897:

<comment>Multi-repository searches do not return a global page: each query chunk fetches `limit` rows for the same `page`, then all rows are merged without a global slice. Chunked selections can therefore show too many rows on page 1 and omit or duplicate rows as the desktop list loads later pages; the chunk queries need a globally consistent pagination strategy.</comment>

<file context>
@@ -390,93 +719,194 @@ async function ghGetPullRequestChecks(
+			const chunks = chunkProjectRepos(projectRepos, qualifiers);
+			const chunkResults = await Promise.all(
+				chunks.map((chunk) =>
+					ghApiSearchPullRequests(ctx.execGh, chunk, qualifiers, page, limit),
+				),
 			);
</file context>

const client = getHostServiceClientByUrl(target.hostUrl);
return client.workspaceCreation.searchGitHubIssues.query({
projectId: firstProject.projectId,
projectIds: target.projects.map((project) => project.projectId),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The default/all-repositories Tasks view fails for any host serving more than 50 repositories because this call sends the entire host group while the searchGitHubIssues input rejects more than 50 projectIds; batching within the supported limit or changing the server contract would keep the all-repositories filter usable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/GitHubIssuesContent/GitHubIssuesContent.tsx, line 109:

<comment>The default/all-repositories Tasks view fails for any host serving more than 50 repositories because this call sends the entire host group while the `searchGitHubIssues` input rejects more than 50 `projectIds`; batching within the supported limit or changing the server contract would keep the all-repositories filter usable.</comment>

<file context>
@@ -72,23 +88,25 @@ export function GitHubIssuesContent({
 				return client.workspaceCreation.searchGitHubIssues.query({
-					projectId: target.projectId,
+					projectId: firstProject.projectId,
+					projectIds: target.projects.map((project) => project.projectId),
 					query: debouncedQuery.trim() || undefined,
 					limit: PAGE_SIZE,
</file context>

const match = repositoryUrl?.match(REPOSITORY_URL_RE);
if (!match) return null;
const key = `${match[1]}/${match[2]}`.toLowerCase();
for (const { projectId, repo } of chunk) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Selecting two local projects that track the same GitHub repository silently drops the results for the later project, so users cannot open those work items in that project. The attribution contract should either deduplicate same-remotes before querying and intentionally expose one project, or preserve all matching project IDs and materialize a row for each selected project.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/host-service/src/trpc/router/workspace-creation/shared/github-search.ts, line 114:

<comment>Selecting two local projects that track the same GitHub repository silently drops the results for the later project, so users cannot open those work items in that project. The attribution contract should either deduplicate same-remotes before querying and intentionally expose one project, or preserve all matching project IDs and materialize a row for each selected project.</comment>

<file context>
@@ -0,0 +1,206 @@
+	const match = repositoryUrl?.match(REPOSITORY_URL_RE);
+	if (!match) return null;
+	const key = `${match[1]}/${match[2]}`.toLowerCase();
+	for (const { projectId, repo } of chunk) {
+		if (`${repo.owner}/${repo.name}`.toLowerCase() === key) return projectId;
+	}
</file context>

[issues],
);

const hasMixedRepos = issueProjectIds.size > 1;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Selecting issues from two project entries that point at the same GitHub repository is blocked as a mixed-repository batch, even though every issue can safely run against the selected project. Compare canonical repository identity (or include it in SelectedIssue) rather than project IDs for this guard.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/components/TasksView/components/TasksTopBar/components/RunIssuesInWorkspacePopover/RunIssuesInWorkspacePopover.tsx, line 151:

<comment>Selecting issues from two project entries that point at the same GitHub repository is blocked as a mixed-repository batch, even though every issue can safely run against the selected project. Compare canonical repository identity (or include it in `SelectedIssue`) rather than project IDs for this guard.</comment>

<file context>
@@ -141,7 +141,19 @@ export function RunIssuesInWorkspacePopover({
+		[issues],
+	);
+
+	const hasMixedRepos = issueProjectIds.size > 1;
+
 	const submitBlocker = useMemo<string | null>(() => {
</file context>

},
];
});
const hasNextPage = page * perPage < data.total_count;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Broad issue searches through the Octokit fallback can advertise pages beyond GitHub's 1,000-result search cap, causing infinite scroll to request unavailable pages. Bounding hasNextPage by the shared GitHub search result limit would keep the fallback consistent with pull-request search.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/host-service/src/trpc/router/workspace-creation/procedures/search-github-issues.ts, line 213:

<comment>Broad issue searches through the Octokit fallback can advertise pages beyond GitHub's 1,000-result search cap, causing infinite scroll to request unavailable pages. Bounding `hasNextPage` by the shared GitHub search result limit would keep the fallback consistent with pull-request search.</comment>

<file context>
@@ -110,82 +152,177 @@ async function ghApiSearchIssues(
+				},
+			];
+		});
+	const hasNextPage = page * perPage < data.total_count;
+	return { items, totalCount: data.total_count, hasNextPage };
+}
</file context>

issues: result.items,
totalCount: result.totalCount,
hasNextPage: result.hasNextPage,
issues: mergeByUpdatedAtDesc(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When selected repositories require multiple query chunks, one requested page returns up to limit issues per chunk and later pages are appended chunk-by-chunk, so the task list can show more than 30 rows and place newer issues after older ones. A global pagination/merge step would need to fetch enough chunk results to produce one ordered limit-sized page (or explicitly expose chunk pagination).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/host-service/src/trpc/router/workspace-creation/procedures/search-github-issues.ts, line 312:

<comment>When selected repositories require multiple query chunks, one requested page returns up to `limit` issues per chunk and later pages are appended chunk-by-chunk, so the task list can show more than 30 rows and place newer issues after older ones. A global pagination/merge step would need to fetch enough chunk results to produce one ordered `limit`-sized page (or explicitly expose chunk pagination).</comment>

<file context>
@@ -110,82 +152,177 @@ async function ghApiSearchIssues(
-				issues: result.items,
-				totalCount: result.totalCount,
-				hasNextPage: result.hasNextPage,
+				issues: mergeByUpdatedAtDesc(
+					chunkResults.map((result) => result.items),
+				),
</file context>

);
const checksByProject = new Map<string, Map<number, PullRequestChecksInfo>>();
await Promise.all(
[...numbersByProject].map(async ([projectId, numbers]) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: One repository's check-enrichment failure removes checks from every other repository in the same page because Promise.all rejects the entire batch and the outer catch keeps merged. Settling each repository independently would preserve successful check summaries while still allowing the failed repository's rows to render.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts, line 773:

<comment>One repository's check-enrichment failure removes checks from every other repository in the same page because `Promise.all` rejects the entire batch and the outer catch keeps `merged`. Settling each repository independently would preserve successful check summaries while still allowing the failed repository's rows to render.</comment>

<file context>
@@ -390,93 +719,194 @@ async function ghGetPullRequestChecks(
+	);
+	const checksByProject = new Map<string, Map<number, PullRequestChecksInfo>>();
+	await Promise.all(
+		[...numbersByProject].map(async ([projectId, numbers]) => {
+			const repo = repoByProject.get(projectId);
+			if (!repo) return;
</file context>

owner: repo.owner,
repo: repo.name,
pull_number: pr.number,
per_page: 100,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Octokit direct review filters inspect only the first 100 reviews. PRs with older matching reviews or review decisions beyond that page can be incorrectly classified as not reviewed or as the wrong state; paginate review history until the viewer match or final decision is established.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/host-service/src/trpc/router/workspace-creation/procedures/search-pull-requests.ts, line 374:

<comment>Octokit direct review filters inspect only the first 100 reviews. PRs with older matching reviews or review decisions beyond that page can be incorrectly classified as not reviewed or as the wrong state; paginate review history until the viewer match or final decision is established.</comment>

<file context>
@@ -166,13 +206,254 @@ async function ghDirectLookup(
+			owner: repo.owner,
+			repo: repo.name,
+			pull_number: pr.number,
+			per_page: 100,
+		});
+		const reviewedByViewer = reviews.some(
</file context>

hasNextPage reads the in-flight page's data, so a fresh next-page fetch
unmounted the sentinel and no indicator showed; the row now stays
mounted during isFetchingNextPage with a spinner.
…icons

- useWorkItemsList extracts the host grouping, batched pagination, row
  attribution, totalCount, and repo-mismatch logic that PullRequestsContent
  and GitHubIssuesContent had duplicated token-for-token; both now keep
  only their query options, row rendering, and actions
- LoadMoreSentinel shares the infinite-scroll sentinel/loading row
- CHECK_STATUS_ICONS replaces the three value-identical status icon maps
  in PullRequestChecksSection, PullRequestChecksSummary, and the
  v2-workspace ChecksSection (v1 ReviewPanel left alone; surface is
  sunset)
@Kitenite
Kitenite merged commit e4d05ce into ParadevAI:main Aug 8, 2026
2 checks passed
Kitenite added a commit that referenced this pull request Aug 8, 2026
Three groups of binary assets with zero references anywhere in the tree:
- .github/pr-assets/ (644K): PR #6201's description screenshots; the
  description embeds the fork's raw URLs, so these copies serve nothing
- assets/ (211K): example.png/notifs.png orphaned since the website
  moved into apps/marketing
- apps/desktop/docs/assets/v1-migration-notices/ (1.2M): PR #6118
  evidence screenshots never linked from any doc; the v1 surface is
  sunset

Kept: apps/desktop/docs/artifacts (referenced by two runbooks) and
packages/cli/demo recordings (outputs of the committed vhs demo kit).
Kitenite added a commit that referenced this pull request Aug 8, 2026
Three groups of binary assets with zero references anywhere in the tree:
- .github/pr-assets/ (644K): PR #6201's description screenshots; the
  description embeds the fork's raw URLs, so these copies serve nothing
- assets/ (211K): example.png/notifs.png orphaned since the website
  moved into apps/marketing
- apps/desktop/docs/assets/v1-migration-notices/ (1.2M): PR #6118
  evidence screenshots never linked from any doc; the v1 surface is
  sunset

Kept: apps/desktop/docs/artifacts (referenced by two runbooks) and
packages/cli/demo recordings (outputs of the committed vhs demo kit).
Kitenite added a commit that referenced this pull request Aug 12, 2026
* docs: weekly update for PRs merged 2026-08-05 to 2026-08-12

- workspaces: sessions (project-less workspaces, #6274), pin + drag-and-drop
  pinning (#6364), list/board views with Merged & Deleted history columns
  (#6296), per-project naming instructions (#6250), multi-PR links per
  branch with remove/restore (#5924)
- automations: session automations (#6280), list health stats + Up next
  grouping + read-only team automations (#6291, #6276), detail page
  Settings/Run History tabs, inline run errors, would-run preview, RRule
  validation (#6305)
- editor: image pane pan/pinch/zoom (#6285)
- tasks: multi-repo filters, expanded task states, PR author/review
  filters, PR checks (#6201)
- monorepos: per-project sparse checkout (#6034)
- customization: project icon + color picker, v1 color carry-over (#6249)
- terminal presets: built-in Superset CLI preset (#6270)
- agents: resume interrupted sessions + Resume Args setting (#6253, #6265),
  Superset hooks toggle + scoping (#6072)
- cli: interactive command browser + branded help (#6273); reference
  updated for session mode, --task, --skip-branch-prefix, --session
  (verified against packages/cli/src/commands)

* docs: tighten wording and drop em dashes

Shorten this week's additions per the writing guide: one thought per
sentence, plainest word, no em dashes as prose punctuation. Also sweeps
the three pre-existing em dashes in recipes.

* docs: add screenshots from the 08-09 changelog batch

cli command browser, agent resume banner, PR view with checks, and the
project icon/color picker. Copied into apps/docs/public/images per the
SOP rather than referenced across apps.
@Roshvan
Roshvan deleted the agent/work-items-filters-pr-checks branch October 11, 2026 14:50
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.

2 participants