-
-
Notifications
You must be signed in to change notification settings - Fork 700
AI dashboard widget + CLI AI generate fix suggestions #1925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
# Conflicts: # apps/webapp/app/components/navigation/SideMenu.tsx
🦋 Changeset detectedLatest commit: 2b74932 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughThis set of changes introduces AI-assisted help integration across both the web application and CLI tools. In the web app, new components, hooks, and context providers are added to enable an AI help widget, shortcut management, and context-aware keyboard shortcuts. The side menu now offers direct AI assistance, and shortcut sheets are refactored for modularity and auto-opening. On the CLI side, error handling is enhanced: build failures and worker errors now generate terminal links for AI-powered troubleshooting, with a new error class and event bus event for build failures. Several UI icons and layouts receive updates, and workspace dependency references are adjusted in a sample package. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SideMenu
participant HelpAndAI
participant useKapaWidget
participant KapaWidget
User->>SideMenu: Clicks AI Help button or presses shortcut
SideMenu->>HelpAndAI: Renders AI Help UI
HelpAndAI->>useKapaWidget: Calls openKapa(query)
useKapaWidget->>KapaWidget: Opens widget in AI mode with query
KapaWidget-->>User: Displays AI assistance interface
sequenceDiagram
participant CLI_User
participant CLI
participant Bundle
participant EventBus
participant aiHelpLink
CLI_User->>CLI: Runs build/dev command
CLI->>Bundle: Executes bundleWorker
Bundle-->>CLI: Throws BundleError on failure
CLI->>EventBus: Emits buildFailed event
EventBus->>aiHelpLink: Calls with error details
aiHelpLink-->>CLI_User: Prints AI help link in terminal
Possibly related PRs
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (2)
apps/webapp/app/components/navigation/SideMenu.tsx (1)
548-599
: Remove console.log statement from production code.There's a console.log statement in the HelpAndAI component that should be removed before deployment.
- console.log("aiHelp", aiHelp);
apps/webapp/app/components/primitives/ShortcutKey.tsx (1)
64-68
: Consider standardizing ternary expression formattingFor consistency with other modifiers, consider using the same ternary formatting style throughout the file.
- return isMac ? ( - <KeyboardEnterIcon className={className} /> - ) : ( - <span className="capitalize">Enter</span> - ); + return isMac ? <KeyboardEnterIcon className={className} /> : <span className="capitalize">Enter</span>;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (25)
.changeset/red-chairs-begin.md
(1 hunks)apps/webapp/app/assets/icons/AISparkleIcon.tsx
(1 hunks)apps/webapp/app/assets/icons/KeyboardEnterIcon.tsx
(1 hunks)apps/webapp/app/components/Shortcuts.tsx
(2 hunks)apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx
(2 hunks)apps/webapp/app/components/navigation/SideMenu.tsx
(5 hunks)apps/webapp/app/components/primitives/Buttons.tsx
(3 hunks)apps/webapp/app/components/primitives/ShortcutKey.tsx
(2 hunks)apps/webapp/app/components/primitives/ShortcutsProvider.tsx
(1 hunks)apps/webapp/app/env.server.ts
(1 hunks)apps/webapp/app/hooks/useKapaWidget.tsx
(1 hunks)apps/webapp/app/hooks/useShortcutKeys.tsx
(2 hunks)apps/webapp/app/root.tsx
(6 hunks)apps/webapp/app/routes/projects.$projectRef.ai-help.ts
(1 hunks)apps/webapp/app/routes/resources.kapa-widget.ts
(1 hunks)apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new.natural-language.tsx
(2 hunks)apps/webapp/app/routes/storybook.shortcuts/route.tsx
(3 hunks)packages/cli-v3/src/build/bundle.ts
(2 hunks)packages/cli-v3/src/cli/common.ts
(3 hunks)packages/cli-v3/src/commands/dev.ts
(2 hunks)packages/cli-v3/src/dev/devOutput.ts
(7 hunks)packages/cli-v3/src/dev/devSession.ts
(2 hunks)packages/cli-v3/src/utilities/cliOutput.ts
(1 hunks)packages/cli-v3/src/utilities/eventBus.ts
(1 hunks)references/hello-world/package.json
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (10)
apps/webapp/app/components/primitives/ShortcutKey.tsx (1)
apps/webapp/app/assets/icons/KeyboardEnterIcon.tsx (1)
KeyboardEnterIcon
(1-12)
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new.natural-language.tsx (1)
apps/webapp/app/assets/icons/AISparkleIcon.tsx (1)
AISparkleIcon
(1-31)
apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx (2)
apps/webapp/app/routes/_app.orgs.$organizationSlug/route.tsx (1)
useCurrentPlan
(23-30)apps/webapp/app/components/primitives/Popover.tsx (2)
Popover
(202-202)PopoverSideMenuTrigger
(208-208)
apps/webapp/app/hooks/useKapaWidget.tsx (4)
apps/webapp/app/root.tsx (1)
loader
(48-70)apps/webapp/app/hooks/useFeatures.ts (1)
useFeatures
(5-9)apps/webapp/app/components/primitives/ShortcutsProvider.tsx (1)
useShortcuts
(37-39)apps/webapp/app/hooks/useSearchParam.ts (1)
useSearchParams
(7-82)
apps/webapp/app/routes/storybook.shortcuts/route.tsx (2)
apps/webapp/app/components/primitives/ShortcutsProvider.tsx (1)
useShortcuts
(37-39)apps/webapp/app/components/primitives/Buttons.tsx (1)
Button
(294-327)
packages/cli-v3/src/dev/devOutput.ts (3)
packages/cli-v3/src/utilities/eventBus.ts (2)
EventBusEventArgs
(24-24)eventBus
(26-26)packages/cli-v3/src/build/bundle.ts (1)
BundleError
(54-61)packages/cli-v3/src/utilities/cliOutput.ts (2)
aiHelpLink
(119-138)prettyError
(73-94)
apps/webapp/app/hooks/useShortcutKeys.tsx (1)
apps/webapp/app/components/primitives/ShortcutsProvider.tsx (1)
useShortcuts
(37-39)
apps/webapp/app/routes/resources.kapa-widget.ts (1)
apps/webapp/app/root.tsx (1)
loader
(48-70)
packages/cli-v3/src/dev/devSession.ts (2)
packages/cli-v3/src/build/bundle.ts (1)
bundleWorker
(63-168)packages/cli-v3/src/utilities/eventBus.ts (1)
eventBus
(26-26)
packages/cli-v3/src/cli/common.ts (2)
packages/core/src/v3/apiClient/stream.ts (1)
e
(210-216)packages/cli-v3/src/build/bundle.ts (1)
BundleError
(54-61)
🪛 Biome (1.9.4)
apps/webapp/app/hooks/useKapaWidget.tsx
[error] 39-39: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🔇 Additional comments (66)
references/hello-world/package.json (2)
6-6
: Workspace protocol for devDependency
Switchingtrigger.dev
toworkspace:*
ensures this example project consumes the local CLI package during development, keeping it in sync with the monorepo.
9-9
: Workspace protocol for runtime dependency
Updating@trigger.dev/sdk
toworkspace:*
aligns the example with the locally built SDK, avoiding drift from published versions.apps/webapp/app/env.server.ts (1)
717-719
: Added Kapa AI integration environment variable.The addition of the
KAPA_AI_WEBSITE_ID
environment variable follows the project's pattern for defining optional configuration variables and will be used to configure the Kapa AI widget throughout the application.packages/cli-v3/src/utilities/eventBus.ts (1)
14-14
: Added build failure event for AI assistance integration.The new
buildFailed
event type follows the existing pattern and will enable the CLI to emit build failure events that can be used to generate AI-powered help links when build errors occur.apps/webapp/app/assets/icons/KeyboardEnterIcon.tsx (1)
1-12
: Clean implementation of keyboard Enter key icon.The SVG implementation uses current color for stroke and fill which allows it to inherit color from CSS, making it flexible for different UI themes and states.
apps/webapp/app/assets/icons/AISparkleIcon.tsx (2)
3-10
: Improved SVG dimensions and structure.The icon dimensions have been updated from 18x18 to 24x24 with explicit width and height attributes, which will ensure consistent rendering across the application.
11-28
: Enhanced path styling with solid colors.Replaced gradient fills with solid colors and added fillRule/clipRule attributes, which simplifies the SVG structure and may improve rendering performance.
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new.natural-language.tsx (4)
86-87
: Improved icon styling with modern class notationThe change from fixed dimensions (
h-4 w-4
) to the more concisesize-4
utility class is a good modernization that maintains the same visual appearance while using Tailwind's newer syntax.
90-91
: Enhanced container styling with better spacing and border radiusAdding
mt-1
provides appropriate spacing between the label and input field, while changing fromrounded-sm
torounded
creates a slightly more noticeable border radius that improves visual consistency with other form elements.
93-93
: Improved inner container styling with overflow controlThe addition of
overflow-hidden
properly contains the child elements, preventing any potential content spillover, while the change torounded-sm
simplifies the border radius implementation.
108-109
: Enhanced button spacing for better visual balanceThe additional left padding (
pl-1.5
) and increased icon spacing (gap-1.5
) improve the visual balance between the icon and text, creating a more polished appearance for the generate button..changeset/red-chairs-begin.md (1)
1-5
: Properly documented AI assistance feature in changesetThe changeset correctly documents the addition of AI assistance links for build errors, which aligns with the code changes in the CLI to support error handling and AI help generation. This ensures proper version tracking for the feature.
packages/cli-v3/src/commands/dev.ts (2)
4-9
: Enhanced error handling with additional importsThe restructured import statement now includes
SkipLoggingError
, which supports the improved error handling for build failures mentioned in the changeset.
20-20
: Added BundleError import for build failure handlingThe import of
BundleError
supports capturing build failures during the development process, enabling the CLI to provide AI-powered assistance when builds fail. This is a key component of the feature described in the changeset.apps/webapp/app/components/primitives/Buttons.tsx (3)
180-180
: Added option to hide shortcut keys in buttonsThe new
hideShortcutKey
boolean prop gives developers more control over button rendering, supporting use cases where shortcut indicators should be conditionally hidden.
196-197
: Destructured the hideShortcutKey prop for use in the componentCorrectly added the new prop to the destructuring pattern, making it available for use in the component's rendering logic.
207-208
: Updated shortcut key rendering conditionThe rendering condition now properly checks both for the existence of a shortcut and that the shortcut display isn't explicitly hidden, providing more flexible control over the UI.
packages/cli-v3/src/cli/common.ts (2)
12-12
: Appropriate import for the new error handlingThe import of the newly created
BundleError
class is necessary for the error handling updates in this file.
58-58
: Improved type accuracyThe return type now includes
undefined
to properly reflect that the function might not return a value when process.exit() is called during a BundleError.packages/cli-v3/src/utilities/cliOutput.ts (1)
119-138
: Looks good - clean implementation of the AI help link generator.The
aiHelpLink
function effectively builds a URL for the AI help feature while taking proper precautions with the query parameter length.packages/cli-v3/src/dev/devSession.ts (1)
176-203
: Good error handling implementation.The try-catch block ensures that build failures are properly reported through the event bus while still letting the error propagate up. This effectively integrates with the new AI help feature.
apps/webapp/app/components/navigation/HelpAndFeedbackPopover.tsx (2)
7-7
: Icon update and import addition look good.The import changes are correctly implemented to support the updated UI components.
Also applies to: 15-15
26-42
: Good implementation of shortcut disabling feature.The component now properly handles disabling shortcuts based on the new
disableShortcut
prop, and the updated icon provides better visual consistency. The shortcut configuration withenabledOnInputElements: false
is appropriate to prevent shortcuts from triggering when users are typing in form fields.apps/webapp/app/routes/storybook.shortcuts/route.tsx (3)
1-7
: Correct imports added for the new shortcut management functionality.The imports have been properly updated to support the new shortcut management features.
21-32
: Successfully integrated the shortcut tester into the storybook layout.The integration of the
DisableTester
component into the mainStory
component is clean and well-organized.
76-104
: Excellent implementation of the shortcut management tester.The
DisableTester
component provides a clear demonstration of how to use the new shortcut management functionality. It effectively shows:
- How to access the shortcut context using the
useShortcuts
hook- How to toggle the global shortcut state
- How to visualize the current shortcut state
- A practical example with an increment counter that can be triggered via shortcut
apps/webapp/app/hooks/useShortcutKeys.tsx (5)
3-3
: Good job adding the necessary import.The addition of the
useShortcuts
import is appropriate for integrating with the global shortcut enablement system.
10-11
: Good addition of the optional enabled property.The optional
enabled
property adds more granular control for individual shortcuts, complementing the global enablement state.
34-35
: Correctly integrating global shortcuts enablement.The hook now properly consumes the global shortcuts enablement state from the
ShortcutsProvider
context.
41-42
: Well-structured enablement logic.The implementation correctly combines multiple factors for determining if a shortcut is enabled:
- Not disabled via the prop
- Global shortcuts are enabled
- The individual shortcut is not explicitly disabled
This provides complete flexibility while maintaining backward compatibility.
49-54
: Consistent application of the enablement flag.You've consistently applied the
isEnabled
flag throughout the hook options, ensuring that all aspects of shortcut handling respect the enablement state.apps/webapp/app/components/navigation/SideMenu.tsx (7)
20-20
: Good addition of useLocation for AI help parameter handling.Adding
useLocation
is necessary for implementing the URL parameter-based AI help functionality.
23-23
: Appropriate icon import for AI feature.The AISparkleIcon import aligns with the new AI assistance feature being added.
59-59
: Good hook import for Kapa widget integration.The import of
useKapaWidget
from the correct relative path is appropriate for managing the AI widget state.
73-76
: Appropriate imports for shortcut functionality.Adding the ShortcutKey and ShortcutsAutoOpen imports supports the keyboard shortcut integration for the AI feature.
283-285
: Good implementation of help and AI component in side menu.The HelpAndAI component is appropriately placed and structured in the side menu footer.
548-563
: Well-implemented URL parameter handling for AI help.The component correctly extracts the
aiHelp
parameter from the URL, removes it to prevent repeated triggering, and passes it to the Kapa widget.
564-597
: Good integration of AI widget with shortcut system.The component:
- Properly includes ShortcutsAutoOpen for keyboard shortcut sheet access
- Passes the appropriate disableShortcut prop to HelpAndFeedback
- Conditionally renders the AI button based on widget availability
- Sets up the correct keyboard shortcut (mod+/) with appropriate tooltip
This creates a cohesive user experience with the new AI feature.
apps/webapp/app/components/primitives/ShortcutsProvider.tsx (3)
1-14
: Well-structured context and types for shortcuts management.The ShortcutsProvider implementation:
- Defines a clear type for the context value
- Properly initializes the context with null
- Has appropriate props type definition
This creates a solid foundation for the global shortcuts management.
15-31
: Excellent provider implementation with proper state management.The provider implementation:
- Initializes the shortcut enablement state to true by default
- Uses useCallback for the state modification functions to prevent unnecessary re-renders
- Memoizes the context value to prevent unnecessary re-renders of consumers
- Correctly provides the value to all children
This follows React best practices for context providers.
33-39
: Good error handling for missing provider.The implementation:
- Provides a clear error message when the hook is used outside a provider
- Uses the nullish coalescing operator for concise error handling
- Exports a clean hook API for consumers
This ensures proper usage of the shortcuts context throughout the application.
apps/webapp/app/components/Shortcuts.tsx (5)
14-15
: Appropriate hook imports for shortcut functionality.Adding useState and useShortcutKeys imports supports the new automatic shortcut opening functionality.
28-28
: Good use of the new shortcut enabled property.Setting
enabled: false
explicitly disables the built-in shortcut trigger, which is now handled by the ShortcutsAutoOpen component.
35-35
: Clean refactoring to use the extracted ShortcutContent.The component now uses the extracted ShortcutContent component, which keeps the code DRY.
40-55
: Well-implemented ShortcutsAutoOpen component.The ShortcutsAutoOpen component:
- Manages its own open state with useState
- Uses useShortcutKeys to listen for the keyboard shortcut
- Opens the sheet when the shortcut is triggered
- Passes the open state to the Sheet component
This creates a clean separation of concerns between shortcut handling and UI display.
57-167
: Good extraction of ShortcutContent for reusability.The ShortcutContent component:
- Properly extracts all the shortcut content from the original component
- Includes the new "Ask AI" shortcut with appropriate key binding
- Maintains the same structure and styling as before
This extraction improves code organization and enables the new ShortcutsAutoOpen functionality.
packages/cli-v3/src/dev/devOutput.ts (5)
50-65
: Nice implementation of AI help for build failuresYou've added a well-structured event handler for build failures that extracts error details and generates an AI help link. This provides a helpful developer experience when builds fail.
111-116
: Good enhancement to error handling with AI assistanceYou've improved the error aggregation for import errors and added AI help link generation. This enhancement makes debugging import errors easier for developers.
125-129
: Well-implemented AI help for task metadata errorsAdding AI help for task metadata parse errors is a good improvement to the developer experience.
135-139
: Good error handling for generic build failuresYou've consistently applied the AI help approach to generic build errors as well, which ensures comprehensive error assistance.
222-222
: Proper event registration and cleanupThe buildFailed event handler is correctly registered and deregistered, maintaining clean event handling.
Also applies to: 234-234
apps/webapp/app/routes/projects.$projectRef.ai-help.ts (4)
9-11
: Good use of Zod schema for parameter validationUsing a schema to validate route parameters is a robust approach that ensures type safety.
13-36
: Well-implemented authentication and project access controlThe loader properly enforces authentication and verifies the user has access to the project. The error handling is also appropriate with 404 responses for not found cases.
38-43
: Good validation of query parameterThe code correctly checks for the presence of the query parameter and returns an appropriate error response when missing.
45-51
: Well-designed redirection to AI helpThe URL construction and redirection logic effectively passes the query to the environment page with the aiHelp parameter, creating a seamless user experience.
apps/webapp/app/root.tsx (3)
54-56
: Good integration of Kapa AI configurationAdding the Kapa configuration to the loader data is a clean approach for making the widget ID available throughout the application.
115-115
: Clean integration of Kapa scriptsThe KapaScripts component is properly added to the head section and receives the websiteId from the loader data.
118-121
: Good implementation of ShortcutsProviderWrapping the application with ShortcutsProvider enables global shortcut management, which is necessary for the AI widget integration.
apps/webapp/app/hooks/useKapaWidget.tsx (4)
10-18
: Good TypeScript declaration for the Kapa APIThe global window interface extension properly types the Kapa function API, improving type safety when interacting with the widget.
87-115
: Comprehensive widget lifecycle managementThe effect properly handles widget rendering, event subscription, and cleanup. The aiHelp parameter processing is well-implemented with URL parameter cleanup after processing.
118-136
: Well-designed widget open functionThe openKapa function properly handles feature flags and configuration before opening the widget. The integration with the shortcuts system to disable keyboard shortcuts when the widget is open is a good UX consideration.
138-142
: Clean API for widget integrationThe hook returns a well-designed API that makes it easy for components to interact with the widget while respecting feature flags.
packages/cli-v3/src/build/bundle.ts (2)
54-61
: Well-structured error class implementationThis new
BundleError
class provides a mechanism to capture and propagate build errors with their associated messages, which will improve error reporting.
141-141
: Good enhancement to error reportingReplacing the generic error with the new
BundleError
class allows passing the detailed error messages from esbuild, which can help with debugging and AI-assisted error resolution.apps/webapp/app/components/primitives/ShortcutKey.tsx (2)
6-6
: Good type import refactoring and new icon integrationThe explicit type imports improve code clarity, and the new icon import will be used for rendering the Enter key.
Also applies to: 9-9
64-68
: Improved visual representation of Enter keyReplacing the Unicode character with a custom SVG icon for the Enter key creates a more consistent and visually appealing shortcut display on Mac platforms.
export function KapaScripts({ websiteId }: { websiteId?: string }) { | ||
if (!websiteId) return null; | ||
|
||
return ( | ||
<> | ||
<script | ||
async | ||
src="https://widget.kapa.ai/kapa-widget.bundle.js" | ||
data-website-id={websiteId} | ||
data-project-name={"Trigger.dev"} | ||
data-project-color={"#6366F1"} | ||
data-project-logo={"https://content.trigger.dev/trigger-logo-circle.png"} | ||
data-render-on-load={"false"} | ||
data-button-hide={"true"} | ||
data-modal-disclaimer-bg-color={"#D7D9DD"} | ||
data-modal-header-bg-color={"#2C3034"} | ||
data-modal-title-color={"#D7D9DD"} | ||
></script> | ||
<script | ||
dangerouslySetInnerHTML={{ | ||
__html: ` | ||
(function () { | ||
let k = window.Kapa; | ||
if (!k) { | ||
let i = function () { | ||
i.c(arguments); | ||
}; | ||
i.q = []; | ||
i.c = function (args) { | ||
i.q.push(args); | ||
}; | ||
window.Kapa = i; | ||
} | ||
})(); | ||
`, | ||
}} | ||
/> | ||
</> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Security consideration with inline script
The KapaScripts component uses dangerouslySetInnerHTML to initialize the Kapa command queue. While this is a common pattern for third-party widget integration, it introduces potential security risks.
Consider if the inline script initialization can be moved to an external file or if there's an alternative approach recommended by Kapa. If not, add a comment explaining why this approach is necessary.
🏁 Script executed:
#!/bin/bash
# Check if Kapa provides documentation on safer initialization methods
echo "Checking for alternative initialization methods in Kapa documentation..."
curl -s https://docs.kapa.ai/widget | grep -A 10 "initialization" || echo "Documentation not found or doesn't mention alternative initialization methods"
Length of output: 388
Add explanatory comment for inline script initialization
The KapaScripts component requires an inline script to set up the window.Kapa
command queue before the external widget bundle loads. Kapa’s public docs (https://docs.kapa.ai/widget) don’t offer an alternative initialization method, so this use of dangerouslySetInnerHTML
is necessary. Please add a code comment in apps/webapp/app/hooks/useKapaWidget.tsx
around the dangerouslySetInnerHTML
block to explain:
- Why we must inline this script (queueing commands before the widget bundle loads)
- That no external or safer init approach is documented by Kapa
File: apps/webapp/app/hooks/useKapaWidget.tsx
Location: lines 37–59 (the dangerouslySetInnerHTML
section)
🧰 Tools
🪛 Biome (1.9.4)
[error] 39-39: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
import { type LoaderFunctionArgs } from "@remix-run/node"; | ||
|
||
export async function loader({ request }: LoaderFunctionArgs) { | ||
const response = await fetch("https://widget.kapa.ai/kapa-widget.bundle.js"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify content security policy compatibility
Make sure your app's Content Security Policy allows loading and executing scripts from the kapa.ai domain.
🏁 Script executed:
#!/bin/bash
# Check if there are any CSP-related headers or meta tags in the codebase
# Look for CSP headers in server-side code
echo "Checking for CSP headers in server responses..."
rg -A 3 -B 3 "Content-Security-Policy" --type ts --type tsx
# Look for CSP meta tags in HTML
echo "Checking for CSP meta tags in HTML/JSX/TSX files..."
rg -A 3 -B 3 '<meta http-equiv="Content-Security-Policy"' --type html --type jsx --type tsx
Length of output: 427
🏁 Script executed:
#!/bin/bash
# Broad search for CSP in all files
echo "Searching for Content-Security-Policy occurrences across the entire codebase..."
rg -A3 -B3 "Content-Security-Policy" .
# Broad search for CSP meta tags
echo "Searching for <meta http-equiv=\"Content-Security-Policy\" tags..."
rg -A3 -B3 '<meta http-equiv="Content-Security-Policy"' .
Length of output: 901
Update Content Security Policy to Allow Kapa Widget Script
The app currently sets only a frame-ancestors
CSP directive. You’ll need to explicitly whitelist the Kapa domain in your script-src policy so the external widget can load. For example, in apps/webapp/app/entry.server.tsx
where you have:
responseHeaders.set(
"Content-Security-Policy",
"frame-ancestors 'self'"
);
update to something like:
responseHeaders.set(
"Content-Security-Policy",
"frame-ancestors 'self'; script-src 'self' https://widget.kapa.ai;"
);
• File: apps/webapp/app/entry.server.tsx
• Location: where Content-Security-Policy
is set
export async function loader({ request }: LoaderFunctionArgs) { | ||
const response = await fetch("https://widget.kapa.ai/kapa-widget.bundle.js"); | ||
const script = await response.text(); | ||
|
||
return new Response(script, { | ||
headers: { | ||
"Content-Type": "application/javascript", | ||
"Cache-Control": "public, max-age=86400", // Cache for 1 day | ||
}, | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling to the loader function
The loader function fetches an external script but doesn't handle potential network failures or server errors.
export async function loader({ request }: LoaderFunctionArgs) {
- const response = await fetch("https://widget.kapa.ai/kapa-widget.bundle.js");
- const script = await response.text();
+ try {
+ const response = await fetch("https://widget.kapa.ai/kapa-widget.bundle.js");
+
+ if (!response.ok) {
+ throw new Error(`Failed to fetch Kapa widget: ${response.status} ${response.statusText}`);
+ }
+
+ const script = await response.text();
+
+ return new Response(script, {
+ headers: {
+ "Content-Type": "application/javascript",
+ "Cache-Control": "public, max-age=86400", // Cache for 1 day
+ },
+ });
+ } catch (error) {
+ console.error("Error loading Kapa widget:", error);
+ // Return an empty script with error logging to prevent page load failures
+ return new Response("console.error('Failed to load Kapa widget');", {
+ headers: {
+ "Content-Type": "application/javascript",
+ "Cache-Control": "no-cache",
+ },
+ });
+ }
-
- return new Response(script, {
- headers: {
- "Content-Type": "application/javascript",
- "Cache-Control": "public, max-age=86400", // Cache for 1 day
- },
- });
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export async function loader({ request }: LoaderFunctionArgs) { | |
const response = await fetch("https://widget.kapa.ai/kapa-widget.bundle.js"); | |
const script = await response.text(); | |
return new Response(script, { | |
headers: { | |
"Content-Type": "application/javascript", | |
"Cache-Control": "public, max-age=86400", // Cache for 1 day | |
}, | |
}); | |
} | |
export async function loader({ request }: LoaderFunctionArgs) { | |
try { | |
const response = await fetch("https://widget.kapa.ai/kapa-widget.bundle.js"); | |
if (!response.ok) { | |
throw new Error(`Failed to fetch Kapa widget: ${response.status} ${response.statusText}`); | |
} | |
const script = await response.text(); | |
return new Response(script, { | |
headers: { | |
"Content-Type": "application/javascript", | |
"Cache-Control": "public, max-age=86400", // Cache for 1 day | |
}, | |
}); | |
} catch (error) { | |
console.error("Error loading Kapa widget:", error); | |
// Return an empty script with error logging to prevent page load failures | |
return new Response("console.error('Failed to load Kapa widget');", { | |
headers: { | |
"Content-Type": "application/javascript", | |
"Cache-Control": "no-cache", | |
}, | |
}); | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
apps/webapp/app/hooks/useKapaWidget.tsx (1)
38-56
:⚠️ Potential issueAdd security comment for inline script initialization.
The use of
dangerouslySetInnerHTML
is flagged by static analysis tools as a potential security risk. While this implementation is necessary for the Kapa widget initialization, you should add a comment explaining why this approach is used.Add a comment explaining that this inline script is required to set up the command queue before the external widget bundle loads, and that Kapa doesn't provide an alternative initialization method:
<script dangerouslySetInnerHTML={{ + // This inline script is necessary to initialize the Kapa command queue before the widget bundle loads + // Kapa's documentation doesn't provide an alternative initialization method that avoids dangerouslySetInnerHTML __html: ` (function () { let k = window.Kapa; if (!k) {🧰 Tools
🪛 Biome (1.9.4)
[error] 39-39: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🧹 Nitpick comments (1)
apps/webapp/app/hooks/useKapaWidget.tsx (1)
103-107
: Consider alternative to setTimeout for widget initialization.The comment indicates that a delay is required for the Kapa browser verification to succeed. While the current implementation works, using a fixed timeout may be fragile.
Consider using a more robust approach if possible:
- Check if Kapa provides an event or callback when verification is complete
- Implement a retry mechanism with increasing delays instead of a fixed timeout
- Add error handling in case the verification fails
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/webapp/app/components/navigation/SideMenu.tsx
(5 hunks)apps/webapp/app/hooks/useKapaWidget.tsx
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
apps/webapp/app/hooks/useKapaWidget.tsx
[error] 39-39: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: units / 🧪 Unit Tests
- GitHub Check: typecheck / typecheck
🔇 Additional comments (5)
apps/webapp/app/components/navigation/SideMenu.tsx (2)
283-285
: Clean restructuring of the footer section.The new flex container provides better layout control for the HelpAndAI component. The use of
justify-between
ensures proper spacing between elements.
548-586
: Well-implemented AI assistance component.The new
HelpAndAI
component properly integrates the AI widget functionality into the side menu with:
- Conditional rendering based on feature flags (
isKapaEnabled
)- Appropriate keyboard shortcut handling
- Clear tooltips showing the shortcut (mod + "/")
- Disabling of conflicting shortcuts when the AI widget is open
The implementation follows good patterns using the hooks API and existing UI components.
apps/webapp/app/hooks/useKapaWidget.tsx (3)
119-139
: Proper shortcut management in openKapa function.The
openKapa
function correctly disables shortcuts when opening the widget and properly handles conditional logic based on feature flags. The callback dependencies are also correctly specified.
87-117
: Good cleanup of event handlers on component unmount.The useEffect hook properly registers event handlers for the Kapa widget's modal open and close events, and cleans them up on unmount. The dependency array is correctly specified to re-register handlers when relevant dependencies change.
19-59
:❓ Verification inconclusive
Verify Kapa widget URL and configuration parameters.
The Kapa widget script is loaded from a fixed URL and configured with several parameters. Ensure that these are the correct parameters for your integration.
🏁 Script executed:
#!/bin/bash # Check for valid Kapa widget configuration parameters echo "Checking Kapa widget documentation for configuration parameters..." curl -s https://docs.kapa.ai/widget | grep -A 20 "data-" || echo "Documentation not found or doesn't mention configuration parameters" echo -e "\nVerifying that the Kapa widget URL is accessible..." curl -s -I https://widget.kapa.ai/kapa-widget.bundle.js | grep "HTTP/" || echo "URL is not accessible"Length of output: 8838
I’ll verify the correct “Website Widget” docs page and extract the expected script parameters.
🏁 Script executed:
#!/bin/bash echo "Checking integration docs status..." curl -sI https://docs.kapa.ai/integrations/website-widget | grep HTTP/ || echo "Integration docs URL not accessible" echo -e "\nExtracting Kapa widget script snippet..." curl -s https://docs.kapa.ai/integrations/website-widget \ | grep -A20 "<script src=\"https://widget.kapa.ai/kapa-widget.bundle.js\"" \ || echo "Widget snippet not found in integration docs"Length of output: 17264
Kapa widget script and parameters verified
The widget bundle URL returns HTTP 200 and the “Website Widget” docs at
/integrations/website-widget
confirm the standard snippet. Before merging, please double-check that your custom settings match your integration:
data-website-id
– must be your actual widget ID from app.kapa.aidata-project-name
,data-project-color
,data-project-logo
– ensure these reflect your brand/integration- Custom flags (
data-render-on-load
,data-button-hide
,data-modal-disclaimer-bg-color
,data-modal-header-bg-color
,data-modal-title-color
) – verify they’re supported and behave as intended- Optional features – if you need search mode, analytics or bot protection, include
data-search-mode-enabled
,data-user-analytics-fingerprint-enabled
,data-bot-protection-mechanism
, etc.No functional changes to the URL or core snippet are needed—just confirm these parameters align with your Kapa integration.
🧰 Tools
🪛 Biome (1.9.4)
[error] 39-39: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
💡 Get a fix for this error using AI
with a link to find an answerSummary by CodeRabbit
New Features
Improvements
Bug Fixes
Chores