Skip to content

Conversation

@horner
Copy link
Member

@horner horner commented Jan 4, 2026

Summary

image

Watch: https://youtube.com/shorts/DkxTvPlXVTk

Add a new demo page showcasing the Kerebron ProseMirror-based rich text editor integrated with Ozwell AI via MCP tools.

Features

  • Kerebron Editor: Loaded from CDN with AdvancedEditorKit for full rich text capabilities
  • AI-controlled document editing via postMessage tools
  • 5 MCP Tools:
    • get_document - Read current document content
    • set_document - Replace entire document
    • insert_text - Insert text at start/end/cursor
    • format_text - Apply bold, italic, headings
    • find_and_replace - Find and replace text
  • Live Event Log showing tool executions in real-time
  • Markdown Preview panel for document state
  • Manual Toolbar with Bold, Italic, and H1 buttons

Integration Pattern

Follows the same postMessage pattern as the tic-tac-toe demo:

  1. Widget sends tool_call with tool_call_id
  2. Parent page executes the tool
  3. Parent sends tool_result back with matching tool_call_id
  4. Widget continues conversation with LLM

Files Changed

  • landing-page/public/kerebron.html - Demo page with OzwellChatConfig and tools
  • landing-page/public/kerebron-app.js - Editor init and tool handlers
  • landing-page/public/kerebron.css - Styling for demo page
  • landing-page/public/landing.html - Added link to Kerebron demo
  • landing-page/server.js - Added route for kerebron.html

Testing

  1. Run npm run dev
  2. Navigate to http://localhost:8080/kerebron.html
  3. Try commands like:
    • "What's in the document?"
    • "Add a paragraph about machine learning at the end"
    • "Replace 'Kerebron' with 'Amazing Editor'"

Screenshots

The demo includes:

  • Left panel: Kerebron rich text editor with formatting toolbar
  • Right panel: Markdown preview and live event log
  • Floating Ozwell chat widget for AI interactions

horner added 2 commits January 4, 2026 13:10
Add a new demo page showcasing the Kerebron ProseMirror-based rich text
editor integrated with Ozwell AI via MCP tools.

Features:
- Kerebron editor loaded from CDN with AdvancedEditorKit
- AI-controlled document editing via postMessage tools
- Tools: get_document, set_document, insert_text, format_text, find_and_replace
- Live event log showing tool executions
- Markdown preview panel
- Manual formatting toolbar (Bold, Italic, H1)

Integration follows the same postMessage pattern as tictactoe demo,
using tool_call_id for proper OpenAI function calling protocol.
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 adds a new demo page showcasing the Kerebron ProseMirror-based rich text editor integrated with Ozwell AI through MCP tools. The integration follows the same postMessage pattern as the existing tic-tac-toe demo, enabling users to edit documents using natural language commands.

Key Changes:

  • Implements 5 MCP tools for AI-controlled document manipulation (get, set, insert, format, find-and-replace)
  • Adds real-time markdown preview and live event logging for debugging
  • Includes manual formatting toolbar alongside AI-powered editing

Reviewed changes

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

Show a summary per file
File Description
landing-page/server.js Adds route handler for /kerebron.html
landing-page/public/landing.html Updates demo video link and adds navigation link to Kerebron demo
landing-page/public/kerebron.html Main demo page with OzwellChatConfig, tool definitions, and editor UI structure
landing-page/public/kerebron.css Comprehensive styling for editor, preview panel, event log, and responsive layout
landing-page/public/kerebron-app.js Editor initialization, tool handlers, postMessage communication, and text-to-HTML conversion utilities

Comment on lines 583 to 602
document.getElementById('bold-btn')?.addEventListener('click', () => {
if (!editor) return;
editor.chain().toggleStrong().run();
updateMarkdownPreview();
logEvent('info', 'Toggle bold');
});

// Italic button
document.getElementById('italic-btn')?.addEventListener('click', () => {
if (!editor) return;
editor.chain().toggleItalic().run();
updateMarkdownPreview();
logEvent('info', 'Toggle italic');
});

// Heading button
document.getElementById('heading-btn')?.addEventListener('click', () => {
if (!editor) return;
editor.chain().setHeading1().run();
updateMarkdownPreview();
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

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

Missing await keyword before updateMarkdownPreview() calls. Since this function is async, the call should be awaited to ensure the preview is updated before logging the event. This could cause race conditions where the log entry appears before the preview actually updates.

Suggested change
document.getElementById('bold-btn')?.addEventListener('click', () => {
if (!editor) return;
editor.chain().toggleStrong().run();
updateMarkdownPreview();
logEvent('info', 'Toggle bold');
});
// Italic button
document.getElementById('italic-btn')?.addEventListener('click', () => {
if (!editor) return;
editor.chain().toggleItalic().run();
updateMarkdownPreview();
logEvent('info', 'Toggle italic');
});
// Heading button
document.getElementById('heading-btn')?.addEventListener('click', () => {
if (!editor) return;
editor.chain().setHeading1().run();
updateMarkdownPreview();
document.getElementById('bold-btn')?.addEventListener('click', async () => {
if (!editor) return;
editor.chain().toggleStrong().run();
await updateMarkdownPreview();
logEvent('info', 'Toggle bold');
});
// Italic button
document.getElementById('italic-btn')?.addEventListener('click', async () => {
if (!editor) return;
editor.chain().toggleItalic().run();
await updateMarkdownPreview();
logEvent('info', 'Toggle italic');
});
// Heading button
document.getElementById('heading-btn')?.addEventListener('click', async () => {
if (!editor) return;
editor.chain().setHeading1().run();
await updateMarkdownPreview();

Copilot uses AI. Check for mistakes.
Comment on lines +569 to +571
document.getElementById('load-sample-btn')?.addEventListener('click', () => {
loadSampleDocument();
});
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

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

Inconsistent event listener pattern compared to other button handlers. Lines 574, 583, 591, and 599 use arrow functions with async, but this handler doesn't need async since it's not awaiting anything. However, for consistency with lines 583 and 591 which should be async, consider making all button handlers either async arrow functions or regular arrow functions consistently.

Copilot uses AI. Check for mistakes.
inList = true;
}
const content = escapeHtml(trimmed.slice(2));
html += `<li>${applyInlineFormatting(content)}</li>`;
Copy link

Copilot AI Jan 4, 2026

Choose a reason for hiding this comment

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

The applyInlineFormatting function is called on already-escaped HTML. Since escapeHtml is called first at line 467 and 483, any special characters are already converted to entities. The function should receive unescaped text, apply formatting, then escape the result. Otherwise, the regex patterns will work but may produce double-escaped content in edge cases.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@aditya-damerla128 aditya-damerla128 left a comment

Choose a reason for hiding this comment

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

kerebron.css line 27 - Back link gets covered by the title on smaller screens - hard to click

kerebron-app.js line 577 - Clear button doesn't work - throws a 404 in console. Think it's the text/x-markdown vs text/html thing?

kerebron.css (dark mode) - Editor text is invisible in dark mode - Kerebron applies light text but the page background stays light

Will attach screenshots in a follow-up comment.

horner and others added 5 commits January 5, 2026 23:18
When the editor is not initialized, error messages are returned to the AI, but these technical error messages may not be helpful for the user. The AI should provide a user-friendly message. However, since the error is passed back to the AI via the tool result, the AI can interpret it. This is acceptable, but consider whether a more user-friendly message would be better.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…tually updates.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
horner and others added 4 commits January 5, 2026 23:26
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.

4 participants