# gbillois/crisismaker architecture

> Architecture diagram of the GitHub repository gbillois/crisismaker, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/gbillois/crisismaker
- Repository: https://github.com/gbillois/crisismaker
- Video tour (about a minute): https://gitdiagram.com/gbillois/crisismaker/video

## Overview

CrisisMaker is a browser-based authoring and export tool for cyber crisis exercise stimuli. Users shape an exercise scenario, create and preview timed stimuli, optionally use AI or Agent mode to draft and revise content, check the exercise, then save or export it. A separate Video Debrief studio supports documentary-style video production. The map follows README-described capabilities and the sampled runtime code; unsampled subsystem links are included only where the README documents them.

Main entry points: [`js/app.js`](https://github.com/gbillois/crisismaker/blob/main/js/app.js) (App controller), [`js/agent-runner.js`](https://github.com/gbillois/crisismaker/blob/main/js/agent-runner.js) (Agent runner), [`js/ai.js`](https://github.com/gbillois/crisismaker/blob/main/js/ai.js) (AI transport), [`js/persistence.js`](https://github.com/gbillois/crisismaker/blob/main/js/persistence.js) (Project persistence)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_authoring["Exercise authoring"]
  node_app["App controller<br/>[app.js]"]
  node_scenario["Scenario data<br/>[data.js]"]
  node_views["Editor views<br/>[views.js]"]
  node_templates["Stimulus templates<br/>[templates.js]"]
  node_stimulus["Stimulus renderer<br/>[templates.js]"]
end

subgraph group_intelligence["AI and Agent"]
  node_ai["AI transport<br/>[ai.js]"]
  node_config["Provider settings<br/>[config.js]"]
  node_agent["Agent runner<br/>[agent-runner.js]"]
  node_agenttools["Agent tools<br/>[agent-tools.js]"]
  node_agentprompts["Agent prompts<br/>[agent-prompts.js]"]
end

subgraph group_output["Review and export"]
  node_checker["Exercise checker<br/>[checker.js]"]
  node_persistence["Project persistence<br/>[persistence.js]"]
end

subgraph group_debrief["Debrief studios"]
  node_debrief["Timeline debrief<br/>[debrief.js]"]
  node_videoapp["Video Debrief studio<br/>[index.html]"]
  node_engine["Video render engine<br/>[scene.html]"]
  node_pipeline["Video production<br/>[build.py]"]
  node_localserver["Local production server<br/>[server.py]"]
  node_mp4["Rendered video"]
end

subgraph group_services["External services"]
  node_browserstore[("Browser storage")]
  node_files["Project files"]
  node_provider{{"AI provider"}}
  node_relay["Cloudflare relay<br/>[llm.js]"]
end

node_user(("Exercise designer"))

node_user -->|"edits exercise"| node_app
node_app -->|"renders interface"| node_views
node_app -->|"manages exercise"| node_scenario
node_views -->|"dispatches actions"| node_app
node_app -->|"creates stimuli"| node_templates
node_templates -->|"renders preview"| node_stimulus
node_app -->|"checks exercise"| node_checker
node_app -->|"saves and loads"| node_persistence
node_persistence -->|"stores checkpoint"| node_browserstore
node_persistence -->|"imports and exports"| node_files
node_app -->|"requests generation"| node_ai
node_app -->|"reads settings"| node_config
node_ai -->|"sends prompts"| node_provider
node_ai -.->|"retries network failures"| node_relay
node_relay -.->|"forwards request"| node_provider
node_app -->|"starts agent run"| node_agent
node_agent -->|"uses instructions"| node_agentprompts
node_agent -->|"dispatches tools"| node_agenttools
node_agenttools -->|"edits exercise"| node_scenario
node_agent -->|"requests model steps"| node_ai
node_app -->|"opens timeline debrief"| node_debrief
node_app -->|"embeds studio"| node_videoapp
node_videoapp -->|"previews scenes"| node_engine
node_videoapp -.->|"requests local production"| node_localserver
node_localserver -->|"starts build"| node_pipeline
node_pipeline -->|"renders frames"| node_engine
node_pipeline -->|"produces MP4"| node_mp4

click node_app "https://github.com/gbillois/crisismaker/blob/main/js/app.js"
click node_scenario "https://github.com/gbillois/crisismaker/blob/main/js/data.js"
click node_views "https://github.com/gbillois/crisismaker/blob/main/js/views.js"
click node_templates "https://github.com/gbillois/crisismaker/blob/main/js/templates.js"
click node_stimulus "https://github.com/gbillois/crisismaker/blob/main/js/templates.js"
click node_ai "https://github.com/gbillois/crisismaker/blob/main/js/ai.js"
click node_config "https://github.com/gbillois/crisismaker/blob/main/js/config.js"
click node_agent "https://github.com/gbillois/crisismaker/blob/main/js/agent-runner.js"
click node_agenttools "https://github.com/gbillois/crisismaker/blob/main/js/agent-tools.js"
click node_agentprompts "https://github.com/gbillois/crisismaker/blob/main/js/agent-prompts.js"
click node_checker "https://github.com/gbillois/crisismaker/blob/main/js/checker.js"
click node_persistence "https://github.com/gbillois/crisismaker/blob/main/js/persistence.js"
click node_relay "https://github.com/gbillois/crisismaker/blob/main/functions/api/llm.js"
click node_debrief "https://github.com/gbillois/crisismaker/blob/main/js/debrief.js"
click node_videoapp "https://github.com/gbillois/crisismaker/blob/main/video-debrief/index.html"
click node_engine "https://github.com/gbillois/crisismaker/blob/main/video-debrief/engine/scene.html"
click node_pipeline "https://github.com/gbillois/crisismaker/blob/main/video-debrief/pipeline/build.py"
click node_localserver "https://github.com/gbillois/crisismaker/blob/main/video-debrief/pipeline/server.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_scenario,node_views,node_templates,node_stimulus toneBlue
class node_ai,node_config,node_agent,node_agenttools,node_agentprompts toneAmber
class node_checker,node_persistence toneMint
class node_debrief,node_videoapp,node_engine,node_pipeline,node_localserver,node_mp4 toneRose
class node_browserstore,node_files,node_provider,node_relay,node_user toneIndigo
```

## Components

### Exercise authoring

- [App controller](https://github.com/gbillois/crisismaker/blob/main/js/app.js): `js/app.js`
- [Scenario data](https://github.com/gbillois/crisismaker/blob/main/js/data.js): `js/data.js`
- [Editor views](https://github.com/gbillois/crisismaker/blob/main/js/views.js): `js/views.js`
- [Stimulus templates](https://github.com/gbillois/crisismaker/blob/main/js/templates.js): `js/templates.js`
- [Stimulus renderer](https://github.com/gbillois/crisismaker/blob/main/js/templates.js): `js/templates.js`

### AI and Agent

- [AI transport](https://github.com/gbillois/crisismaker/blob/main/js/ai.js): `js/ai.js`
- [Provider settings](https://github.com/gbillois/crisismaker/blob/main/js/config.js): `js/config.js`
- [Agent runner](https://github.com/gbillois/crisismaker/blob/main/js/agent-runner.js): `js/agent-runner.js`
- [Agent tools](https://github.com/gbillois/crisismaker/blob/main/js/agent-tools.js): `js/agent-tools.js`
- [Agent prompts](https://github.com/gbillois/crisismaker/blob/main/js/agent-prompts.js): `js/agent-prompts.js`

### Review and export

- [Exercise checker](https://github.com/gbillois/crisismaker/blob/main/js/checker.js): `js/checker.js`
- [Project persistence](https://github.com/gbillois/crisismaker/blob/main/js/persistence.js): `js/persistence.js`

### Debrief studios

- [Timeline debrief](https://github.com/gbillois/crisismaker/blob/main/js/debrief.js): `js/debrief.js`
- [Video Debrief studio](https://github.com/gbillois/crisismaker/blob/main/video-debrief/index.html): `video-debrief/index.html`
- [Video render engine](https://github.com/gbillois/crisismaker/blob/main/video-debrief/engine/scene.html): `video-debrief/engine/scene.html`
- [Video production](https://github.com/gbillois/crisismaker/blob/main/video-debrief/pipeline/build.py): `video-debrief/pipeline/build.py`
- [Local production server](https://github.com/gbillois/crisismaker/blob/main/video-debrief/pipeline/server.py): `video-debrief/pipeline/server.py`
- **Rendered video**

### External services

- **Browser storage**
- **Project files**
- **AI provider**
- [Cloudflare relay](https://github.com/gbillois/crisismaker/blob/main/functions/api/llm.js): `functions/api/llm.js`

### Other components

- **Exercise designer**

## Connections

- Exercise designer → App controller: edits exercise
- App controller → Editor views: renders interface
- App controller → Scenario data: manages exercise
- Editor views → App controller: dispatches actions
- App controller → Stimulus templates: creates stimuli
- Stimulus templates → Stimulus renderer: renders preview
- App controller → Exercise checker: checks exercise
- App controller → Project persistence: saves and loads
- Project persistence → Browser storage: stores checkpoint
- Project persistence → Project files: imports and exports
- App controller → AI transport: requests generation
- App controller → Provider settings: reads settings
- AI transport → AI provider: sends prompts
- AI transport → Cloudflare relay: retries network failures
- Cloudflare relay → AI provider: forwards request
- App controller → Agent runner: starts agent run
- Agent runner → Agent prompts: uses instructions
- Agent runner → Agent tools: dispatches tools
- Agent tools → Scenario data: edits exercise
- Agent runner → AI transport: requests model steps
- App controller → Timeline debrief: opens timeline debrief
- App controller → Video Debrief studio: embeds studio
- Video Debrief studio → Video render engine: previews scenes
- Video Debrief studio → Local production server: requests local production
- Local production server → Video production: starts build
- Video production → Video render engine: renders frames
- Video production → Rendered video: produces MP4
