Fix queued external file dispatch - #2089
Conversation
|
🚨 SLOP COP 🚨 · I am SlopCop, and I am reviewing this pull request now. I will review security, code quality, architecture, and performance in parallel. I will also test the affected path when local test tools permit it. |
There was a problem hiding this comment.
🚨 SLOP COP 🚨 · review
Plain-English summary: Each queued file-open request now gets a unique local number. React then creates a new dispatcher for every request.
This fixes the stuck queue. The second request no longer reuses the settled state from the first request.
I found no actionable issues.
- Security: The change adds no external input or security boundary. Installed plugins already use the existing trusted file-open contract.
- Code quality: The request key directly matches the React lifecycle fault. The names and types are clear.
- Architecture: I found no matching queue abstraction worth sharing. A new abstraction would add more code than value here.
- Performance: Queue copy work stays small and bounded. The lazy import stays cached, and keyed unmounts remove hook subscriptions.
- Tests: The focused Turbo test passed both tests. It verifies acceptance, exactly-once dispatch, and FIFO invocation.
- Validation: The app type check passed. All current GitHub checks passed.
Two reviewers noted that accepted open operations can overlap. That behavior existed before this patch and matches the documented acceptance contract.
I attempted the browser check. The development server did not become ready after eight minutes during its initial SDK type bundle, so doobie could not test the route.
What was wrong
PR #2005 queued normalized external-file intents but rendered one unkeyed
AppFileExternalNavigationDispatcher. After the first request settled, React reused that component for the next queue item, so itsdidSettleRefremainedtrue; the second accepted request neither dispatched nor left the queue, and every later request remained blocked behind it. This is the verified post-merge review finding.What changed
This is intentionally limited to internal React state and identity. It does not change the experimental plugin SDK signature, public plugin API, server/daemon wire data, or host RPC contracts, so no API audit entry or
HOST_DAEMON_PROTOCOL_VERSIONbump is needed.How you verified
Before the production change, the new focused regression failed with one dispatch:
expected "vi.fn()" to be called 2 times, but got 1 times.After the fix and a clean rebase onto current
origin/main(7f3d2ac66):pnpm exec turbo run test --filter=@bb/app --force -- src/components/plugin/AppFileExternalNavigationHost.test.tsx— 2 passed.pnpm exec turbo run test --filter=@bb/app --force— 411 files passed; 3,157 tests passed and 3 skipped.pnpm exec turbo run typecheck --filter=@bb/app --force— passed.pnpm exec turbo run lint --filter=@bb/app --force— passed with 0 errors (156 existing warnings).pnpm exec turbo run build --filter=@bb/app --force— passed.node apps/app/scripts/check-bundle-budget.mjs— passed (boot payload 428.7 KB Brotli vs. 467.8 KB budget).