mirror of
https://github.com/stablyai/orca.git
synced 2026-10-27 08:02:51 +00:00
Route PR page metadata by repo host
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -270,3 +270,4 @@ Done means: reviewers and future agents can understand the vision, implementatio
|
||||
- [x] 2026-06-12: Aligned Automations manual-run disabled states with the backend run-target resolver so saved run contexts now disable Run Now when the project-host setup is missing or not ready, instead of failing after dispatch. Verified with focused automation availability tests, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`.
|
||||
- [x] 2026-06-12: Routed GitHub drawer label/assignee/reviewer metadata reads through the same task source context as issue/PR mutations, including slug-addressed Project view rows and reviewer request/remove actions, so same-repo multi-host drawers do not fall back to the repo owner or focused runtime. Verified with a focused source-boundary test, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`.
|
||||
- [x] 2026-06-13: Tightened runtime project-host setup mutations so older remote servers that advertise `project-host-setup.v1` but not `workspace-run-context.v1` are blocked before setup/clone/create/update/delete RPCs mutate server state; read-only hydration still degrades to repo-derived compatibility rows. Verified with focused repo capability tests, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`.
|
||||
- [x] 2026-06-13: Routed the full-page Pull Request metadata popovers through the PR repo owner host instead of ambient focused runtime state, so reviewer, label, and assignee reads align with the existing repo-owned mutation routing. Verified with a focused PR host-boundary test, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`.
|
||||
|
||||
@@ -523,7 +523,6 @@ function PRReviewersPanel({
|
||||
reviewRequests: item.reviewRequests
|
||||
}))
|
||||
const patchWorkItem = useAppStore((s) => s.patchWorkItem)
|
||||
const settings = useAppStore((s) => s.settings)
|
||||
const repoOwnerSettings = useAppStore(
|
||||
useShallow((s) => getSettingsForRepoRuntimeOwner(s, item.repoId ?? null))
|
||||
)
|
||||
@@ -601,11 +600,12 @@ function PRReviewersPanel({
|
||||
open && reviewSlug ? reviewSlug.owner : null,
|
||||
open && reviewSlug ? reviewSlug.repo : null,
|
||||
reviewerSeedUsers.map((user) => user.login),
|
||||
settings
|
||||
repoOwnerSettings
|
||||
)
|
||||
const reviewerMetadataByPath = useRepoAssignees(
|
||||
open && !reviewSlug ? repoPath : null,
|
||||
open && !reviewSlug ? item.repoId : null
|
||||
open && !reviewSlug ? item.repoId : null,
|
||||
repoOwnerSettings
|
||||
)
|
||||
const reviewerMetadata = reviewSlug ? reviewerMetadataBySlug : reviewerMetadataByPath
|
||||
const displayItem = { ...item, reviewRequests: localReviewRequests }
|
||||
@@ -4960,6 +4960,9 @@ function GHEditSection({
|
||||
const assigneesItemKey = `${item.repoId}\0${item.id}`
|
||||
const patchWorkItem = useAppStore((s) => s.patchWorkItem)
|
||||
const patchProjectRowContent = useAppStore((s) => s.patchProjectRowContent)
|
||||
const repoOwnerSettings = useAppStore(
|
||||
useShallow((s) => getSettingsForRepoRuntimeOwner(s, item.repoId ?? repoId ?? null))
|
||||
)
|
||||
const { isPending, run } = useImmediateMutation()
|
||||
// Why: when the dialog opens from a Project view, mutations route through
|
||||
// *BySlug IPCs and we must keep `projectViewCache` in sync alongside
|
||||
@@ -4983,15 +4986,22 @@ function GHEditSection({
|
||||
const slugRepo = projectOrigin?.repo ?? null
|
||||
const repoLabelsByPath = useRepoLabels(
|
||||
projectOrigin ? null : repoPath,
|
||||
projectOrigin ? null : repoId
|
||||
projectOrigin ? null : repoId,
|
||||
repoOwnerSettings
|
||||
)
|
||||
const repoLabelsBySlug = useRepoLabelsBySlug(slugOwner, slugRepo)
|
||||
const repoLabelsBySlug = useRepoLabelsBySlug(slugOwner, slugRepo, repoOwnerSettings)
|
||||
const repoLabels = projectOrigin ? repoLabelsBySlug : repoLabelsByPath
|
||||
const repoAssigneesByPath = useRepoAssignees(
|
||||
projectOrigin ? null : repoPath,
|
||||
projectOrigin ? null : repoId
|
||||
projectOrigin ? null : repoId,
|
||||
repoOwnerSettings
|
||||
)
|
||||
const repoAssigneesBySlug = useRepoAssigneesBySlug(
|
||||
slugOwner,
|
||||
slugRepo,
|
||||
assignees,
|
||||
repoOwnerSettings
|
||||
)
|
||||
const repoAssigneesBySlug = useRepoAssigneesBySlug(slugOwner, slugRepo, assignees)
|
||||
const repoAssignees = projectOrigin ? repoAssigneesBySlug : repoAssigneesByPath
|
||||
|
||||
// Why: sync local assignees when item changes or when the detail fetch
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const COMPONENT_ROOT = __dirname
|
||||
|
||||
function componentSource(relativePath: string): string {
|
||||
return readFileSync(join(COMPONENT_ROOT, relativePath), 'utf8')
|
||||
}
|
||||
|
||||
function sourceBetween(source: string, startPattern: string, endPattern: string): string {
|
||||
const start = source.indexOf(startPattern)
|
||||
expect(start).toBeGreaterThanOrEqual(0)
|
||||
const end = source.indexOf(endPattern, start + startPattern.length)
|
||||
expect(end).toBeGreaterThan(start)
|
||||
return source.slice(start, end)
|
||||
}
|
||||
|
||||
describe('PullRequestPage host boundaries', () => {
|
||||
it('routes reviewer metadata and mutations through the PR repo owner host', () => {
|
||||
const source = componentSource('PullRequestPage.tsx')
|
||||
const section = sourceBetween(source, 'function PRReviewersPanel', 'function isPRFileViewed')
|
||||
|
||||
expect(section).toContain('getSettingsForRepoRuntimeOwner(s, item.repoId ?? null)')
|
||||
expect(section).toContain('useRepoAssigneesBySlug(')
|
||||
expect(section).toContain('repoOwnerSettings')
|
||||
expect(section).toContain('useRepoAssignees(')
|
||||
expect(section).toContain('repoOwnerSettings')
|
||||
expect(section).toContain('getActiveRuntimeTarget(repoOwnerSettings)')
|
||||
})
|
||||
|
||||
it('routes PR edit metadata through the same repo owner host as mutations', () => {
|
||||
const source = componentSource('PullRequestPage.tsx')
|
||||
const section = sourceBetween(source, 'function GHEditSection', 'function GHCommentComposer')
|
||||
|
||||
expect(section).toContain('getSettingsForRepoRuntimeOwner(s, item.repoId ?? repoId ?? null)')
|
||||
expect(section).toContain('useRepoLabels(')
|
||||
expect(section).toContain('useRepoLabelsBySlug(slugOwner, slugRepo, repoOwnerSettings)')
|
||||
expect(section).toContain('useRepoAssignees(')
|
||||
expect(section).toContain('useRepoAssigneesBySlug(')
|
||||
expect(section).toContain('repoOwnerSettings')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user