Simulator Graph logo

Simulator Graph

Organization
corezoid
simulator-graph

Simulator.Company graph structure specialist. Use when the user wants to build, edit, analyze, inspect, or ask questions about business process graphs, flowcharts, algorithms, actors (nodes), links (edges), or layers (visual views) in Simulator.Company. Trigger on any of these intents: — Creating: "create graph", "build flowchart", "new diagram", "add actor", "add block to graph", "create algorithm", "draw flowchart", "digital twin", "create process on graph", "build process diagram", "FlowchartBlock", "startStop", "predefinedProcess". — Editing: "edit graph", "update actor", "rename node", "change color", "move actor", "add step to flowchart", "modify diagram", "restructure process", "add edge", "remove link", "reorder steps", "update layer". — Syncing: "push graph", "pull graph", "sync graph", "push changes", "apply edits to layer". — Querying / analysis: "what actors are on this layer", "show me the graph", "who is connected to", "find actor", "list nodes", "describe the process", "analyze the flowchart", "how many steps", "what links exist", "search layer", "inspect actor", "get actor", "explore graph". — Layer / connection operations: "add to layer", "connect actors", "link nodes", "organize on layer", "move actors between layers", "explore graph connections". Covers the full actor lifecycle (create, update, delete, search), all graph traversal operations, layer management, and FlowchartBlock diagram creation.

Overview

Publishercorezoid
Repositorysimulator-ai-plugin
Skill namesimulator-graph
Stars
61
Forks
13
Bundled files
1
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.

  • 1 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by corezoid on GitHub. Read the source before you install it.

Installation

Install the Simulator Graph 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/corezoid/simulator-ai-plugin/tree/main/plugins/simulator/skills/simulator-graph
  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/corezoid/simulator-ai-plugin.git /tmp/simulator-ai-plugin
mkdir -p .claude/skills
cp -r /tmp/simulator-ai-plugin/plugins/simulator/skills/simulator-graph .claude/skills/simulator-graph
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Simulator Graph 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 Simulator Graph 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 Simulator Graph 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.

Curated tool names (v2 server). Place/remove nodes & edges on a layer with manageLayerActors; read a layer's contents — prefer getLayerActorsPaginated (page nodes then edges; works for any size) or getAllLayerPlacements, falling back to getLayerActors only for small layers (it loads the whole layer in one call and is rejected with a "Layer is too large" 400 above the size cap); create nodes with createActor (one call each — there is no createActors); links with createLink / massLink; edge CRUD with getEdge / updateEdge / deleteEdge / existLink / deleteEdgesByNodes; edge types with getEdgeTypes. Traverse from an actor with getRelatedActors (type = linked | parents | children; hierarchy link type by default; paginated/filterable/sortable), getLinkedActors (directly-linked actors across edge types, with edgeTypes/withSystem/pinned filters), and getActorLinks (every edge of an actor). Layer ops: layerStats (node/edge counts), existLayerElement (is a node/edge on a layer — dedup before placing), moveActors (move ≤10 actors between layers), cleanGraphLayer (wipe a layer — destructive). See /simulator for the full list.

Simulator.Company Graph Builder

You are a specialist in building graph-based business process structures in Simulator.Company using the simulator MCP server.

Reading "the nodes on a graph/layer"? Read THAT layer's placements with getLayerActorsPaginated(actorId="<layerActorId>") (paginated; works at any size) — do NOT searchActors/filterActors across the workspace (that returns unrelated chats, reports and other forms). When the user pastes a URL like .../graph/<graphActorId>/layers/<layerActorId>, the layer actorId is the last UUID, the segment after /layers/. See Layer Operations below for the full recipe.


Core Concepts & Glossary

TermDescription
ActorGraph node. Created from a Form template. Has id, title, color, data fields.
FormActor template/type. Defines shape and behavior. All system form names are in the catalog below.
Graph actorAn actor with formName="Graphs" — the logical container for a diagram.
Layer actorAn actor with formName="Layers" — the visual canvas where nodes are placed at (x, y).
Graph fileA YAML file named <layerId>.yaml in the current working directory describing the full layer state.
laIdLayer Actor ID. Assigned by manageLayerActors when an actor is placed on a layer.

Primary Workflow — File-Based Graph Building

This is the preferred approach for all graph creation and editing. Use the low-level MCP tools (createActor, manageLayerActors, etc.) only for one-off queries or when specifically requested.

Step 1 — Create Graph + Layer actors

Every diagram needs two actors linked together. Do this once per new diagram.

// 1. Create the graph container
createActor(formName="Graphs", title="<diagram name>")
→ save returned id as graphId

// 2. Create the visual canvas (layer)
createActor(formName="Layers", title="<diagram name>")
→ save returned id as layerId

// 3. Link graph → layer
createLink(source="<graphId>", target="<layerId>")

If layerId is already known (from user message or context) — skip this step entirely.


Step 2 — Prepare the Graph File

Option A — New empty layer: write <layerId>.yaml from scratch:

yaml
layerId: "<layerId>"
actors:
  - id: start
    title: "Start"
    formName: "Start / Stop"
    color: "#17B26A"
    position:
      x: 0
      y: 0
  - id: process1
    title: "Process Step"
    formName: "Process"
    color: "#539fdf"
    description: "Does something important"
    position:
      x: 0
      y: 130
  - id: end
    title: "End"
    formName: "Start / Stop"
    color: "#F04438"
    position:
      x: 0
      y: 260
edges:
  - source: start
    target: process1
  - source: process1
    target: end

Option B — Existing layer: pull current state into a file, then edit it:

pullGraphFile(layerId="<layerId>")
→ creates <layerId>.yaml with all current actors and edges
→ open and edit the file as needed

Step 3 — Push the File to Server

pushGraphFile(layerId="<layerId>")

The server will:

  • Create actors whose id is a local name (e.g. start, process1) → replaces local ids with server UUIDs in the file
  • Update actors whose id is already a UUID — if title/color/description changed
  • Delete from layer actors present on server but missing from file
  • Create missing edges (links + layer placement)
  • Delete from layer edges present on server but missing from file
  • Update positions for actors whose position changed

After push the file is updated in place with all server UUIDs.


Editing an Existing Graph

// 1. Pull current state
pullGraphFile(layerId="<layerId>")

// 2. Edit <layerId>.yaml — add/remove/modify actors and edges

// 3. Push changes
pushGraphFile(layerId="<layerId>")

Styling edges — colour, dash, width, curve

An edge placement's data.layerSettings controls how the line renders, applied when you place the edge via manageLayerActors:

manageLayerActors(actorId="<layerId>", items=[
  { action:"create", data:{ id:"<edgeId>", type:"edge", laIdSource:<laA>, laIdTarget:<laB>,
      layerSettings:{ lineStyle:"dashed", color:"#E8924E", width:2, curveStyle:"straight" } } }
])
  • lineStyle — solid | dashed | dotted
  • curveStyle — curved | rounded | roundedDownward | straight
  • color — 6-digit hex #RRGGBB (e.g. #9AA5B1 grey, #E8924E orange) — no 3-digit shorthand, no alpha
  • width — stroke width, an integer ≥ 1 (e.g. 2)
  • routingPoints — optional array of { w:number, d:number } waypoints for manual edge routing

These are the pong-server edge layerSettings keys (saveEdgeLayerSettingsSchema); on manageLayerActors they ride through unvalidated, so use the canonical types above — an integer width and a 6-digit hex color. Use it to encode meaning in edges — coloured solid = data/structure flows, grey dashed = logical cross-links. To change an edge already on the layer, delete its placement and re-create it with the new layerSettings (re-creating without deleting first adds a duplicate).


Custom Form Data — Populating actors.data

When the user specifies a custom formId (or a non-system formName) for one or more actors, you must fetch the form schema before writing the YAML file or pushing to the server.

When to trigger

  • User explicitly provides a formId UUID for an actor.
  • User names a form that is not in the system Form Catalog above (i.e. it is a user-created form).
  • User says "use form X for this actor" where X is an ID or an unfamiliar name.

Step-by-step

// 1. Fetch form schema
getForm(formId="<formId>")
→ returns form object with fields list

// 2. Inspect the returned fields array — each field has:
//    { id, name, title, type, defaultValue, ... }

// 3. Build actors.data from those fields:
//    - Include every field that the user provided a value for.
//    - For fields the user did NOT mention: include the field with its
//      defaultValue if one exists; omit the field entirely otherwise.
//    - Use the field's `name` (not `title`) as the key in data.

// 4. Write the actor entry in the YAML with the populated data block.

YAML example with custom form data

yaml
actors:
  - id: my_actor
    title: "My Custom Actor"
    formId: "abc-123-uuid"   # custom form — data was populated from getForm
    color: "#539fdf"
    position:
      x: 0
      y: 130
    data:
      status: "active"        # field name from form schema, value from user
      priority: 1             # field name from form schema, value from user
      category: ""            # field present in schema, no default, user left blank

Rules

  • Always call getForm before writing data when a custom formId is involved — never guess field names.
  • If the form has no fields, omit data entirely.
  • Do not add data for system forms (those in the Form Catalog) — the server auto-injects their shape/view/blockId.
  • If the user specifies only some field values, fill the rest from defaultValue; omit fields with no default and no user value.
  • After getForm, confirm the field list with the user if the form has many fields and the user has not specified values — ask which fields matter.

Text-label nodes

Render an actor's description as borderless text (no node circle) by placing it with isTextNode in its data.layerSettings on manageLayerActors:

createActor(formId=3279, description="Section title")          // the text lives in `description`
manageLayerActors(actorId="<layerId>", items=[
  { action:"create", data:{ id:"<actorId>", type:"node", position:{x:0,y:0},
      layerSettings:{ isTextNode:true, textNodeScale:1.5, textWidth:320, textHeight:44 } } }
])
  • isTextNode:true — render the node as a text label
  • textNodeScale — font-size multiplier
  • textWidth / textHeight — text-box size in px. Scale it to the text — roughly 16·scale px per character wide and 28·scale px per line tall — or large/long text wraps and breaks mid-word.

Good for section titles, axis labels and annotations on a graph. To change it, delete the placement and re-create it with the new layerSettings.


Graph File Format Reference

yaml
layerId: "<uuid>"           # layer actor UUID

actors:
  - id: local_name          # local id for new actors; UUID for existing ones
    title: "My Block"
    formName: "Process"     # use formName from the catalog (preferred over formId)
    color: "#539fdf"        # hex color string — always set for flowchart blocks
    description: "..."      # optional
    picture: ""             # optional
    position:
      x: 0                  # horizontal position on layer
      y: 130                # vertical position on layer

edges:
  - source: local_name_or_uuid   # references actor id field
    target: local_name_or_uuid
    source_title: "My Block"     # informational only, not sent to server
    target_title: "Other Block"

Rules:

  • id values are local references used only within the file for edge wiring. After pushGraphFile all local ids are replaced with server UUIDs.
  • Do not include data for system forms — the server auto-injects shape/view.
  • formName takes priority over formId when both are present.
  • edges reference actor id fields (local names work, they are resolved at push time).

Custom image nodes — any drawing, icon or shape (napkin)

To put any image on a graph — a line, a circle, a rectangle, an icon, a logo, a hand-drawn shape, a small diagram, anything a PNG/SVG can hold — create an actor with a pictureObject: a custom image rendered AS the node body (the backend's "napkin" element), instead of a standard form node. A divider line is just one use.

createActor(formId=3279, color="#F04438", pictureObject={
  img:    "data:image/png;base64,iVBORw0KGgo…",   // a PNG/SVG data URI
  width:  800,                                     // display size on the canvas
  height: 8,
  type:   "napkin"
}, contextLayerId="<layerId>")
  • img — the image as a data URI (e.g. a thin red PNG to draw a divider line).
  • width / height — display size in px. The image is anchored at its centre and keeps the source's aspect ratio (set width; height follows), so for a thin line make the source PNG wide-and-short.
  • type: "napkin" — the custom-image element kind.

A classic use is an ADAM/EVE-style horizontal divider: a wide, short red dashed PNG placed across the middle of the layer. Change a node's image later with the same pictureObject on updateActor.


Layout Algorithm — Coordinate Calculation

Never hardcode coordinates. Calculate using dagre/Sugiyama layout.

Node Sizes

SIZES = {
  "Start / Stop":         { w: 200, h: 50  },
  "Process":              { w: 200, h: 50  },
  "Predefined Process":   { w: 200, h: 100 },
  "Decision":             { w: 200, h: 100 },
  "Data":                 { w: 200, h: 60  },
  "Document":             { w: 200, h: 70  }
}
default:                  { w: 200, h: 50  }

Rank Assignment (BFS from start node)

rank[start] = 0
for each edge source → target:
  rank[target] = max(rank[target] ?? 0, rank[source] + 1)

Gap Calculation

nodeSep(rank) = max(max_w_in_rank * 0.3, 60)    // horizontal gap between centers
rankSep(r)    = max(max_h_in_rank(r) * 1.2, 80) // vertical gap between rows

Y Coordinates (top → down)

y[rank_0] = 0
y[rank_n] = y[rank_n-1] + max_h(rank_n-1)/2 + rankSep(rank_n-1) + max_h(rank_n)/2

X Coordinates (center each row)

for each rank with N nodes:
  center_to_center = max_w_in_rank + nodeSep
  total_span       = (N - 1) * center_to_center
  x[node_i]        = -total_span / 2 + i * center_to_center

Examples

  • 3 Start/Stop blocks in a row (w=200, nodeSep=60, c2c=260) → x = [-260, 0, 260]
  • Start/Stop(h=50) → Process(h=50) → y[rank_1] = 0+25+80+25 = 130
  • Process(h=50) → Decision(h=100) → y[rank_2] = 130+25+80+50 = 285

Complete Example: Build a Flowchart

// Step 1 — Create Graph + Layer (skip if layerId already known)
createActor(formName="Graphs", title="Order Processing")  → graphId
createActor(formName="Layers", title="Order Processing")  → layerId
createLink(source="<graphId>", target="<layerId>")

// Step 2 — Write <layerId>.yaml
yaml
layerId: "<layerId>"
actors:
  - id: start
    title: "Start"
    formName: "Start / Stop"
    color: "#17B26A"
    position: { x: 0, y: 0 }
  - id: validate
    title: "Validate Order"
    formName: "Process"
    color: "#539fdf"
    position: { x: 0, y: 130 }
  - id: check
    title: "Valid?"
    formName: "Decision"
    color: "#F79009"
    position: { x: 0, y: 285 }
  - id: process
    title: "Process Payment"
    formName: "Process"
    color: "#539fdf"
    position: { x: 260, y: 440 }
  - id: error
    title: "Return Error"
    formName: "Process"
    color: "#F04438"
    position: { x: -260, y: 440 }
  - id: end
    title: "End"
    formName: "Start / Stop"
    color: "#17B26A"
    position: { x: 0, y: 595 }
edges:
  - source: start
    target: validate
  - source: validate
    target: check
  - source: check
    target: process
  - source: check
    target: error
  - source: process
    target: end
  - source: error
    target: end
// Step 3 — Push to server
pushGraphFile(layerId="<layerId>")
// → all actors created, edges drawn, file updated with server UUIDs

Form Catalog — All Available Form Names

Pass formName to createActor or in the graph YAML file. The server resolves the name to ID automatically.

Graph & Layer

formNameUsage
"Graphs"Graph container actor
"Layers"Layer (visual canvas) actor

Flowchart Blocks

Always set color (hex string) for flowchart blocks.

formNameDescription
"Start / Stop"Start or end node
"Process"Process step
"Decision"Decision diamond
"Predefined Process"Predefined / subroutine process
"Document"Document shape
"Data"Data parallelogram
"Documents"Multi-document stack
"Stored Data"Stored data shape
"Off-page Reference"Off-page connector
"Preparation"Preparation / initialization
"API Call"API call block
"Manual Input"Manual input
"Delay"Delay block
"Database"Database cylinder
"Manual Operation"Manual operation
"Terminator"Oval terminator
"Root Node"Root node
"Null"Universal generic node
"Flowchart"Nested flowchart reference

Diagram Types

formNameDescription
"Petri Net"Petri net diagram
"Sequence Diagram"Sequence diagram
"Actor Graph"Actor graph
"Mind Map"Mind map
"Corezoid"Corezoid process diagram

Corezoid Nodes

formNameDescription
"Corezoid Start"Entry point
"Corezoid API Call"External API call
"Corezoid Condition"Condition / routing
"Corezoid Code"Code execution
"Corezoid Copy Task"Copy task
"Corezoid Modify Task"Modify task
"Corezoid Sum"Aggregation / sum
"Corezoid Delay"Time delay
"Corezoid Database Call"DB call
"Corezoid Waiting for Callback"Async wait
"Corezoid Call a Process"Sub-process call
"Corezoid Reply to Process"Reply to caller
"Corezoid Queue"Queue node
"Corezoid Get from Queue"Dequeue
"Corezoid Set Parameters"Set task parameters
"Corezoid End: Success"Success terminal
"Corezoid End: Error"Error terminal
"Corezoid GIT Call"GIT call

AWS Services

formNameformNameformName
"EC2""Lambda""RDS"
"App Runner""EKS Cloud""EKS Distro"
"EFS""Client VPN""Elastic Container Registry"
"Certificate Manager""Simple Queue Service""Inspector"
"GuardDuty""Data Pipeline""Kinesis"
"Key Management Service""DynamoDB""Elastic Kubernetes Service"
"Secrets Manager""Elastic Load Balancing""Route 53"
"ElastiCache""CloudWatch""Transfer Family"
"Managed Streaming for Apache Kafka""Amplify""Budgets"
"Simple Storage Service""Transit Gateway""Network Firewall"
"OpenSearch Service""WAF""Virtual Private Cloud"
"Simple Notification Service""API Gateway""Transcribe"
"Athena""QuickSight""CloudFront"
"Global Accelerator""Backup""DocumentDB"
"Glue""RDS on VMware"

AI / ML

formNameDescription
"GPT"GPT model node
"Anthropic"Anthropic model node
"Grok"Grok model node
"SLM"Small language model
"Devin"Devin AI agent
"Black box (Mind)"Opaque mind component
"Black box (LLM)"Opaque LLM component
"Black box (Actor)"Opaque actor component
"Black box (Seq)"Opaque sequence component
"Grey box (Actor)"Semi-transparent actor
"Grey box (Mind)"Semi-transparent mind
"Grey box (LLM)"Semi-transparent LLM
"Grey box (Seq)"Semi-transparent sequence

UML / OOP

formNameDescription
"Class"UML class
"Interface"UML interface
"Component"UML component
"Package"UML package
"Artifact"UML artifact

Other

formNameDescription
"Human"Human participant
"Node"Generic network node
"Branch Node"Branch point
"White box"Transparent white container
"Place"Physical location
"Token"Token / badge
"Flag"Flag marker
"Program"Program block
"Current Position"Current position marker
"Transition"State transition
"Stubnet"Stub network
"Marketplace"Marketplace node

Low-Level MCP Tools (one-off operations)

Use these for targeted queries, not for building graphs (use the file workflow instead). Call tools with named arguments (the curated v2 tools take typed params — there is no single body blob). A layer is addressed by its layer-actor UUID — the actorId argument of the layer tools below (the same id the file workflow calls the layerId).

Actor Operations

createActor(formName="Process", title="Step", color="#539fdf")   // one actor per call — there is no createActors
getActor(actorId="<actorId>")
getActorByRef(formId=<formId>, ref="<ref>")
updateActor(formId=<formId>, actorId="<actorId>", title="Updated")
deleteActor(actorId="<actorId>")                                 // one at a time — there is no bulk-actor delete

Link (edge) Operations

// Single link. edgeTypeId defaults to the workspace hierarchy type when omitted —
// pass it only for a different edge type (see getEdgeTypes).
createLink(source="<a>", target="<b>")                  → edgeId

// Up to 50 links in one call; each object's edgeTypeId is optional (same hierarchy default).
massLink(links=[{"source":"<a>","target":"<b>"}, ...])

// massLink/createLink create the logical edge only. To also show an edge on a layer,
// place it with manageLayerActors (actorId = the layer-actor UUID):
manageLayerActors(actorId="<layerActorId>", items=[{"action":"create","data":{"id":"<edgeId>","type":"edge","laIdSource":<laA>,"laIdTarget":<laB>}}])

// Edge LINE STYLE — put it in the placed edge's data.layerSettings.lineStyle
// (solid | dashed | dotted; omit → solid). Use distinct styles for distinct
// edge meanings (e.g. dashed = dependency, dotted = hint, solid = hierarchy):
manageLayerActors(actorId="<layerActorId>", items=[{"action":"create","data":{"id":"<edgeId>","type":"edge","laIdSource":<laA>,"laIdTarget":<laB>,"layerSettings":{"lineStyle":"dashed"}}}])
// To CHANGE an edge's style, DELETE its placement then create it again — re-creating
// without deleting first adds a DUPLICATE placement (the line is drawn twice).

// existLink REQUIRES edgeTypeId (unlike createLink) — pass it explicitly to find/dedupe an edge by its endpoints:
existLink(source="<a>", target="<b>", edgeTypeId=<id>)  → edge id if it exists
getEdge(edgeId="<edgeId>")
updateEdge(edgeId="<edgeId>", name="New label", pinned=true)     // fields: name, linkedActorId, curveStyle, pinned
deleteEdge(edgeId="<edgeId>")
deleteEdgesByNodes(links=[{"source":"<a>","target":"<b>","edgeTypeId":<id>}])   // bulk delete by endpoints (1-200); edgeTypeId required per object

Layer Operations

Reading "the nodes/actors on a graph" means reading THAT LAYER's placements — never a workspace-wide search. searchActors / filterActors without a layer constraint scan the whole workspace and return unrelated actors (chats, daily reports, other forms) — they are the WRONG tool for "what's on this graph/layer". Use the layer-read tools below, addressing the layer by its layer-actor UUID.

Getting the layer UUID from a pasted URL. Simulator graph URLs look like:

https://<host>/actors_graph/<workspaceId>/graph/<graphActorId>/layers/<layerActorId>
                            └ workspace ┘        └ graph root ┘         └ THE LAYER ┘
  • The layer actorId is the last UUID — the segment after /layers/. Read it with the tools below (e.g. getLayerActorsPaginated(actorId="<layerActorId>")).
  • If the path ends at /graph/<id>/<mode> (mode = layers|actors|trees) with no /layers/ segment, that <id> is the layer/graph-folder to open.
  • The UUID after /graph/ is the graph ROOT actor (a Graphs-form actor), not the canvas of nodes — don't read it expecting the layer's members.
// READING A LAYER — default to the paginated read; it works for a layer of ANY size.
// Start with layerStats to learn the counts, then page nodes and edges:
layerStats(actorId="<layerActorId>")                     // node/edge counts — call first
getLayerActorsPaginated(actorId="<layerActorId>", type="nodes", limit=50, offset=0)  // walk offset until a short/empty page
getLayerActorsPaginated(actorId="<layerActorId>", type="edges", limit=50, offset=0)  // then the edges
getAllLayerPlacements(layerId="<layerActorId>")          // nodes-only one-shot shortcut (engine tool, any size)
searchLayerActors(actorId="<layerActorId>", query="...")

// getLayerActors is a SMALL-LAYER shortcut only — it loads the whole layer (nodes + edges)
// at once and the backend REJECTS it with a 400 ("Layer is too large (… nodes, … edges,
// total: …). Maximum allowed: N.") once nodes+edges exceed the size cap (~300). Do not reach
// for it first to read a layer; if you do and hit that error, switch to getLayerActorsPaginated
// (do NOT give up). `filter` keeps each page small.
getLayerActors(actorId="<layerActorId>")                 // whole layer in one call — small layers only
existLayerElement(actorId="<layerActorId>", id="<actorOrEdgeId>", type="actor")  // is a node/edge on the layer — dedupe before placing
moveActors(sourceActorId="<layerA>", targetActorId="<layerB>", items=[{"actorId":"<a1>"}])  // ≤10 actors between layers
cleanGraphLayer(actorId="<layerActorId>")                // wipe the layer (actors remain) — destructive

Graph Traversal

getRelatedActors(type="linked", actorId="<actorId>")  // type: "linked"|"parents"|"children"; defaults to the hierarchy link type
getActorLinks(actorId="<actorId>")                    // every edge of an actor
getLinkedActors(actorId="<actorId>")                  // directly-linked actors across edge types

// Related actors filtered/ranked by an account balance, in one query:
// "the actors related to X whose account N balance is > / < a value".
filterActors(formId=<formId>, linkedToActorId="<anchorActorId>",
             accountNameId="<nameId>", currencyId=<id>,
             amountFrom=<min>, amountTo=<max>,        // amountFrom = balance >=, amountTo = balance <=
             orderBy="balance", orderValue="DESC")    // omit linkedToActorId for a form-wide ranking
// linkedToActorDirection="children" keeps only the anchor's children (expand/collapse a node),
// "parents" only its parents; omit / "both" = either direction (default).

// Save tokens: every read/traversal tool above (getRelatedActors, getActor,
// getLayerActors, searchLayerActors, searchActors, filterActors, ...) accepts an
// optional `filter` field-selection arg — comma-separated fields to return, e.g.
// filter="id,title,formId" (dotted paths like data.status pick nested data fields).
// The server returns only those fields. NOT a row filter (that's search / q).
getRelatedActors(type="children", actorId="<actorId>", filter="id,title,formId")

Financial Operations

Accounts are a finance concern — see /simulator-finance for the full workflow. Quick reference:

Accounts

getAccounts(actorId="<actor>")
getAccount(accountId="<acc>")
createAccountPair(accountName="Balance", currencyName="USD")     // bootstrap: creates name + currency if missing AND grants pair access
createAccount(actorId="<actor>", nameId="<name>", currencyId="<cur>", accountType="default")
setAccountAmount(accountId="<acc>", amount=1000)                 // fixed-balance correction
deleteAccount(actorId="<actor>", currencyId="<cur>", nameId="<name>", accountType="default")

Currencies & Account Names

getCurrencies()
createCurrency(name="USD", symbol="$", precision=2)
getAccountNames()
createAccountName(name="Balance", abbreviation="BAL")

Key Rules

  • File-based workflow is preferred for building and editing graphs — write a YAML file, then pushGraphFile.
  • Create Graph + Layer first, then work with the layer's YAML file. Never skip the graph→layer link.
  • formName takes priority over formId in the YAML file and in createActor calls.
  • Do NOT include data in the YAML for system forms — the server auto-injects shape/view/blockId.
  • For custom forms (formId specified by user or formName not in the catalog): call getForm(formId) first, then build actors.data from the returned field schema using field name as keys.
  • Always set color (hex string) for flowchart blocks.
  • Local id values in the YAML are replaced with server UUIDs after pushGraphFile. Use short readable names ( start, validate, end) for new actors.
  • pullGraphFile → edit → pushGraphFile is the standard edit cycle for existing layers.
  • laId ≠ actorId. The file workflow handles laId management automatically.
  • Space actors ~200–300 px apart; use the layout algorithm for coordinates.
  • To place a user/person on the graph, use their twin actor — resolve it with getSystemActor(objType="user", objId=<userId>) and place that actorId. A bare userId is not a graph node. (See $CLAUDE_PLUGIN_ROOT/docs/entities/users.md.)

Reference Documents

PathWhen to read
$CLAUDE_PLUGIN_ROOT/docs/entities/actors.mdFull actor property list and types
$CLAUDE_PLUGIN_ROOT/docs/entities/links.mdLink/edge properties and type system
$CLAUDE_PLUGIN_ROOT/docs/entities/layers.mdLayer types and behavior
$CLAUDE_PLUGIN_ROOT/docs/user-flows/graph-functionality.mdGraph building walkthrough with test scenarios
$CLAUDE_PLUGIN_ROOT/docs/user-flows/actor-graph-management.mdManaging actors on graphs — practical patterns

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Simulator Graph AI skill do?

Simulator.Company graph structure specialist. Use when the user wants to build, edit, analyze, inspect, or ask questions about business process graphs, flowcharts, algorithms, actors (nodes), links (edges), or layers (visual views) in Simulator.Company. Trigger on any of these intents: — Creating: "create graph", "build flowchart", "new diagram", "add actor", "add block to graph", "create algorithm", "draw flowchart", "digital twin", "create process on graph", "build process diagram", "FlowchartBlock", "startStop", "predefinedProcess". — Editing: "edit graph", "update actor", "rename node",...

Why use Simulator Graph on TypingMind?

Because you install it once and use it with any model. Simulator Graph 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 Simulator Graph in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/corezoid/simulator-ai-plugin/tree/main/plugins/simulator/skills/simulator-graph. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Simulator Graph?

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 Simulator Graph?

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

Is the Simulator Graph AI skill free?

Yes. It is published on GitHub by corezoid 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 👇