Skip to content

Manual edits to email capture widget#23

Merged
djanogly merged 4 commits intodevfrom
pr/email-capture-size
Mar 12, 2026
Merged

Manual edits to email capture widget#23
djanogly merged 4 commits intodevfrom
pr/email-capture-size

Conversation

@djanogly
Copy link
Contributor

@djanogly djanogly commented Mar 12, 2026

Make email collection less obtrusive, but persistent.

@djanogly djanogly requested a review from Copilot March 12, 2026 11:03
@vercel
Copy link

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
opencom-landing Ready Ready Preview, Comment Mar 12, 2026 11:33am
opencom-web Ready Ready Preview, Comment Mar 12, 2026 11:33am

@qodo-code-review
Copy link

Review Summary by Qodo

Reduce email capture widget size and improve visibility

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Reduce email capture widget padding and spacing
• Remove "Skip" button from email capture form
• Show email capture without requiring visitor message
• Adjust footer and input container spacing
Diagram
flowchart LR
  A["Email Capture Widget"] -->|"Reduce padding"| B["Smaller visual footprint"]
  A -->|"Remove Skip button"| C["Encourage email submission"]
  A -->|"Remove message requirement"| D["Show earlier in conversation"]
  B --> E["Less obtrusive UI"]
  C --> E
  D --> E
Loading

Grey Divider

File Changes

1. apps/widget/src/styles.css ✨ Enhancement +6/-4

Reduce spacing and padding throughout widget

• Adjusted .opencom-messages padding from 16px to 16px 16px 0px 16px (removed bottom padding)
• Commented out .opencom-conversation-footer gap property
• Changed .opencom-input-container padding from 12px 16px 16px to 10px
• Reduced .opencom-email-capture padding from 12px 16px to 8px 10px

apps/widget/src/styles.css


2. apps/widget/src/components/ConversationView.tsx ✨ Enhancement +1/-1

Remove message requirement for email capture

• Commented out the condition if (!hasVisitorSentMessage) return; to show email capture without
 requiring visitor to send a message first

apps/widget/src/components/ConversationView.tsx


3. apps/widget/src/components/conversationView/Footer.tsx ✨ Enhancement +2/-2

Remove skip button from email form

• Commented out the "Skip" button in the email capture form to remove the dismiss option

apps/widget/src/components/conversationView/Footer.tsx


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 12, 2026

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Unused prop fails lint🐞 Bug ⛯ Reliability
Description
ConversationFooter still destructures onEmailDismiss but the only usage (Skip button) was
commented out, violating @typescript-eslint/no-unused-vars and causing pnpm -r lint to fail.
This blocks merge/CI.
Code

apps/widget/src/components/conversationView/Footer.tsx[R130-132]

+              {/* <button onClick={onEmailDismiss} className="opencom-email-skip" type="button">
               Skip
-              </button>
+              </button> */}
Evidence
The repo ESLint config treats unused variables as an error. ConversationFooter destructures
onEmailDismiss, but the Skip button that used it is now commented out, leaving onEmailDismiss
unused and triggering a lint error.

apps/widget/src/components/conversationView/Footer.tsx[38-67]
apps/widget/src/components/conversationView/Footer.tsx[96-134]
.eslintrc.js[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`ConversationFooter` destructures `onEmailDismiss`, but the Skip button that used it is commented out. With `@typescript-eslint/no-unused-vars` set to `error`, widget lint fails.
### Issue Context
This repo’s ESLint config enforces unused-vars errors, and the root `lint` runs package lints recursively.
### Fix Focus Areas
- apps/widget/src/components/conversationView/Footer.tsx[38-67]
- apps/widget/src/components/conversationView/Footer.tsx[96-134]
- .eslintrc.js[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Email prompt undismissable 🐞 Bug ✓ Correctness
Description
The UI no longer renders any control that calls handleEmailDismiss, so users cannot dismiss email
capture without submitting an email and the opencom_email_dismissed mechanism becomes unreachable.
This can leave the email capture permanently visible for users who don’t want to provide an email.
Code

apps/widget/src/components/conversationView/Footer.tsx[R130-132]

+              {/* <button onClick={onEmailDismiss} className="opencom-email-skip" type="button">
               Skip
-              </button>
+              </button> */}
Evidence
ConversationView still defines and passes a dismiss handler that persists dismissal to
sessionStorage, but Footer no longer renders the Skip button that invokes it. Therefore dismissal
via UI is impossible even though the logic exists.

apps/widget/src/components/conversationView/Footer.tsx[96-134]
apps/widget/src/components/ConversationView.tsx[252-283]
apps/widget/src/components/ConversationView.tsx[32-41]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Email capture can no longer be dismissed because the Footer UI no longer calls `onEmailDismiss`, even though ConversationView still implements dismissal behavior.
### Issue Context
`handleEmailDismiss` persists a dismissal flag in sessionStorage (`opencom_email_dismissed`). With the Skip button removed, that path is unreachable from the UI.
### Fix Focus Areas
- apps/widget/src/components/conversationView/Footer.tsx[96-134]
- apps/widget/src/components/ConversationView.tsx[252-283]
- apps/widget/src/components/ConversationView.tsx[32-41]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Email capture triggers early🐞 Bug ✓ Correctness
Description
The smart email capture effect no longer returns when hasVisitorSentMessage is false, so
showEmailCapture can be enabled immediately on widget open before any visitor message is sent.
This undermines the intent of the hasVisitorSentMessage state and makes the prompt appear earlier
than the rest of the logic implies.
Code

apps/widget/src/components/ConversationView.tsx[R160-163]

+    // if (!hasVisitorSentMessage) return;
   if (!automationSettings?.collectEmailEnabled) return;

   const agentCount = agentMessageCount;
Evidence
hasVisitorSentMessage starts false and is only set true after sending a message; the code
previously gated email capture on that but now the guard is commented out. When
opencom_email_dismissed is not set, the effect immediately sets showEmailCapture(true)
regardless of message activity.

apps/widget/src/components/ConversationView.tsx[153-168]
apps/widget/src/components/ConversationView.tsx[32-45]
apps/widget/src/components/ConversationView.tsx[185-210]
apps/widget/src/components/ConversationView.tsx[39-41]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Email capture now shows before the visitor has sent any message because the `hasVisitorSentMessage` guard is commented out, causing early prompting.
### Issue Context
`hasVisitorSentMessage` is only set after sending a visitor message, and the effect has an early branch that shows capture whenever the dismissal flag is false.
### Fix Focus Areas
- apps/widget/src/components/ConversationView.tsx[153-183]
- apps/widget/src/components/ConversationView.tsx[185-210]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Mobile padding override 🐞 Bug ✓ Correctness
Description
The reduced .opencom-email-capture padding is overridden on small screens by an existing mobile
media query that sets a larger padding, so the “less obtrusive” sizing change won’t apply on mobile.
This makes the widget inconsistent across breakpoints.
Code

apps/widget/src/styles.css[R1023-1024]

+  padding: 8px 10px;
 background: linear-gradient(135deg, #faf5ff 0%, #ede9fe 100%);
Evidence
Base styles set .opencom-email-capture padding to 8px 10px, but the mobile media query later in
the same stylesheet overrides it to 14px 16px for max-width 480px, nullifying the change on
mobile.

apps/widget/src/styles.css[1022-1027]
apps/widget/src/styles.css[1886-1888]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Mobile CSS overrides the newly reduced email capture padding, so the change does not apply on small screens.
### Issue Context
There is an existing `@media (max-width: 480px)` rule that sets `.opencom-email-capture` padding larger than the base rule.
### Fix Focus Areas
- apps/widget/src/styles.css[1022-1027]
- apps/widget/src/styles.css[1886-1888]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@qodo-code-review
Copy link

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: checks

Failed stage: Summarize check results [❌]

Failed test name: ""

Failure summary:

The GitHub Action failed due to blocking failures in apps/widget during both linting and
typechecking:
- ESLint failed in apps/widget with exit status 1 because of an unused variable error:

- apps/widget/src/components/conversationView/Footer.tsx:53:3@typescript-eslint/no-unused-vars:
onEmailDismiss is defined but never used (allowed unused args must match /^_/u).
- This caused
ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL for @opencom/widget@0.1.0 lint (eslint src --ext .ts,.tsx).
-
TypeScript typecheck failed in apps/widget with exit status 2 due to the same unused parameter being
treated as an error:
- apps/widget/src/components/conversationView/Footer.tsx(53,3)TS6133:
onEmailDismiss is declared but its value is never read.
- This caused
ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL for @opencom/widget@0.1.0 typecheck (tsc --noEmit).
- Although
other packages reported only warnings (e.g., no-explicit-any, react-hooks/exhaustive-deps) and tests
passed, the workflow summary marked Lint (web + convex) and Typecheck (web + convex) as failed,
leading to the final job exit code 1.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

205:  packages/types lint: Warning: React version was set to "detect" in eslint-plugin-react settings, but the "react" package is not installed. Assuming latest React version for linting.
206:  packages/ui lint: Done
207:  packages/types lint: Done
208:  apps/landing lint$ next lint
209:  packages/convex lint$ eslint convex scripts tests --ext .ts
210:  apps/landing lint: `next lint` is deprecated and will be removed in Next.js 16.
211:  apps/landing lint: For new projects, use create-next-app to choose your preferred linter.
212:  apps/landing lint: For existing projects, migrate to the ESLint CLI:
213:  apps/landing lint: npx @next/codemod@canary next-lint-to-eslint-cli .
214:  packages/convex lint: Warning: React version was set to "detect" in eslint-plugin-react settings, but the "react" package is not installed. Assuming latest React version for linting.
215:  apps/landing lint:  ⚠ The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/app/api-reference/config/eslint#migrating-existing-config
216:  apps/landing lint: Attention: Next.js now collects completely anonymous telemetry regarding usage.
217:  apps/landing lint: This information is used to shape Next.js' roadmap and prioritize features.
218:  apps/landing lint: You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
219:  apps/landing lint: https://nextjs.org/telemetry
220:  apps/landing lint: ✔ No ESLint warnings or errors
221:  apps/landing lint: Done
...

376:  packages/convex lint:   90:12  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
377:  packages/convex lint: /home/runner/work/opencom/opencom/packages/convex/tests/visitorDirectoryAuthorizationSemantics.test.ts
378:  packages/convex lint:    62:81  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
379:  packages/convex lint:    74:10  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
380:  packages/convex lint:    77:81  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
381:  packages/convex lint:    91:10  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
382:  packages/convex lint:   116:13  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
383:  packages/convex lint:   138:10  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
384:  packages/convex lint:   165:13  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
385:  packages/convex lint:   187:10  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
386:  packages/convex lint:   200:65  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
387:  packages/convex lint:   215:10  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
388:  packages/convex lint:   233:65  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
389:  packages/convex lint:   254:10  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
390:  packages/convex lint:   348:65  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
391:  packages/convex lint: ✖ 146 problems (0 errors, 146 warnings)
392:  packages/convex lint: Done
393:  apps/mobile lint$ eslint . --ext .ts,.tsx
394:  apps/web lint$ eslint src --ext .ts,.tsx
395:  apps/mobile lint: /home/runner/work/opencom/opencom/apps/mobile/src/contexts/BackendContext.tsx
396:  apps/mobile lint:   33:6  warning  React Hook useEffect has a missing dependency: 'loadBackendStorage'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
397:  apps/mobile lint: ✖ 1 problem (0 errors, 1 warning)
398:  apps/mobile lint: Done
399:  apps/web lint: /home/runner/work/opencom/opencom/apps/web/src/app/login/page.test.tsx
400:  apps/web lint:   45:42  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
401:  apps/web lint: /home/runner/work/opencom/opencom/apps/web/src/app/settings/MessengerSettingsSection.test.tsx
402:  apps/web lint:   24:61  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
403:  apps/web lint: /home/runner/work/opencom/opencom/apps/web/src/app/signup/page.test.tsx
404:  apps/web lint:   42:42  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
405:  apps/web lint: /home/runner/work/opencom/opencom/apps/web/src/components/ResponsiveLayout.tsx
406:  apps/web lint:   152:6  warning  React Hook useEffect has a missing dependency: 'closePanel'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
407:  apps/web lint: /home/runner/work/opencom/opencom/apps/web/src/contexts/BackendContext.tsx
408:  apps/web lint:   86:6  warning  React Hook useEffect has a missing dependency: 'loadBackendStorage'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
409:  apps/web lint: ✖ 5 problems (0 errors, 5 warnings)
410:  apps/web lint: Done
411:  apps/widget lint$ eslint src --ext .ts,.tsx
412:  apps/widget lint: /home/runner/work/opencom/opencom/apps/widget/src/components/ConversationView.test.tsx
413:  apps/widget lint:    53:6   warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
414:  apps/widget lint:    55:32  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
415:  apps/widget lint:    71:48  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
416:  apps/widget lint:    96:74  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
417:  apps/widget lint:   265:37  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
418:  apps/widget lint:   266:35  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
419:  apps/widget lint:   284:49  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
420:  apps/widget lint: /home/runner/work/opencom/opencom/apps/widget/src/components/ConversationView.tsx
421:  apps/widget lint:   146:6  warning  React Hook useEffect has missing dependencies: 'sessionTokenRef' and 'visitorId'. Either include them or remove the dependency array  react-hooks/exhaustive-deps
422:  apps/widget lint: /home/runner/work/opencom/opencom/apps/widget/src/components/HelpCenter.tsx
423:  apps/widget lint:   149:6  warning  React Hook useEffect has a missing dependency: 'setSelectedCollectionKey'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
424:  apps/widget lint:   158:6  warning  React Hook useEffect has a missing dependency: 'setSelectedCollectionKey'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
425:  apps/widget lint: /home/runner/work/opencom/opencom/apps/widget/src/components/conversationView/Footer.tsx
426:  apps/widget lint:   53:3  error  'onEmailDismiss' is defined but never used. Allowed unused args must match /^_/u  @typescript-eslint/no-unused-vars
427:  apps/widget lint: /home/runner/work/opencom/opencom/apps/widget/src/hooks/useWidgetConversationFlow.ts
428:  apps/widget lint:   192:6  warning  React Hook useCallback has a missing dependency: 'visitorIdRef'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
429:  apps/widget lint: ✖ 12 problems (1 error, 11 warnings)
430:  apps/widget lint: Failed
431:  /home/runner/work/opencom/opencom/apps/widget:
432:  ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  @opencom/widget@0.1.0 lint: `eslint src --ext .ts,.tsx`
433:  Exit status 1
434:  ELIFECYCLE  Command failed with exit code 1.
435:  ##[error]Process completed with exit code 1.
436:  ##[group]Run pnpm typecheck
...

449:  packages/web-shared typecheck: Done
450:  packages/ui typecheck: Done
451:  apps/landing typecheck$ tsc --noEmit
452:  packages/convex typecheck$ tsc --noEmit
453:  apps/landing typecheck: Done
454:  packages/convex typecheck: Done
455:  apps/mobile typecheck$ tsc --noEmit
456:  apps/web typecheck$ tsc --noEmit
457:  packages/sdk-core typecheck$ tsc --noEmit
458:  packages/sdk-core typecheck: Done
459:  apps/mobile typecheck: Done
460:  apps/web typecheck: Done
461:  apps/widget typecheck$ tsc --noEmit
462:  packages/react-native-sdk typecheck$ tsc --noEmit
463:  packages/react-native-sdk typecheck: Done
464:  ##[error]apps/widget typecheck: src/components/conversationView/Footer.tsx(53,3): error TS6133: 'onEmailDismiss' is declared but its value is never read.
465:  apps/widget typecheck: Failed
466:  /home/runner/work/opencom/opencom/apps/widget:
467:  ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  @opencom/widget@0.1.0 typecheck: `tsc --noEmit`
468:  Exit status 2
469:  ELIFECYCLE  Command failed with exit code 2.
470:  ##[error]Process completed with exit code 2.
471:  ##[group]Run pnpm security:convex-auth-guard
...

507:  > opencom@0.1.0 security:headers-check /home/runner/work/opencom/opencom
508:  > node scripts/ci-security-headers-check.js
509:  [security-headers-check] OK: web and landing header requirements validated.
510:  ##[group]Run pnpm test:convex
511:  �[36;1mpnpm test:convex�[0m
512:  shell: /usr/bin/bash -e {0}
513:  env:
514:  PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
515:  ##[endgroup]
516:  > opencom@0.1.0 test:convex /home/runner/work/opencom/opencom
517:  > pnpm --filter @opencom/convex test
518:  > @opencom/convex@0.1.0 test /home/runner/work/opencom/opencom/packages/convex
519:  > vitest run
520:  �[1m�[46m RUN �[49m�[22m �[36mv4.0.17 �[39m�[90m/home/runner/work/opencom/opencom/packages/convex�[39m
521:  �[32m✓�[39m tests/runtimeTypeHardeningGuard.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 41�[2mms�[22m�[39m
522:  �[90mstderr�[2m | tests/aiAgentRuntimeSafety.test.ts�[2m > �[22m�[2maiAgentActions runtime safety�[2m > �[22m�[2mpersists a handoff message when generation fails
523:  �[22m�[39mAI generation error: Error: gateway timeout
524:  at �[90m/home/runner/work/opencom/opencom/packages/convex/�[39mtests/aiAgentRuntimeSafety.test.ts:592:40
525:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:145:11
526:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:915:26
527:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:1243:20
528:  at new Promise (<anonymous>)
529:  at runWithTimeout (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:1209:10)
530:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:1653:37
531:  at Traces.$ (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/vitest@4.0.17_@opentelemetry+api@1.9.0_@types+node@20.19.30_@vitest+ui@4.0.18_jiti@1.21.7_jsd_znh4lc65ld7o7n72tbcfnzmloy/node_modules/�[4mvitest�[24m/dist/chunks/traces.CCmnQaNT.js:142:27)
532:  at trace (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/vitest@4.0.17_@opentelemetry+api@1.9.0_@types+node@20.19.30_@vitest+ui@4.0.18_jiti@1.21.7_jsd_znh4lc65ld7o7n72tbcfnzmloy/node_modules/�[4mvitest�[24m/dist/chunks/test.B8ej_ZHS.js:239:21)
533:  at runTest (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:1653:12)
534:  �[90mstderr�[2m | tests/aiAgentRuntimeSafety.test.ts�[2m > �[22m�[2maiAgentActions runtime safety�[2m > �[22m�[2mfalls back to a persisted bot message if handoff fails after generation error
535:  �[22m�[39mAI generation error: Error: provider unavailable
536:  at �[90m/home/runner/work/opencom/opencom/packages/convex/�[39mtests/aiAgentRuntimeSafety.test.ts:670:40
537:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:145:11
538:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:915:26
539:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:1243:20
540:  at new Promise (<anonymous>)
541:  at runWithTimeout (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:1209:10)
542:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:1653:37
543:  at Traces.$ (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/vitest@4.0.17_@opentelemetry+api@1.9.0_@types+node@20.19.30_@vitest+ui@4.0.18_jiti@1.21.7_jsd_znh4lc65ld7o7n72tbcfnzmloy/node_modules/�[4mvitest�[24m/dist/chunks/traces.CCmnQaNT.js:142:27)
544:  at trace (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/vitest@4.0.17_@opentelemetry+api@1.9.0_@types+node@20.19.30_@vitest+ui@4.0.18_jiti@1.21.7_jsd_znh4lc65ld7o7n72tbcfnzmloy/node_modules/�[4mvitest�[24m/dist/chunks/test.B8ej_ZHS.js:239:21)
545:  at runTest (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:1653:12)
546:  �[90mstderr�[2m | tests/aiAgentRuntimeSafety.test.ts�[2m > �[22m�[2maiAgentActions runtime safety�[2m > �[22m�[2mfalls back to a persisted bot message if handoff fails after generation error
547:  �[22m�[39mFailed to handoff after AI generation error: Error: handoff unavailable
548:  at �[90m/home/runner/work/opencom/opencom/packages/convex/�[39mtests/aiAgentRuntimeSafety.test.ts:700:15
549:  at Mock (file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+spy@4.0.17/node_modules/�[4m@vitest/spy�[24m/dist/index.js:285:34)
550:  at handleGenerationFailure �[90m(/home/runner/work/opencom/opencom/packages/convex/�[39mconvex/aiAgentActions.ts:610:31�[90m)�[39m
551:  �[90m    at processTicksAndRejections (node:internal/process/task_queues:95:5)�[39m
552:  at Function.handler [as _handler] �[90m(/home/runner/work/opencom/opencom/packages/convex/�[39mconvex/aiAgentActions.ts:781:14�[90m)�[39m
553:  at �[90m/home/runner/work/opencom/opencom/packages/convex/�[39mtests/aiAgentRuntimeSafety.test.ts:711:20
554:  at file:///home/runner/work/opencom/opencom/node_modules/�[4m.pnpm�[24m/@vitest+runner@4.0.17/node_modules/�[4m@vitest/runner�[24m/dist/index.js:915:20
555:  �[32m✓�[39m tests/aiAgentRuntimeSafety.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 51�[2mms�[22m�[39m
556:  �[32m✓�[39m tests/reportingCsatEligibilitySemantics.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
557:  �[32m✓�[39m tests/visitorDirectoryAuthorizationSemantics.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
558:  �[90mstderr�[2m | tests/notificationRouting.test.ts�[2m > �[22m�[2mnotification routing�[2m > �[22m�[2mremoves invalid agent and visitor tokens after transport errors
559:  �[22m�[39m[Push] Failed to send to ExponentPushToken[agent-invalid]: DeviceNotRegistered: The device is not registered
560:  [Push] Failed to send to ExponentPushToken[visitor-invalid]: DeviceNotRegistered: The device is not registered
561:  �[32m✓�[39m tests/auditLogs.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
...

678:  + First Load JS shared by all             102 kB
679:  ├ chunks/186ceb5a-cd350ebda3c37bce.js  54.2 kB
680:  ├ chunks/5470-86efb4adbf0b2de3.js      45.8 kB
681:  └ other shared chunks (total)          1.93 kB
682:  ○  (Static)   prerendered as static content
683:  ƒ  (Dynamic)  server-rendered on demand
684:  ##[group]Run node scripts/ci-audit-gate.js
685:  �[36;1mnode scripts/ci-audit-gate.js�[0m
686:  shell: /usr/bin/bash -e {0}
687:  env:
688:  PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
689:  ##[endgroup]
690:  [audit-gate] All 2 high/critical advisories are allowlisted.
691:  - [critical] fast-xml-parser (id=1113567) allowlisted until 2026-05-31 (owner: mobile-sdk-team)
692:  - [high] fast-xml-parser (id=1113570) allowlisted until 2026-05-31 (owner: mobile-sdk-team)
693:  ##[group]Run failures=0
694:  �[36;1mfailures=0�[0m
695:  �[36;1m�[0m
696:  �[36;1mreport_blocking() {�[0m
697:  �[36;1m  name="$1"�[0m
698:  �[36;1m  outcome="$2"�[0m
699:  �[36;1m  if [ "$outcome" = "success" ]; then�[0m
700:  �[36;1m    echo "::notice::$name passed"�[0m
701:  �[36;1m  elif [ "$outcome" = "skipped" ]; then�[0m
702:  �[36;1m    echo "::warning::$name skipped"�[0m
703:  �[36;1m  else�[0m
704:  �[36;1m    echo "::error::$name failed"�[0m
705:  �[36;1m    failures=1�[0m
706:  �[36;1m  fi�[0m
707:  �[36;1m}�[0m
708:  �[36;1m�[0m
709:  �[36;1mreport_warning() {�[0m
710:  �[36;1m  name="$1"�[0m
711:  �[36;1m  outcome="$2"�[0m
712:  �[36;1m  if [ "$outcome" = "success" ]; then�[0m
713:  �[36;1m    echo "::notice::$name passed"�[0m
714:  �[36;1m  elif [ "$outcome" = "skipped" ]; then�[0m
715:  �[36;1m    echo "::warning::$name skipped"�[0m
716:  �[36;1m  else�[0m
717:  �[36;1m    echo "::warning::$name failed (warning only)"�[0m
718:  �[36;1m  fi�[0m
...

723:  �[36;1mreport_blocking "Convex raw auth guard" "success"�[0m
724:  �[36;1mreport_warning "Convex validator any guard" "success"�[0m
725:  �[36;1mreport_blocking "Secret scan gate" "success"�[0m
726:  �[36;1mreport_blocking "Security headers policy check" "success"�[0m
727:  �[36;1mreport_blocking "Convex backend tests" "success"�[0m
728:  �[36;1mreport_blocking "Web production build" "success"�[0m
729:  �[36;1mreport_blocking "Dependency audit gate" "success"�[0m
730:  �[36;1m�[0m
731:  �[36;1mif [ "$failures" -ne 0 ]; then�[0m
732:  �[36;1m  exit 1�[0m
733:  �[36;1mfi�[0m
734:  shell: /usr/bin/bash -e {0}
735:  env:
736:  PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
737:  ##[endgroup]
738:  ##[error]Lint (web + convex) failed
739:  ##[error]Typecheck (web + convex) failed
740:  ##[notice]Convex raw auth guard passed
741:  ##[notice]Convex validator any guard passed
742:  ##[notice]Secret scan gate passed
743:  ##[notice]Security headers policy check passed
744:  ##[notice]Convex backend tests passed
745:  ##[notice]Web production build passed
746:  ##[notice]Dependency audit gate passed
747:  ##[error]Process completed with exit code 1.
748:  Post job cleanup.

Comment on lines +130 to +132
{/* <button onClick={onEmailDismiss} className="opencom-email-skip" type="button">
Skip
</button>
</button> */}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Email prompt undismissable 🐞 Bug ✓ Correctness

The UI no longer renders any control that calls handleEmailDismiss, so users cannot dismiss email
capture without submitting an email and the opencom_email_dismissed mechanism becomes unreachable.
This can leave the email capture permanently visible for users who don’t want to provide an email.
Agent Prompt
### Issue description
Email capture can no longer be dismissed because the Footer UI no longer calls `onEmailDismiss`, even though ConversationView still implements dismissal behavior.

### Issue Context
`handleEmailDismiss` persists a dismissal flag in sessionStorage (`opencom_email_dismissed`). With the Skip button removed, that path is unreachable from the UI.

### Fix Focus Areas
- apps/widget/src/components/conversationView/Footer.tsx[96-134]
- apps/widget/src/components/ConversationView.tsx[252-283]
- apps/widget/src/components/ConversationView.tsx[32-41]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts the widget conversation UI to make the email capture prompt feel less visually prominent by tightening spacing and simplifying the footer layout.

Changes:

  • Tweaked padding in the messages area, input container, and email capture container.
  • Removed footer spacing (gap) between stacked footer elements.
  • Commented out the “Skip” action for email capture and relaxed the email-capture gating condition.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
apps/widget/src/styles.css Reduces padding/spacing around messages, footer, and email capture UI.
apps/widget/src/components/conversationView/Footer.tsx Removes (comments out) the email “Skip” button in the footer UI.
apps/widget/src/components/ConversationView.tsx Changes email capture eligibility behavior by removing the “visitor has sent a message” gate.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Djanogly <45178753+djanogly@users.noreply.github.com>
@djanogly djanogly merged commit 8b7fe2a into dev Mar 12, 2026
4 of 5 checks passed
@djanogly djanogly deleted the pr/email-capture-size branch March 12, 2026 11:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants