mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 00:03:20 +00:00
Implements the filtering behavior described in docs/remove-repo-github-views.md so removed repositories are excluded from GitHub task and project views.
5.9 KiB
5.9 KiB
Remove Repos From GitHub Views
Problem
When a repo is removed from Orca, GitHub Tasks/Projects can still surface that repo’s data.
Current behavior is mixed:
- Tasks repo selection is pruned when
reposchanges, so new fetches target only live repos. removeRepodoes not evict GitHub caches (workItemsCache,prCache,issueCache,checksCache,commentsCache) and does not clear in-flight work-item requests.- Project table rendering is cache-driven and currently unfiltered by “repos opened in Orca”, so removed-repo rows remain visible until a refetch happens to exclude them.
- Project row actions already gate on slug→repo matching; unmatched rows fall back to slug-mode/open-in-GitHub behavior. Visibility is the gap, not action routing.
Code Reality (must be reflected in design)
workItemsCacheKey(repoId, limit, query)is repo-id keyed.selectTaskPageWorkItemsCacheEntriesstill callsworkItemsCacheKey(repo.path, ...)(wrong key).findTaskPageDialogWorkItemscans wholeworkItemsCache, but requires bothidandrepoIdmatch.repoScopedCacheKeyfor PR/issue/check/comment caches is${repoId ?? repoPath}::${suffix}; legacy path-keyed entries can exist.ProjectViewWrappercurrently passes unfilteredtabletoProjectViewList.useRepoSlugIndexcurrently returns only a lookup function (no "ready/rebuilding" state), so callers cannot distinguish "index still rebuilding" from "no rows match".useRepoSlugIndexalready evicts cache entries for repos no longer instate.repos, but repo removal does not explicitly clear by repo id at removal time.
Root Cause
Two independent correctness gaps:
- No repo-removal cache invalidation in GitHub slice.
- No project-row visibility filter against currently opened Orca repos.
Non-Goals
- No GitHub-side deletion/mutation of issues, PRs, or project items.
- No server-side “opened in Orca” project filter.
- No Linear/GitLab behavior changes.
- No auto-clone flow from project rows.
Required Changes
- Add GitHub-slice repo-eviction API
- Add
evictGitHubRepoCaches(repoId: string, repoPath?: string)ingithub.ts. - Evict all matching keys from:
workItemsCache(repo-id prefix and legacy path prefix)prCache,issueCache,checksCache,commentsCache(id/path scoped)
- Drop matching
inflightWorkItemsRequestskeys. - Bump
workItemsInvalidationNoncewhen anyworkItemsCacheentries were evicted.
- Call eviction from repo removal
- In
repos.ts removeRepo, after backend remove succeeds and before final state prune, read repo path from current state and call:evictGitHubRepoCaches(repoId, repoPath)clearRepoSlugCacheEntry(repoId)
- Keep this call in renderer state path (same window that executes removal).
- Fix Tasks selector keying
selectTaskPageWorkItemsCacheEntriesmust userepo.idforworkItemsCacheKey.repoPathstays inTaskPageRepoSourceStateonly for UI identity/retry labels.
- Filter project rows client-side
- In
ProjectViewWrapper, derivevisibleRowsfromtable.rowswhererow.content.repositoryresolves via slug index to at least one live Orca repo. - Exclude missing/invalid/unresolvable repository rows once slug index is resolved for current repo set.
- Extend
useRepoSlugIndex(or add a companion hook) to expose readiness for the current repo snapshot (e.g.,{ lookupSlug, ready }or generation token). - While slug index is rebuilding for a new repo snapshot, keep last rendered filtered table to avoid flash-to-empty; apply strict filtering once ready.
- Pass filtered table to
ProjectViewList. - Keep row action guards; do not rely on filtering alone.
- Close stale dialogs/modals on repo/slug changes
- If
dialogRepoItem.repoIdis no longer in live repos, close dialog. - If a slug currently in
slugDialog/repoNotInOrcanow resolves to a live repo, close stale unknown-repo state.
Consistency and Concurrency
- In-flight race: removal must clear in-flight work-item dedupe keys before nonce-driven re-fetch paths can reuse stale in-flight entries.
projectViewCacheis keyed by project/view/query, not repo; repo removal cannot key-evict rows surgically. Row filtering is the correctness boundary.- Multi-window: cache invalidation is renderer-local unless each window executes equivalent invalidation on repo change events. Document as eventual consistency unless cross-window invalidation is explicitly wired.
- External mutation (remote URL/repo transfer): slug cache can stale. Repo-removal invalidation is required; remote-change invalidation is separate follow-up.
Feasibility Constraints
- There is no single GitHub API call that applies “repo is currently opened in Orca” filtering to a Project view.
- Project query overrides are not a substitute for this requirement; they are user-entered search strings and do not provide safe/complete set filtering for dynamic Orca repo membership.
- Slug resolution has real cost (IPC + git remote resolution, possibly runtime RPC). Keep async generation guards and avoid blocking render on a full rebuild.
Edge Cases
- Removing the last repo: Tasks selection collapses to empty/all-eligible behavior; Project table should render zero visible rows after slug resolution settles.
- Multiple Orca repos mapping to same slug: row remains visible while any matching repo exists.
- Non-GitHub repos or unresolved slugs: filtered out from Project visibility.
- Repo removed while dialog is open: dialog must close.
- Legacy path-keyed cache entries: evict alongside repo-id keys.
Rollout Order
- Add
evictGitHubRepoCacheswith tests (id/path key eviction, inflight clearing, nonce bump conditions). - Wire
removeRepoto eviction +clearRepoSlugCacheEntry; add repo-removal tests. - Fix
task-page-cache-selectorskeying + tests. - Add
ProjectViewWrapperfiltered-table and stale-dialog cleanup + tests. - Run typecheck, lint, targeted renderer/store tests.