Curated tool names (v2 server). Place/remove nodes & edges on a layer with
manageLayerActors; read a layer's contents — prefergetLayerActorsPaginated(page nodes then edges; works for any size) orgetAllLayerPlacements, falling back togetLayerActorsonly 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 withcreateActor(one call each — there is nocreateActors); links withcreateLink/massLink; edge CRUD withgetEdge/updateEdge/deleteEdge/existLink/deleteEdgesByNodes; edge types withgetEdgeTypes. Traverse from an actor withgetRelatedActors(type = linked | parents | children; hierarchy link type by default; paginated/filterable/sortable),getLinkedActors(directly-linked actors across edge types, withedgeTypes/withSystem/pinnedfilters), andgetActorLinks(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/simulatorfor 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 NOTsearchActors/filterActorsacross the workspace (that returns unrelated chats, reports and other forms). When the user pastes a URL like.../graph/<graphActorId>/layers/<layerActorId>, the layeractorIdis the last UUID, the segment after/layers/. See Layer Operations below for the full recipe.
Core Concepts & Glossary
| Term | Description |
|---|---|
| Actor | Graph node. Created from a Form template. Has id, title, color, data fields. |
| Form | Actor template/type. Defines shape and behavior. All system form names are in the catalog below. |
| Graph actor | An actor with formName="Graphs" — the logical container for a diagram. |
| Layer actor | An actor with formName="Layers" — the visual canvas where nodes are placed at (x, y). |
| Graph file | A YAML file named <layerId>.yaml in the current working directory describing the full layer state. |
| laId | Layer 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:
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
idis a local name (e.g.start,process1) → replaces local ids with server UUIDs in the file - Update actors whose
idis 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
positionchanged
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|dottedcurveStyle—curved|rounded|roundedDownward|straightcolor— 6-digit hex#RRGGBB(e.g.#9AA5B1grey,#E8924Eorange) — no 3-digit shorthand, no alphawidth— 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
formIdUUID 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
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
getFormbefore writingdatawhen a custom formId is involved — never guess field names. - If the form has no fields, omit
dataentirely. - Do not add
datafor 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 labeltextNodeScale— font-size multipliertextWidth/textHeight— text-box size in px. Scale it to the text — roughly16·scalepx per character wide and28·scalepx 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
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:
idvalues are local references used only within the file for edge wiring. AfterpushGraphFileall local ids are replaced with server UUIDs.- Do not include
datafor system forms — the server auto-injects shape/view. formNametakes priority overformIdwhen both are present.edgesreference actoridfields (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 (setwidth;heightfollows), 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
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
| formName | Usage |
|---|---|
"Graphs" |
Graph container actor |
"Layers" |
Layer (visual canvas) actor |
Flowchart Blocks
Always set
color(hex string) for flowchart blocks.
| formName | Description |
|---|---|
"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
| formName | Description |
|---|---|
"Petri Net" |
Petri net diagram |
"Sequence Diagram" |
Sequence diagram |
"Actor Graph" |
Actor graph |
"Mind Map" |
Mind map |
"Corezoid" |
Corezoid process diagram |
Corezoid Nodes
| formName | Description |
|---|---|
"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
| formName | formName | formName |
|---|---|---|
"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
| formName | Description |
|---|---|
"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
| formName | Description |
|---|---|
"Class" |
UML class |
"Interface" |
UML interface |
"Component" |
UML component |
"Package" |
UML package |
"Artifact" |
UML artifact |
Other
| formName | Description |
|---|---|
"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
actorIdis 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 (aGraphs-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
// 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-financefor 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.
formNametakes priority overformIdin the YAML file and increateActorcalls.- Do NOT include
datain 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 buildactors.datafrom the returned field schema using fieldnameas keys. - Always set
color(hex string) for flowchart blocks. - Local
idvalues in the YAML are replaced with server UUIDs afterpushGraphFile. Use short readable names (start,validate,end) for new actors. pullGraphFile→ edit →pushGraphFileis 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 thatactorId. A bareuserIdis not a graph node. (See$CLAUDE_PLUGIN_ROOT/docs/entities/users.md.)
Reference Documents
| Path | When to read |
|---|---|
$CLAUDE_PLUGIN_ROOT/docs/entities/actors.md |
Full actor property list and types |
$CLAUDE_PLUGIN_ROOT/docs/entities/links.md |
Link/edge properties and type system |
$CLAUDE_PLUGIN_ROOT/docs/entities/layers.md |
Layer types and behavior |
$CLAUDE_PLUGIN_ROOT/docs/user-flows/graph-functionality.md |
Graph building walkthrough with test scenarios |
$CLAUDE_PLUGIN_ROOT/docs/user-flows/actor-graph-management.md |
Managing actors on graphs — practical patterns |
Source: corezoid/simulator-ai-plugin — distributed by TomeVault.