Problem
When the active promo is closed via finishPromo/cancelPromo, closePromo calls triggerNextPromo and the next queued promo starts. skipPromo clears the active promo and removes it from the queue, but never calls triggerNextPromo — so pending promos stay in the queue until some unrelated requestStart/sendEvent happens.
Real paths that hit this:
- the README pattern
useUnmount(() => skipPromo());
- onboarding integration:
closeHint -> skipPromo (initOnboardingIntegration).
A user closes a hint, and the next queued promo silently never shows.
Repro
const controller = new Controller(testOptions);
await controller.requestStart('boardPoll'); // active
await controller.requestStart('ganttPoll'); // pending
controller.skipPromo('boardPoll');
expect(controller.state.base.activePromo).toBe('ganttPoll'); // FAILS: null
Where
src/promo-manager/core/controller.ts — skipPromo (missing triggerNextPromo after clearing active)
Problem
When the active promo is closed via
finishPromo/cancelPromo,closePromocallstriggerNextPromoand the next queued promo starts.skipPromoclears the active promo and removes it from the queue, but never callstriggerNextPromo— so pending promos stay in the queue until some unrelatedrequestStart/sendEventhappens.Real paths that hit this:
useUnmount(() => skipPromo());closeHint->skipPromo(initOnboardingIntegration).A user closes a hint, and the next queued promo silently never shows.
Repro
Where
src/promo-manager/core/controller.ts—skipPromo(missingtriggerNextPromoafter clearing active)