Skip to content

Commit 8558edf

Browse files
authored
Merge pull request #678 from nteract/support-ai
Support AI
2 parents b89bebd + fa21634 commit 8558edf

17 files changed

Lines changed: 5114 additions & 651 deletions

.cursorrules

Lines changed: 527 additions & 0 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,47 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Added
11+
12+
#### AI Enablement — Phase 2
13+
14+
Five features to deepen AI integration with Semiotic.
15+
16+
**Compact System Prompt** (`ai/system-prompt.md`):
17+
- ~30-line prompt listing all 24 components grouped by data shape (flat array, hierarchical, network, realtime)
18+
- Marks required and distinguishing props per component
19+
- Designed for pasting into custom instructions or system prompts
20+
21+
**Embeddings-Friendly Examples** (`ai/examples.md`):
22+
- Copy-paste-ready examples for 13 chart types covering all 4 data shapes
23+
- Each example includes import, realistic inline data, and key props annotation
24+
- Covers: LineChart (single + multi-line), Scatterplot, Heatmap, BarChart, StackedBarChart, GroupedBarChart, TreeDiagram, Treemap, CirclePack, ForceDirectedGraph, SankeyDiagram, ChordDiagram
25+
26+
**`validateProps` Function** (exported from `semiotic/ai`):
27+
- `validateProps(componentName, props)` returns `{ valid: boolean, errors: string[] }`
28+
- Validates: component name, required props, prop types, enum values, unknown props (typo detection)
29+
- Delegates data shape validation to existing `validateArrayData`/`validateObjectData`/`validateNetworkData`
30+
- Static validation map covering all 24 components with per-prop type and enum constraints
31+
32+
**CLI Tool** (`ai/cli.js`):
33+
- `npx semiotic-ai` — dumps CLAUDE.md to stdout
34+
- `npx semiotic-ai --schema` — dumps ai/schema.json
35+
- `npx semiotic-ai --compact` — dumps ai/system-prompt.md
36+
- `npx semiotic-ai --examples` — dumps ai/examples.md
37+
- Plain Node.js, no dependencies, no build step
38+
39+
**MCP Server** (`ai/mcp-server.ts`):
40+
- Exposes 20 SVG-renderable chart components as MCP tools
41+
- Renders to static SVG via `ReactDOMServer.renderToStaticMarkup`
42+
- Uses `ai/schema.json` for tool definitions, `validateProps` for error reporting
43+
- Component registry maps names to React components
44+
- Separate build: `npm run build:mcp` (TypeScript → `ai/dist/`)
45+
- Usage: `npx semiotic-mcp` in Claude Desktop or any MCP client
46+
47+
---
48+
849
## [3.0.0-beta.1] - 2026-02-28
950

1051
### Added

CLAUDE.md

Lines changed: 530 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,22 @@ Frame API without giving up the simpler interface.
3636
Sankey diagrams, chord diagrams, tree layouts, treemaps, and circle packing
3737
are all React components with the same clean prop API as LineChart.
3838

39-
**When to use something else.** Need a line chart for a dashboard?
40-
[Recharts](https://recharts.org) is simpler and has a larger ecosystem.
41-
Semiotic is built for projects that need network diagrams, statistical
42-
summaries, annotation systems, or custom mark rendering alongside
43-
standard charts — all in one library.
39+
**What Semiotic does that other libraries don't:**
40+
- Force-directed graphs, Sankey diagrams, chord diagrams, treemaps, and circle packing — as React components with the same clean API as LineChart
41+
- Real-time streaming charts rendered on canvas at 60fps
42+
- Built-in annotation system with hover, click, and custom annotation types
43+
- Server-side SVG rendering for email, OG images, and PDFs
44+
45+
**When to use something else.** Need a standard line or bar chart for a dashboard?
46+
[Recharts](https://recharts.org) has a larger ecosystem and more community examples.
47+
Semiotic is built for projects that need network visualization, statistical summaries,
48+
or custom mark rendering — capabilities that general-purpose charting libraries don't offer.
49+
50+
**AI-ready.** Semiotic ships with structured schemas (`ai/schema.json`), an
51+
`import from "semiotic/ai"` entry point, and an MCP server — all designed for
52+
LLM code generation. AI coding assistants can generate correct Semiotic code on
53+
the first try. Run `npx semiotic-ai --help` for CLI options or add `semiotic-mcp`
54+
to your MCP client config for tool-based chart rendering.
4455

4556
## Install
4657

@@ -145,6 +156,7 @@ Import only what you need:
145156
import { LineChart } from "semiotic/xy" // 125 KB (vs 218 KB full)
146157
import { BarChart } from "semiotic/ordinal" // 140 KB
147158
import { ForceDirectedGraph } from "semiotic/network" // 133 KB
159+
import { LineChart } from "semiotic/ai" // HOC-only surface for AI generation
148160
```
149161

150162
## TypeScript

ai/cli.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env node
2+
"use strict"
3+
4+
const fs = require("fs")
5+
const path = require("path")
6+
7+
const pkgRoot = path.resolve(__dirname, "..")
8+
9+
const FILES = {
10+
default: path.join(pkgRoot, "CLAUDE.md"),
11+
"--schema": path.join(__dirname, "schema.json"),
12+
"--compact": path.join(__dirname, "system-prompt.md"),
13+
"--examples": path.join(__dirname, "examples.md"),
14+
}
15+
16+
const HELP = `
17+
semiotic-ai — Dump Semiotic AI context to stdout
18+
19+
Usage:
20+
npx semiotic-ai Print CLAUDE.md (full reference)
21+
npx semiotic-ai --schema Print ai/schema.json (tool definitions)
22+
npx semiotic-ai --compact Print ai/system-prompt.md (compact prompt)
23+
npx semiotic-ai --examples Print ai/examples.md (copy-paste examples)
24+
npx semiotic-ai --help Show this help message
25+
`.trim()
26+
27+
const flag = process.argv[2]
28+
29+
if (flag === "--help" || flag === "-h") {
30+
console.log(HELP)
31+
process.exit(0)
32+
}
33+
34+
const filePath = flag ? FILES[flag] : FILES.default
35+
36+
if (!filePath) {
37+
console.error(`Unknown flag: ${flag}\n`)
38+
console.error(HELP)
39+
process.exit(1)
40+
}
41+
42+
try {
43+
const content = fs.readFileSync(filePath, "utf-8")
44+
process.stdout.write(content)
45+
} catch (err) {
46+
console.error(`Error reading ${filePath}: ${err.message}`)
47+
process.exit(1)
48+
}

ai/componentRegistry.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Maps component names to their React component + category.
3+
* Used by the MCP server to look up components for rendering.
4+
*/
5+
import type { ComponentType } from "react"
6+
7+
import { LineChart } from "../src/components/charts/xy/LineChart"
8+
import { AreaChart } from "../src/components/charts/xy/AreaChart"
9+
import { StackedAreaChart } from "../src/components/charts/xy/StackedAreaChart"
10+
import { Scatterplot } from "../src/components/charts/xy/Scatterplot"
11+
import { BubbleChart } from "../src/components/charts/xy/BubbleChart"
12+
import { Heatmap } from "../src/components/charts/xy/Heatmap"
13+
14+
import { BarChart } from "../src/components/charts/ordinal/BarChart"
15+
import { StackedBarChart } from "../src/components/charts/ordinal/StackedBarChart"
16+
import { GroupedBarChart } from "../src/components/charts/ordinal/GroupedBarChart"
17+
import { SwarmPlot } from "../src/components/charts/ordinal/SwarmPlot"
18+
import { BoxPlot } from "../src/components/charts/ordinal/BoxPlot"
19+
import { DotPlot } from "../src/components/charts/ordinal/DotPlot"
20+
import { PieChart } from "../src/components/charts/ordinal/PieChart"
21+
import { DonutChart } from "../src/components/charts/ordinal/DonutChart"
22+
23+
import { ForceDirectedGraph } from "../src/components/charts/network/ForceDirectedGraph"
24+
import { ChordDiagram } from "../src/components/charts/network/ChordDiagram"
25+
import { SankeyDiagram } from "../src/components/charts/network/SankeyDiagram"
26+
import { TreeDiagram } from "../src/components/charts/network/TreeDiagram"
27+
import { Treemap } from "../src/components/charts/network/Treemap"
28+
import { CirclePack } from "../src/components/charts/network/CirclePack"
29+
30+
export interface RegistryEntry {
31+
component: ComponentType<any>
32+
category: "xy" | "ordinal" | "network"
33+
}
34+
35+
export const COMPONENT_REGISTRY: Record<string, RegistryEntry> = {
36+
LineChart: { component: LineChart, category: "xy" },
37+
AreaChart: { component: AreaChart, category: "xy" },
38+
StackedAreaChart: { component: StackedAreaChart, category: "xy" },
39+
Scatterplot: { component: Scatterplot, category: "xy" },
40+
BubbleChart: { component: BubbleChart, category: "xy" },
41+
Heatmap: { component: Heatmap, category: "xy" },
42+
43+
BarChart: { component: BarChart, category: "ordinal" },
44+
StackedBarChart: { component: StackedBarChart, category: "ordinal" },
45+
GroupedBarChart: { component: GroupedBarChart, category: "ordinal" },
46+
SwarmPlot: { component: SwarmPlot, category: "ordinal" },
47+
BoxPlot: { component: BoxPlot, category: "ordinal" },
48+
DotPlot: { component: DotPlot, category: "ordinal" },
49+
PieChart: { component: PieChart, category: "ordinal" },
50+
DonutChart: { component: DonutChart, category: "ordinal" },
51+
52+
ForceDirectedGraph: { component: ForceDirectedGraph, category: "network" },
53+
ChordDiagram: { component: ChordDiagram, category: "network" },
54+
SankeyDiagram: { component: SankeyDiagram, category: "network" },
55+
TreeDiagram: { component: TreeDiagram, category: "network" },
56+
Treemap: { component: Treemap, category: "network" },
57+
CirclePack: { component: CirclePack, category: "network" },
58+
}

0 commit comments

Comments
 (0)