feat(frontend): promote priority support for Capgo plugins - #2828
feat(frontend): promote priority support for Capgo plugins#2828WcaleNieWolny wants to merge 8 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughChangesThe PR adds deterministic priority-support promotion selection, organization eligibility checks, dashboard banners, a localized presentation modal, and an animated support story. It also adds GitHub connection handling, shared fade-in styling, component declarations, and tests. Priority Support Promotion
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant AppPage
participant PrioritySupportPromo
participant PrioritySupportPromoBanner
participant PresentationModal
participant AccountSettings
AppPage->>PrioritySupportPromo: determine daily active variant
AppPage->>PrioritySupportPromoBanner: render eligible support promotion
PrioritySupportPromoBanner->>PresentationModal: open presentation
PresentationModal->>AccountSettings: navigate with GitHub connection query
AccountSettings->>PrioritySupportPromo: consume connection query
AccountSettings->>AccountSettings: open GitHub profile dialog
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Stale comment
Risk: medium. Left a non-blocking comment (not approved): Cursor Bugbot was not present, and this PR is above the low-risk approval threshold due to substantial new dashboard promo UI and account-settings behavior. Assigned a human reviewer for the user-facing changes.
Sent by Cursor Approval Agent: Pull Request Approver External
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/dashboard/PrioritySupportPresentationModal.vue`:
- Line 293: Remove one ownership path for slide accessibility state: retain the
declarative :inert and :aria-hidden bindings on the slide articles, and delete
the corresponding imperative slide.inert and slide.setAttribute('aria-hidden',
...) writes from initDeck and go. Apply the same change to all three affected
slide elements while preserving the cur-based bindings.
- Line 389: Add the missing priority-support-story-github-handle translation key
to messages/en.json with the appropriate English GitHub handle text, matching
the key used by PrioritySupportPresentationModal.vue.
In `@src/components/dashboard/PrioritySupportPromoBanner.vue`:
- Around line 192-211: Move the fade-in keyframes, .animate-fade-in animation
rule, and prefers-reduced-motion override from PrioritySupportPromoBanner.vue
and the other three components into the shared src/styles/style.css stylesheet.
Remove all duplicated local definitions while preserving the existing class name
and animation behavior.
In `@src/components/dashboard/PrioritySupportStory.vue`:
- Around line 2202-2291: Consolidate the duplicated CSS blocks for
.pss-merge-box, .pss-confirm-merge, .pss-merged-state, and .pss-reply-stack into
single readable definitions, preserving the intended effective values including
.pss-merged-state’s flex layout, left alignment, and required positioning.
Remove the unused .pss-resolution-timeline and .pss-priority-label rules because
neither selector appears in the template.
- Around line 157-158: Update the selector guard in startStory to log a warning
identifying the unresolved story selector before returning, while preserving the
existing early-return behavior and type narrowing. Include enough
selector/context information in the warning to diagnose which required element
is missing.
In `@tests/priority-support-promo.unit.test.ts`:
- Around line 74-85: Validate that the `<template>` and `<style scoped>` markers
are found in the loaded SFC source before slicing in the imperative story
selector test. Assert both index values are non-negative, then use those
validated indices to derive script and template so marker changes fail
explicitly rather than producing misleading assertions.
- Around line 13-86: Update all five test cases in the “priority support
promotion” describe block to use it.concurrent() instead of it(), preserving
their existing assertions and bodies.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 47431750-2c5a-4b4b-b9ac-9ff16079df08
📒 Files selected for processing (10)
messages/en.jsonsrc/components.d.tssrc/components/dashboard/BuilderPromoBanner.vuesrc/components/dashboard/PrioritySupportPresentationModal.vuesrc/components/dashboard/PrioritySupportPromoBanner.vuesrc/components/dashboard/PrioritySupportStory.vuesrc/pages/app/[app].vuesrc/pages/settings/account/index.vuesrc/services/prioritySupportPromo.tstests/priority-support-promo.unit.test.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
There was a problem hiding this comment.
All reported issues were addressed across 10 files
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Re-trigger cubic
There was a problem hiding this comment.
Stale comment
Risk: medium. Left a non-blocking comment (not approved): Cursor Bugbot was not present, and this PR is above the low-risk approval threshold due to substantial new dashboard promo UI and account-settings behavior. Human review remains needed; reviewer already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/dashboard/PrioritySupportPresentationModal.vue (2)
9-9: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winUse the frontend import alias.
Replace the relative import with
~/components/dashboard/PrioritySupportStory.vue.As per coding guidelines: "Import using
~/alias forsrc/directory in frontend code instead of relative paths."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/dashboard/PrioritySupportPresentationModal.vue` at line 9, Update the PrioritySupportStory import in PrioritySupportPresentationModal.vue to use the frontend ~/ alias targeting components/dashboard/PrioritySupportStory.vue instead of the relative path.Source: Coding guidelines
231-241: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winCancel stale lifecycle continuations after
nextTick().A later prop change can invalidate either watcher while it awaits
nextTick(). The old continuation can then initialize a closed modal or restart an inactive story.
src/components/dashboard/PrioritySupportPresentationModal.vue#L231-L241: register watcher cleanup or use an activation token. SkipinitDeck()and focus when the open operation is stale.src/components/dashboard/PrioritySupportStory.vue#L488-L495: register watcher cleanup or use an activation token. SkipstartStory()when the active operation is stale.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/dashboard/PrioritySupportPresentationModal.vue` around lines 231 - 241, Cancel stale watcher continuations after nextTick in both src/components/dashboard/PrioritySupportPresentationModal.vue lines 231-241 and src/components/dashboard/PrioritySupportStory.vue lines 488-495. In the open watcher, use cleanup or an activation token so stale operations skip initDeck() and modalEl focus; in the story watcher, apply the same guard so stale operations skip startStory().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/dashboard/DeploymentBanner.vue`:
- Around line 467-470: Move the DeploymentBanner animation offset from the
inline style into an approved shared animation class in src/styles/style.css and
apply that class to the banner. In
src/components/dashboard/PrioritySupportStory.vue, replace the scoped .pss-*
styles with equivalent Tailwind and DaisyUI utilities; if the animated mock
cannot be represented with utilities, document and approve the narrowly scoped
component-CSS exception.
---
Outside diff comments:
In `@src/components/dashboard/PrioritySupportPresentationModal.vue`:
- Line 9: Update the PrioritySupportStory import in
PrioritySupportPresentationModal.vue to use the frontend ~/ alias targeting
components/dashboard/PrioritySupportStory.vue instead of the relative path.
- Around line 231-241: Cancel stale watcher continuations after nextTick in both
src/components/dashboard/PrioritySupportPresentationModal.vue lines 231-241 and
src/components/dashboard/PrioritySupportStory.vue lines 488-495. In the open
watcher, use cleanup or an activation token so stale operations skip initDeck()
and modalEl focus; in the story watcher, apply the same guard so stale
operations skip startStory().
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 054b3350-c02e-46f4-afaa-7c3f0ae2adc5
📒 Files selected for processing (9)
messages/en.jsonsrc/components/dashboard/BuilderPromoBanner.vuesrc/components/dashboard/DeploymentBanner.vuesrc/components/dashboard/PrioritySupportPresentationModal.vuesrc/components/dashboard/PrioritySupportPromoBanner.vuesrc/components/dashboard/PrioritySupportStory.vuesrc/components/dashboard/TrialBanner.vuesrc/styles/style.csstests/priority-support-promo.unit.test.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
💤 Files with no reviewable changes (3)
- src/components/dashboard/TrialBanner.vue
- src/components/dashboard/PrioritySupportPromoBanner.vue
- src/components/dashboard/BuilderPromoBanner.vue
There was a problem hiding this comment.
Stale comment
Risk: medium. Left a non-blocking comment (not approved): Cursor Bugbot was not present, and this PR is above the low-risk approval threshold due to substantial new dashboard promo UI and account-settings behavior. Human review remains needed; reviewer already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/dashboard/PrioritySupportStory.vue (1)
489-496: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winCancel stale story startup.
When
activebecomesfalsewhile this watcher waits fornextTick(), the newer watcher stops the story. The earlier watcher then resumes and callsstartStory()for an inactive component. This can run the GSAP timeline and matrix animation while the story is hidden.Use
onCleanupor a request token. Check it afterawait nextTick()before callingstartStory().Proposed fix
-watch([() => props.active, reduce], async ([active]) => { +watch([() => props.active, reduce], async ([active], _, onCleanup) => { + let cancelled = false + onCleanup(() => { + cancelled = true + }) + if (!active) { stopStory() return } await nextTick() + if (cancelled || !props.active) + return startStory() }, { immediate: true })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/dashboard/PrioritySupportStory.vue` around lines 489 - 496, Update the watcher around active and reduce to cancel stale startup attempts: register cleanup or use a request token before await nextTick(), then verify the watcher is still current and active before calling startStory(). Preserve stopStory() and the immediate watcher behavior for inactive states.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/dashboard/PrioritySupportPresentationModal.vue`:
- Around line 251-264: Update the reduce watcher in
PrioritySupportPresentationModal so that when isReduced becomes true it kills
the active GSAP slide and entrance timelines, in addition to stopping
issuePulse, then settles the current slide state before returning. Store
references to the timelines created by go() and enter() so the watcher can
terminate them while preserving normal animation behavior when reduced motion is
disabled.
---
Outside diff comments:
In `@src/components/dashboard/PrioritySupportStory.vue`:
- Around line 489-496: Update the watcher around active and reduce to cancel
stale startup attempts: register cleanup or use a request token before await
nextTick(), then verify the watcher is still current and active before calling
startStory(). Preserve stopStory() and the immediate watcher behavior for
inactive states.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 90927188-2070-400d-a5ca-8b00f06d0ce3
📒 Files selected for processing (4)
src/components/dashboard/PrioritySupportPresentationModal.vuesrc/components/dashboard/PrioritySupportStory.vuesrc/services/prioritySupportPromo.tstests/priority-support-promo.unit.test.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
There was a problem hiding this comment.
Stale comment
Risk: medium. Left a non-blocking comment (not approved): Cursor Bugbot was not present, and this PR is above the low-risk approval threshold due to substantial new dashboard promo UI and account-settings behavior. Human review remains needed; reviewer already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Stale comment
Risk: medium. Left a non-blocking comment (not approved): Cursor Bugbot was not present, and this PR is above the low-risk approval threshold due to substantial new dashboard promo UI and account-settings behavior. Human review remains needed; reviewer already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/priority-support-promo.unit.test.ts (1)
87-103: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winCount unique selectors in the consistency guard.
selectors.lengthcounts duplicate occurrences, but the loop validatesnew Set(selectors). Repeated matches can satisfy the> 40threshold while the test checks only a small set of selectors.Proposed fix
- expect(selectors.length).toBeGreaterThan(40) - for (const selector of new Set(selectors)) + const uniqueSelectors = new Set(selectors) + expect(uniqueSelectors.size).toBeGreaterThan(40) + for (const selector of uniqueSelectors) expect(template, `${selector} must exist in the story template`).toContain(selector.slice(1))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/priority-support-promo.unit.test.ts` around lines 87 - 103, Update the selector-count assertion in the “keeps every imperative story selector connected to template markup” test to count unique selectors, matching the subsequent new Set(selectors) validation loop. Preserve the existing threshold and template-membership checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@tests/priority-support-promo.unit.test.ts`:
- Around line 87-103: Update the selector-count assertion in the “keeps every
imperative story selector connected to template markup” test to count unique
selectors, matching the subsequent new Set(selectors) validation loop. Preserve
the existing threshold and template-membership checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5e742e8f-60f8-452e-a968-e8fe031dd753
📒 Files selected for processing (3)
playwright/e2e/priority-support.spec.tssrc/components/dashboard/PrioritySupportPresentationModal.vuetests/priority-support-promo.unit.test.ts
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
Cap-go/capacitor-updater(manual)
There was a problem hiding this comment.
All reported issues were addressed across 3 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
There was a problem hiding this comment.
Stale comment
Risk: medium. Left a non-blocking comment (not approved): Cursor Bugbot was not present, and this PR is above the low-risk approval threshold due to substantial new dashboard promo UI and account-settings behavior. Human review remains needed; reviewer already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Stale comment
Risk: medium. Left a non-blocking comment (not approved): Cursor Bugbot was not present, and this PR is above the low-risk approval threshold due to substantial new dashboard promo UI and account-settings behavior. Human review remains needed; reviewer already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
There was a problem hiding this comment.
1 issue found across 5 files (changes from recent commits).
Confidence score: 4/5
- In
tests/priority-support-promo.unit.test.ts, removing regression tests that still align with current fixtures weakens protection aroundopenGeneration/stopDeckMotionand transition cancellation behavior, which could let motion/accessibility regressions slip through unnoticed. Reintroduce the dropped tests (or replace them with equivalent coverage tied to updated behavior) and document why fixture parity changed.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="tests/priority-support-promo.unit.test.ts">
<violation number="1" location="tests/priority-support-promo.unit.test.ts:22">
P2: This delta drops two regression tests that still match live implementation fixtures: the priority-support modal motion/accessibility cancellation test (symbols `openGeneration`, `stopDeckMotion`, `slideTransition`, `entranceTweens` remain in `PrioritySupportPresentationModal.vue`) and the GitHub-profile-dialog mounting test (`githubProfileDialogReady` handoff still exists in `account/index.vue`). Since the underlying behavior is unchanged, these removals silently reduce coverage for two previously fixed bug areas (accessibility state changes and dialog-before-teleport timing). If the intent was to de-brittle the white-box string matching, consider replacing them with behavior-level assertions (e.g., simulating reduced-motion/runtime misuse or verifying profile form mounts before the Teleport renders) rather than dropping coverage outright.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
There was a problem hiding this comment.
Risk: medium. Left a non-blocking comment (not approved): Cursor Bugbot was not present, and this PR is above the low-risk approval threshold due to substantial new dashboard promo UI and account-settings behavior. Human review remains needed; reviewer already assigned.
Sent by Cursor Approval Agent: Pull Request Approver External
|





Summary
Motivation
Paid and trial users already receive priority support for Capgo plugins, but the benefit is easy to miss. This experience makes the support path concrete, encourages users to report bugs and request features, and explains how linking GitHub lets Capgo recognize their issues automatically.
Business Impact
Showing the complete support loop builds confidence before users need help and increases the chance they experience fast maintainer support directly. That should strengthen trust in Capgo and improve awareness of a benefit already included in paid plans and trials.
Test Plan
bun lintbun run lint:deadcodebun typecheckTZ=UTC bun test:unit— 175 files, 1,207 tests passedCHOKIDAR_USEPOLLING=true bun run buildSummary by CodeRabbit
New Features
Bug Fixes
Tests