# Corezoid Simulator AI Plugin Simulator AI Plugin

> > **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

- Skill: `tomevault-io/corezoid-simulator-ai-plugin-simulator-ai-plugin` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/corezoid-simulator-ai-plugin-simulator-ai-plugin`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/corezoid-simulator-ai-plugin-simulator-ai-plugin/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/corezoid-simulator-ai-plugin-simulator-ai-plugin

---


> **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

| 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:

```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

| 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 `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

// 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

| 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](https://github.com/corezoid/simulator-ai-plugin) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-07-05 -->

