fix(host): escape cancels a launched navigation; browse joins deferGroupRegistration

- Escape in the path editor now supersedes a navigation the editor already
  launched (request-sequence bump + loading reset), so a late success cannot
  jump to the cancelled path; the single-pane fallback keeps covering a
  superseded selection preview (ds-review-bot).
- The browse flow's pair registration rides ui-slots' new
  deferGroupRegistration (one occupant, both holes, as a unit — construction
  or late rival conflicts roll back wholesale and fail loud), mirroring
  -native and deleting the would-be clone.
This commit is contained in:
creatixchu
2026-07-29 03:20:24 +08:00
parent 4208676278
commit 905b4555a3
4 changed files with 76 additions and 19 deletions
@@ -352,6 +352,24 @@ describe('DirectoryBrowser', () => {
expect(screen.getByLabelText('browser.editPath')).toBeTruthy()
})
it('ignores a pending navigation that settles after Escape cancelled the editor', async () => {
const pending: ((listing: DirectoryListing) => void)[] = []
const b = mount()
await waitFor(() => { expect(screen.getByRole('listitem')).toBeTruthy() })
fireEvent.click(screen.getByRole('button', { name: 'browser.editPath' }))
const input = screen.getByLabelText('browser.editPath')
b.listDirectory.mockImplementation(() =>
new Promise<DirectoryListing>((settle) => { pending.push(settle) }))
fireEvent.change(input, { target: { value: DOCS } })
fireEvent.keyDown(input, { key: 'Enter' })
fireEvent.keyDown(input, { key: 'Escape' })
// The cancelled navigation settling late must not jump the view to DOCS.
await act(async () => { pending.shift()!(listingFor(DOCS)) })
expect(screen.queryByText('harness')).toBeNull()
expect(screen.getByText('Documents')).toBeTruthy()
expect(screen.queryByRole('status')).toBeNull()
})
it('keeps a newer path edit when an older slow navigation settles', async () => {
const pending: ((listing: DirectoryListing) => void)[] = []
const b = mount()