A split-screen interface for human-AI collaborative authoring
The Live-Edit Pattern enables real-time collaboration between humans and AI assistants through a simple but powerful approach: a local JSON file as shared memory. The human author works in a browser-based editor, feedback auto-saves to a file, and the AI assistant reads it on command.
Originally developed for eLearning content authoring, but applicable to any structured content workflow.
Most tools implement one of these primitives:
| Primitive | Exists In |
|---|---|
| Split-screen UI | Grok Studio, Claude Artifacts |
| Local JSON state | PseudoWrite, H5P |
| Interrupt/resume pattern | LangGraph checkpointers |
| Story Bible shared context | Sudowrite, NovelAI |
Live-Edit Pattern combines all four. No existing tool does this.
Most human-AI collaboration tools require:
- Copy-pasting between browser and AI chat
- Cloud accounts and API keys
- Complex setup
Live-Edit Pattern is different:
- Local-first OR Remote: Run locally or deploy to any web server
- No API keys needed: Works with any AI assistant that can read files (Claude Code, Cursor, etc.)
- Human-controlled: You decide when the AI looks at your feedback
- Zero lock-in: Plain JSON files you own
Run on your machine with python3 server.py. Perfect for solo work.
Deploy to any web server with PHP. Enables:
- Edit from anywhere - Phone, tablet, travel laptop
- Team collaboration - Multiple editors, one AI processor
- AI pulls via HTTP - Simple curl to fetch changes
┌─────────────────────────────────────────────────────────┐
│ SHARED CANVAS │
│ ┌─────────────────────┬───────────────────────────┐ │
│ │ │ │ │
│ │ PREVIEW PANE │ AUTHORING PANE │ │
│ │ (iframe) │ │ │
│ │ │ - Content selector │ │
│ │ Your content │ - Edit fields │ │
│ │ renders here │ - Notes for AI │ │
│ │ │ │ │
│ └─────────────────────┴───────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
↓ auto-save
┌─────────────────────┐
│ notes-for-ai.json │ ← AI reads this
└─────────────────────┘
# Clone the repo
git clone https://github.com/ekras-doloop/live-edit-pattern.git
cd live-edit-pattern
# Start the server
python3 server.py
# Open in browser
# http://localhost:8080Then tell your AI assistant:
"Read the file
notes-for-ai.jsonand make the changes I requested"
The split-screen interface shows:
- Left: Live preview of your content
- Right: Editing panel with fields and a "Notes for AI" textarea
Every keystroke triggers a debounced save (500ms delay) to:
content.json- Your actual contentnotes-for-ai.json- Feedback for the AI
With Claude Code:
You: check
Claude: *reads notes-for-ai.json*
I see you want to change the heading on slide 3...
With Cursor/other AI editors:
Read notes-for-ai.json and implement the requested changes
The AI modifies your content files. Refresh the preview to see changes. Repeat.
live-edit-pattern/
├── index.html # Main split-screen interface
├── server.py # Local Python server
├── content.json # Your content (customize this)
├── notes-for-ai.json # Auto-generated feedback file
├── preview/ # Your preview templates
│ └── index.html # Preview renderer
├── docs/
│ ├── architecture.svg
│ └── RESEARCH.md # Prior art research
├── examples/
│ ├── blog-editor/ # Example: Blog post editor
│ ├── slide-deck/ # Example: Presentation slides
│ └── elearning/ # Example: eLearning module editor
├── LICENSE # MIT
└── README.md
Edit config.js to customize:
const CONFIG = {
// Content file to edit
contentFile: 'content.json',
// Notes file for AI
notesFile: 'notes-for-ai.json',
// Preview URL
previewUrl: 'preview/index.html',
// Auto-save delay (ms)
saveDelay: 500,
// Panel width (px)
panelWidth: 520
};| Endpoint | Method | Purpose |
|---|---|---|
/api/content |
GET | Load content |
/api/content |
POST | Save content |
/api/notes |
POST | Save notes for AI |
| Endpoint | Method | Purpose |
|---|---|---|
/api/content.php?file=X |
GET | Load content file |
/api/save.php |
POST | Save content to JSON |
/api/notes.php |
GET | Get all notes for AI |
/api/notes.php |
POST | Save note for AI |
Deploy to any PHP-enabled web server (shared hosting, VPS, etc.):
api/save.php - Save content edits:
<?php
header('Content-Type: application/json');
$input = json_decode(file_get_contents('php://input'), true);
$file = "../content/" . basename($input['file']) . ".json";
file_put_contents($file, json_encode($input['data'], JSON_PRETTY_PRINT));
echo json_encode(['success' => true]);api/notes.php - Save/retrieve notes for AI:
<?php
header('Content-Type: application/json');
$notesFile = __DIR__ . '/../notes-for-ai.json';
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
echo file_exists($notesFile) ? file_get_contents($notesFile) : '{"notes":[]}';
exit;
}
$input = json_decode(file_get_contents('php://input'), true);
$notes = json_decode(file_get_contents($notesFile), true) ?? ['notes' => []];
$notes['notes'][] = array_merge($input, ['timestamp' => date('c')]);
file_put_contents($notesFile, json_encode($notes, JSON_PRETTY_PRINT));
echo json_encode(['success' => true]);// Change relative to absolute paths
fetch('/api/notes.php')# Pull notes for AI
curl -s "https://yourserver.com/api/notes.php"
# Pull content file
curl -s "https://yourserver.com/content/lesson-1.json"
# With basic auth (if protected)
curl -s -u "user:pass" "https://yourserver.com/api/notes.php"Add .htaccess:
AuthType Basic
AuthName "Authoring Studio"
AuthUserFile /path/to/.htpasswd
Require valid-user# 1. Human edits on web (from anywhere)
# 2. AI pulls changes
curl -s "https://yourserver.com/api/notes.php" > notes-from-web.json
# 3. AI processes notes, updates content locally
# 4. AI pushes updates (via git, FTP, or API)
# 5. RepeatSix ready-to-use schemas covering common content types:
| Example | Use Case | Schema Highlights |
|---|---|---|
blog-editor |
Blog posts | Title, sections with headings/body |
slide-deck |
Presentations | Slides with types (title, content, bullets) |
elearning |
Training modules | Objectives, content sections, quizzes |
technical-docs |
API documentation | Endpoints, methods, parameters, responses |
knowledge-base |
FAQ/Help centers | Categories, articles, tags, search |
meeting-notes |
Team meetings | Attendees, agenda, decisions, action items |
cd examples/[example-name]
python3 ../../server.py
# Open http://localhost:8080{
"title": "My Post",
"sections": [
{ "heading": "Introduction", "body": "..." }
]
}{
"title": "My Presentation",
"slides": [
{ "type": "title", "heading": "Welcome" },
{ "type": "content", "heading": "Topic 1", "bullets": [...] }
]
}{
"title": "Module 1: Introduction",
"objectives": ["Understand X", "Apply Y"],
"sections": [
{ "type": "content", "heading": "Overview", "body": "..." },
{ "type": "quiz", "question": "...", "options": [...], "correct": 0 }
]
}{
"title": "API Reference",
"version": "1.0",
"endpoints": [
{
"method": "GET",
"path": "/api/users",
"description": "List all users",
"parameters": [...],
"response": { "status": 200, "body": {...} }
}
]
}{
"title": "Help Center",
"categories": [
{
"name": "Getting Started",
"articles": [
{ "title": "Quick Start Guide", "content": "...", "tags": ["setup"] }
]
}
]
}{
"title": "Sprint Planning",
"date": "2026-01-26",
"attendees": [
{ "name": "Alice", "role": "PM", "status": "present" }
],
"agenda": ["Review backlog", "Assign tasks"],
"decisions": [
{ "decision": "Ship v2 by Friday", "owner": "Bob", "priority": "high" }
],
"actionItems": [
{ "task": "Update docs", "assignee": "Carol", "due": "2026-01-28", "status": "pending" }
]
}Create your own preview/index.html that:
- Fetches
content.json - Renders it however you want
- Listens for postMessage to sync with the editor
// In your preview
window.addEventListener('message', (e) => {
if (e.data.type === 'contentUpdated') {
loadContent();
}
});Modify index.html to add fields for your content type:
<div class="field">
<label>Custom Field</label>
<input type="text" id="customField" data-path="metadata.custom">
</div>The data-path attribute maps to the JSON structure.
This pattern combines ideas from:
| Source | Contribution |
|---|---|
| Grok Studio (xAI) | Split-screen UI paradigm |
| PseudoWrite | Local JSON as app state |
| H5P / Adapt Framework | JSON-based content architecture |
| LangGraph | Human-in-the-loop interrupt/resume |
| Descript | "Transcript-as-truth" bidirectional sync |
| Sudowrite/NovelAI | "Story Bible" shared context pattern |
Full research: RESEARCH.md
| Tool | Limitation |
|---|---|
| ChatGPT/Claude web | Can't read your local files |
| Cursor/Copilot | Code-focused, not content authoring |
| Notion AI | Cloud-only, no local files |
| Google Docs + Gemini | Cloud-only, limited AI control |
Live-Edit Pattern works with any AI that can read files, requires no accounts or API keys, and keeps all data local.
PRs welcome! Especially:
- New example editors (especially eLearning templates)
- Preview templates
- Documentation improvements
- Accessibility enhancements
MIT - Use it however you want.
Created by Gaurav Rastogi
Pattern documented with assistance from Claude (Anthropic).