<h1 align="center">
<a href="https://prompts.chat">
Generates one complete investigation (25 panels + basic metadata) for a single user/project combination. This is the production pipeline — one invocation produces one investigation.
Loading actions...
<a href="https://prompts.chat">
TypeScript and ESLint rules that MUST be followed when creating, modifying, or reviewing any file under apps/frontend/, including .ts, .tsx, .js, and .jsx files. Also apply when discussing frontend linting, type safety, or ESLint configuration.
risks
Generates one complete investigation (25 panels + basic metadata) for a single user/project combination. This is the production pipeline — one invocation produces one investigation.
data/users.csv (row for this user)data/projects.csv (row for this project)viewer_style field (see Template Router below)Select template based on the user's viewer_style column in users.csv:
| viewer_style | Template File | Users |
|---|---|---|
| blog | templates/viewer-intelligence-blog.md | 07, 13 |
| magazine | templates/viewer-magazine.md | 04, 06, 10, 14, 16, 26 |
| dossier | templates/viewer-dossier.md | 01, 03, 08, 12, 23 |
| first-person | templates/viewer-first-person.md | 02, 11, 17, 20, 22 |
| comic-text | templates/viewer-comic-text.md | 18, 19, 21, 24, 25 |
| quantitative | templates/viewer-quantitative.md | 05, 09, 15, 27, 29 |
| scenario-brief | templates/viewer-scenario-brief.md | 28 |
CRITICAL: Read the correct template for this user. Each template has different panel structures, writing rules, and quality gates. Do NOT use blog template structure for a dossier user.
Follow the template's specific structure. Examples:
Quality check after Step 2:
Follow the template's core section:
Quality check after Step 3:
Follow the template's closing structure:
Quality check after Step 4:
Generate metadata.json with basic project fields only. Knowledge extraction (entities, causal links, chains, systems, themes) happens on the GatorSquare platform after upload — the studio does NOT extract knowledge.
{
"project_id": "investigation-slug",
"title": "Full title",
"subtitle": "One-line hook or tagline",
"summary": "2-3 sentence overview of the investigation and its core finding",
"description": "Full paragraph description for SEO and detail page",
"author": "User display name",
"author_id": "user_id",
"author_role": "Professional role",
"author_location": "City",
"viewer_style": "dossier|magazine|first-person|quantitative|blog|comic-text|scenario-brief",
"investigation_date": "2026-03-XX",
"panel_count": 25,
"estimated_word_count": 6000,
"tags": ["tag1", "tag2", "...10-20 granular keywords"],
"topic_categories": ["Economics", "Security"]
}
Two classification layers:
tags — granular keywords (10-20 per investigation). Used for filtering and search.topic_categories — broad umbrella categories (2-4 per investigation). Used for Topics filter panel.topic_categories is NOT a fixed list. The AI agent decides what categories fit. Be consistent across investigations (if "Economics" in one, not "Economic Systems" in another). New categories appear automatically on the platform.
CRITICAL: investigation.json must use Studio viewer format. The viewer reads moments not panels, and text not narration. Getting this wrong = blank viewer.
database/{user_id}/{project_number}/
investigation.json <- Studio viewer data (format below)
metadata.json <- Basic project metadata
README.md <- Human-readable summary
investigation.json format (MUST match Studio viewer/index.html):
{
"project_id": "project-1",
"title": "Investigation Title",
"subtitle": "One-line hook",
"author": "Author Name",
"layout": "narrator",
"default_style": "text-only",
"characters": {"NARRATOR": {"name": "Narrator"}},
"moments": [
{
"panel_id": "panel-01",
"speaker": "NARRATOR",
"text": "Full panel text content here...",
"image": "",
"title": "Panel Title",
"word_count": 250,
"metadata": {
"stage": "foundation",
"mood": "tension",
"dimension": "economic"
}
}
],
"presentation": {
"layout": "narrator",
"show_speaker_badge": false,
"text_position": "full-width",
"transition": "cut",
"typewriter_speed": 25,
"viewer_style": "dossier"
},
"cost_summary": { "panels": 25, "total": 0 }
}
Per-moment metadata: Each moment carries lightweight metadata from the writing process:
stage — which narrative stage this panel belongs to (e.g. "foundation", "investigation", "implications")mood — the intended emotional beat (e.g. "tension", "revelation", "authority")dimension — the primary analytical dimension (e.g. "economic", "geopolitical", "social")Field mapping — use the RIGHT names (wrong names = blank viewer):
moments NOT panels — viewer reads DATA.momentstext NOT narration — viewer reads moment.textproject_id NOT comic_id — must match folder name (e.g. "project-1")panel_id: "panel-01" NOT panel_number: 1speaker: always "NARRATOR" for text-onlyimage: empty string "" for text-only modeBefore writing, internalize the user's voice by reading their voice_description from users.csv. The voice must be:
Voice test: If you covered the author name AND the template formatting, could someone familiar with the profiles guess who wrote it?
MANDATORY: Every investigation must use web search to ground content in real March 2026 data:
Do NOT rely solely on training data. The Iran war is fictional but the economic data, historical context, and institutional information must be REAL and CURRENT.