{"id":29530,"plugin_id":"plugin_asdk_app_6ac4c3b919f48191a49821b96bdc33a2","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-09T00:04:18.568Z","digest":"f075a8f14224ee200b9cadb7614e05cfea6767f4b84feafe52e57def4aba4cac","against":null,"payload":{"description":"Corezoid state diagram creation specialist. Use when the user wants to create a new Corezoid state diagram, build a state machine, design a status / lifecycle store, or set up a \"state\" object with conv_type \"state\". Activate when the user says \"create a state diagram\", \"build a state machine\", \"new state diagram\", \"design states\", \"track status\", \"user lifecycle\", \"состояния\", \"стейт диаграмма\", \"создать state diagram\", or mentions storing state-by-ref between processes.\n","included_files":[],"name":"corezoid-state-diagram-create","skill_md_contents":"---\nname: corezoid-state-diagram-create\ndescription: >\n  Corezoid state diagram creation specialist. Use when the user wants to create\n  a new Corezoid state diagram, build a state machine, design a status / lifecycle\n  store, or set up a \"state\" object with conv_type \"state\". Activate when the\n  user says \"create a state diagram\", \"build a state machine\", \"new state diagram\",\n  \"design states\", \"track status\", \"user lifecycle\", \"состояния\", \"стейт диаграмма\",\n  \"создать state diagram\", or mentions storing state-by-ref between processes.\n---\n\n# Create a New Corezoid State Diagram\n\nYou are a specialist in creating Corezoid **state diagrams** (`conv_type: \"state\"`) using the `corezoid` MCP server.\n\nA state diagram is a long-lived data store: each task is one entity's state, referenced by a stable `ref`. Other processes read, create, and modify these state tasks. The state diagram itself only contains states (parked tasks), transitions between them, and a tiny subset of helper nodes.\n\nBefore you start, make sure you understand:\n- A state diagram has `conv_type: \"state\"` at the root (not `\"process\"`).\n- Only 10 node types are allowed: Start, Condition, Code, Set Parameters, Copy Task, Modify Task, Set State (= a state node), Delay, Queue, End: Success, End: Error.\n- API Call, Call a Process, Reply to Process, DB Call, Git Call, Sum, API Form are **forbidden** inside a state diagram — they belong in the driver process.\n\nRead `${CLAUDE_PLUGIN_ROOT}/docs/state-diagrams/state-diagram-overview.md` if you need a refresher on the model.\n\n---\n\n## Step 1: Gather Requirements\n\nAsk the user for the following before proceeding:\n\n- **What entity is being tracked?** (user, order, device, subscription, account, …)\n- **What is the `ref`?** — the stable identifier (e.g. `userId`, `orderId`). This is the lookup key every reader and writer will use.\n- **List the states.** A name and a one-line description for each (e.g. `Pending`, `Active`, `Suspended`, `Closed`).\n- **List the transitions.** For every state, what data change causes it to move to which other state? (e.g. `Active → Suspended when status == \"suspended\"`).\n- **Initial state.** Which state does a newly created task enter first?\n- **Terminal states.** Which states are \"End: Success\" / \"End: Error\", if any?\n- **Side effects on entry / exit (optional).** Should entering a state trigger a notification, stamp a timestamp, etc.? (These are Copy Task / Modify Task nodes between states.)\n\nIf any of the above is missing, ask the user before continuing.\n\n---\n\n## Step 2: Create the Empty State Diagram\n\nCall MCP tool **`create-state-diagram`** with:\n- `folder_path`: Relative path to the folder directory. Omit to use the current directory.\n- `process_name`: the state diagram name.\n\nThis creates an empty state diagram in Corezoid with `conv_type: \"state\"` and writes its skeleton JSON to `<ID>_<Name>.conv.json` inside `folder_path`. The returned file path is `PROCESS_PATH` — all subsequent steps use it.\n\n> ⚠️ Always verify `folder_path` points to the intended target folder. Omitting it places the diagram in the project root, which may not be the correct location.\n\n> ⚠️ Open the new file and confirm `\"conv_type\": \"state\"` at the root before doing anything else. The push pipeline now accepts both `\"process\"` and `\"state\"`, but if `conv_type` is accidentally `\"process\"`, the next push will redeploy it as a regular process.\n\n**Already exists in Corezoid?** If the user pre-created the diagram in the Corezoid UI, pull it instead: call MCP tool **`pull-process`** with `process_id: <id>`. `pull-process` works for both processes and state diagrams — the resulting file preserves `conv_type: \"state\"`.\n\n---\n\n## Step 3: Design the State Diagram Structure\n\nA state diagram is structured as:\n\n| # | Node | obj_type | Purpose |\n|---|------|----------|---------|\n| 1 | Start | 1 | Entry — routes a newly-created task to its initial state |\n| 2 | _(optional)_ Set Parameters / Code | 0 | Compute / normalise data on entry |\n| 3 | One state node per state | 0 (logic begins with `api_callback`) | Park the task until externally modified |\n| 4 | _(optional)_ Copy Task / Modify Task between states | 0 | Side effects on transition |\n| 5 | _(optional)_ Delay node | 0 | Time-bounded states (e.g. trial expiry) |\n| 6 | End: Success | 2 | Terminal state for \"happy\" closure |\n| 7 | End: Error | 2 | Terminal state for failure closure |\n\n### State node anatomy (memorise this shape)\n\n```json\n{\n  \"id\": \"<24-hex>\",\n  \"obj_type\": 0,\n  \"condition\": {\n    \"logics\": [\n      { \"type\": \"api_callback\" },\n      {\n        \"type\": \"go_if_const\",\n        \"to_node_id\": \"<other_state_id>\",\n        \"conditions\": [\n          { \"param\": \"status\", \"const\": \"blocked\", \"fun\": \"eq\", \"cast\": \"string\" }\n        ]\n      },\n      { \"type\": \"go\", \"to_node_id\": \"<self_id>\" }\n    ],\n    \"semaphors\": []\n  },\n  \"title\": \"Active\",\n  \"x\": 880, \"y\": 400,\n  \"extra\": \"{\\\"modeForm\\\":\\\"expand\\\",\\\"icon\\\":\\\"state\\\"}\",\n  \"options\": null\n}\n```\n\nKey invariants for every state node:\n- **First logic is `api_callback`** (with no other fields). This is what \"parks\" the task.\n- One `go_if_const` per outbound transition. Order matters — first match wins.\n- **Last logic is `go` pointing back to the node's own id** (the \"stay here\" fallback).\n- `extra` must include `\"icon\":\"state\"` so the UI renders the state pill correctly.\n- Do not add `err_node_id` — `api_callback` does not surface the regular error path.\n\n---\n\n## Step 4: Generate the State Diagram JSON\n\nProduce a valid `.conv.json` file with the following root envelope:\n\n```json\n{\n  \"obj_type\": 1,\n  \"obj_id\": <id from step 2>,\n  \"parent_id\": <folder_id>,\n  \"title\": \"<State Diagram Name>\",\n  \"description\": \"\",\n  \"status\": \"active\",\n  \"params\": [],\n  \"ref_mask\": true,\n  \"conv_type\": \"state\",\n  \"scheme\": {\n    \"nodes\": [],\n    \"web_settings\": [[], []]\n  }\n}\n```\n\n### Core rules\n\n- `conv_type` **must** be `\"state\"`.\n- Node IDs are 24-character hex: `^[0-9a-f]{24}$`. Generate with `crypto.randomBytes(12).toString('hex')` or any equivalent.\n- Connect nodes only through the `go` / `go_if_const` `to_node_id` fields.\n- Every node that uses logic with `err_node_id` (Code, Set Parameters, Copy Task, Modify Task, Queue) must point at a dedicated End: Error node.\n- Use descriptive node `title` values — they are the state names visible on the canvas and in dashboards.\n- Layout: spread states **horizontally** (different `x` per state), keep the Start above them. State nodes sit around `y ≈ 400`, Start at `y = 100`. Increment `x` by ≈ 320–400 between adjacent states. Place End nodes at the bottom (`y ≈ 700–900`).\n\n### Allowed logics inside a state diagram\n\n| Node | Logic `type` | Notes |\n|---|---|---|\n| Start | `go` (`obj_type: 1`) | Exactly one per diagram |\n| State (Set State) | `api_callback` + `go_if_const`s + self-`go` | The structural heart of the diagram |\n| Condition | `go_if_const` | For pre-state routing |\n| Code | `api_code` | Avoid unless necessary; prefer `set_param` |\n| Set Parameters | `set_param` | Compute / stamp fields |\n| Copy Task | `api_copy` with `mode: \"create\"` | Fan out to another process (notifications, audit) — **not** to write back to this same diagram |\n| Modify Task | `api_copy` with `mode: \"modify\"` | Update a task by `ref` in some target process — note: in-place edits to the current task should use `set_param` instead |\n| Delay | semaphor-only | Time-bounded states |\n| Queue | `api_queue` | Ordered / throttled processing |\n| End | (`obj_type: 2`) | Terminal node (success or error icon) |\n\n### Variables for constants\n\nIf a node references an external id (e.g. another process to notify), store it as a Corezoid variable and reference it as `{{env_var[@variable-name]}}` — never hardcode. Use **`cz-variables`** with `action: \"create-variable\"` if the variable does not yet exist. See `${CLAUDE_PLUGIN_ROOT}/docs/variables-guide.md`.\n\n### Common pitfalls\n\n- Forgetting `\"icon\":\"state\"` in `extra` for a state node — the node renders as a plain logic node.\n- Missing the trailing self-loop `go` on a state node — the task escapes the state on every callback.\n- Putting an API Call, Call a Process, or Reply to Process node in a state diagram — these are **forbidden**. Move them into the driver process.\n- Using `api_copy mode: \"modify\"` from inside the state diagram targeting its own ref — that creates an infinite re-callback loop. Use `set_param` to update the current task in place instead.\n- Raw JSON objects as `extra` / `data` values — must be stringified (`\"{\\\"k\\\":\\\"v\\\"}\"`).\n\n---\n\n## Step 5: Validate with Lint\n\nCall MCP tool **`lint-process`** with `process_path: \"<PROCESS_PATH>\"`.\n\nFix every reported error and re-run until the output is clean. Do not proceed with lint errors.\n\n> If the linter complains about a forbidden logic (`api`, `api_rpc`, `api_rpc_reply`, `db_call`, `git_call`, `api_sum`, `api_form`), remove the node and re-design the side effect to live in the driver process.\n\n---\n\n## Step 6: Deploy\n\nCall MCP tool **`push-process`** with `process_path: \"<PROCESS_PATH>\"`.\n\nIf the push fails:\n- Re-read the file and confirm `\"conv_type\": \"state\"` is present at the root.\n- Confirm every state node ends in `go → self`.\n- Confirm only allowed logic types are present.\n\nAfter a successful push, notify the user:\n\n> \"State diagram deployed. Refresh the Corezoid page to see the new diagram. To start using it, create the driver process that calls `api_copy mode:create` with a `ref` to add entities, and `mode:modify` to drive transitions.\"\n\n---\n\n## Step 7 (optional): Build the Driver Process\n\nA state diagram is useless without a driver process that creates and modifies its tasks. If the user has not already built one, offer to:\n\n1. Hand off to `/corezoid-create` to scaffold the driver process.\n2. Wire it with three node patterns:\n   - **Read state:** `set_param` with `{{conv[<sd_id>].ref[{{ref}}].<field>}}`\n   - **Create state task:** `api_copy` with `conv_id: <sd_id>`, `ref: {{<ref>}}`, `mode: \"create\"`, `data: {...}`\n   - **Modify state task:** `api_copy` with `conv_id: <sd_id>`, `ref: {{<ref>}}`, `mode: \"modify\"`, `data: {...}`\n\nRead `${CLAUDE_PLUGIN_ROOT}/docs/state-diagrams/state-diagram-process-interaction.md` for full templates.\n\nRecommend creating an alias (`/corezoid-alias-manager`) for the state diagram so the driver references `@user-states` instead of a numeric id.\n\n---\n\n## Reference Documents\n\n| Path | When to read |\n|---|---|\n| `${CLAUDE_PLUGIN_ROOT}/docs/state-diagrams/state-diagram-overview.md` | Concepts, allowed nodes, root structure |\n| `${CLAUDE_PLUGIN_ROOT}/docs/state-diagrams/state-diagram-node-structures.md` | Canonical JSON for every allowed node type |\n| `${CLAUDE_PLUGIN_ROOT}/docs/state-diagrams/state-diagram-process-interaction.md` | How driver processes read / create / modify state tasks |\n| `${CLAUDE_PLUGIN_ROOT}/docs/nodes/set-state-node.md` | Background on Set State (legacy `obj_type:3` form) and the `{{conv[...]}}` template |\n| `${CLAUDE_PLUGIN_ROOT}/docs/nodes/copy-task-node.md` | Error catalogue for `api_copy` |\n| `${CLAUDE_PLUGIN_ROOT}/docs/nodes/condition-node.md` | `go_if_const` reference |\n| `${CLAUDE_PLUGIN_ROOT}/docs/variables-guide.md` | Variables (`{{env_var[@…]}}`) |\n\n## Example Files\n\n| Path | Description |\n|---|---|\n| `${CLAUDE_PLUGIN_ROOT}/samples/state-diagrams/user-status-state-diagram.conv.json` | Minimal two-state diagram (`Active` ⇄ `Inactive`) |\n| `${CLAUDE_PLUGIN_ROOT}/samples/state-diagrams/user-status-driver-process.conv.json` | Companion driver process that reads + modifies the state |\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}