@biolytics.ai/diascope
v0.1.2
Published
Turn D2 diagrams into narrated interactive stories
Readme
DiaScope
Turn any codebase, system, or flow into a narrated interactive diagram story — a self-contained .html file your audience can step through with arrow keys.
You author a D2 diagram and a YAML narration sidecar. DiaScope renders the diagram, wires up the step-by-step navigation, and writes one file you can open in a browser or share anywhere.
Docs: https://diascope.biolytics.ai
Or: install the narrate skill and let an agent do it for you.
How it looks
Each story is a full-screen page: diagram on the left, narration panel on the right. Each step highlights the relevant nodes, pans/zooms to them, and shows the title + body text. Click a node for detail. Press → to advance.
Interactive features
- Step-by-step narration with active node highlighting
- Automatic pan and zoom to the current step
Focusmode to isolate active nodes and edgesFitplus manual zoom controls- Keyboard navigation with arrow keys
- Clickable node detail panels
- Edge hover tooltips
See the live example and feature docs at https://diascope.biolytics.ai.
Requirements
- Node.js 18+
d2on your PATH
Install
npm install -g @biolytics.ai/diascopeHuman-driven workflow
1. Write your D2 diagram — and optionally annotate it with # @step markers:
# @step step-01
Client -> Server: POST /api/data
# @step step-02
Server -> Database: SELECT ...
# @step step-03
Database -> Server: result row
Server -> Client: 200 OK# @step comments are invisible to the D2 renderer. They tell diascope init which nodes belong to which narrative beat.
2. Scaffold the narration:
diascope init auth-flow.d2
# → writes auth-flow.story.yaml3. Fill in the narration — edit auth-flow.story.yaml:
meta:
title: "Auth Flow"
d2_source: auth-flow.d2
steps:
- id: step-01
tag: "01"
title: "Client sends authenticated request"
body: |
The client attaches a short-lived JWT in the Authorization header.
Tokens expire after 15 minutes — refresh before expiry or the
request is rejected at the next step.
nodes:
- Client
- Server
- id: step-02
tag: "02"
title: "Server queries the database"
nodes:
- Server
- Database4. Build:
diascope build auth-flow.d2 auth-flow.story.yaml -o auth-flow.html
open auth-flow.htmlAgent-driven workflow
Install the narrate skill into your coding agent. Then just point it at code:
"Narrate the payment flow in
src/payments/" "Create a diagram story explaining how the sync engine works" "Help me explain the request lifecycle to a new developer"
The agent reads your code, writes the D2 diagram and .story.yaml, runs diascope build, and hands you the .html.
Install for Claude Code
git clone https://github.com/Biolytics-AI/DiaScope.git ~/.claude/diascope
mkdir -p ~/.agents/skills
ln -s ~/.claude/diascope/skills ~/.agents/skills/diascopeRestart Claude Code. Full instructions: .claude/INSTALL.md
Install for Codex
Tell Codex:
Fetch and follow instructions from https://raw.githubusercontent.com/Biolytics-AI/DiaScope/main/.codex/INSTALL.mdFull instructions: .codex/INSTALL.md
Story format reference
The .story.yaml file is the source of truth for all narration. The .d2 file is never modified by DiaScope tooling.
Full reference: docs/story-format.md
Linking steps to nodes
nodes: values must match D2 node names exactly (case-sensitive):
| D2 source | nodes: value |
|-----------------|-----------------|
| Client | Client |
| System.Client | System.Client |
| "My Service" | My Service |
diascope build warns you if any referenced node ID isn't found in the rendered SVG.
Detail panels and edge tooltips
detail_panels:
Server: |
<p>Handles auth and routing. Rate limited: 1000 req/s.</p>
edge_tooltips:
"POST /api/data": "Authenticated with Bearer token"CLI reference
diascope build <diagram.d2> <story.yaml> [options]
-o, --out <file> Output HTML (default: <story>.html)
--viewer-bundle <path> Custom path/URL for viewer JS bundle
diascope init <diagram.d2> [options]
-o, --out <file> Output story file (default: <diagram>.story.yaml)Examples
Working examples live in examples/. The current vLLM example includes:
examples/vLLM/deployment.d2examples/vLLM/deployment.story.yamlexamples/vLLM/README.md
You can also browse the same example in the docs at https://diascope.biolytics.ai/examples/vllm-deployment/.
JS library
Embed in a framework or custom shell:
import { DiaScopeViewer } from "@biolytics.ai/diascope";
import { parseStoryFile, storyToViewerOptions } from "@biolytics.ai/diascope/story";
const story = parseStoryFile(yamlString);
const viewer = new DiaScopeViewer({
...storyToViewerOptions(story),
autoBindControls: true,
});
viewer.init();The viewer expects svg-pan-zoom on window.svgPanZoom (or via options.svgPanZoom). See templates/story.html for a complete working shell.
Release process
DiaScope releases are published from GitHub, not from local machines.
- Open a PR into
main. - Merge only after
build-and-testandbuild-docspass. - Create and push a version tag like
v0.1.0. - GitHub Actions publishes
@biolytics.ai/diascopeto npm and creates the matching GitHub Release.
Local npm publish should only be used for dry-runs and debugging.
LLM patching guide
When asking an LLM to update a .story.yaml:
- Add steps by appending to
steps[]with a new uniqueid - Node IDs come from the
.d2file — never invent them bodysupports inline HTML; use|block scalar for multi-line- Preserve existing
idvalues — they match# @stepannotations in the.d2 - Run
diascope buildafter edits to validate and regenerate
