feat: Self-documenting CLI with init, schema, info commands

- Add `init` command to generate starter YAML templates with documentation
- Add `schema` command for CLI-based schema reference
- Add `schema.json` for IDE autocompletion (VS Code, JetBrains)
- Add `info` command and `--version` flag
- Update README with CLI Reference section
This commit is contained in:
lennyzeltser
2026-01-15 13:32:21 -05:00
parent 6edcbab673
commit 958e3fee82
5 changed files with 838 additions and 28 deletions
+42 -19
View File
@@ -7,6 +7,7 @@ After parsing the annotated conversation data you supply in a YAML file, this to
- [How This Is Useful](#how-this-is-useful) - [How This Is Useful](#how-this-is-useful)
- [Installation](#installation) - [Installation](#installation)
- [Quick Start](#quick-start) - [Quick Start](#quick-start)
- [CLI Reference](#cli-reference)
- [YAML Schema](#yaml-schema) - [YAML Schema](#yaml-schema)
- [Output Features](#output-features) - [Output Features](#output-features)
- [Embedding in Websites](#embedding-in-websites) - [Embedding in Websites](#embedding-in-websites)
@@ -75,31 +76,52 @@ Note: This requires [Bun](https://bun.sh) to be installed (for the build step).
## Quick Start ## Quick Start
Create a YAML file defining your conversation, then generate the HTML: Generate a starter template, customize it, then build:
```bash ```bash
conversation-replay build examples/london-scam.yaml -o demo.html # Create a documented template
``` conversation-replay init demo.yaml
Output: # Edit demo.yaml to define your conversation, then build
``` conversation-replay build demo.yaml -o demo.html
Loading examples/london-scam.yaml...
Building demo.html...
Done! Generated demo.html
Title: London Scam - Social Engineering Demo
Scenarios: 1
- London Scam: 17 steps (Matt (compromised account), Rakesh)
```
```bash
# Open in browser # Open in browser
open demo.html open demo.html
``` ```
The generated replay is responsive, supports dark mode automatically, and looks nice across various browsers and devices. The generated replay is responsive, supports dark mode automatically, and looks nice across various browsers and devices.
To explore an existing example instead:
```bash
conversation-replay build examples/london-scam.yaml -o demo.html
```
## CLI Reference
| Command | Description |
|---------|-------------|
| `build <file.yaml> -o <output.html>` | Generate HTML from a YAML file |
| `validate <file.yaml>` | Check a YAML file for errors |
| `init <file.yaml>` | Create a starter template with inline documentation |
| `schema [section]` | Show schema reference (sections: `meta`, `colors`, `speed`, `steps`) |
| `info` | Show tool name, version, and author |
| `--version` | Show version number |
| `--help` | Show help |
Options for `build`:
- `--theme <theme>` &mdash; Override theme (`chat`, `email`, `slack`, `terminal`, `generic`)
- `--no-header` &mdash; Exclude the header with title and description
For IDE autocompletion, add this to the top of your YAML file:
```yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/lennyzeltser/conversation-replay/master/schema.json
```
## YAML Schema ## YAML Schema
Run `conversation-replay schema` for a quick reference, or see below for details.
### Basic Structure ### Basic Structure
```yaml ```yaml
@@ -271,8 +293,10 @@ conversation-replay/
│ ├── cli.ts # CLI entry point │ ├── cli.ts # CLI entry point
│ ├── parser.ts # YAML parsing & validation │ ├── parser.ts # YAML parsing & validation
│ ├── generator.ts # HTML generation (CSS/JS injection) │ ├── generator.ts # HTML generation (CSS/JS injection)
│ ├── schema.ts # Template generation & schema utilities
│ └── types.ts # TypeScript definitions │ └── types.ts # TypeScript definitions
├── examples/ # Demo YAML files ├── examples/ # Demo YAML files
├── schema.json # JSON Schema for IDE autocompletion
└── package.json └── package.json
``` ```
@@ -282,14 +306,11 @@ conversation-replay/
# Install dependencies # Install dependencies
bun install bun install
# Build # Run CLI during development
bun run src/cli.ts build examples/london-scam.yaml -o demo.html bun run src/cli.ts build examples/london-scam.yaml -o demo.html
# Validate without building
bun run src/cli.ts validate examples/london-scam.yaml bun run src/cli.ts validate examples/london-scam.yaml
bun run src/cli.ts init my-demo.yaml
# Build with options bun run src/cli.ts schema
bun run src/cli.ts build examples/london-scam.yaml -o demo.html --theme email --no-header
``` ```
--- ---
@@ -303,6 +324,8 @@ bun run src/cli.ts build examples/london-scam.yaml -o demo.html --theme email --
| `src/types.ts` | Schema definitions. Edit this to add new YAML properties. | | `src/types.ts` | Schema definitions. Edit this to add new YAML properties. |
| `src/generator.ts` | The core engine. Generates the HTML, CSS, and runtime JavaScript. | | `src/generator.ts` | The core engine. Generates the HTML, CSS, and runtime JavaScript. |
| `src/parser.ts` | Input validation logic. | | `src/parser.ts` | Input validation logic. |
| `src/schema.ts` | Template generation, JSON schema, and CLI schema reference. |
| `schema.json` | JSON Schema for IDE autocompletion. Regenerate with `schema --json`. |
### Architecture ### Architecture
+2 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "conversation-replay", "name": "conversation-replay",
"version": "0.1.13", "version": "0.1.14",
"description": "Create annotated replays of text conversations", "description": "Create annotated replays of text conversations",
"main": "dist/cli.js", "main": "dist/cli.js",
"type": "module", "type": "module",
@@ -9,6 +9,7 @@
}, },
"files": [ "files": [
"dist", "dist",
"schema.json",
"README.md" "README.md"
], ],
"scripts": { "scripts": {
+292
View File
@@ -0,0 +1,292 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://github.com/lennyzeltser/conversation-replay/schema.json",
"title": "Conversation Replay Demo",
"description": "Schema for conversation-replay YAML configuration files",
"type": "object",
"required": [
"meta",
"scenarios"
],
"properties": {
"meta": {
"type": "object",
"description": "Demo metadata and configuration",
"required": [
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Demo title shown in header",
"minLength": 1
},
"description": {
"type": "string",
"description": "Brief description shown below title"
},
"theme": {
"type": "string",
"enum": [
"chat",
"email",
"slack",
"terminal",
"generic"
],
"description": "Visual theme for message styling",
"default": "chat"
},
"articleUrl": {
"type": "string",
"description": "URL for 'View Article' link in header"
},
"hideHeaderInIframe": {
"type": "boolean",
"description": "Auto-hide header when embedded in iframe",
"default": true
},
"autoAdvance": {
"type": "boolean",
"description": "Auto-play next scenario when current one completes"
},
"annotationLabel": {
"type": "string",
"description": "Label shown above annotation content",
"default": "Behind the Scenes"
},
"timerStyle": {
"type": "string",
"enum": [
"bar",
"circle"
],
"description": "Countdown timer display style",
"default": "circle"
},
"cornerStyle": {
"type": "string",
"enum": [
"rounded",
"straight"
],
"description": "Border radius style for containers and bubbles",
"default": "rounded"
},
"initialBlur": {
"type": "number",
"description": "Blur amount in pixels for play overlay",
"default": 1,
"minimum": 0
},
"colors": {
"type": "object",
"description": "Custom color overrides",
"properties": {
"accent": {
"type": "string",
"description": "Primary accent color (buttons, links)"
},
"pageBg": {
"type": "string",
"description": "Page background color"
},
"canvasBg": {
"type": "string",
"description": "Chat container background"
},
"leftBg": {
"type": "string",
"description": "Left participant bubble background"
},
"leftBorder": {
"type": "string",
"description": "Left participant bubble border"
},
"rightBg": {
"type": "string",
"description": "Right participant bubble background"
},
"rightBorder": {
"type": "string",
"description": "Right participant bubble border"
},
"tabInactiveColor": {
"type": "string",
"description": "Inactive tab text color"
},
"annotationText": {
"type": "string",
"description": "Annotation text color"
},
"annotationBorder": {
"type": "string",
"description": "Annotation accent bar color"
}
}
},
"speed": {
"type": "object",
"description": "Timing configuration for playback",
"properties": {
"minDelay": {
"type": "number",
"description": "Minimum delay between steps (ms)",
"default": 3000
},
"maxDelay": {
"type": "number",
"description": "Maximum delay between steps (ms)",
"default": 8000
},
"msPerWord": {
"type": "number",
"description": "Milliseconds per word for reading time",
"default": 200
},
"annotationMultiplier": {
"type": "number",
"description": "Time multiplier for annotations",
"default": 1.15
},
"upNextDelay": {
"type": "number",
"description": "'Up Next' display duration (ms)",
"default": 2500
}
}
}
}
},
"scenarios": {
"type": "array",
"description": "One or more conversation scenarios (shown as tabs if multiple)",
"minItems": 1,
"items": {
"type": "object",
"required": [
"id",
"title",
"participants",
"steps"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this scenario",
"minLength": 1
},
"title": {
"type": "string",
"description": "Display title (shown in tab)",
"minLength": 1
},
"participants": {
"type": "array",
"description": "People/entities in this conversation",
"minItems": 1,
"items": {
"type": "object",
"required": [
"id",
"label"
],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier (referenced in message 'from' field)"
},
"label": {
"type": "string",
"description": "Display name shown above messages"
},
"role": {
"type": "string",
"enum": [
"left",
"right"
],
"description": "Which side messages appear on",
"default": "left"
}
}
}
},
"steps": {
"type": "array",
"description": "Sequence of messages, annotations, and transitions",
"minItems": 1,
"items": {
"oneOf": [
{
"type": "object",
"description": "A message from a participant",
"required": [
"type",
"from",
"content"
],
"properties": {
"type": {
"const": "message"
},
"from": {
"type": "string",
"description": "Participant ID"
},
"content": {
"type": "string",
"description": "Message text"
},
"codeBlock": {
"type": "string",
"description": "Optional code/preformatted text"
},
"footnote": {
"type": "string",
"description": "Optional italic footnote"
}
}
},
{
"type": "object",
"description": "An educational annotation/callout",
"required": [
"type",
"content"
],
"properties": {
"type": {
"const": "annotation"
},
"content": {
"type": "string",
"description": "Annotation text"
}
}
},
{
"type": "object",
"description": "A scene break/transition",
"required": [
"type",
"content"
],
"properties": {
"type": {
"const": "transition"
},
"content": {
"type": "string",
"description": "Transition text (e.g., 'Later that day...')"
}
}
}
]
}
}
}
}
}
}
}
+88 -8
View File
@@ -5,12 +5,16 @@
* Usage: * Usage:
* conversation-replay build <scenario.yaml> -o <output.html> * conversation-replay build <scenario.yaml> -o <output.html>
* conversation-replay validate <scenario.yaml> * conversation-replay validate <scenario.yaml>
* conversation-replay init <output.yaml>
* conversation-replay schema [section]
*/ */
import { parseArgs } from 'util'; import { parseArgs } from 'util';
import { loadDemo, ParseError } from './parser'; import { loadDemo, ParseError } from './parser';
import { buildDemo } from './generator'; import { buildDemo } from './generator';
import { generateTemplate, getSchemaReference, jsonSchema } from './schema';
import type { Theme } from './types'; import type { Theme } from './types';
import packageJson from '../package.json';
const HELP = ` const HELP = `
conversation-replay - Create annotated replays of text conversations from YAML conversation-replay - Create annotated replays of text conversations from YAML
@@ -18,22 +22,31 @@ conversation-replay - Create annotated replays of text conversations from YAML
Usage: Usage:
conversation-replay build <scenario.yaml> -o <output.html> [options] conversation-replay build <scenario.yaml> -o <output.html> [options]
conversation-replay validate <scenario.yaml> conversation-replay validate <scenario.yaml>
conversation-replay --help conversation-replay init <output.yaml> [--theme <theme>]
conversation-replay schema [section] [--json]
conversation-replay info
conversation-replay --help | --version
Commands: Commands:
build Generate HTML from a scenario file build Generate HTML from a scenario file
validate Check a scenario file for errors validate Check a scenario file for errors
init Create a starter YAML template with documentation
schema Show schema reference (sections: meta, colors, speed, steps)
info Show tool name, version, author, and links
Options: Options:
-o, --output <path> Output HTML file path (required for build) -o, --output <path> Output HTML file path (required for build)
--theme <theme> Override theme (chat, email, slack, terminal, generic) --theme <theme> Override theme (chat, email, slack, terminal, generic)
--no-header Exclude the demo header --no-header Exclude the demo header
--json Output JSON schema (for schema command)
-h, --help Show this help message -h, --help Show this help message
-v, --version Show version number
Examples: Examples:
conversation-replay build demo.yaml -o demo.html conversation-replay build demo.yaml -o demo.html
conversation-replay build demo.yaml -o demo.html --theme email conversation-replay init my-demo.yaml
conversation-replay validate demo.yaml conversation-replay schema meta
conversation-replay info
`; `;
const VALID_THEMES = ['chat', 'email', 'slack', 'terminal', 'generic']; const VALID_THEMES = ['chat', 'email', 'slack', 'terminal', 'generic'];
@@ -45,21 +58,39 @@ async function main() {
output: { type: 'string', short: 'o' }, output: { type: 'string', short: 'o' },
theme: { type: 'string' }, theme: { type: 'string' },
'no-header': { type: 'boolean' }, 'no-header': { type: 'boolean' },
json: { type: 'boolean' },
help: { type: 'boolean', short: 'h' }, help: { type: 'boolean', short: 'h' },
version: { type: 'boolean', short: 'v' },
}, },
allowPositionals: true, allowPositionals: true,
}); });
if (values.version) {
console.log(`conversation-replay v${packageJson.version}`);
process.exit(0);
}
if (values.help || positionals.length === 0) { if (values.help || positionals.length === 0) {
console.log(HELP); console.log(HELP);
process.exit(0); process.exit(0);
} }
const command = positionals[0]; const command = positionals[0];
const inputFile = positionals[1]; const arg1 = positionals[1];
if (!inputFile) { // Commands that don't require an input file
console.error('Error: No input file specified\n'); if (command === 'schema') {
handleSchema(arg1, values.json);
process.exit(0);
}
if (command === 'info') {
handleInfo();
process.exit(0);
}
if (!arg1) {
console.error('Error: No file specified\n');
console.log(HELP); console.log(HELP);
process.exit(1); process.exit(1);
} }
@@ -74,11 +105,15 @@ async function main() {
try { try {
switch (command) { switch (command) {
case 'build': case 'build':
await handleBuild(inputFile, values); await handleBuild(arg1, values);
break; break;
case 'validate': case 'validate':
await handleValidate(inputFile); await handleValidate(arg1);
break;
case 'init':
await handleInit(arg1, values.theme as Theme | undefined);
break; break;
default: default:
@@ -159,6 +194,51 @@ async function handleValidate(inputFile: string) {
} }
} }
async function handleInit(outputFile: string, theme?: Theme) {
const fs = await import('fs/promises');
// Check if file exists
try {
await fs.access(outputFile);
console.error(`Error: File already exists: ${outputFile}`);
console.error('Use a different filename or delete the existing file.');
process.exit(1);
} catch {
// File doesn't exist, good to proceed
}
const template = generateTemplate(theme);
await fs.writeFile(outputFile, template, 'utf-8');
console.log(`Created ${outputFile}`);
console.log('');
console.log('Next steps:');
console.log(` 1. Edit ${outputFile} to define your conversation`);
console.log(` 2. Validate: conversation-replay validate ${outputFile}`);
console.log(` 3. Build: conversation-replay build ${outputFile} -o output.html`);
console.log('');
console.log('For schema reference: conversation-replay schema');
}
function handleInfo() {
console.log(`
Conversation Replay v${packageJson.version}
https://github.com/lennyzeltser/conversation-replay
Created by Lenny Zeltser
https://zeltser.com
`.trim());
}
function handleSchema(section?: string, outputJson?: boolean) {
if (outputJson) {
console.log(JSON.stringify(jsonSchema, null, 2));
return;
}
console.log(getSchemaReference(section));
}
main().catch(error => { main().catch(error => {
console.error('Unexpected error:', error); console.error('Unexpected error:', error);
process.exit(1); process.exit(1);
+414
View File
@@ -0,0 +1,414 @@
/**
* Schema utilities for conversation-replay
*
* Provides:
* - YAML template generation for `init` command
* - JSON Schema for IDE autocomplete
* - Schema reference output for `schema` command
*/
import type { Theme } from './types';
/**
* Generate a starter YAML template with inline documentation
*/
export function generateTemplate(theme?: Theme): string {
const selectedTheme = theme || 'chat';
return `# Conversation Replay - Demo Configuration
# Documentation: https://github.com/lennyzeltser/conversation-replay
#
# Run: conversation-replay build this-file.yaml -o output.html
# Validate: conversation-replay validate this-file.yaml
meta:
title: "My Demo Title" # Required: shown in header
description: "A brief description" # Optional: shown below title
theme: ${selectedTheme} # chat | email | slack | terminal | generic
# articleUrl: "/related-article" # Optional: "View Article" link
# annotationLabel: "Behind the Scenes" # Label for annotation steps
# autoAdvance: true # Auto-play next scenario when current ends
# Timer and visual style
# timerStyle: circle # circle | bar
# cornerStyle: rounded # rounded | straight
# initialBlur: 1 # Blur amount for play overlay (px)
# Custom colors (all optional)
# colors:
# accent: "#4f46e5" # Buttons, links (Indigo 600)
# pageBg: "#f8fafc" # Page background (Slate 50)
# canvasBg: "#ffffff" # Chat container background
# leftBg: "#eef2ff" # Left bubble background (Indigo 50)
# leftBorder: "transparent" # Left bubble border
# rightBg: "#f1f5f9" # Right bubble background (Slate 100)
# rightBorder: "transparent" # Right bubble border
# annotationText: "#475569" # Annotation text (Slate 600)
# annotationBorder: "#cbd5e1" # Annotation accent bar (Slate 300)
# Timing configuration (all in milliseconds)
# speed:
# minDelay: 3000 # Minimum delay between steps
# maxDelay: 8000 # Maximum delay between steps
# msPerWord: 200 # Reading time per word
# annotationMultiplier: 1.15 # Extra time for annotations
# upNextDelay: 2500 # "Up Next" display time
scenarios:
- id: main
title: "Scenario Title" # Shown in tab (if multiple scenarios)
participants:
- id: user1
label: "Person A"
role: left # Messages appear on left
- id: user2
label: "Person B"
role: right # Messages appear on right
steps:
# Message from a participant
- type: message
from: user1 # Must match a participant id
content: "Hello! This is a sample message."
- type: message
from: user2
content: "Hi there! Here's a response."
# footnote: "Optional italic footnote below the message"
# Message with code block
# - type: message
# from: user2
# content: "Here's some code:"
# codeBlock: |
# function example() {
# return "hello";
# }
# Annotation - educational callout with accent bar
- type: annotation
content: "This annotation explains something to the viewer."
# Transition - centered scene break
# - type: transition
# content: "Later that day..."
# Additional scenarios appear as tabs
# - id: part2
# title: "Part Two"
# participants:
# - id: analyst
# label: "Analyst"
# role: left
# steps:
# - type: message
# from: analyst
# content: "This is another scenario."
`;
}
/**
* JSON Schema for conversation-replay YAML files
*/
export const jsonSchema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://github.com/lennyzeltser/conversation-replay/schema.json",
"title": "Conversation Replay Demo",
"description": "Schema for conversation-replay YAML configuration files",
"type": "object",
"required": ["meta", "scenarios"],
"properties": {
"meta": {
"type": "object",
"description": "Demo metadata and configuration",
"required": ["title"],
"properties": {
"title": {
"type": "string",
"description": "Demo title shown in header",
"minLength": 1
},
"description": {
"type": "string",
"description": "Brief description shown below title"
},
"theme": {
"type": "string",
"enum": ["chat", "email", "slack", "terminal", "generic"],
"description": "Visual theme for message styling",
"default": "chat"
},
"articleUrl": {
"type": "string",
"description": "URL for 'View Article' link in header"
},
"hideHeaderInIframe": {
"type": "boolean",
"description": "Auto-hide header when embedded in iframe",
"default": true
},
"autoAdvance": {
"type": "boolean",
"description": "Auto-play next scenario when current one completes"
},
"annotationLabel": {
"type": "string",
"description": "Label shown above annotation content",
"default": "Behind the Scenes"
},
"timerStyle": {
"type": "string",
"enum": ["bar", "circle"],
"description": "Countdown timer display style",
"default": "circle"
},
"cornerStyle": {
"type": "string",
"enum": ["rounded", "straight"],
"description": "Border radius style for containers and bubbles",
"default": "rounded"
},
"initialBlur": {
"type": "number",
"description": "Blur amount in pixels for play overlay",
"default": 1,
"minimum": 0
},
"colors": {
"type": "object",
"description": "Custom color overrides",
"properties": {
"accent": { "type": "string", "description": "Primary accent color (buttons, links)" },
"pageBg": { "type": "string", "description": "Page background color" },
"canvasBg": { "type": "string", "description": "Chat container background" },
"leftBg": { "type": "string", "description": "Left participant bubble background" },
"leftBorder": { "type": "string", "description": "Left participant bubble border" },
"rightBg": { "type": "string", "description": "Right participant bubble background" },
"rightBorder": { "type": "string", "description": "Right participant bubble border" },
"tabInactiveColor": { "type": "string", "description": "Inactive tab text color" },
"annotationText": { "type": "string", "description": "Annotation text color" },
"annotationBorder": { "type": "string", "description": "Annotation accent bar color" }
}
},
"speed": {
"type": "object",
"description": "Timing configuration for playback",
"properties": {
"minDelay": { "type": "number", "description": "Minimum delay between steps (ms)", "default": 3000 },
"maxDelay": { "type": "number", "description": "Maximum delay between steps (ms)", "default": 8000 },
"msPerWord": { "type": "number", "description": "Milliseconds per word for reading time", "default": 200 },
"annotationMultiplier": { "type": "number", "description": "Time multiplier for annotations", "default": 1.15 },
"upNextDelay": { "type": "number", "description": "'Up Next' display duration (ms)", "default": 2500 }
}
}
}
},
"scenarios": {
"type": "array",
"description": "One or more conversation scenarios (shown as tabs if multiple)",
"minItems": 1,
"items": {
"type": "object",
"required": ["id", "title", "participants", "steps"],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this scenario",
"minLength": 1
},
"title": {
"type": "string",
"description": "Display title (shown in tab)",
"minLength": 1
},
"participants": {
"type": "array",
"description": "People/entities in this conversation",
"minItems": 1,
"items": {
"type": "object",
"required": ["id", "label"],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier (referenced in message 'from' field)"
},
"label": {
"type": "string",
"description": "Display name shown above messages"
},
"role": {
"type": "string",
"enum": ["left", "right"],
"description": "Which side messages appear on",
"default": "left"
}
}
}
},
"steps": {
"type": "array",
"description": "Sequence of messages, annotations, and transitions",
"minItems": 1,
"items": {
"oneOf": [
{
"type": "object",
"description": "A message from a participant",
"required": ["type", "from", "content"],
"properties": {
"type": { "const": "message" },
"from": { "type": "string", "description": "Participant ID" },
"content": { "type": "string", "description": "Message text" },
"codeBlock": { "type": "string", "description": "Optional code/preformatted text" },
"footnote": { "type": "string", "description": "Optional italic footnote" }
}
},
{
"type": "object",
"description": "An educational annotation/callout",
"required": ["type", "content"],
"properties": {
"type": { "const": "annotation" },
"content": { "type": "string", "description": "Annotation text" }
}
},
{
"type": "object",
"description": "A scene break/transition",
"required": ["type", "content"],
"properties": {
"type": { "const": "transition" },
"content": { "type": "string", "description": "Transition text (e.g., 'Later that day...')" }
}
}
]
}
}
}
}
}
}
};
/**
* Generate human-readable schema reference for CLI output
*/
export function getSchemaReference(section?: string): string {
if (section === 'meta') {
return `
META OPTIONS
============
Required:
title: string Demo title shown in header
Optional:
description: string Brief description below title
theme: string chat | email | slack | terminal | generic (default: chat)
articleUrl: string URL for "View Article" link
annotationLabel: string Label for annotations (default: "Behind the Scenes")
autoAdvance: boolean Auto-play next scenario when current ends
hideHeaderInIframe: bool Auto-hide header when embedded (default: true)
timerStyle: string circle | bar (default: circle)
cornerStyle: string rounded | straight (default: rounded)
initialBlur: number Play overlay blur in px (default: 1)
colors: object Custom color overrides (see: schema colors)
speed: object Timing configuration (see: schema speed)
`;
}
if (section === 'colors') {
return `
COLOR OPTIONS (meta.colors)
===========================
All colors are optional CSS color values (hex, rgb, named colors, etc.)
accent: string Buttons, links (default: #4f46e5)
pageBg: string Page background (default: #f8fafc)
canvasBg: string Chat container background (default: #ffffff)
leftBg: string Left bubble background (default: #eef2ff)
leftBorder: string Left bubble border (default: transparent)
rightBg: string Right bubble background (default: #f1f5f9)
rightBorder: string Right bubble border (default: transparent)
tabInactiveColor: string Inactive tab text (default: #94a3b8)
annotationText: string Annotation text (default: #475569)
annotationBorder: string Annotation accent bar (default: #cbd5e1)
`;
}
if (section === 'speed') {
return `
SPEED OPTIONS (meta.speed)
==========================
All values are in milliseconds.
minDelay: number Minimum delay between steps (default: 3000)
maxDelay: number Maximum delay between steps (default: 8000)
msPerWord: number Reading time per word (default: 200)
annotationMultiplier: num Extra time multiplier for annotations (default: 1.15)
upNextDelay: number "Up Next" indicator duration (default: 2500)
`;
}
if (section === 'steps') {
return `
STEP TYPES
==========
MESSAGE - A chat bubble from a participant
type: message (required)
from: string Participant ID (required)
content: string Message text (required)
codeBlock: string Optional preformatted code block
footnote: string Optional italic footnote
ANNOTATION - Educational callout with accent bar
type: annotation (required)
content: string Annotation text (required)
TRANSITION - Centered scene break
type: transition (required)
content: string Transition text (required)
`;
}
// Full schema reference
return `
CONVERSATION REPLAY SCHEMA
==========================
STRUCTURE
---------
meta: Demo configuration (see: schema meta)
scenarios: Array of conversation scenarios
SCENARIO
--------
id: string Unique identifier (required)
title: string Display title for tab (required)
participants: array People in conversation (required)
steps: array Message/annotation sequence (required)
PARTICIPANT
-----------
id: string Unique ID, used in message 'from' field (required)
label: string Display name shown above messages (required)
role: string left | right (default: left)
STEP TYPES
----------
message Chat bubble (requires: from, content)
annotation Educational callout (requires: content)
transition Scene break (requires: content)
Use 'schema <section>' for details:
schema meta Meta/configuration options
schema colors Color customization
schema speed Timing configuration
schema steps Step type details
`;
}