Skip to content

Move prompts to config folder#12

Open
manuelgruber wants to merge 1 commit intomainfrom
chore-find-ai-prompts-8d02f
Open

Move prompts to config folder#12
manuelgruber wants to merge 1 commit intomainfrom
chore-find-ai-prompts-8d02f

Conversation

@manuelgruber
Copy link
Copy Markdown
Member

@manuelgruber manuelgruber commented Oct 31, 2025

Move prompts to config folder
Add AI prompts configuration and integrate into content scripts

  • Created a new prompts configuration file (config/prompts.js) to centralize AI prompts and schemas.
  • Updated manifest.json to include web accessible resources for inpage scripts.
  • Refactored classifyClickbait method in ai-manager.js to utilize the new prompt configuration.
  • Enhanced BaitBreakerContentManager in content-script.js to inject prompts into the page context.
  • Updated inpage.js to use injected prompts for classification and summarization.
  • Adjusted webpack.config.js to ensure inpage.js is included in the build process.

Summary by CodeRabbit

  • Refactor

    • Centralized AI prompt templates and response schema for consistent classification and summarization.
  • New Features

    • Injects a lightweight in-page helper so page-level logic can access the shared prompts before other content runs.
  • Chores

    • Build/config updated to include the in-page script as a runtime resource.

Note

Centralizes AI prompts/schema and updates background, content, and inpage scripts to use injected prompts, exposing/copying inpage.js via manifest and build config.

  • Config:
    • Add config/prompts.js with CLASSIFICATION_SCHEMA, prompt templates, and builders (buildClassificationPrompt, buildSummarizationContext).
  • Background:
    • Update src/background/ai-manager.js to use buildClassificationPrompt and CLASSIFICATION_SCHEMA for classifyClickbait.
  • Content Script:
    • Enhance src/content/content-script.js to inject prompts into page context (window.__BB_PROMPTS__) and load src/content/inpage.js.
  • Inpage Script:
    • Refactor src/content/inpage.js to consume injected prompts, build prompts/context helpers, and apply responseConstraint from CLASSIFICATION_SCHEMA.
  • Manifest:
    • Add web_accessible_resources for src/content/inpage.js.
  • Build:
    • Update webpack.config.js to copy src/content/inpage.js into the build.

Written by Cursor Bugbot for commit 5052014. This will update automatically on new commits. Configure here.

- Created a new prompts configuration file (`config/prompts.js`) to centralize AI prompts and schemas.
- Updated `manifest.json` to include web accessible resources for inpage scripts.
- Refactored `classifyClickbait` method in `ai-manager.js` to utilize the new prompt configuration.
- Enhanced `BaitBreakerContentManager` in `content-script.js` to inject prompts into the page context.
- Updated `inpage.js` to use injected prompts for classification and summarization.
- Adjusted `webpack.config.js` to ensure inpage.js is included in the build process.
Copilot AI review requested due to automatic review settings October 31, 2025 00:43
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 31, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Centralizes AI prompt schemas, templates, and builders into config/prompts.js; exposes src/content/inpage.js via web_accessible_resources in manifest.json; updates background, content, and inpage scripts to use centralized prompts; adds build rule to include inpage.js in distribution.

Changes

Cohort / File(s) Summary
Prompt Configuration
config/prompts.js
New module exporting CLASSIFICATION_SCHEMA, CLASSIFICATION_PROMPT_TEMPLATE, SUMMARIZATION_CONTEXT_TEMPLATE, buildClassificationPrompt(title), buildSummarizationContext(title = ''), and aggregated PROMPTS object
Extension Manifest & Build
manifest.json,
webpack.config.js
Added top-level web_accessible_resources entry exposing src/content/inpage.js to <all_urls>; added CopyWebpackPlugin pattern copying src/content/inpage.js into the build output
Background AI Logic
src/background/ai-manager.js
classifyClickbait refactored to call buildClassificationPrompt(linkText) and use CLASSIFICATION_SCHEMA from centralized config instead of an inline schema and prompt string
Content Script
src/content/content-script.js
Added injectInPageScript() on BaitBreakerContentManager to embed window.__BB_PROMPTS__ and inject/load inpage.js; called during initialization with re-injection guard and error handling
In-Page Script
src/content/inpage.js
Now reads prompts from window.__BB_PROMPTS__ (fallback to built-in), exposes buildClassificationPrompt/buildSummarizationContext usage, and uses CLASSIFICATION_SCHEMA for classification requests (removed inline prompt/schema)

Sequence Diagram(s)

sequenceDiagram
    participant CS as Content Script
    participant Page as Web Page
    participant Inpage as In-Page Script
    participant AI as AI service

    CS->>CS: initialize()
    CS->>Page: inject <script> setting window.__BB_PROMPTS__
    CS->>Page: append inpage.js
    Page->>Inpage: inpage.js runs, reads window.__BB_PROMPTS__

    Page->>Inpage: classify(title)
    Inpage->>Inpage: buildClassificationPrompt(title)
    Inpage->>AI: send prompt + CLASSIFICATION_SCHEMA
    AI-->>Inpage: classification result
    Inpage-->>Page: return classification

    Page->>Inpage: summarize(text, context)
    Inpage->>Inpage: buildSummarizationContext(context.title)
    Inpage->>AI: send summarization request
    AI-->>Inpage: summary
    Inpage-->>Page: return summary
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review prompt builders for proper escaping and placeholder handling (buildClassificationPrompt, buildSummarizationContext)
  • Verify injectInPageScript() correctly sets window.__BB_PROMPTS__, prevents duplicate injection, and handles errors
  • Confirm manifest web_accessible_resources and webpack copy pattern produce the expected runtime artifact and path

Poem

🐇 A little prompt hops into one file,
Neat and tidy, arranged with a smile.
Injected on pages to chatter and sing,
Classify, summarize — ready to bring.
Hooray for prompts that now live as a team! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Move prompts to config folder' is concise and directly describes the main change: the creation and centralization of AI prompts into a new configuration module at config/prompts.js. The title accurately reflects the primary refactoring objective of the changeset, which involves consolidating prompt schemas and templates from multiple locations into a single configuration file.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore-find-ai-prompts-8d02f

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

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 centralizes AI prompt configuration by extracting hardcoded prompts and schemas into a shared configuration file. The prompts are now injected into the in-page script via a global variable, ensuring consistency across different execution contexts (background script, content script, and page context).

  • Centralized all AI prompts and schemas in config/prompts.js
  • Modified the in-page script to receive prompts via dependency injection through window.__BB_PROMPTS__
  • Updated webpack and manifest configurations to enable proper script injection

Reviewed Changes

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

Show a summary per file
File Description
config/prompts.js New file containing centralized prompt templates, schemas, and helper functions
src/background/ai-manager.js Updated to import and use centralized prompts instead of hardcoded values
src/content/content-script.js Added method to inject prompts into page context and load inpage.js
src/content/inpage.js Refactored to accept prompts via window.__BB_PROMPTS__ with fallback defaults
manifest.json Added web_accessible_resources to allow inpage.js to be loaded
webpack.config.js Added copy pattern for inpage.js to dist directory

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

},
{ from: 'icons', to: 'icons' },
{ from: 'src/styles', to: 'styles' },
{ from: 'src/content/inpage.js', to: 'src/content/inpage.js' },
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The inpage.js file is being copied directly without transformation, but it contains ES6 module code that won't work in a page context script. Since this file is loaded via a <script> tag in the page context (not as a module), any ES6 imports would fail. Consider either: (1) bundling this file through webpack's entry points like other scripts, or (2) ensuring it doesn't use ES6 module syntax. Currently it uses an IIFE which is correct, but this approach bypasses webpack's bundling and any potential transformations.

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +74
script.textContent = `
window.__BB_PROMPTS__ = ${JSON.stringify(prompts)};
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The prompts object is serialized using JSON.stringify without sanitization. While the current prompt templates appear safe, if any template values were to contain user input or untrusted data in the future, this could create an XSS vulnerability. Consider adding validation or using a safer serialization approach. Additionally, the template literal creates a script that's directly inserted into the page context, which should be carefully reviewed for any potential injection risks.

Suggested change
script.textContent = `
window.__BB_PROMPTS__ = ${JSON.stringify(prompts)};
// Escape </script> to prevent XSS if any prompt contains it
const safePromptsJSON = JSON.stringify(prompts).replace(/<\/script/gi, '<\\/script');
script.textContent = `
window.__BB_PROMPTS__ = ${safePromptsJSON};

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +7
CLASSIFICATION_PROMPT_TEMPLATE: 'Analyze if this title is clickbait (uses curiosity gap, emotional triggers, or withholds key information).\nTitle: "{title}"\n\nReturn JSON with fields: isClickbait (boolean), confidence (0-1), reason (short).',
SUMMARIZATION_CONTEXT_TEMPLATE: 'Answer the clickbait-style question concisely in one short sentence. Title: {title}',
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The fallback prompt template uses \\n escape sequences which differ from the template literal format used in config/prompts.js (lines 24-27). This inconsistency makes the fallback harder to maintain and could lead to subtle behavioral differences if the fallback is ever used. Consider using a template literal here as well for consistency.

Suggested change
CLASSIFICATION_PROMPT_TEMPLATE: 'Analyze if this title is clickbait (uses curiosity gap, emotional triggers, or withholds key information).\nTitle: "{title}"\n\nReturn JSON with fields: isClickbait (boolean), confidence (0-1), reason (short).',
SUMMARIZATION_CONTEXT_TEMPLATE: 'Answer the clickbait-style question concisely in one short sentence. Title: {title}',
CLASSIFICATION_PROMPT_TEMPLATE: `Analyze if this title is clickbait (uses curiosity gap, emotional triggers, or withholds key information).

Copilot uses AI. Check for mistakes.
@manuelgruber manuelgruber marked this pull request as draft November 3, 2025 17:47
@manuelgruber manuelgruber marked this pull request as ready for review November 3, 2025 17:47
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on December 15

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

// Check if already injected
if (window.__BB_INPAGE_INJECTED__) {
return;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Inpage.js Injection Check Fails Across Contexts

The inpage.js duplicate injection check is ineffective. The window.__BB_INPAGE_INJECTED__ flag is set in the page context, but the content script checks its own isolated window object, allowing inpage.js to be injected multiple times.

Fix in Cursor Fix in Web

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/content/content-script.js (1)

65-78: Escape </script> before inlining prompts

Embedding JSON.stringify(prompts) directly leaves any </script substring intact. If a prompt template ever contains it, this inline script terminates early, __BB_PROMPTS__ never initializes, and the page-context bridge breaks. Escape the sequence before writing into the DOM.

       const prompts = {
         CLASSIFICATION_PROMPT_TEMPLATE,
         SUMMARIZATION_CONTEXT_TEMPLATE,
         CLASSIFICATION_SCHEMA
       };
 
+      const safePromptsJSON = JSON.stringify(prompts).replace(/<\/script/gi, '<\\/script');
       // Inject prompts into page context first
       const script = document.createElement('script');
       script.textContent = `
-        window.__BB_PROMPTS__ = ${JSON.stringify(prompts)};
+        window.__BB_PROMPTS__ = ${safePromptsJSON};
         window.__BB_INPAGE_INJECTED__ = true;
       `;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b203f41 and 5052014.

📒 Files selected for processing (6)
  • config/prompts.js (1 hunks)
  • manifest.json (1 hunks)
  • src/background/ai-manager.js (2 hunks)
  • src/content/content-script.js (3 hunks)
  • src/content/inpage.js (2 hunks)
  • webpack.config.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
config/prompts.js (1)
src/content/inpage.js (1)
  • PROMPTS (5-17)
src/content/inpage.js (1)
config/prompts.js (4)
  • PROMPTS (56-62)
  • PROMPTS (56-62)
  • buildClassificationPrompt (34-36)
  • buildSummarizationContext (49-51)
src/background/ai-manager.js (1)
config/prompts.js (3)
  • buildClassificationPrompt (34-36)
  • CLASSIFICATION_SCHEMA (10-18)
  • CLASSIFICATION_SCHEMA (10-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (4)
config/prompts.js (4)

10-18: LGTM! Well-structured schema definition.

The JSON Schema is properly defined with appropriate type constraints and required fields.


24-27: LGTM! Clear and well-structured prompt template.

The template provides clear instructions for clickbait classification.


42-42: LGTM! Concise summarization template.

The template is clear and appropriate for its use case.


56-62: LGTM! Clean aggregated export.

The PROMPTS object provides a convenient single export for all prompt-related functionality.

Comment on lines +34 to +36
export function buildClassificationPrompt(title) {
return CLASSIFICATION_PROMPT_TEMPLATE.replace('{title}', title.replace(/"/g, '\\"'));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add input validation and comprehensive escaping.

This function has multiple issues:

  1. Runtime error risk: If title is null or undefined, calling .replace() will throw a TypeError.
  2. Incomplete escaping: Only escaping double quotes is insufficient. Consider:
    • Backslashes before quotes (e.g., title = 'test\\"') could break the escaping
    • Newlines, tabs, and other control characters could disrupt the prompt structure
    • Potential prompt injection attacks via unescaped special characters

Apply this diff to add validation and more robust escaping:

 export function buildClassificationPrompt(title) {
+  if (typeof title !== 'string') {
+    throw new TypeError('Title must be a string');
+  }
+  // Escape backslashes first, then quotes, then newlines
+  const escaped = title
+    .replace(/\\/g, '\\\\')
+    .replace(/"/g, '\\"')
+    .replace(/\n/g, '\\n')
+    .replace(/\r/g, '\\r')
+    .replace(/\t/g, '\\t');
-  return CLASSIFICATION_PROMPT_TEMPLATE.replace('{title}', title.replace(/"/g, '\\"'));
+  return CLASSIFICATION_PROMPT_TEMPLATE.replace('{title}', escaped);
 }
🤖 Prompt for AI Agents
In config/prompts.js around lines 34–36, the buildClassificationPrompt function
currently assumes title is a string and only escapes double quotes; update it to
validate and robustly escape input: first check title is non-null/undefined
(throw an Error or return a safe default if invalid), coerce to String, then
perform escaping in the correct order (escape backslashes first, then double
quotes), replace control characters (newline, carriage return, tab and other
non-printables) with safe escape sequences (e.g. \n, \r, \t or remove), and
optionally enforce a maximum length; finally use the escaped string in
CLASSIFICATION_PROMPT_TEMPLATE.replace('{title}', escapedTitle).

Comment on lines +49 to +51
export function buildSummarizationContext(title = '') {
return SUMMARIZATION_CONTEXT_TEMPLATE.replace('{title}', title);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Critical: Missing input escaping creates prompt injection vulnerability.

Unlike buildClassificationPrompt, this function does not escape the title parameter before inserting it into the prompt. This creates a security vulnerability where malicious or unexpected input could:

  • Inject arbitrary instructions into the AI prompt
  • Manipulate the AI's behavior
  • Produce unexpected or harmful outputs

Additionally, the inconsistency between the two builder functions creates confusion and maintenance issues.

Apply this diff to add proper validation and escaping:

 export function buildSummarizationContext(title = '') {
+  if (typeof title !== 'string') {
+    title = String(title);
+  }
+  // Escape special characters to prevent prompt injection
+  const escaped = title
+    .replace(/\\/g, '\\\\')
+    .replace(/\n/g, '\\n')
+    .replace(/\r/g, '\\r')
+    .replace(/\t/g, '\\t');
-  return SUMMARIZATION_CONTEXT_TEMPLATE.replace('{title}', title);
+  return SUMMARIZATION_CONTEXT_TEMPLATE.replace('{title}', escaped);
 }
📝 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.

Suggested change
export function buildSummarizationContext(title = '') {
return SUMMARIZATION_CONTEXT_TEMPLATE.replace('{title}', title);
}
export function buildSummarizationContext(title = '') {
if (typeof title !== 'string') {
title = String(title);
}
// Escape special characters to prevent prompt injection
const escaped = title
.replace(/\\/g, '\\\\')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\t/g, '\\t');
return SUMMARIZATION_CONTEXT_TEMPLATE.replace('{title}', escaped);
}
🤖 Prompt for AI Agents
In config/prompts.js around lines 49-51, the buildSummarizationContext function
inserts the raw title into the prompt template which creates a prompt-injection
vulnerability; update the function to mirror buildClassificationPrompt by
validating and escaping the title before replacing it into
SUMMARIZATION_CONTEXT_TEMPLATE (e.g., trim, enforce a sensible max length,
sanitize/escape characters that could alter prompt structure, and reuse the
existing escape helper used by buildClassificationPrompt), then replace the
template placeholder with the escaped value and add a small unit test to cover
malicious/edge-case titles.

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.

3 participants