Figure logo

Figure

OrganizationPopular
vectorize-io
figure

Draw an animated figure (boxes, arrows, moving data) as one self-contained SVG for a GitHub README, PR, issue or blog post. Use when a change or an explanation needs a diagram — how a request flows, what a background job does, what a feature changed — or when the user asks for a diagram, figure, animation or "show it visually". The docs site uses the interactive React figures instead.

Overview

Publishervectorize-io
Repositoryhindsight
Skill namefigure
Stars
44K
Forks
5.8K
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by vectorize-io on GitHub. Read the source before you install it.

Installation

Install the Figure AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/vectorize-io/hindsight/tree/main/.claude/skills/figure
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/vectorize-io/hindsight.git /tmp/hindsight
mkdir -p .claude/skills
cp -r /tmp/hindsight/.claude/skills/figure .claude/skills/figure
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Figure in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Figure on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Figure is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Figure

One animated SVG, no scripts, no upload: it renders and plays anywhere markdown does — GitHub README, PR and issue comments, blog posts, Notion. ~15 kB for a figure that would be a 2 MB video, sharp at any size, and it follows the reader's light or dark theme.

You write a JSON spec — never SVG, never a .ts figure file (those are only for the docs site's interactive figures, see below). One command renders it. No install, no build, no browser.

1. Write the spec

A spec is { "props": { "layout": …, "edges": […], "steps": […] } }. Do not save it as a file in the repo. It is an input, not a deliverable, and a stray spec.json is the one mess this skill must not leave behind — pipe it in (step 2), and the rendered SVG keeps a copy of it for you.

json
{
  "props": {
    "speed": 2000,
    "layout": {
      "gap": 48,
      "children": [
        { "id": "agent", "label": "Your AI Agent" },
        {
          "id": "api",
          "label": "Hindsight API",
          "direction": "column",
          "gap": 24,
          "children": [{ "id": "retain", "label": "Retain", "sub": "LLM extraction" }]
        },
        {
          "id": "bank",
          "label": "Memory Bank",
          "direction": "column",
          "gap": 28,
          "children": [
            { "id": "facts", "label": "Facts", "sub": "world · experience", "shape": "store" },
            { "id": "obs", "label": "Observations", "shape": "store" }
          ]
        }
      ]
    },
    "edges": [
      { "id": "call", "from": "agent", "to": "retain", "label": "retain()" },
      { "id": "store", "from": "retain", "to": "facts", "label": "extract" },
      { "id": "consolidate", "from": "facts", "to": "obs", "label": "consolidate", "quiet": true }
    ],
    "steps": [
      {
        "label": "retain()",
        "flow": [
          {
            "edges": { "edge": "call", "data": "“Alice joined Google in March”" },
            "say": "Your agent sends what happened."
          },
          {
            "edges": "store",
            "show": {
              "facts": [
                {
                  "tag": "world",
                  "tone": "blue",
                  "text": "Alice joined Google",
                  "meta": "Mar 2026",
                  "mark": "new"
                }
              ]
            },
            "say": "An LLM pulls out the facts."
          },
          {
            "edges": "consolidate",
            "ms": 2600,
            "show": { "obs": [{ "text": "Alice works at Google", "meta": "2 sources" }] },
            "say": "The worker merges them into one belief."
          }
        ]
      }
    ]
  }
}

Layout — a tree. A group has children, and label (which draws a frame around it), direction: "row" | "column", gap, align. Anything else is a box: { id, label, sub?, shape? }, where shape is "store" for a database cylinder (data at rest) or "decision" for a diamond. Plain boxes are the things that do something. Give every box a stable id.

Edges — { from, to, label?, id?, around?, quiet? }; from/to name a box or a group. around: "above" | "below" arcs over the boxes in between; quiet: true draws the edge only while a step uses it (for long edges that would cut across the picture).

Steps and beats — each step is one story the figure tells; the SVG plays them in a loop. A beat is one moment: edges (a hop id, { edge, back, data } for a reverse hop or a data chip, or an array to run several at once), say (the caption; it stays until the next say), show (fills the content card inside a box and persists to the end of the step), light (highlight boxes for that beat), ms (how long the beat lasts).

Card rows — { tag?, tone?, text, meta?, mark?, mono? }. tone is blue | purple | green | orange | gray. Use tag for the kind of thing (world, user, page), meta for a detail, and mark for what happened to it (new, ✓, cited, ↻).

Keep it honest and specific: real example data beats placeholders, and every claim in a label, card or caption must match what the code actually does — check the code, don't assume.

2. Render it — from stdin, so nothing is left on disk

bash
cd hindsight-interfig
npm run svg -- - ../path/to/out.svg <<'SPEC'
{ "props": { "layout": …, "edges": […], "steps": […] } }
SPEC

The quoted <<'SPEC' heredoc passes the JSON through untouched, and the only file produced is the SVG. Zero dependencies, no browser, no build.

Other forms:

bash
npm run svg -- what-hindsight-does out.svg   # a figure from figures/, by name
npm run svg -- --spec out.svg                # print the spec an SVG carries, to edit and re-render

Every SVG embeds its own spec in <metadata>, so a figure stays editable without anyone keeping the JSON: read it back with --spec, change what you need, render again. That is why a spec file is never worth committing.

Use npm run svg, not node scripts/... directly: the script name is the interface, the path is not.

3. Look at it before you ship it

Always. Text that overflows its box, an arrow crossing a box, a caption that does not match what is moving — obvious on sight, invisible in the source.

bash
cd $(dirname out.svg) && python3 -m http.server 8777 &   # the browser tool blocks file:// URLs

Then open http://localhost:8777/out.svg, screenshot it, wait a few seconds and screenshot again to catch a later beat. open out.svg works too when a human is watching.

4. Put it where it belongs

  • PR or issue comment — commit the SVG on the branch, then reference its raw URL: ![figure](https://raw.githubusercontent.com/<owner>/<repo>/<branch>/<path>.svg). GitHub renders and animates it immediately. (Dragging a file into a comment also works, but only a human can do that, and GitHub keeps a fresh upload private for several minutes.)
  • README or repo docs — commit it and link it with a relative path.
  • Blog post — hindsight-docs/static/img/blog/, referenced as /img/blog/<name>.svg. An SVG under hindsight-docs/static/ is also read by the docs-skill generator: it pulls the spec out of the image and writes the narration into the skill, so an agent reading the docs gets the content and not a dead image link.
  • The docs site's own pages — don't use an SVG. Those pages embed the interactive React figure, which has tabs, pause, speed and hover. Add a hindsight-interfig/figures/<name>.ts instead and <Flow {...figure.props} /> on the page (see hindsight-interfig/README.md).

A worked example

The spec in step 1 is a complete, working figure — copy it and edit. Any SVG you find carries its own spec too: npm run svg -- --spec <file>.svg prints it back, so an existing figure is the fastest starting point for a new one.

What the SVG cannot do

It loops through every step with no controls: no tabs, no pause, no hover. If the figure needs those, it belongs on the docs site as a React figure. Keep an SVG to one or two steps so the loop comes back round quickly.

Frequently asked questions

What does the Figure AI skill do?

Draw an animated figure (boxes, arrows, moving data) as one self-contained SVG for a GitHub README, PR, issue or blog post. Use when a change or an explanation needs a diagram — how a request flows, what a background job does, what a feature changed — or when the user asks for a diagram, figure, animation or "show it visually". The docs site uses the interactive React figures instead.

Why use Figure on TypingMind?

Because you install it once and use it with any model. Figure is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Figure in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/vectorize-io/hindsight/tree/main/.claude/skills/figure. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Figure?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Figure?

As many as you like. As long as a model supports skills, you can use Figure with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Figure AI skill free?

Yes. It is published on GitHub by vectorize-io under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇