From simulator
Manages actors (records) for Simulator.Company form templates: create, read, update, delete, search, filter, and query connected processes/API keys.
How this skill is triggered — by the user, by Claude, or both
Slash command
/simulator:simulator-actorsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Curated tool names (v2 server):** `createActor`, `getActor`, `getActorByRef`,
Curated tool names (v2 server):
createActor,getActor,getActorByRef,updateActor,setActorStatus,deleteActor,searchActors,filterActors,searchLayerActors,getSystemActor,getCorezoidProcesses. Call them by these exact names.
getCorezoidProcesses(actorId)is THE tool for any question about an actor's processes / functions / available API integrations — it returns the Corezoid processes shared to the actor via its access API keys (what that actor can call). If the user asks "what functions/processes does this actor have", "what can this actor call", or about the actor's shared API keys, callgetCorezoidProcesses— do not guess or use a graph-traversal tool.
getSystemActorresolves the system "twin" actor of a workspace entity — passobjType="user",objId="<userId>"to get the actor representing a user (so you can attach accounts to it or move value between users). Find theuserIdfirst withsearchUsers/getUsers. Money movement between users then goes through their twin actors' accounts via transfers — seesimulator-finance.
You create and manage actors — the instances of a form template (Account
Template). An actor's field values live in its data object. Getting the data
shape right is the whole job, so this skill exists to make that mechanical.
Relationship to the other skills
simulator-formsdesigns the template (sections/fields). Read it / a form first to learn the fieldids.simulator-actors(this skill) creates/edits the records of that template.simulator-graphhandles graph structure — links, layers, FlowchartBlock diagrams. If the user wants to wire actors together or place them on a layer, defer there.simulator-financehandles accounts/transactions on actors.
Verify accId is known before any tool call. If not provided, ask:
Ask the user — in their own language (English, Ukrainian, or Russian) — which workspace to work in, i.e. for the Workspace ID (
accId).
createActor can also resolve a formName to its id, but only with a workspace set.
data is keyed by field idAn actor's data is keyed by each form field's id (item_<digits>) — not by
the field title and not by its secondary key. So the first step of every actor
create/update is:
getForm(formId) (or searchForms then getForm). Pass
filter="id,title,sections" to keep it small.id and class.data using the per-class value shapes below.| Form field class / source | Value in data |
|---|---|
edit text / password / email / phone | string — "[email protected]" |
edit int / float | number — 1 |
check | boolean — true |
radio | the selected option's value (string) — "o2" |
select (static options) | array of chosen option object(s) — [{"color":"#863434","title":"one","value":"s1"}] |
select → layer/actorFilter/actorsBag/actors/formFilter | [{"type":"actor","title":…,"value":"<actor UUID>"}] (formFilter = the actors of a given form) |
select → forms | [{"type":"form","title":…,"value":<form id number>}] |
select → currencies | [{"type":"currency","title":…,"value":<currency id number>}] |
select → accountNames | [{"type":"accountName","title":…,"value":"<account-name UUID>"}] |
select → workspaceMembers | [{"type":"workspaceMembers","title":…,"value":<user id number>}] |
select → api/corezoidSyncApi | array of synced options ([] until synced) |
multiSelect | array — [{"title":"one","value":"…"},{"title":"two","value":"…"}] |
calendar | {"startDate":…,"endDate":…,"timeZoneOffset":-180,"sendInvite":false} (unix seconds) |
upload | array of file refs ([] when empty) |
label / button / image | no entry — display-only |
The
typediscriminator only appears on dynamicselectvalues. Staticselect/multiSelectvalues carry just{title,value,color?}. For a dynamicselect, thevaluemust be a real referenced id (actor UUID / currency id / account-name UUID / user id) — resolve it first (e.g.getCurrencies,getAccountNames,searchActors) rather than guessing.
Geolocation (top-level, not
data). An actor carries an optional position independent of its form fields:geoPosition—{"lat": <number>, "lon": <number>}in WGS84 decimal degrees, ornullto clear — andgeoName— a location name string, ornull. Both are set oncreateActor/updateActor. Latitude is hard-bounded to -90..90 (out of range is rejected), longitude outside ±180 wraps cyclically, and coordinates round to 6 decimals;lat/lonare set as a pair.
Full reference: $CLAUDE_PLUGIN_ROOT/docs/entities/actors.md and …/forms.md.
__form__<formId>:<itemId>)An actor can instantiate several forms at once (a multiform actor; the linked form
tree is called a UAT). Its data then carries fields from more than one form, namespaced
by a key prefix:
formId (the one you pass to createActor/updateActor) →
the plain field id, e.g. "name".__form__<thatFormId>:<itemId>.// data for an actor created under its root form, with one field from form 16951
{
"name": "Kulo Oleksandr",
"__form__16951:position": "Software engineer"
}
The prefix changes only the key — the value still follows the per-class shapes above. Notes:
<thatFormId>'s field ids, getForm(<thatFormId>) just like the root form.getFormsTree(accId, formId) / getLinkedForms(typeLink, formId)
(see simulator-forms) to find which forms a multiform actor spans before writing its data.PUT /actors/actor_forms) is still not a curated
tool — but you can already write/read multiform data via createActor/updateActor/getActor.In a UAT workspace, an actor can only be created under the root form of the tree — not
under an arbitrary leaf. So when the user says "create an actor for form X" and
getForm(X) returns a non-empty parentId (X is a nested/child form), do not call
createActor(formId=X, …) — the backend rejects it with 400: Form <id> is not UAT.
Instead:
parentId from X to the root form of the UAT tree (getForm repeatedly until
parentId is empty).createActor with formId = the root."name"), and the requested child
form's fields under the __form__<childFormId>:<itemId> prefix.// Request: "create an actor for form Employee (16951)", where Employee.parentId = People (16950)
// → create under the ROOT People (16950), not under Employee:
createActor(formId=16950, title="Olena Kovalenko", data={
"name": "Olena Kovalenko", // People (root) field
"__form__16951:position": "Senior Backend Engineer" // Employee (child) field
})
Do NOT flip the child form to
uatstatus viasetFormStatusto "work around" the error — that mutates the shared template for everyone. Use the root form as theformIdinstead.
createActor(
formId=42, # or formName="Car" (resolved via the workspace)
title="Toyota Camry 2023",
color="#409547", # optional
ref="car-toyota-camry-2023", # optional, unique per form
contextLayerId="<layer UUID>", # optional — place it on a layer
data={
"item_make": "Toyota",
"item_model": "Camry",
"item_year": 2023,
"item_active": true,
"item_cond": [ {"title":"excellent","value":"c1"} ],
"item_owner": [ {"type":"workspaceMembers","title":"Alex Kulo","value":1} ]
})
formId (number) or formName (string, resolved to its id).item_* keys not present in the form.label/button/image) get no data entry.getActor(actorId="<UUID>", filter="id,title,data") # by UUID
getActorByRef(formId=42, ref="car-…", filter="id,title,data") # by (form, ref)
Use filter to fetch only the fields you need — actor data can be large.
updateActor(
formId=42, actorId="<UUID>",
data={ "item_year": 2024, "item_active": false }) # only these keys change
updateActor is a partial update of data — keys you include are replaced, the rest
are untouched. You can also set title/description/color/status/ref. To clear a
multi-value field, send [].
Re-key by ref. updateActor(formId, actorId, ref="…") sets or changes the actor's
external reference — a stable business key, unique per form — the same key createActor
accepts, but now editable after creation. Then address the actor by its key instead of its
UUID: getActorByRef(formId, ref). Omit ref to leave it unchanged.
Embed a smart form (script) in an actor. Set appId (on createActor / updateActor)
to a Smart Form (CDU/Script app) actor id — the actor's card then renders/runs that smart
form; appSettings {autorun, expired, users, groups, fullWidth} tunes it. See
simulator-smart-forms.
Rich description (BBCode). An actor's description renders BBCode — chips like
[actor=<otherActorId>]Label[/actor] (nested actor card) and [application=<smartFormId>]Label[/application]
(smart-form chip), plus formatting ([b], [color=…], [h2], [ul][*]…[/ul], [url=…]) and
[md]…[/md] for markdown. Fetch the environment's exact tag set with getBbcodeTags.
BBCode is processed only OUTSIDE [md] blocks. The reverse matters too: a description is rendered as BBCode by default, not markdown, so any markdown you write (##, -, **bold**, tables) MUST be wrapped in [md]…[/md] or it shows as literal text — applies to every createActor/updateActor description, Events actors (chats/meetings/tasks) included (e.g. description="[md]## Agenda\n- item[/md]"). See docs/entities/reactions.md → "Embedding".
A hole is an empty placeholder slot on a graph, rendered as a hollow node: it marks a position in the structure that is not yet filled. A hole becomes a normal actor once it is filled with data — ideal for laying out a template / "company DNA" graph up front and turning each slot into a real actor as the data arrives.
createActor(formId=3279, title="Budget", hole=true) # create a hole
updateActor(formId=3279, actorId="<UUID>", hole=true) # turn an existing actor into a hole
updateActor(formId=3279, actorId="<UUID>", hole=false) # fill it — hole → normal actor
hole is a top-level boolean on createActor / updateActor; omit it → default false.status and data (a hole can still carry a title). hole=false
alone flips a hole back to a normal node.manageLayerActors — see simulator-graph).setActorStatus(actorId="<UUID>", status="verified")
deleteActor(actorId="<UUID>") # irreversible — confirm with the user first
searchActors — free-text across the workspacesearchActors(accId="ws_xxx", query="camry", limit=20, filter="id,title,formId")
Best for "find the actor named …". Run before createActor to avoid duplicates.
filterActors — list/rank a form's actors, optionally by an account balance# All actors of a form, newest first
filterActors(formId=42, orderBy="updated_at", withStats=true)
# Data-field filter on the actor data
filterActors(formId=42, q="status=active", status="verified,pending")
# Rank by an account's CURRENT balance, scoped to one anchor actor's neighbours
filterActors(
formId=42,
linkedToActorId="<anchor UUID>", # only actors linked to this one (both directions)
accountNameId="<account-name UUID>",
currencyId=9,
amountFrom=1000, # balance >= 1000
orderBy="balance", orderValue="DESC",
withStats=true)
# Only the CHILD actors of a node (e.g. expand/collapse a node's children)
filterActors(formId=42, linkedToActorId="<anchor UUID>", linkedToActorDirection="children")
# ...or only its parents: linkedToActorDirection="parents"; omit / "both" = either direction (default)
q filters on actor data fields; search does full-text on the title; status
filters by status.getAccounts(actorId, from, to) (a simulator-finance task).10^precision.searchLayerActors — search within one layersearchLayerActors(actorId="<layer UUID>", query="camry")
# 1. Resolve the template and its field ids
searchForms(accId="ws_xxx", q="Car") → formId 42
getForm(formId=42, filter="id,title,sections") → field ids: item_make, item_year, …
# 2. Avoid a duplicate
searchActors(accId="ws_xxx", query="Camry 2023")
# 3. Create the record
createActor(formId=42, title="Toyota Camry 2023",
data={ "item_make":"Toyota", "item_model":"Camry", "item_year":2023 })
# 4. (optional) attach an account — see simulator-finance
createAccount(actorId="<new UUID>", nameId="<aname>", currencyId=1, accountType="fact")
| Path | When to read |
|---|---|
$CLAUDE_PLUGIN_ROOT/docs/entities/actors.md | Actor data protocol + per-class value shapes |
$CLAUDE_PLUGIN_ROOT/docs/entities/forms.md | Field-class catalogue / dynamic select sources |
$CLAUDE_PLUGIN_ROOT/docs/entities/search.md | Search & filter internals |
getForm first — data keys are the form's field ids, not titles.parentId, it's a leaf of a UAT tree — create the actor under the root form and put the leaf's fields under __form__<childId>:<field>. Symptom of using the wrong root: 400: Form <id> is not UAT.select values reference real ids; resolve them, don't guess.createActor accepts formName (resolved in the active workspace) when you don't have the id.updateActor is partial; deleteActor is irreversible — confirm first.simulator-graph.getCorezoidProcesses(actorId) lists the Corezoid processes shared to an actor via its access API keys — i.e. the functions/processes that actor can call.npx claudepluginhub corezoid/simulator-ai-plugin --plugin simulatorAssists with the Simulator.Company business process management platform and its API. Activates for queries about actors, forms, accounts, transactions, and guides use of MCP tools.
Universal Corezoid assistant. Use when the user asks anything about Corezoid processes, wants to work with process JSON files, mentions process nodes, MCP tools, process validation, or any Corezoid-specific task. Also use when the user mentions "Corezoid", "BPM process", "conv.json", "push process", "run task", or asks for general platform knowledge. This skill provides deep knowledge of the platform model and guides you to use the Corezoid MCP tools correctly.
Manages a Paperclip AI-agent company as a board member via chat: onboarding, agent management, approvals, task monitoring, cost oversight, and work product review.