Skip to content

Refactor and modularize web inbox, notifications, and SDK components#26

Merged
djanogly merged 94 commits intomainfrom
dev
Mar 13, 2026
Merged

Refactor and modularize web inbox, notifications, and SDK components#26
djanogly merged 94 commits intomainfrom
dev

Conversation

@djanogly
Copy link
Contributor

This pull request introduces several improvements to both the codebase and developer documentation, with a focus on enhancing type safety, maintainability, and CI reliability. The most significant changes are the refactoring of Convex usage in the mobile app to use local wrapper hooks, updates to type safety guidelines and documentation, and enhancements to the CI workflow to better summarize and gate check results.

Mobile app Convex integration refactor:

Type safety and documentation:

  • Added a new "Convex Type Safety Playbook" to the documentation and updated the CONTRIBUTING.md guidelines to require usage of local Convex wrapper hooks and adapters for all new code, both in web and mobile. The guidelines now discourage direct use of generic Convex factories and promote keeping workarounds local when type errors occur. [1] [2]
  • Expanded backend and frontend guidelines to enforce the use of wrapper hooks and avoid direct convex/react imports in runtime UI modules, including for mobile.

CI workflow improvements:

  • Updated .github/workflows/ci.yml to add continue-on-error: true and id fields to each step, and introduced a new "Summarize check results" step that reports pass/fail status for each check, blocking the workflow only if critical checks fail. This provides clearer feedback and more robust gating of deployments.

Roadmap and planning updates:

  • Updated ROADMAP.md to clarify and reprioritize outstanding tasks, including CI dependencies, type safety migration, and mobile parity. Added detailed notes on Convex type safety migration hotspots and batching/performance refactor targets, as well as expanded the feature and SDK planning sections. [1] [2] [3]

These changes collectively improve developer experience, code maintainability, and project reliability.

djanogly and others added 13 commits March 11, 2026 14:29
Move and update docs
…ing-ref-factories

sdk-core string ref replacements
…al-convex-wrapper-hooks

introduce-mobile-local-convex-wrapper-hooks
* Manual edits to email capture widget (+ CI summary labels text)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Djanogly <45178753+djanogly@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…TBC) (#24)

* Add file uploads - UI needs work

* improve styling, remove Snippets button

* Update unit tests

* skip dismiss email collection test

* fallback and tweaks

* Limit filetypes

Partially completed - the upload spoofing hardening is improved, but not all the way to magic-byte sniffing. We now require an allowlisted extension from the normalized filename on both the client and backend in supportAttachments.ts (line 70) and supportAttachments.ts (line 57), and added regression coverage in supportAttachments.test.ts (line 151) and supportAttachments.test.ts (line 8). I did not add signature checks, because the current finalizeUpload boundary is a Convex mutation and ctx.storage.get() is only available in actions. Doing true magic-byte validation would need a larger refactor of that finalize flow.
* Proper AI knowledge handling with Mastra

* feat: replace legacy AI agent knowledge retrieval with Convex Vector Search

* docs: update spec to mention convex instead of mastra

* docs: archive use-convex-vector-search and update main specs

* fix: use existing Vercel AI Gateway client for embedding generation

* fix: retrieve full embedding document in aiAgentActionsKnowledge to access contentType and contentId

* working AI agent and suggestions

* Fixes for Typing gaps, unused ref, invalid vector filter chaining

Unused ref warning in packages/convex/convex/embeddings.ts
Invalid vector filter chaining in packages/convex/convex/suggestions.ts

* harden types

* update AGENTS.md
@djanogly djanogly requested a review from Copilot March 13, 2026 16:05
@vercel
Copy link

vercel bot commented Mar 13, 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 13, 2026 5:03pm
opencom-web Ready Ready Preview, Comment Mar 13, 2026 5:03pm

@qodo-code-review
Copy link

Review Summary by Qodo

Modularize Convex backend, enhance test infrastructure, and improve test reliability

✨ Enhancement 🧪 Tests 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• **Modularized Convex backend architecture**: Refactored monolithic files (testData.ts,
  series.ts, visitors.ts, testing/helpers.ts) into focused, domain-specific submodules,
  improving code organization and maintainability while preserving backward compatibility through
  re-exports
• **Enhanced test data infrastructure**: Created comprehensive E2E test data seeding mutations
  (seedTour, seedSurvey, seedCarousel, seedOutboundMessage, seedArticles, seedVisitor,
  seedSegment, seedMessengerSettings, seedAIAgentSettings) with environment-based guards
• **Improved test reliability**: Replaced implicit dialog handling with explicit confirmation button
  clicks in E2E tests (outbound.spec.ts, carousels.spec.ts), and removed conditional test data
  setup logic
• **Enhanced type safety**: Improved type consistency in diagnostics script by changing messageId
  from string | null to Id<"messages"> | null
• **Simplified test flows**: Removed redundant authentication refresh logic and replaced conditional
  test skipping with explicit assertions
• **Documentation**: Added OpenSpec changelog entry tracking architectural changes for mobile Convex
  wrapper hooks
Diagram
flowchart LR
  A["Monolithic<br/>Convex Files"] -->|Extract & Modularize| B["Domain-Specific<br/>Submodules"]
  B -->|Re-export| C["Backward Compatible<br/>Public API"]
  D["Implicit Dialog<br/>Handling"] -->|Replace with| E["Explicit UI<br/>Interactions"]
  F["Conditional Test<br/>Setup"] -->|Simplify to| G["Direct Assertions"]
  H["Generic Type<br/>Definitions"] -->|Improve to| I["Convex ID<br/>Types"]
  B --> J["Enhanced Code<br/>Organization"]
  C --> J
  E --> K["Improved Test<br/>Reliability"]
  G --> K
Loading

Grey Divider

File Changes

1. packages/convex/convex/testData.ts Refactoring +22/-3354

Modularize test data mutations into specialized submodules

• Refactored monolithic test data file by extracting mutations into modular submodules (seeds,
 cleanup, demoWorkspace, landing)
• Replaced 3300+ lines of inline mutation implementations with re-exported imports from specialized
 modules
• Maintained all 25 exported mutations with identical signatures and return types
• Improved code organization and maintainability by separating concerns into focused files

packages/convex/convex/testData.ts


2. apps/web/e2e/public-pages.spec.ts 🧪 Tests +4/-33

Remove conditional test data setup from public pages spec

• Removed test data setup logic that conditionally updated help center access policy based on admin
 secret
• Deleted imports for getPublicWorkspaceContext and updateHelpCenterAccessPolicy helper
 functions
• Removed hasAdminSecret environment variable check and conditional workspace policy update
• Added clarifying comment explaining that public help center boundary testing is covered by backend
 policy tests

apps/web/e2e/public-pages.spec.ts


3. apps/web/e2e/snippets.spec.ts 🧪 Tests +1/-3

Replace test skip with explicit assertion for auth validation

• Replaced conditional test.skip() with direct assertion on authentication result
• Changed error handling from skipping test to failing with explicit expectation
• Simplified test setup logic by removing conditional branching

apps/web/e2e/snippets.spec.ts


View more (109)
4. packages/convex/convex/testing/helpers.ts Refactoring +98/-2618

Modularize testing helpers into separate domain-specific modules

• Refactored monolithic helpers file into modular structure by extracting 2600+ lines into separate
 helper modules
• Created new helper modules for series, workspace, conversations, notifications, content, email,
 tickets, AI, cleanup, and support attachments
• Updated main file to import and re-export all helpers from their respective modules
• Maintains backward compatibility by preserving all public API exports

packages/convex/convex/testing/helpers.ts


5. packages/convex/convex/testData/seeds.ts ✨ Enhancement +682/-0

Add comprehensive E2E test data seeding mutations

• Created new file with seed mutations for E2E testing data generation
• Implemented seedTour, seedSurvey, seedCarousel, seedOutboundMessage, seedArticles,
 seedVisitor, seedSegment, seedMessengerSettings, and seedAIAgentSettings mutations
• Added requireTestDataEnabled() guard to prevent test data mutations when ALLOW_TEST_DATA
 environment variable is not set
• Exported all seed mutations as seedMutations object for organized access

packages/convex/convex/testData/seeds.ts


6. apps/web/e2e/outbound.spec.ts 🐞 Bug fix +8/-6

Replace implicit dialog handling with explicit confirmation clicks

• Replaced browser dialog handling with explicit confirmation button clicks in delete operations
• Updated "should delete message" test to click confirm button instead of relying on dialog.accept()
• Updated "Checklists" delete test to use explicit confirmation button instead of dialog handler
• Improved test reliability by using explicit UI interactions rather than implicit dialog handling

apps/web/e2e/outbound.spec.ts


7. packages/convex/scripts/trigger-ai-response-diagnostics.ts ✨ Enhancement +1/-1

Improve type safety for message ID in diagnostics script

• Changed messageId type from string | null to Id<"messages"> | null for type safety
• Improves type consistency with Convex ID system

packages/convex/scripts/trigger-ai-response-diagnostics.ts


8. packages/convex/convex/series.ts Refactoring +28/-2429

Modularize series implementation into focused submodules

• Refactored large monolithic file into modular exports from three separate submodules
• Removed ~2400 lines of implementation code (validators, helpers, and function definitions)
• Created three focused export groups: authoring operations, runtime processing, and telemetry
 tracking
• Maintains backward compatibility by re-exporting all public APIs from new modular structure

packages/convex/convex/series.ts


9. packages/convex/convex/visitors.ts Refactoring +3/-1067

Modularize visitors implementation into focused submodules

• Removed ~1070 lines of implementation code including validators, helpers, and mutation/query
 handlers
• Refactored into three focused export modules: core queries, directory queries, and mutations
• Maintains all public API surface through re-exports from new submodules
• Improves code organization and maintainability by separating concerns

packages/convex/convex/visitors.ts


10. apps/web/e2e/carousels.spec.ts 🧪 Tests +1/-4

Simplify carousel deletion test and auth flow

• Removed refreshAuthState import and its invocation from test setup
• Replaced dialog auto-accept pattern with explicit button click for confirmation
• Simplified authentication flow by removing redundant refresh state check
• Updated carousel deletion test to use explicit confirmation button interaction

apps/web/e2e/carousels.spec.ts


11. openspec/changes/archive/2026-03-11-introduce-mobile-local-convex-wrapper-hooks/.openspec.yaml 📝 Documentation +1/-0

Add OpenSpec changelog entry for mobile Convex hooks

• Added new OpenSpec changelog entry documenting mobile Convex wrapper hooks introduction
• Provides tracking for architectural changes related to mobile app integration

openspec/changes/archive/2026-03-11-introduce-mobile-local-convex-wrapper-hooks/.openspec.yaml


12. .github/workflows/ci.yml Additional files +63/-1

...

.github/workflows/ci.yml


13. AGENTS.md Additional files +565/-0

...

AGENTS.md


14. CONTRIBUTING.md Additional files +11/-1

...

CONTRIBUTING.md


15. ROADMAP.md Additional files +166/-6

...

ROADMAP.md


16. apps/mobile/app/(app)/conversation/[id].tsx Additional files +18/-36

...

apps/mobile/app/(app)/conversation/[id].tsx


17. apps/mobile/app/(app)/index.tsx Additional files +9/-34

...

apps/mobile/app/(app)/index.tsx


18. apps/mobile/app/(app)/onboarding.tsx Additional files +12/-16

...

apps/mobile/app/(app)/onboarding.tsx


19. apps/mobile/app/(app)/settings.tsx Additional files +16/-27

...

apps/mobile/app/(app)/settings.tsx


20. apps/mobile/app/_layout.tsx Additional files +2/-2

...

apps/mobile/app/_layout.tsx


21. apps/mobile/package.json Additional files +1/-1

...

apps/mobile/package.json


22. apps/mobile/src/contexts/AuthContext.tsx Additional files +13/-34

...

apps/mobile/src/contexts/AuthContext.tsx


23. apps/mobile/src/contexts/NotificationContext.tsx Additional files +14/-13

...

apps/mobile/src/contexts/NotificationContext.tsx


24. apps/mobile/src/hooks/convex/types.ts Additional files +175/-0

...

apps/mobile/src/hooks/convex/types.ts


25. apps/mobile/src/hooks/convex/useAuthConvex.ts Additional files +79/-0

...

apps/mobile/src/hooks/convex/useAuthConvex.ts


26. apps/mobile/src/hooks/convex/useConversationConvex.ts Additional files +95/-0

...

apps/mobile/src/hooks/convex/useConversationConvex.ts


27. apps/mobile/src/hooks/convex/useInboxConvex.ts Additional files +49/-0

...

apps/mobile/src/hooks/convex/useInboxConvex.ts


28. apps/mobile/src/hooks/convex/useNotificationRegistrationConvex.ts Additional files +37/-0

...

apps/mobile/src/hooks/convex/useNotificationRegistrationConvex.ts


29. apps/mobile/src/hooks/convex/useOnboardingConvex.ts Additional files +61/-0

...

apps/mobile/src/hooks/convex/useOnboardingConvex.ts


30. apps/mobile/src/hooks/convex/useSettingsConvex.ts Additional files +137/-0

...

apps/mobile/src/hooks/convex/useSettingsConvex.ts


31. apps/mobile/src/lib/convex/hooks.ts Additional files +59/-0

...

apps/mobile/src/lib/convex/hooks.ts


32. apps/mobile/src/typeHardeningGuard.test.ts Additional files +181/-0

...

apps/mobile/src/typeHardeningGuard.test.ts


33. apps/web/e2e/SKIP_REGISTRY.md Additional files +0/-2

...

apps/web/e2e/SKIP_REGISTRY.md


34. apps/web/e2e/ai-agent-settings.spec.ts Additional files +21/-18

...

apps/web/e2e/ai-agent-settings.spec.ts


35. apps/web/e2e/auth.spec.ts Additional files +5/-3

...

apps/web/e2e/auth.spec.ts


36. apps/web/e2e/csat.spec.ts Additional files +19/-12

...

apps/web/e2e/csat.spec.ts


37. apps/web/e2e/fixtures.ts Additional files +12/-1

...

apps/web/e2e/fixtures.ts


38. apps/web/e2e/helpers/auth-refresh.ts Additional files +238/-38

...

apps/web/e2e/helpers/auth-refresh.ts


39. apps/web/e2e/helpers/storage-state.ts Additional files +97/-0

...

apps/web/e2e/helpers/storage-state.ts


40. apps/web/e2e/helpers/widget-helpers.ts Additional files +84/-13

...

apps/web/e2e/helpers/widget-helpers.ts


41. apps/web/e2e/home-settings.spec.ts Additional files +63/-97

...

apps/web/e2e/home-settings.spec.ts


42. apps/web/e2e/inbox.spec.ts Additional files +33/-6

...

apps/web/e2e/inbox.spec.ts


43. apps/web/e2e/knowledge.spec.ts Additional files +50/-320

...

apps/web/e2e/knowledge.spec.ts


44. apps/web/e2e/reports.spec.ts Additional files +1/-12

...

apps/web/e2e/reports.spec.ts


45. apps/web/e2e/tooltips.spec.ts Additional files +30/-4

...

apps/web/e2e/tooltips.spec.ts


46. apps/web/e2e/widget-features.spec.ts Additional files +144/-77

...

apps/web/e2e/widget-features.spec.ts


47. apps/web/e2e/widget.spec.ts Additional files +21/-9

...

apps/web/e2e/widget.spec.ts


48. apps/web/next.config.js Additional files +1/-1

...

apps/web/next.config.js


49. apps/web/package.json Additional files +3/-3

...

apps/web/package.json


50. apps/web/src/app/articles/ArticlesImportSection.tsx Additional files +355/-0

...

apps/web/src/app/articles/ArticlesImportSection.tsx


51. apps/web/src/app/articles/ArticlesListSection.tsx Additional files +263/-0

...

apps/web/src/app/articles/ArticlesListSection.tsx


52. apps/web/src/app/articles/DeleteArticleDialog.tsx Additional files +49/-0

...

apps/web/src/app/articles/DeleteArticleDialog.tsx


53. apps/web/src/app/articles/[id]/page.test.tsx Additional files +298/-0

...

apps/web/src/app/articles/[id]/page.test.tsx


54. apps/web/src/app/articles/[id]/page.tsx Additional files +138/-46

...

apps/web/src/app/articles/[id]/page.tsx


55. apps/web/src/app/articles/articlesAdminTypes.ts Additional files +113/-0

...

apps/web/src/app/articles/articlesAdminTypes.ts


56. apps/web/src/app/articles/articlesAdminUtils.test.ts Additional files +85/-0

...

apps/web/src/app/articles/articlesAdminUtils.test.ts


57. apps/web/src/app/articles/articlesAdminUtils.ts Additional files +181/-0

...

apps/web/src/app/articles/articlesAdminUtils.ts


58. apps/web/src/app/articles/collections/page.tsx Additional files +8/-14

...

apps/web/src/app/articles/collections/page.tsx


59. apps/web/src/app/articles/hooks/useArticleCollectionsConvex.ts Additional files +60/-0

...

apps/web/src/app/articles/hooks/useArticleCollectionsConvex.ts


60. apps/web/src/app/articles/hooks/useArticleEditorConvex.ts Additional files +120/-0

...

apps/web/src/app/articles/hooks/useArticleEditorConvex.ts


61. apps/web/src/app/articles/hooks/useArticlesAdminConvex.ts Additional files +158/-0

...

apps/web/src/app/articles/hooks/useArticlesAdminConvex.ts


62. apps/web/src/app/articles/page.tsx Additional files +174/-744

...

apps/web/src/app/articles/page.tsx


63. apps/web/src/app/audit-logs/page.tsx Additional files +1/-1

...

apps/web/src/app/audit-logs/page.tsx


64. apps/web/src/app/campaigns/carousels/[id]/page.tsx Additional files +15/-29

...

apps/web/src/app/campaigns/carousels/[id]/page.tsx


65. apps/web/src/app/campaigns/email/[id]/page.tsx Additional files +7/-15

...

apps/web/src/app/campaigns/email/[id]/page.tsx


66. apps/web/src/app/campaigns/hooks/useCampaignsPageConvex.ts Additional files +156/-0

...

apps/web/src/app/campaigns/hooks/useCampaignsPageConvex.ts


67. apps/web/src/app/campaigns/hooks/useCarouselEditorConvex.ts Additional files +89/-0

...

apps/web/src/app/campaigns/hooks/useCarouselEditorConvex.ts


68. apps/web/src/app/campaigns/hooks/useEmailCampaignEditorConvex.ts Additional files +85/-0

...

apps/web/src/app/campaigns/hooks/useEmailCampaignEditorConvex.ts


69. apps/web/src/app/campaigns/hooks/usePushCampaignEditorConvex.ts Additional files +77/-0

...

apps/web/src/app/campaigns/hooks/usePushCampaignEditorConvex.ts


70. apps/web/src/app/campaigns/hooks/useSeriesEditorConvex.ts Additional files +105/-0

...

apps/web/src/app/campaigns/hooks/useSeriesEditorConvex.ts


71. apps/web/src/app/campaigns/page.tsx Additional files +22/-41

...

apps/web/src/app/campaigns/page.tsx


72. apps/web/src/app/campaigns/push/[id]/page.tsx Additional files +11/-16

...

apps/web/src/app/campaigns/push/[id]/page.tsx


73. apps/web/src/app/campaigns/series/[id]/SeriesEditorCanvas.tsx Additional files +127/-0

...

apps/web/src/app/campaigns/series/[id]/SeriesEditorCanvas.tsx


74. apps/web/src/app/campaigns/series/[id]/SeriesEditorInspector.tsx Additional files +319/-0

...

apps/web/src/app/campaigns/series/[id]/SeriesEditorInspector.tsx


75. apps/web/src/app/campaigns/series/[id]/SeriesEditorSidebar.tsx Additional files +314/-0

...

apps/web/src/app/campaigns/series/[id]/SeriesEditorSidebar.tsx


76. apps/web/src/app/campaigns/series/[id]/page.tsx Additional files +109/-870

...

apps/web/src/app/campaigns/series/[id]/page.tsx


77. apps/web/src/app/campaigns/series/[id]/seriesBlockUi.tsx Additional files +57/-0

...

apps/web/src/app/campaigns/series/[id]/seriesBlockUi.tsx


78. apps/web/src/app/campaigns/series/[id]/seriesEditorTypes.ts Additional files +138/-0

...

apps/web/src/app/campaigns/series/[id]/seriesEditorTypes.ts


79. apps/web/src/app/checklists/[id]/page.tsx Additional files +8/-43

...

apps/web/src/app/checklists/[id]/page.tsx


80. apps/web/src/app/checklists/checklistTypes.ts Additional files +46/-0

...

apps/web/src/app/checklists/checklistTypes.ts


81. apps/web/src/app/checklists/hooks/useChecklistBuilderConvex.ts Additional files +61/-0

...

apps/web/src/app/checklists/hooks/useChecklistBuilderConvex.ts


82. apps/web/src/app/checklists/hooks/useChecklistsPageConvex.ts Additional files +64/-0

...

apps/web/src/app/checklists/hooks/useChecklistsPageConvex.ts


83. apps/web/src/app/checklists/page.tsx Additional files +7/-18

...

apps/web/src/app/checklists/page.tsx


84. apps/web/src/app/help/[slug]/page.tsx Additional files +12/-21

...

apps/web/src/app/help/[slug]/page.tsx


85. apps/web/src/app/help/helpCenterLinks.ts Additional files +72/-0

...

apps/web/src/app/help/helpCenterLinks.ts


86. apps/web/src/app/help/hooks/useHelpCenterConvex.ts Additional files +159/-0

...

apps/web/src/app/help/hooks/useHelpCenterConvex.ts


87. apps/web/src/app/help/page.tsx Additional files +8/-19

...

apps/web/src/app/help/page.tsx


88. apps/web/src/app/inbox/InboxAiReviewPanel.tsx Additional files +208/-0

...

apps/web/src/app/inbox/InboxAiReviewPanel.tsx


89. apps/web/src/app/inbox/InboxConversationListPane.tsx Additional files +185/-0

...

apps/web/src/app/inbox/InboxConversationListPane.tsx


90. apps/web/src/app/inbox/InboxThreadPane.test.tsx Additional files +244/-0

...

apps/web/src/app/inbox/InboxThreadPane.test.tsx


91. apps/web/src/app/inbox/InboxThreadPane.tsx Additional files +735/-0

...

apps/web/src/app/inbox/InboxThreadPane.tsx


92. apps/web/src/app/inbox/README.md Additional files +43/-0

...

apps/web/src/app/inbox/README.md


93. apps/web/src/app/inbox/hooks/useInboxAttentionCues.test.tsx Additional files +124/-0

...

apps/web/src/app/inbox/hooks/useInboxAttentionCues.test.tsx


94. apps/web/src/app/inbox/hooks/useInboxAttentionCues.ts Additional files +172/-0

...

apps/web/src/app/inbox/hooks/useInboxAttentionCues.ts


95. apps/web/src/app/inbox/hooks/useInboxCompactPanels.test.tsx Additional files +123/-0

...

apps/web/src/app/inbox/hooks/useInboxCompactPanels.test.tsx


96. apps/web/src/app/inbox/hooks/useInboxCompactPanels.ts Additional files +90/-0

...

apps/web/src/app/inbox/hooks/useInboxCompactPanels.ts


97. apps/web/src/app/inbox/hooks/useInboxConversationListPaneConvex.ts Additional files +16/-0

...

apps/web/src/app/inbox/hooks/useInboxConversationListPaneConvex.ts


98. apps/web/src/app/inbox/hooks/useInboxConvex.ts Additional files +215/-0

...

apps/web/src/app/inbox/hooks/useInboxConvex.ts


99. apps/web/src/app/inbox/hooks/useInboxMessageActions.test.ts Additional files +49/-0

...

apps/web/src/app/inbox/hooks/useInboxMessageActions.test.ts


100. apps/web/src/app/inbox/hooks/useInboxMessageActions.ts Additional files +271/-0

...

apps/web/src/app/inbox/hooks/useInboxMessageActions.ts


101. apps/web/src/app/inbox/hooks/useInboxSelectionSync.test.tsx Additional files +143/-0

...

apps/web/src/app/inbox/hooks/useInboxSelectionSync.test.tsx


102. apps/web/src/app/inbox/hooks/useInboxSelectionSync.ts Additional files +147/-0

...

apps/web/src/app/inbox/hooks/useInboxSelectionSync.ts


103. apps/web/src/app/inbox/hooks/useInboxSuggestionsCount.ts Additional files +73/-0

...

apps/web/src/app/inbox/hooks/useInboxSuggestionsCount.ts


104. apps/web/src/app/inbox/inboxRenderTypes.ts Additional files +105/-0

...

apps/web/src/app/inbox/inboxRenderTypes.ts


105. apps/web/src/app/inbox/page.tsx Additional files +456/-1430

...

apps/web/src/app/inbox/page.tsx


106. apps/web/src/app/knowledge/internal/[id]/page.tsx Additional files +9/-307

...

apps/web/src/app/knowledge/internal/[id]/page.tsx


107. apps/web/src/app/knowledge/internal/new/page.tsx Additional files +3/-207

...

apps/web/src/app/knowledge/internal/new/page.tsx


108. apps/web/src/app/knowledge/page.tsx Additional files +2/-699

...

apps/web/src/app/knowledge/page.tsx


109. apps/web/src/app/onboarding/hooks/useOnboardingConvex.ts Additional files +73/-0

...

apps/web/src/app/onboarding/hooks/useOnboardingConvex.ts


110. apps/web/src/app/onboarding/page.tsx Additional files +8/-15

...

apps/web/src/app/onboarding/page.tsx


111. apps/web/src/app/outbound/[id]/OutboundClickActionPanel.tsx Additional files +128/-0

...

apps/web/src/app/outbound/[id]/OutboundClickActionPanel.tsx


112. Additional files not shown Additional files +0/-0

...

Additional files not shown


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 13, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (5) 📎 Requirement gaps (0)

Grey Divider


Action required

1. getInternalRef uses makeFunctionReference 📘 Rule violation ⛯ Reliability
Description
makeFunctionReference(...) is executed inside getInternalRef, so it runs per-call rather than
once at module load time. This violates the requirement to create function references at module
scope only and can introduce per-invocation overhead/instability.
Code

packages/convex/convex/testAdmin.ts[R30-32]

+function getInternalRef(name: string): unknown {
+  return makeFunctionReference(name);
+}
Evidence
PR Compliance ID 72006 requires makeFunctionReference(...) calls to occur at module scope only.
The PR adds getInternalRef() which calls makeFunctionReference(name) inside a function body,
meaning the reference is created dynamically at runtime.

Rule 72006: Create makeFunctionReference values at module scope only
packages/convex/convex/testAdmin.ts[30-32]

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

## Issue description
`makeFunctionReference(name)` is called inside `getInternalRef()`, which violates the rule that `makeFunctionReference(...)` must only be executed at module scope.
## Issue Context
This code is an admin gateway that dispatches to internal test mutations; it currently creates refs dynamically per invocation.
## Fix Focus Areas
- packages/convex/convex/testAdmin.ts[15-39]
- packages/convex/convex/testAdmin.ts[61-96]

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


2. CREATE_INVITATION_REF string ref📘 Rule violation ✓ Correctness
Description
The PR introduces a manual string-based ref via
makeFunctionReference("workspaceMembers:createInvitation") plus as unknown as casting, instead
of using generated refs. This weakens type safety and violates the required reference ordering and
unsafe-cast restrictions.
Code

packages/convex/convex/workspaceMembers.ts[R37-44]

+const CREATE_INVITATION_REF = makeFunctionReference<
+  "mutation",
+  CreateInvitationArgs,
+  CreateInvitationResult
+>("workspaceMembers:createInvitation") as unknown as InternalMutationRef<
+  CreateInvitationArgs,
+  CreateInvitationResult
+>;
Evidence
PR Compliance IDs 72008 and 96849 require preferring generated api/internal refs over manual
makeFunctionReference strings, and ID 72009 restricts as unknown as type-escape casts in runtime
code. The PR adds a module-scope manual ref and casts it with as unknown as, then uses it for
runtime mutation execution.

Rule 72008: Prefer generated backend function references over manual makeFunctionReference
Rule 96849: Standardize Convex backend function reference boundaries ordering
Rule 72009: Restrict unsafe type-escape casts in new runtime code
packages/convex/convex/workspaceMembers.ts[37-44]
packages/convex/convex/workspaceMembers.ts[400-407]

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

## Issue description
`workspaceMembers.ts` uses `makeFunctionReference(&amp;quot;workspaceMembers:createInvitation&amp;quot;)` with an `as unknown as` cast, violating the preferred generated-ref ordering and the unsafe-cast restrictions.
## Issue Context
This is backend runtime code; the compliance rules require generated `api`/`internal` refs first, and type escapes only in tightly-scoped, documented hotspots.
## Fix Focus Areas
- packages/convex/convex/workspaceMembers.ts[1-51]
- packages/convex/convex/workspaceMembers.ts[392-408]

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


3. v.any() lacks exception📘 Rule violation ⛨ Security
Description
New/modified Convex handler args include v.any() but there is no corresponding entry in
security/convex-v-any-arg-exceptions.json. This violates the requirement to document every
v.any() usage with a tracked exception record.
Code

packages/convex/convex/testing/helpers/content.ts[R213-220]

+const updateTestArticle = internalMutation({
+  args: {
+    id: v.id("articles"),
+    title: v.optional(v.string()),
+    content: v.optional(v.string()),
+    audienceRules: v.optional(v.any()),
+    widgetLargeScreen: v.optional(v.boolean()),
+  },
Evidence
PR Compliance ID 96842 requires every v.any() in changed Convex handlers to be documented in
security/convex-v-any-arg-exceptions.json. The PR introduces audienceRules: v.optional(v.any())
in a new helper module, but the exceptions file contains only an entry for testAdmin.ts and none
for this handler.

Rule 96842: Use narrow Convex validators for args; document any v.any() exceptions
packages/convex/convex/testing/helpers/content.ts[213-220]
security/convex-v-any-arg-exceptions.json[1-17]

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

## Issue description
`v.any()` is used in new/changed Convex handler args, but the required exception entries are missing from `security/convex-v-any-arg-exceptions.json`.
## Issue Context
The compliance gate requires a documented exception per `v.any()` usage.
## Fix Focus Areas
- packages/convex/convex/testing/helpers/content.ts[210-225]
- security/convex-v-any-arg-exceptions.json[1-17]

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


View more (4)
4. E2E uses class selector📘 Rule violation ⛯ Reliability
Description
The updated Playwright E2E test locates elements via CSS class selectors instead of stable
data-testid attributes. This makes tests brittle and violates the selector standardization
requirement.
Code

apps/web/e2e/widget-features.spec.ts[R127-134]

+  const widget = getWidgetContainer(page);
+  const toursTab = widget.getByTitle("Product Tours").first();
+  await expect(toursTab).toBeVisible({ timeout: 10000 });
+  await toursTab.click();
+
+  const availableTour = widget.locator(".opencom-tour-item:not([disabled])").first();
+  await expect(availableTour).toBeVisible({ timeout: 10000 });
+  await availableTour.click();
Evidence
PR Compliance ID 96850 requires E2E selectors to use data-testid instead of CSS classes/text for
element targeting. The PR adds a selector targeting .opencom-tour-item via
locator(".opencom-tour-item:not([disabled])").

Rule 96850: Use data-testid attributes for E2E test selectors
apps/web/e2e/widget-features.spec.ts[127-134]

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

## Issue description
The E2E test targets widget UI via CSS classes (e.g., `.opencom-tour-item`), which violates the requirement to use `data-testid` selectors.
## Issue Context
Class names and DOM structure are unstable and often change during refactors; `data-testid` is the required stable contract for E2E.
## Fix Focus Areas
- apps/web/e2e/widget-features.spec.ts[127-135]

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


5. requireSeriesManagePermission throws Error📘 Rule violation ⛨ Security
Description
A not-authenticated condition is signaled via throw new Error("Not authenticated") rather than the
standardized Convex error helper. This breaks consistency for auth errors and violates the required
error signaling mechanism.
Code

packages/convex/convex/series/shared.ts[R83-91]

+export async function requireSeriesManagePermission(
+  ctx: QueryCtx | MutationCtx,
+  workspaceId: Id<"workspaces">
+) {
+  const user = await getAuthenticatedUserFromSession(ctx);
+  if (!user) {
+    throw new Error("Not authenticated");
+  }
+  await requirePermission(ctx, user._id, workspaceId, "settings.workspace");
Evidence
PR Compliance ID 96869 requires using standardized helpers (throwNotAuthenticated,
throwNotFound, throwPermissionDenied) for auth/not-found/permission-denied cases. The new code
throws a generic Error for a not-authenticated case.

Rule 96869: Use standardized Convex error helpers for auth and not-found cases
packages/convex/convex/series/shared.ts[83-91]

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

## Issue description
A not-authenticated condition throws `new Error(&amp;quot;Not authenticated&amp;quot;)` instead of using the standardized Convex error helpers.
## Issue Context
Standardized error helpers are required for consistent auth/not-found/permission-denied signaling across Convex.
## Fix Focus Areas
- packages/convex/convex/series/shared.ts[83-92]

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


6. Bad validateOrigin ref🐞 Bug ✓ Correctness
Description
packages/convex/convex/http.ts creates VALIDATE_ORIGIN_REF with "workspaces.validateOrigin" (dot)
instead of the colon-separated Convex function name, so ctx.runQuery will throw and
validateOriginForWorkspace will return {valid:false}. This causes CORS-protected routes like
/geolocation to reject valid workspace requests with 403.
Code

packages/convex/convex/http.ts[R250-255]

+const VALIDATE_ORIGIN_REF = makeFunctionReference<
+  "query",
+  ValidateOriginArgs,
+  ValidateOriginResult
+>("workspaces.validateOrigin") as PublicQueryRef<ValidateOriginArgs, ValidateOriginResult>;
+
Evidence
The HTTP router uses a makeFunctionReference string that doesn’t match the established Convex
function naming convention used elsewhere in the repo (colon-separated). Because
validateOriginForWorkspace treats any runQuery error as an invalid workspace ID, this wrong
reference will systematically force origin validation to fail.

packages/convex/convex/http.ts[250-336]
packages/convex/convex/suggestions.ts[188-196]
packages/convex/convex/workspaces.ts[408-413]

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

## Issue description
`packages/convex/convex/http.ts` constructs `VALIDATE_ORIGIN_REF` using an invalid function name string (`&amp;quot;workspaces.validateOrigin&amp;quot;`). Convex function identifiers in this repo use colon-separated names (e.g. `&amp;quot;workspaces:validateOrigin&amp;quot;`), so `runQuery` will fail and origin validation will incorrectly reject requests.
### Issue Context
This breaks endpoints that call `validateOriginForWorkspace` (e.g. `/geolocation`), returning 403 for valid workspace requests.
### Fix Focus Areas
- packages/convex/convex/http.ts[250-255]

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


7. Any-args gate nonblocking 🐞 Bug ⛨ Security
Description
.github/workflows/ci.yml runs the Convex v.any() guard with continue-on-error and then reports it
via report_warning, so the job does not fail even when the gate script exits with code 1. This
allows undocumented or expired v.any() validator usage to merge without CI blocking.
Code

.github/workflows/ci.yml[R109-113]

+          report_blocking "Lint" "${{ steps.lint.outcome }}"
+          report_blocking "Typecheck" "${{ steps.typecheck.outcome }}"
+          report_blocking "Convex raw auth guard" "${{ steps.convex_auth_guard.outcome }}"
+          report_warning "Convex validator any guard" "${{ steps.convex_any_guard.outcome }}"
+          report_blocking "Secret scan gate" "${{ steps.secret_scan.outcome }}"
Evidence
The workflow explicitly routes the any-args gate outcome through a non-blocking path
(report_warning), and only report_blocking increments the failures counter that triggers exit 1.
Meanwhile, the gate script is designed to hard-fail the process on violations, so the workflow
configuration negates the intended enforcement.

.github/workflows/ci.yml[49-52]
.github/workflows/ci.yml[97-121]
scripts/ci-convex-any-args-gate.js[259-265]

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

## Issue description
The CI workflow downgrades the `pnpm security:convex-any-args-gate` step to warning-only, so violations no longer fail the `checks` job even though the script exits with code 1.
### Issue Context
This removes enforcement for the repository’s v.any() exception registry policy and allows undocumented/expired exceptions to land without CI blocking.
### Fix Focus Areas
- .github/workflows/ci.yml[49-52]
- .github/workflows/ci.yml[109-113]

ⓘ 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

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

This PR refactors multiple web/mobile feature surfaces to use local, typed Convex wrapper hooks, adds new UI/domain modules (inbox/outbound/campaigns/articles), and improves CI/E2E reliability via better gating and more resilient Playwright flows.

Changes:

  • Introduces new web feature modules + typed Convex wrapper hooks across outbound, inbox, help center, checklists, campaigns, and articles admin.
  • Adds new domain hooks/utilities + unit tests for several inbox/editor/admin utilities.
  • Hardens E2E + CI behavior (storage-state sanitization, fewer brittle selectors, and CI step summarization/gating).

Reviewed changes

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

Show a summary per file
File Description
apps/web/src/app/outbound/outboundMessageUi.tsx Adds outbound message UI helpers (options, icons, badge classes).
apps/web/src/app/outbound/hooks/useOutboundMessagesPageConvex.ts Adds typed Convex wrapper for outbound listing + mutations.
apps/web/src/app/outbound/hooks/useOutboundMessageEditorConvex.ts Adds typed Convex wrapper for outbound editor queries/mutations.
apps/web/src/app/outbound/hooks/useOutboundMessageEditorController.ts Adds controller hook coordinating editor form state + Convex calls.
apps/web/src/app/outbound/[id]/editorState.test.ts Adds Vitest coverage for editor state helpers.
apps/web/src/app/outbound/[id]/OutboundTriggerPanel.tsx Adds trigger configuration panel UI.
apps/web/src/app/outbound/[id]/OutboundStatisticsPanel.tsx Adds statistics panel UI.
apps/web/src/app/outbound/[id]/OutboundPreviewPanel.tsx Adds message preview rendering for chat/post/banner.
apps/web/src/app/outbound/[id]/OutboundFrequencyPanel.tsx Adds frequency configuration panel UI.
apps/web/src/app/outbound/[id]/OutboundFieldLabel.tsx Adds shared label component for outbound editor.
apps/web/src/app/outbound/[id]/OutboundEditorHeader.tsx Adds editor header UI (status, preview, save, activate/pause).
apps/web/src/app/outbound/[id]/OutboundClickActionPanel.tsx Adds click-action editor UI for outbound messages.
apps/web/src/app/onboarding/page.tsx Migrates onboarding page to a local Convex wrapper hook.
apps/web/src/app/onboarding/hooks/useOnboardingConvex.ts Adds typed Convex wrapper for hosted onboarding queries/mutations.
apps/web/src/app/knowledge/internal/new/page.tsx Replaces internal-article creation page with redirect to articles flow.
apps/web/src/app/inbox/inboxRenderTypes.ts Introduces shared inbox render/type contracts for hooks/components.
apps/web/src/app/inbox/hooks/useInboxSuggestionsCount.ts Adds hook to load async suggestions count (sidecar).
apps/web/src/app/inbox/hooks/useInboxSelectionSync.ts Adds hook to sync selection with URL query and reconcile list.
apps/web/src/app/inbox/hooks/useInboxSelectionSync.test.tsx Adds unit tests for selection sync + route building.
apps/web/src/app/inbox/hooks/useInboxMessageActions.test.ts Adds unit tests for optimistic last-message clearing logic.
apps/web/src/app/inbox/hooks/useInboxConvex.ts Adds typed Convex wrapper for inbox data/actions.
apps/web/src/app/inbox/hooks/useInboxConversationListPaneConvex.ts Adds typed Convex wrapper for visitor presence query.
apps/web/src/app/inbox/hooks/useInboxCompactPanels.ts Adds compact panel state machine hook for small viewports.
apps/web/src/app/inbox/hooks/useInboxCompactPanels.test.tsx Adds unit tests for compact panel behavior.
apps/web/src/app/inbox/hooks/useInboxAttentionCues.ts Adds title update + sound/notification cue orchestration.
apps/web/src/app/inbox/hooks/useInboxAttentionCues.test.tsx Adds unit tests for cue suppression + title changes.
apps/web/src/app/inbox/README.md Documents inbox orchestration module boundaries/ownership.
apps/web/src/app/inbox/InboxConversationListPane.tsx Adds conversation list pane component using new hooks/types.
apps/web/src/app/help/page.tsx Migrates help center page to local Convex wrapper hooks.
apps/web/src/app/help/hooks/useHelpCenterConvex.ts Adds typed Convex wrappers for help center page + article page.
apps/web/src/app/help/helpCenterLinks.ts Adds helpers for building help URLs and persisting workspace id.
apps/web/src/app/help/[slug]/page.tsx Migrates help article page to wrapper hooks + feedback gating.
apps/web/src/app/checklists/page.tsx Migrates checklists page to typed wrapper hook + shared types.
apps/web/src/app/checklists/hooks/useChecklistsPageConvex.ts Adds typed wrappers for checklists list/create/update/delete.
apps/web/src/app/checklists/hooks/useChecklistBuilderConvex.ts Adds typed wrappers for checklist builder queries/mutation.
apps/web/src/app/checklists/checklistTypes.ts Extracts checklist domain types to a shared module.
apps/web/src/app/checklists/[id]/page.tsx Migrates checklist builder page to wrappers + shared types.
apps/web/src/app/campaigns/series/[id]/seriesEditorTypes.ts Adds series editor domain types + parsing/date helpers.
apps/web/src/app/campaigns/series/[id]/seriesBlockUi.tsx Adds series block UI helpers (icons/colors).
apps/web/src/app/campaigns/series/[id]/SeriesEditorCanvas.tsx Adds series editor canvas rendering blocks/connections.
apps/web/src/app/campaigns/push/[id]/page.tsx Migrates push campaign editor to wrapper hook; hardens stats rendering.
apps/web/src/app/campaigns/page.tsx Migrates campaigns index to a consolidated wrapper hook.
apps/web/src/app/campaigns/hooks/useSeriesEditorConvex.ts Adds typed wrapper hook for series editor queries/mutations.
apps/web/src/app/campaigns/hooks/usePushCampaignEditorConvex.ts Adds typed wrapper hook for push campaign editor queries/mutations.
apps/web/src/app/campaigns/hooks/useEmailCampaignEditorConvex.ts Adds typed wrapper hook for email campaign editor queries/mutations.
apps/web/src/app/campaigns/hooks/useCarouselEditorConvex.ts Adds typed wrapper hook for carousel editor queries/mutations.
apps/web/src/app/campaigns/hooks/useCampaignsPageConvex.ts Adds typed wrapper hook consolidating campaigns list/actions.
apps/web/src/app/campaigns/email/[id]/page.tsx Migrates email campaign editor to wrapper hook; hardens stats rendering.
apps/web/src/app/campaigns/carousels/[id]/page.tsx Migrates carousel editor to wrapper hook; hardens stats rendering.
apps/web/src/app/audit-logs/page.tsx Fixes AuditLogViewer import path.
apps/web/src/app/articles/hooks/useArticlesAdminConvex.ts Adds typed wrapper hook for articles admin flows (import/export).
apps/web/src/app/articles/hooks/useArticleEditorConvex.ts Adds typed wrapper hook for article editor + assets management.
apps/web/src/app/articles/hooks/useArticleCollectionsConvex.ts Adds typed wrapper hook for collections admin page actions.
apps/web/src/app/articles/collections/page.tsx Migrates collections page to wrapper hook; guards articleCount usage.
apps/web/src/app/articles/articlesAdminUtils.ts Adds admin utilities for filtering + import signature building.
apps/web/src/app/articles/articlesAdminUtils.test.ts Adds Vitest coverage for filtering behavior.
apps/web/src/app/articles/articlesAdminTypes.ts Adds typed contracts for articles admin UI + import/export.
apps/web/src/app/articles/DeleteArticleDialog.tsx Adds a modal confirmation dialog component for deletes.
apps/web/package.json Updates lint command, Convex version, and adds web-shared dep.
apps/web/next.config.js Transpiles @opencom/web-shared for Next build compatibility.
apps/web/e2e/widget.spec.ts Makes widget selectors more resilient; clears volatile storage keys; skips flaky dismiss test.
apps/web/e2e/tooltips.spec.ts Improves workspace id discovery + deterministic confirm flow.
apps/web/e2e/snippets.spec.ts Converts auth guard from skip to assertion failure.
apps/web/e2e/reports.spec.ts Simplifies auth refresh usage.
apps/web/e2e/public-pages.spec.ts Removes nondeterministic restricted-boundary E2E path and documents why.
apps/web/e2e/outbound.spec.ts Moves delete confirmation to UI confirm button flow.
apps/web/e2e/inbox.spec.ts Extracts convert-to-ticket retry helper; tightens suggestions expectations.
apps/web/e2e/helpers/widget-helpers.ts Adds helper waits and improves visibility checks for tours/surveys/AI UI.
apps/web/e2e/helpers/storage-state.ts Adds sanitization utilities to remove volatile localStorage from storageState.
apps/web/e2e/fixtures.ts Refreshes auth and sanitizes storage state before/after worker contexts.
apps/web/e2e/csat.spec.ts Makes visitor identity deterministic via visitorKey + email derivation.
apps/web/e2e/carousels.spec.ts Removes redundant auth refresh; switches deletes to confirm-button flow.
apps/web/e2e/auth.spec.ts Makes signup button selection resilient to UI wording changes.
apps/web/e2e/ai-agent-settings.spec.ts Improves settings navigation + deterministic section expansion.
apps/web/e2e/SKIP_REGISTRY.md Updates skip registry entries after E2E refactors.
apps/mobile/src/typeHardeningGuard.test.ts Adds guard tests preventing direct convex/react usage outside approved boundaries.
apps/mobile/src/lib/convex/hooks.ts Adds typed mobile adapter hooks around convex/react.
apps/mobile/src/hooks/convex/useSettingsConvex.ts Adds typed wrapper hook for mobile settings flows.
apps/mobile/src/hooks/convex/useOnboardingConvex.ts Adds typed wrapper hook for mobile onboarding flows.
apps/mobile/src/hooks/convex/useNotificationRegistrationConvex.ts Adds typed wrapper hook for push token registration/debugging.
apps/mobile/src/hooks/convex/useInboxConvex.ts Adds typed wrapper hook for mobile inbox listing + presence.
apps/mobile/src/hooks/convex/useConversationConvex.ts Adds typed wrapper hook for mobile conversation thread flows.
apps/mobile/src/hooks/convex/useAuthConvex.ts Adds typed wrapper hook for mobile auth context + onboarding routing.
apps/mobile/src/hooks/convex/types.ts Adds typed mobile Convex records used by wrapper hooks and UI.
apps/mobile/src/contexts/NotificationContext.tsx Migrates to wrapper hook; memoizes debug logging helper.
apps/mobile/src/contexts/AuthContext.tsx Migrates to wrapper hooks and shared mobile Convex types.
apps/mobile/package.json Updates Convex version.
apps/mobile/app/_layout.tsx Adjusts route segment detection for auth navigation guard.
apps/mobile/app/(app)/settings.tsx Migrates to wrapper hook for settings data/actions.
apps/mobile/app/(app)/onboarding.tsx Migrates to wrapper hook for onboarding flows.
apps/mobile/app/(app)/index.tsx Migrates inbox screen to wrapper hooks + shared mobile types.
apps/mobile/app/(app)/conversation/[id].tsx Migrates conversation screen to wrapper hook + shared message type.
CONTRIBUTING.md Adds Convex type-safety playbook + updates frontend/mobile guidance.
.github/workflows/ci.yml Adds continue-on-error + summarization step that gates only critical failures.

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

Comment on lines +53 to +68
export function parseRuleText(
value: string,
label: string
): { value?: Record<string, unknown>; error?: string } {
const trimmed = value.trim();
if (!trimmed) {
return { value: undefined };
}

try {
const parsed = JSON.parse(trimmed) as Record<string, unknown>;
return { value: parsed };
} catch {
return { error: `${label} must be valid JSON.` };
}
}
Comment on lines +36 to +107
function renderPreview(
messageType: MessageType,
content: MessageContent,
postButtonForm: PostButtonFormState
) {
switch (messageType) {
case "chat":
return (
<div className="bg-white rounded-lg shadow-lg p-4 max-w-sm">
<div className="flex items-start gap-3">
<div className="w-8 h-8 rounded-full bg-primary/50 flex items-center justify-center text-white text-sm">
{content.senderId ? "A" : "B"}
</div>
<div className="flex-1">
<div className="bg-gray-100 rounded-lg p-3">
<p className="text-sm">{content.text || "Your message here..."}</p>
</div>
</div>
</div>
</div>
);

case "post": {
const postPreviewButtons = getPostPreviewButtons(postButtonForm);

return (
<div className="bg-white rounded-lg shadow-lg max-w-md overflow-hidden">
{content.imageUrl && <img src={content.imageUrl} alt="" className="w-full h-40 object-cover" />}
{content.videoUrl && (
<video src={content.videoUrl} controls className="w-full max-h-64 bg-black" />
)}
<div className="p-6">
<h3 className="text-xl font-bold mb-2">{content.title || "Title"}</h3>
<p className="text-gray-600">{content.body || "Your announcement content..."}</p>
{postPreviewButtons.length > 0 && (
<div className="mt-4 flex gap-2">
{postPreviewButtons.map((button, index) =>
button.variant === "secondary" ? (
<Button key={`${button.text}-${index}`} size="sm" variant="outline">
{button.text}
</Button>
) : (
<Button key={`${button.text}-${index}`} size="sm">
{button.text}
</Button>
)
)}
</div>
)}
</div>
</div>
);
}

case "banner":
return (
<div
className={`${content.style === "floating" ? "shadow-lg" : ""} bg-primary text-white p-3 flex items-center justify-between`}
>
<p className="text-sm font-medium">{content.text || "Your banner text..."}</p>
{content.dismissible !== false && (
<button
type="button"
className="text-white/80 hover:text-white"
aria-label="Dismiss banner"
>
x
</button>
)}
</div>
);
}
Comment on lines +17 to +36
export function getSeriesBlockIcon(type: BlockType): React.JSX.Element {
switch (type) {
case "rule":
return <Filter className="h-4 w-4" />;
case "wait":
return <Clock className="h-4 w-4" />;
case "email":
return <Mail className="h-4 w-4" />;
case "push":
return <Bell className="h-4 w-4" />;
case "chat":
return <MessageSquare className="h-4 w-4" />;
case "post":
return <MessageSquare className="h-4 w-4" />;
case "carousel":
return <GitBranch className="h-4 w-4" />;
case "tag":
return <Tag className="h-4 w-4" />;
}
}
Comment on lines +21 to +31
export function useInboxSuggestionsCount({
selectedConversationId,
isSidecarEnabled,
messageCountSignal,
getSuggestionsForConversation,
}: UseInboxSuggestionsCountArgs): UseInboxSuggestionsCountResult {
const [suggestionsCount, setSuggestionsCount] = useState(0);
const [isSuggestionsCountLoading, setIsSuggestionsCountLoading] = useState(false);

useEffect(() => {
let cancelled = false;
@qodo-code-review
Copy link

CI Feedback 🧐

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

Action: e2e

Failed stage: Playwright E2E suite [❌]

Failed test name: Web Admin - AI Agent Settings › should display AI Agent section on settings page

Failure summary:

  • The GitHub Action failed during the Playwright E2E run (pnpm playwright test) because Playwright
    could not launch Chromium: browserType.launch: Executable doesn't exist at
    /home/runner/.cache/ms-playwright/.../chrome-headless-shell.
  • This indicates the Playwright browser binaries were not downloaded/installed in the CI environment
    (Playwright suggests running pnpm exec playwright install).
  • Because the browser executable was missing, many E2E tests failed immediately (e.g.
    apps/web/e2e/ai-agent-settings.spec.ts:59:7), resulting in 137 failed and the test command exiting
    with code 1 (ELIFECYCLE Command failed with exit code 1).
  • The subsequent e2e-reliability-gate step also failed because the unexpected-failure budget is 0 and
    it observed 137 unexpected failures: [e2e-reliability-gate] unexpected exceeded threshold:
    observed=137 budget=0 allowance=0 threshold=0.
Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

217:  + @vitest/ui 4.0.17
218:  + convex 1.32.0
219:  + eslint 8.57.1
220:  + eslint-plugin-react 7.37.5
221:  + eslint-plugin-react-hooks 5.2.0
222:  + prettier 3.8.0
223:  + tsx 4.21.0
224:  + typescript 5.9.3
225:  + vitest 4.0.17
226:  + wrangler 4.66.0
227:  Done in 9s
228:  ##[group]Run missing=0
229:  �[36;1mmissing=0�[0m
230:  �[36;1mfor name in E2E_BACKEND_URL TEST_ADMIN_SECRET; do�[0m
231:  �[36;1m  if [ -z "${!name}" ]; then�[0m
232:  �[36;1m    echo "::error::Missing required secret: $name"�[0m
233:  �[36;1m    missing=1�[0m
...

259:  E2E_TEST_PASSWORD: 
260:  E2E_SUMMARY_PATH: artifacts/e2e-summary.json
261:  E2E_RELIABILITY_REPORT_PATH: artifacts/e2e-reliability-report.json
262:  E2E_RELIABILITY_BUDGET_PATH: security/e2e-reliability-budget.json
263:  E2E_RELIABILITY_ALLOWLIST_PATH: security/e2e-reliability-allowlist.json
264:  TEST_RUN_ID: ci-23059452755-1
265:  PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
266:  ##[endgroup]
267:  > opencom@0.1.0 web:test:e2e /home/runner/work/opencom/opencom
268:  > set -a; source packages/convex/.env.local; set +a; pnpm playwright test
269:  sh: 1: source: not found
270:  [WebServer] 
271:  [WebServer]  �[33m�[1m⚠�[22m�[39m The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/app/api-reference/config/eslint#migrating-existing-config
272:  Running 190 tests using 4 workers
273:  ✘    1 [chromium] › apps/web/e2e/carousels.spec.ts:87:7 › Web Admin - Carousel Management › runs deterministic activate/pause/duplicate/delete lifecycle (1ms)
274:  -    5 [chromium] › apps/web/e2e/carousels.spec.ts:137:7 › Web Admin - Carousel Management › surfaces editor validation errors for CTA URLs and deep links
275:  ✘    2 [chromium] › apps/web/e2e/ai-agent-settings.spec.ts:59:7 › Web Admin - AI Agent Settings › should display AI Agent section on settings page (2ms)
276:  ✘    3 [chromium] › apps/web/e2e/ai-agent.spec.ts:123:7 › Inbox AI deterministic workflow › shows AI-handled review metadata and deep-links to the source message (1ms)
277:  -    6 [chromium] › apps/web/e2e/ai-agent.spec.ts:170:7 › Inbox AI deterministic workflow › filters handoff conversations and shows handoff reason consistency
278:  ✘    4 [chromium] › apps/web/e2e/audit-logs.spec.ts:107:7 › Web Admin - Audit Logs › should navigate to audit logs page (2ms)
279:  -    7 [chromium] › apps/web/e2e/audit-logs.spec.ts:114:7 › Web Admin - Audit Logs › should display seeded audit entries and show detail metadata
280:  -    8 [chromium] › apps/web/e2e/audit-logs.spec.ts:143:7 › Web Admin - Audit Logs › should filter audit logs by resource type
281:  -    9 [chromium] › apps/web/e2e/audit-logs.spec.ts:176:7 › Web Admin - Audit Logs › should trigger filtered export
282:  ✘   10 [chromium] › apps/web/e2e/audit-logs.spec.ts:107:7 › Web Admin - Audit Logs › should navigate to audit logs page (retry #1) (2ms)
283:  -   14 [chromium] › apps/web/e2e/audit-logs.spec.ts:114:7 › Web Admin - Audit Logs › should display seeded audit entries and show detail metadata (retry #1)
284:  -   15 [chromium] › apps/web/e2e/audit-logs.spec.ts:143:7 › Web Admin - Audit Logs › should filter audit logs by resource type (retry #1)
285:  -   16 [chromium] › apps/web/e2e/audit-logs.spec.ts:176:7 › Web Admin - Audit Logs › should trigger filtered export (retry #1)
286:  ✘   11 [chromium] › apps/web/e2e/carousels.spec.ts:87:7 › Web Admin - Carousel Management › runs deterministic activate/pause/duplicate/delete lifecycle (retry #1) (1ms)
287:  -   17 [chromium] › apps/web/e2e/carousels.spec.ts:137:7 › Web Admin - Carousel Management › surfaces editor validation errors for CTA URLs and deep links (retry #1)
288:  ✘   13 [chromium] › apps/web/e2e/ai-agent.spec.ts:123:7 › Inbox AI deterministic workflow › shows AI-handled review metadata and deep-links to the source message (retry #1) (1ms)
289:  -   18 [chromium] › apps/web/e2e/ai-agent.spec.ts:170:7 › Inbox AI deterministic workflow › filters handoff conversations and shows handoff reason consistency (retry #1)
290:  ✘   12 [chromium] › apps/web/e2e/ai-agent-settings.spec.ts:59:7 › Web Admin - AI Agent Settings › should display AI Agent section on settings page (retry #1) (2ms)
291:  ✘   20 [chromium] › apps/web/e2e/audit-logs.spec.ts:107:7 › Web Admin - Audit Logs › should navigate to audit logs page (retry #2) (2ms)
292:  -   23 [chromium] › apps/web/e2e/audit-logs.spec.ts:114:7 › Web Admin - Audit Logs › should display seeded audit entries and show detail metadata (retry #2)
293:  -   24 [chromium] › apps/web/e2e/audit-logs.spec.ts:143:7 › Web Admin - Audit Logs › should filter audit logs by resource type (retry #2)
294:  -   25 [chromium] › apps/web/e2e/audit-logs.spec.ts:176:7 › Web Admin - Audit Logs › should trigger filtered export (retry #2)
295:  ✘   19 [chromium] › apps/web/e2e/carousels.spec.ts:87:7 › Web Admin - Carousel Management › runs deterministic activate/pause/duplicate/delete lifecycle (retry #2) (1ms)
296:  -   26 [chromium] › apps/web/e2e/carousels.spec.ts:137:7 › Web Admin - Carousel Management › surfaces editor validation errors for CTA URLs and deep links (retry #2)
297:  ✘   21 [chromium] › apps/web/e2e/ai-agent-settings.spec.ts:59:7 › Web Admin - AI Agent Settings › should display AI Agent section on settings page (retry #2) (4ms)
...

832:  ✘  560 [chromium] › apps/web/e2e/outbound.spec.ts:617:7 › Series Builder › should gate activation with readiness blockers until valid (1ms)
833:  ✘  561 [chromium] › apps/web/e2e/outbound.spec.ts:617:7 › Series Builder › should gate activation with readiness blockers until valid (retry #1) (1ms)
834:  ✘  562 [chromium] › apps/web/e2e/outbound.spec.ts:617:7 › Series Builder › should gate activation with readiness blockers until valid (retry #2) (1ms)
835:  ✘  563 [chromium] › apps/web/e2e/outbound.spec.ts:635:7 › Series Builder › should support connection authoring with explicit default branch labels (1ms)
836:  ✘  564 [chromium] › apps/web/e2e/outbound.spec.ts:635:7 › Series Builder › should support connection authoring with explicit default branch labels (retry #1) (1ms)
837:  ✘  565 [chromium] › apps/web/e2e/outbound.spec.ts:635:7 › Series Builder › should support connection authoring with explicit default branch labels (retry #2) (1ms)
838:  ✘  566 [chromium] › apps/web/e2e/outbound.spec.ts:678:7 › Series Builder › should validate global rule editors before save (1ms)
839:  ✘  567 [chromium] › apps/web/e2e/outbound.spec.ts:678:7 › Series Builder › should validate global rule editors before save (retry #1) (1ms)
840:  ✘  568 [chromium] › apps/web/e2e/outbound.spec.ts:678:7 › Series Builder › should validate global rule editors before save (retry #2) (1ms)
841:  🧹 Cleaning up E2E test environment...
842:  ℹ️ Shared test state not found; continuing cleanup via test email domain match
843:  🗑️ Deleting test data...
844:  ℹ️ No test data to clean up
845:  🎉 Teardown complete!
846:  1) [chromium] › apps/web/e2e/ai-agent-settings.spec.ts:59:7 › Web Admin - AI Agent Settings › should display AI Agent section on settings page 
847:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
848:  ╔═════════════════════════════════════════════════════════════════════════╗
849:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
850:  ║ Please run the following command to download new browsers:              ║
851:  ║                                                                         ║
852:  ║     pnpm exec playwright install                                        ║
853:  ║                                                                         ║
854:  ║ <3 Playwright Team                                                      ║
855:  ╚═════════════════════════════════════════════════════════════════════════╝
856:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
857:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
858:  ╔═════════════════════════════════════════════════════════════════════════╗
859:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
860:  ║ Please run the following command to download new browsers:              ║
861:  ║                                                                         ║
862:  ║     pnpm exec playwright install                                        ║
863:  ║                                                                         ║
864:  ║ <3 Playwright Team                                                      ║
865:  ╚═════════════════════════════════════════════════════════════════════════╝
866:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
867:  test-results/ai-agent-settings-Web-Admi-a8388-nt-section-on-settings-page-chromium-retry1/trace.zip
868:  Usage:
869:  pnpm exec playwright show-trace test-results/ai-agent-settings-Web-Admi-a8388-nt-section-on-settings-page-chromium-retry1/trace.zip
870:  ────────────────────────────────────────────────────────────────────────────────────────────────
871:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
872:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
873:  ╔═════════════════════════════════════════════════════════════════════════╗
874:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
875:  ║ Please run the following command to download new browsers:              ║
876:  ║                                                                         ║
877:  ║     pnpm exec playwright install                                        ║
878:  ║                                                                         ║
879:  ║ <3 Playwright Team                                                      ║
880:  ╚═════════════════════════════════════════════════════════════════════════╝
881:  2) [chromium] › apps/web/e2e/ai-agent-settings.spec.ts:65:7 › Web Admin - AI Agent Settings › should toggle AI agent enable/disable 
882:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
883:  ╔═════════════════════════════════════════════════════════════════════════╗
884:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
885:  ║ Please run the following command to download new browsers:              ║
886:  ║                                                                         ║
887:  ║     pnpm exec playwright install                                        ║
888:  ║                                                                         ║
889:  ║ <3 Playwright Team                                                      ║
890:  ╚═════════════════════════════════════════════════════════════════════════╝
891:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
892:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
893:  ╔═════════════════════════════════════════════════════════════════════════╗
894:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
895:  ║ Please run the following command to download new browsers:              ║
896:  ║                                                                         ║
897:  ║     pnpm exec playwright install                                        ║
898:  ║                                                                         ║
899:  ║ <3 Playwright Team                                                      ║
900:  ╚═════════════════════════════════════════════════════════════════════════╝
901:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
902:  test-results/ai-agent-settings-Web-Admi-09aa3-gle-AI-agent-enable-disable-chromium-retry1/trace.zip
903:  Usage:
904:  pnpm exec playwright show-trace test-results/ai-agent-settings-Web-Admi-09aa3-gle-AI-agent-enable-disable-chromium-retry1/trace.zip
905:  ────────────────────────────────────────────────────────────────────────────────────────────────
906:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
907:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
908:  ╔═════════════════════════════════════════════════════════════════════════╗
909:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
910:  ║ Please run the following command to download new browsers:              ║
911:  ║                                                                         ║
912:  ║     pnpm exec playwright install                                        ║
913:  ║                                                                         ║
914:  ║ <3 Playwright Team                                                      ║
915:  ╚═════════════════════════════════════════════════════════════════════════╝
916:  3) [chromium] › apps/web/e2e/ai-agent-settings.spec.ts:81:7 › Web Admin - AI Agent Settings › should save AI agent settings 
917:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
918:  ╔═════════════════════════════════════════════════════════════════════════╗
919:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
920:  ║ Please run the following command to download new browsers:              ║
921:  ║                                                                         ║
922:  ║     pnpm exec playwright install                                        ║
923:  ║                                                                         ║
924:  ║ <3 Playwright Team                                                      ║
925:  ╚═════════════════════════════════════════════════════════════════════════╝
926:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
927:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
928:  ╔═════════════════════════════════════════════════════════════════════════╗
929:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
930:  ║ Please run the following command to download new browsers:              ║
931:  ║                                                                         ║
932:  ║     pnpm exec playwright install                                        ║
933:  ║                                                                         ║
934:  ║ <3 Playwright Team                                                      ║
935:  ╚═════════════════════════════════════════════════════════════════════════╝
936:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
937:  test-results/ai-agent-settings-Web-Admi-92d18-ould-save-AI-agent-settings-chromium-retry1/trace.zip
938:  Usage:
939:  pnpm exec playwright show-trace test-results/ai-agent-settings-Web-Admi-92d18-ould-save-AI-agent-settings-chromium-retry1/trace.zip
940:  ────────────────────────────────────────────────────────────────────────────────────────────────
941:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
942:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
943:  ╔═════════════════════════════════════════════════════════════════════════╗
944:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
945:  ║ Please run the following command to download new browsers:              ║
946:  ║                                                                         ║
947:  ║     pnpm exec playwright install                                        ║
948:  ║                                                                         ║
949:  ║ <3 Playwright Team                                                      ║
950:  ╚═════════════════════════════════════════════════════════════════════════╝
951:  4) [chromium] › apps/web/e2e/ai-agent-settings.spec.ts:93:7 › Web Admin - AI Agent Settings › should display AI personality settings when enabled 
952:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
953:  ╔═════════════════════════════════════════════════════════════════════════╗
954:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
955:  ║ Please run the following command to download new browsers:              ║
956:  ║                                                                         ║
957:  ║     pnpm exec playwright install                                        ║
958:  ║                                                                         ║
959:  ║ <3 Playwright Team                                                      ║
960:  ╚═════════════════════════════════════════════════════════════════════════╝
961:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
962:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
963:  ╔═════════════════════════════════════════════════════════════════════════╗
964:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
965:  ║ Please run the following command to download new browsers:              ║
966:  ║                                                                         ║
967:  ║     pnpm exec playwright install                                        ║
968:  ║                                                                         ║
969:  ║ <3 Playwright Team                                                      ║
970:  ╚═════════════════════════════════════════════════════════════════════════╝
971:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
972:  test-results/ai-agent-settings-Web-Admi-544e7-ality-settings-when-enabled-chromium-retry1/trace.zip
973:  Usage:
974:  pnpm exec playwright show-trace test-results/ai-agent-settings-Web-Admi-544e7-ality-settings-when-enabled-chromium-retry1/trace.zip
975:  ────────────────────────────────────────────────────────────────────────────────────────────────
976:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
977:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
978:  ╔═════════════════════════════════════════════════════════════════════════╗
979:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
980:  ║ Please run the following command to download new browsers:              ║
981:  ║                                                                         ║
982:  ║     pnpm exec playwright install                                        ║
983:  ║                                                                         ║
984:  ║ <3 Playwright Team                                                      ║
985:  ╚═════════════════════════════════════════════════════════════════════════╝
986:  5) [chromium] › apps/web/e2e/ai-agent.spec.ts:123:7 › Inbox AI deterministic workflow › shows AI-handled review metadata and deep-links to the source message 
987:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
988:  ╔═════════════════════════════════════════════════════════════════════════╗
989:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
990:  ║ Please run the following command to download new browsers:              ║
991:  ║                                                                         ║
992:  ║     pnpm exec playwright install                                        ║
993:  ║                                                                         ║
994:  ║ <3 Playwright Team                                                      ║
995:  ╚═════════════════════════════════════════════════════════════════════════╝
996:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
997:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
998:  ╔═════════════════════════════════════════════════════════════════════════╗
999:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1000:  ║ Please run the following command to download new browsers:              ║
1001:  ║                                                                         ║
1002:  ║     pnpm exec playwright install                                        ║
1003:  ║                                                                         ║
1004:  ║ <3 Playwright Team                                                      ║
1005:  ╚═════════════════════════════════════════════════════════════════════════╝
1006:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1007:  test-results/ai-agent-Inbox-AI-determin-3c303-links-to-the-source-message-chromium-retry1/trace.zip
1008:  Usage:
1009:  pnpm exec playwright show-trace test-results/ai-agent-Inbox-AI-determin-3c303-links-to-the-source-message-chromium-retry1/trace.zip
1010:  ────────────────────────────────────────────────────────────────────────────────────────────────
1011:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1012:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1013:  ╔═════════════════════════════════════════════════════════════════════════╗
1014:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1015:  ║ Please run the following command to download new browsers:              ║
1016:  ║                                                                         ║
1017:  ║     pnpm exec playwright install                                        ║
1018:  ║                                                                         ║
1019:  ║ <3 Playwright Team                                                      ║
1020:  ╚═════════════════════════════════════════════════════════════════════════╝
1021:  6) [chromium] › apps/web/e2e/audit-logs.spec.ts:107:7 › Web Admin - Audit Logs › should navigate to audit logs page 
1022:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1023:  ╔═════════════════════════════════════════════════════════════════════════╗
1024:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1025:  ║ Please run the following command to download new browsers:              ║
1026:  ║                                                                         ║
1027:  ║     pnpm exec playwright install                                        ║
1028:  ║                                                                         ║
1029:  ║ <3 Playwright Team                                                      ║
1030:  ╚═════════════════════════════════════════════════════════════════════════╝
1031:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1032:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1033:  ╔═════════════════════════════════════════════════════════════════════════╗
1034:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1035:  ║ Please run the following command to download new browsers:              ║
1036:  ║                                                                         ║
1037:  ║     pnpm exec playwright install                                        ║
1038:  ║                                                                         ║
1039:  ║ <3 Playwright Team                                                      ║
1040:  ╚═════════════════════════════════════════════════════════════════════════╝
1041:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1042:  test-results/audit-logs-Web-Admin---Aud-bd280-navigate-to-audit-logs-page-chromium-retry1/trace.zip
1043:  Usage:
1044:  pnpm exec playwright show-trace test-results/audit-logs-Web-Admin---Aud-bd280-navigate-to-audit-logs-page-chromium-retry1/trace.zip
1045:  ────────────────────────────────────────────────────────────────────────────────────────────────
1046:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1047:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1048:  ╔═════════════════════════════════════════════════════════════════════════╗
1049:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1050:  ║ Please run the following command to download new browsers:              ║
1051:  ║                                                                         ║
1052:  ║     pnpm exec playwright install                                        ║
1053:  ║                                                                         ║
1054:  ║ <3 Playwright Team                                                      ║
1055:  ╚═════════════════════════════════════════════════════════════════════════╝
1056:  7) [chromium] › apps/web/e2e/carousels.spec.ts:87:7 › Web Admin - Carousel Management › runs deterministic activate/pause/duplicate/delete lifecycle 
1057:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1058:  ╔═════════════════════════════════════════════════════════════════════════╗
1059:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1060:  ║ Please run the following command to download new browsers:              ║
1061:  ║                                                                         ║
1062:  ║     pnpm exec playwright install                                        ║
1063:  ║                                                                         ║
1064:  ║ <3 Playwright Team                                                      ║
1065:  ╚═════════════════════════════════════════════════════════════════════════╝
1066:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1067:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1068:  ╔═════════════════════════════════════════════════════════════════════════╗
1069:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1070:  ║ Please run the following command to download new browsers:              ║
1071:  ║                                                                         ║
1072:  ║     pnpm exec playwright install                                        ║
1073:  ║                                                                         ║
1074:  ║ <3 Playwright Team                                                      ║
1075:  ╚═════════════════════════════════════════════════════════════════════════╝
1076:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1077:  test-results/carousels-Web-Admin---Caro-e46cf--duplicate-delete-lifecycle-chromium-retry1/trace.zip
1078:  Usage:
1079:  pnpm exec playwright show-trace test-results/carousels-Web-Admin---Caro-e46cf--duplicate-delete-lifecycle-chromium-retry1/trace.zip
1080:  ────────────────────────────────────────────────────────────────────────────────────────────────
1081:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1082:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1083:  ╔═════════════════════════════════════════════════════════════════════════╗
1084:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1085:  ║ Please run the following command to download new browsers:              ║
1086:  ║                                                                         ║
1087:  ║     pnpm exec playwright install                                        ║
1088:  ║                                                                         ║
1089:  ║ <3 Playwright Team                                                      ║
1090:  ╚═════════════════════════════════════════════════════════════════════════╝
1091:  8) [chromium] › apps/web/e2e/chat.spec.ts:153:9 › Inbox chat responsiveness › chat controls remain usable on desktop viewport 
1092:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1093:  ╔═════════════════════════════════════════════════════════════════════════╗
1094:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1095:  ║ Please run the following command to download new browsers:              ║
1096:  ║                                                                         ║
1097:  ║     pnpm exec playwright install                                        ║
1098:  ║                                                                         ║
1099:  ║ <3 Playwright Team                                                      ║
1100:  ╚═════════════════════════════════════════════════════════════════════════╝
1101:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1102:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1103:  ╔═════════════════════════════════════════════════════════════════════════╗
1104:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1105:  ║ Please run the following command to download new browsers:              ║
1106:  ║                                                                         ║
1107:  ║     pnpm exec playwright install                                        ║
1108:  ║                                                                         ║
1109:  ║ <3 Playwright Team                                                      ║
1110:  ╚═════════════════════════════════════════════════════════════════════════╝
1111:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1112:  test-results/chat-Inbox-chat-responsive-e3ec2--usable-on-desktop-viewport-chromium-retry1/trace.zip
1113:  Usage:
1114:  pnpm exec playwright show-trace test-results/chat-Inbox-chat-responsive-e3ec2--usable-on-desktop-viewport-chromium-retry1/trace.zip
1115:  ────────────────────────────────────────────────────────────────────────────────────────────────
1116:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1117:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1118:  ╔═════════════════════════════════════════════════════════════════════════╗
1119:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1120:  ║ Please run the following command to download new browsers:              ║
1121:  ║                                                                         ║
1122:  ║     pnpm exec playwright install                                        ║
1123:  ║                                                                         ║
1124:  ║ <3 Playwright Team                                                      ║
1125:  ╚═════════════════════════════════════════════════════════════════════════╝
1126:  9) [chromium] › apps/web/e2e/csat.spec.ts:137:9 › CSAT deterministic lifecycle › shows CSAT prompt interaction on desktop viewport 
1127:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1128:  ╔═════════════════════════════════════════════════════════════════════════╗
1129:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1130:  ║ Please run the following command to download new browsers:              ║
1131:  ║                                                                         ║
1132:  ║     pnpm exec playwright install                                        ║
1133:  ║                                                                         ║
1134:  ║ <3 Playwright Team                                                      ║
1135:  ╚═════════════════════════════════════════════════════════════════════════╝
1136:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1137:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1138:  ╔═════════════════════════════════════════════════════════════════════════╗
1139:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1140:  ║ Please run the following command to download new browsers:              ║
1141:  ║                                                                         ║
1142:  ║     pnpm exec playwright install                                        ║
1143:  ║                                                                         ║
1144:  ║ <3 Playwright Team                                                      ║
1145:  ╚═════════════════════════════════════════════════════════════════════════╝
1146:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1147:  test-results/csat-CSAT-deterministic-li-f6c78-raction-on-desktop-viewport-chromium-retry1/trace.zip
1148:  Usage:
1149:  pnpm exec playwright show-trace test-results/csat-CSAT-deterministic-li-f6c78-raction-on-desktop-viewport-chromium-retry1/trace.zip
1150:  ────────────────────────────────────────────────────────────────────────────────────────────────
1151:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1152:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1153:  ╔═════════════════════════════════════════════════════════════════════════╗
1154:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1155:  ║ Please run the following command to download new browsers:              ║
1156:  ║                                                                         ║
1157:  ║     pnpm exec playwright install                                        ║
1158:  ║                                                                         ║
1159:  ║ <3 Playwright Team                                                      ║
1160:  ╚═════════════════════════════════════════════════════════════════════════╝
1161:  10) [chromium] › apps/web/e2e/help-center-import.spec.ts:22:7 › Help Center Markdown Import › imports docs folder and shows articles in help center 
1162:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1163:  ╔═════════════════════════════════════════════════════════════════════════╗
1164:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1165:  ║ Please run the following command to download new browsers:              ║
1166:  ║                                                                         ║
1167:  ║     pnpm exec playwright install                                        ║
1168:  ║                                                                         ║
1169:  ║ <3 Playwright Team                                                      ║
1170:  ╚═════════════════════════════════════════════════════════════════════════╝
1171:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1172:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1173:  ╔═════════════════════════════════════════════════════════════════════════╗
1174:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1175:  ║ Please run the following command to download new browsers:              ║
1176:  ║                                                                         ║
1177:  ║     pnpm exec playwright install                                        ║
1178:  ║                                                                         ║
1179:  ║ <3 Playwright Team                                                      ║
1180:  ╚═════════════════════════════════════════════════════════════════════════╝
1181:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1182:  test-results/help-center-import-Help-Ce-36ada-ows-articles-in-help-center-chromium-retry1/trace.zip
1183:  Usage:
1184:  pnpm exec playwright show-trace test-results/help-center-import-Help-Ce-36ada-ows-articles-in-help-center-chromium-retry1/trace.zip
1185:  ────────────────────────────────────────────────────────────────────────────────────────────────
1186:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1187:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1188:  ╔═════════════════════════════════════════════════════════════════════════╗
1189:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1190:  ║ Please run the following command to download new browsers:              ║
1191:  ║                                                                         ║
1192:  ║     pnpm exec playwright install                                        ║
1193:  ║                                                                         ║
1194:  ║ <3 Playwright Team                                                      ║
1195:  ╚═════════════════════════════════════════════════════════════════════════╝
1196:  11) [chromium] › apps/web/e2e/home-settings.spec.ts:74:7 › Web Admin - Home Settings › should load home settings section on settings page 
1197:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1198:  ╔═════════════════════════════════════════════════════════════════════════╗
1199:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1200:  ║ Please run the following command to download new browsers:              ║
1201:  ║                                                                         ║
1202:  ║     pnpm exec playwright install                                        ║
1203:  ║                                                                         ║
1204:  ║ <3 Playwright Team                                                      ║
1205:  ╚═════════════════════════════════════════════════════════════════════════╝
1206:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1207:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1208:  ╔═════════════════════════════════════════════════════════════════════════╗
1209:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1210:  ║ Please run the following command to download new browsers:              ║
1211:  ║                                                                         ║
1212:  ║     pnpm exec playwright install                                        ║
1213:  ║                                                                         ║
1214:  ║ <3 Playwright Team                                                      ║
1215:  ╚═════════════════════════════════════════════════════════════════════════╝
1216:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1217:  test-results/home-settings-Web-Admin----e53d4-gs-section-on-settings-page-chromium-retry1/trace.zip
1218:  Usage:
1219:  pnpm exec playwright show-trace test-results/home-settings-Web-Admin----e53d4-gs-section-on-settings-page-chromium-retry1/trace.zip
1220:  ────────────────────────────────────────────────────────────────────────────────────────────────
1221:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1222:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1223:  ╔═════════════════════════════════════════════════════════════════════════╗
1224:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1225:  ║ Please run the following command to download new browsers:              ║
1226:  ║                                                                         ║
1227:  ║     pnpm exec playwright install                                        ║
1228:  ║                                                                         ║
1229:  ║ <3 Playwright Team                                                      ║
1230:  ╚═════════════════════════════════════════════════════════════════════════╝
1231:  12) [chromium] › apps/web/e2e/home-settings.spec.ts:79:7 › Web Admin - Home Settings › should toggle home enabled/disabled 
1232:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1233:  ╔═════════════════════════════════════════════════════════════════════════╗
1234:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1235:  ║ Please run the following command to download new browsers:              ║
1236:  ║                                                                         ║
1237:  ║     pnpm exec playwright install                                        ║
1238:  ║                                                                         ║
1239:  ║ <3 Playwright Team                                                      ║
1240:  ╚═════════════════════════════════════════════════════════════════════════╝
1241:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1242:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1243:  ╔═════════════════════════════════════════════════════════════════════════╗
1244:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1245:  ║ Please run the following command to download new browsers:              ║
1246:  ║                                                                         ║
1247:  ║     pnpm exec playwright install                                        ║
1248:  ║                                                                         ║
1249:  ║ <3 Playwright Team                                                      ║
1250:  ╚═════════════════════════════════════════════════════════════════════════╝
1251:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1252:  test-results/home-settings-Web-Admin----2a5d3-oggle-home-enabled-disabled-chromium-retry1/trace.zip
1253:  Usage:
1254:  pnpm exec playwright show-trace test-results/home-settings-Web-Admin----2a5d3-oggle-home-enabled-disabled-chromium-retry1/trace.zip
1255:  ────────────────────────────────────────────────────────────────────────────────────────────────
1256:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1257:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1258:  ╔═════════════════════════════════════════════════════════════════════════╗
1259:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1260:  ║ Please run the following command to download new browsers:              ║
1261:  ║                                                                         ║
1262:  ║     pnpm exec playwright install                                        ║
1263:  ║                                                                         ║
1264:  ║ <3 Playwright Team                                                      ║
1265:  ╚═════════════════════════════════════════════════════════════════════════╝
1266:  13) [chromium] › apps/web/e2e/home-settings.spec.ts:86:7 › Web Admin - Home Settings › should add a card to home configuration 
1267:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1268:  ╔═════════════════════════════════════════════════════════════════════════╗
1269:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1270:  ║ Please run the following command to download new browsers:              ║
1271:  ║                                                                         ║
1272:  ║     pnpm exec playwright install                                        ║
1273:  ║                                                                         ║
1274:  ║ <3 Playwright Team                                                      ║
1275:  ╚═════════════════════════════════════════════════════════════════════════╝
1276:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1277:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1278:  ╔═════════════════════════════════════════════════════════════════════════╗
1279:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1280:  ║ Please run the following command to download new browsers:              ║
1281:  ║                                                                         ║
1282:  ║     pnpm exec playwright install                                        ║
1283:  ║                                                                         ║
1284:  ║ <3 Playwright Team                                                      ║
1285:  ╚═════════════════════════════════════════════════════════════════════════╝
1286:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1287:  test-results/home-settings-Web-Admin----50ca2--card-to-home-configuration-chromium-retry1/trace.zip
1288:  Usage:
1289:  pnpm exec playwright show-trace test-results/home-settings-Web-Admin----50ca2--card-to-home-configuration-chromium-retry1/trace.zip
1290:  ────────────────────────────────────────────────────────────────────────────────────────────────
1291:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1292:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1293:  ╔═════════════════════════════════════════════════════════════════════════╗
1294:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1295:  ║ Please run the following command to download new browsers:              ║
1296:  ║                                                                         ║
1297:  ║     pnpm exec playwright install                                        ║
1298:  ║                                                                         ║
1299:  ║ <3 Playwright Team                                                      ║
1300:  ╚═════════════════════════════════════════════════════════════════════════╝
1301:  14) [chromium] › apps/web/e2e/home-settings.spec.ts:106:7 › Web Admin - Home Settings › should change card visibility setting 
1302:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1303:  ╔═════════════════════════════════════════════════════════════════════════╗
1304:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1305:  ║ Please run the following command to download new browsers:              ║
1306:  ║                                                                         ║
1307:  ║     pnpm exec playwright install                                        ║
1308:  ║                                                                         ║
1309:  ║ <3 Playwright Team                                                      ║
1310:  ╚═════════════════════════════════════════════════════════════════════════╝
1311:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1312:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1313:  ╔═════════════════════════════════════════════════════════════════════════╗
1314:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1315:  ║ Please run the following command to download new browsers:              ║
1316:  ║                                                                         ║
1317:  ║     pnpm exec playwright install                                        ║
1318:  ║                                                                         ║
1319:  ║ <3 Playwright Team                                                      ║
1320:  ╚═════════════════════════════════════════════════════════════════════════╝
1321:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1322:  test-results/home-settings-Web-Admin----43b05-nge-card-visibility-setting-chromium-retry1/trace.zip
1323:  Usage:
1324:  pnpm exec playwright show-trace test-results/home-settings-Web-Admin----43b05-nge-card-visibility-setting-chromium-retry1/trace.zip
1325:  ────────────────────────────────────────────────────────────────────────────────────────────────
1326:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1327:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1328:  ╔═════════════════════════════════════════════════════════════════════════╗
1329:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1330:  ║ Please run the following command to download new browsers:              ║
1331:  ║                                                                         ║
1332:  ║     pnpm exec playwright install                                        ║
1333:  ║                                                                         ║
1334:  ║ <3 Playwright Team                                                      ║
1335:  ╚═════════════════════════════════════════════════════════════════════════╝
1336:  15) [chromium] › apps/web/e2e/home-settings.spec.ts:123:7 › Web Admin - Home Settings › should save home settings 
1337:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1338:  ╔═════════════════════════════════════════════════════════════════════════╗
1339:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1340:  ║ Please run the following command to download new browsers:              ║
1341:  ║                                                                         ║
1342:  ║     pnpm exec playwright install                                        ║
1343:  ║                                                                         ║
1344:  ║ <3 Playwright Team                                                      ║
1345:  ╚═════════════════════════════════════════════════════════════════════════╝
1346:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1347:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1348:  ╔═════════════════════════════════════════════════════════════════════════╗
1349:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1350:  ║ Please run the following command to download new browsers:              ║
1351:  ║                                                                         ║
1352:  ║     pnpm exec playwright install                                        ║
1353:  ║                                                                         ║
1354:  ║ <3 Playwright Team                                                      ║
1355:  ╚═════════════════════════════════════════════════════════════════════════╝
1356:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1357:  test-results/home-settings-Web-Admin----ee8d0-s-should-save-home-settings-chromium-retry1/trace.zip
1358:  Usage:
1359:  pnpm exec playwright show-trace test-results/home-settings-Web-Admin----ee8d0-s-should-save-home-settings-chromium-retry1/trace.zip
1360:  ────────────────────────────────────────────────────────────────────────────────────────────────
1361:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1362:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1363:  ╔═════════════════════════════════════════════════════════════════════════╗
1364:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1365:  ║ Please run the following command to download new browsers:              ║
1366:  ║                                                                         ║
1367:  ║     pnpm exec playwright install                                        ║
1368:  ║                                                                         ║
1369:  ║ <3 Playwright Team                                                      ║
1370:  ╚═════════════════════════════════════════════════════════════════════════╝
1371:  16) [chromium] › apps/web/e2e/home-settings.spec.ts:139:7 › Web Admin - Home Settings › should show home preview when cards are added 
1372:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1373:  ╔═════════════════════════════════════════════════════════════════════════╗
1374:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1375:  ║ Please run the following command to download new browsers:              ║
1376:  ║                                                                         ║
1377:  ║     pnpm exec playwright install                                        ║
1378:  ║                                                                         ║
1379:  ║ <3 Playwright Team                                                      ║
1380:  ╚═════════════════════════════════════════════════════════════════════════╝
1381:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1382:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1383:  ╔═════════════════════════════════════════════════════════════════════════╗
1384:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1385:  ║ Please run the following command to download new browsers:              ║
1386:  ║                                                                         ║
1387:  ║     pnpm exec playwright install                                        ║
1388:  ║                                                                         ║
1389:  ║ <3 Playwright Team                                                      ║
1390:  ╚═════════════════════════════════════════════════════════════════════════╝
1391:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1392:  test-results/home-settings-Web-Admin----e0e23-review-when-cards-are-added-chromium-retry1/trace.zip
1393:  Usage:
1394:  pnpm exec playwright show-trace test-results/home-settings-Web-Admin----e0e23-review-when-cards-are-added-chromium-retry1/trace.zip
1395:  ────────────────────────────────────────────────────────────────────────────────────────────────
1396:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1397:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1398:  ╔═════════════════════════════════════════════════════════════════════════╗
1399:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1400:  ║ Please run the following command to download new browsers:              ║
1401:  ║                                                                         ║
1402:  ║     pnpm exec playwright install                                        ║
1403:  ║                                                                         ║
1404:  ║ <3 Playwright Team                                                      ║
1405:  ╚═════════════════════════════════════════════════════════════════════════╝
1406:  17) [chromium] › apps/web/e2e/identity-verification.spec.ts:8:7 › Identity Verification Flow › should display security settings section 
1407:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1408:  ╔═════════════════════════════════════════════════════════════════════════╗
1409:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1410:  ║ Please run the following command to download new browsers:              ║
1411:  ║                                                                         ║
1412:  ║     pnpm exec playwright install                                        ║
1413:  ║                                                                         ║
1414:  ║ <3 Playwright Team                                                      ║
1415:  ╚═════════════════════════════════════════════════════════════════════════╝
1416:  Retry #1 ───────────────────────────────────────────────────────────────────────────────────────
1417:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1418:  ╔═════════════════════════════════════════════════════════════════════════╗
1419:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1420:  ║ Please run the following command to download new browsers:              ║
1421:  ║                                                                         ║
1422:  ║     pnpm exec playwright install                                        ║
1423:  ║                                                                         ║
1424:  ║ <3 Playwright Team                                                      ║
1425:  ╚═════════════════════════════════════════════════════════════════════════╝
1426:  attachment #1: trace (application/zip) ─────────────────────────────────────────────────────────
1427:  test-results/identity-verification-Iden-98297-y-security-settings-section-chromium-retry1/trace.zip
1428:  Usage:
1429:  pnpm exec playwright show-trace test-results/identity-verification-Iden-98297-y-security-settings-section-chromium-retry1/trace.zip
1430:  ────────────────────────────────────────────────────────────────────────────────────────────────
1431:  Retry #2 ───────────────────────────────────────────────────────────────────────────────────────
1432:  Error: browserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell
1433:  ╔═════════════════════════════════════════════════════════════════════════╗
1434:  ║ Looks like Playwright Test or Playwright was just installed or updated. ║
1435:  ║ Please run the following command to download new browsers:              ║
1436:  ║                                                                         ║
1437:  ║     pnpm exec playwright install          ...

Comment on lines +30 to +32
function getInternalRef(name: string): unknown {
return makeFunctionReference(name);
}

Choose a reason for hiding this comment

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

Action required

1. getinternalref uses makefunctionreference 📘 Rule violation ⛯ Reliability

makeFunctionReference(...) is executed inside getInternalRef, so it runs per-call rather than
once at module load time. This violates the requirement to create function references at module
scope only and can introduce per-invocation overhead/instability.
Agent Prompt
## Issue description
`makeFunctionReference(name)` is called inside `getInternalRef()`, which violates the rule that `makeFunctionReference(...)` must only be executed at module scope.

## Issue Context
This code is an admin gateway that dispatches to internal test mutations; it currently creates refs dynamically per invocation.

## Fix Focus Areas
- packages/convex/convex/testAdmin.ts[15-39]
- packages/convex/convex/testAdmin.ts[61-96]

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

Comment on lines +109 to +113
report_blocking "Lint" "${{ steps.lint.outcome }}"
report_blocking "Typecheck" "${{ steps.typecheck.outcome }}"
report_blocking "Convex raw auth guard" "${{ steps.convex_auth_guard.outcome }}"
report_warning "Convex validator any guard" "${{ steps.convex_any_guard.outcome }}"
report_blocking "Secret scan gate" "${{ steps.secret_scan.outcome }}"

Choose a reason for hiding this comment

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

Action required

7. Any-args gate nonblocking 🐞 Bug ⛨ Security

.github/workflows/ci.yml runs the Convex v.any() guard with continue-on-error and then reports it
via report_warning, so the job does not fail even when the gate script exits with code 1. This
allows undocumented or expired v.any() validator usage to merge without CI blocking.
Agent Prompt
### Issue description
The CI workflow downgrades the `pnpm security:convex-any-args-gate` step to warning-only, so violations no longer fail the `checks` job even though the script exits with code 1.

### Issue Context
This removes enforcement for the repository’s v.any() exception registry policy and allows undocumented/expired exceptions to land without CI blocking.

### Fix Focus Areas
- .github/workflows/ci.yml[49-52]
- .github/workflows/ci.yml[109-113]

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

@djanogly djanogly merged commit 27568d1 into main Mar 13, 2026
3 of 4 checks passed
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