# JSON live preview

> Edit a Texuli blueprint as JSON, read the validator's diagnostics with their JSON paths, and watch @texuli/player paint it at the untrusted tier.

Language: en
Canonical: https://texuli.com/workflows-page/json/
Markdown: https://texuli.com/workflows-page/json.md (this page). Every texuli.com page has a Markdown twin at its URL plus `.md` (the home page is https://texuli.com/index.md), and any page URL answers `Accept: text/markdown` with its twin instead of HTML.
Last Updated: 2026-11-13

---

@texuli/player · spec 0.3.0

Texuli builds interfaces from validated JSON. Edit a blueprint on the left: it is checked as you type, and only a blueprint with no errors is painted by the real player, at the untrusted tier an agent's output gets. Nothing you type leaves the browser.

## Blueprint

 Example

Local state with a list variable, $state bindings, closed on-actions, a sortable list bound to the list and a read-only workflow graph.

 Blueprint JSON 263 lines

```
{
  "format": "texuli-blueprint",
  "version": 1,
  "spec": "0.3.0",
  "id": "json-preview-release-board",
  "catalog": "0000000000000000000000000000000000000000000000000000000000000000",
  "status": "draft",
  "createdAt": "2026-10-27T09:00:00Z",
  "updatedAt": "2026-10-27T09:00:00Z",
  "generator": {
    "kind": "agent",
    "name": "Harbor assistant",
    "model": "example-model"
  },
  "state": {
    "priorities": {
      "type": "list",
      "maxItems": 12,
      "initial": [
        {
          "id": "search",
          "label": "Faster search",
          "owner": "Search team"
        },
        {
          "id": "export",
          "label": "CSV export",
          "owner": "Data team"
        },
        {
          "id": "invite",
          "label": "Team invites",
          "owner": "Growth team"
        }
      ]
    },
    "review": {
      "type": "enum",
      "values": [
        "Priorities (not reviewed)",
        "Priorities (reordered)",
        "Priorities (pipeline checked)"
      ]
    },
    "showPipeline": {
      "type": "boolean",
      "initial": true
    }
  },
  "tree": {
    "id": "layout-page",
    "props": {
      "title": "Release week at Harbor Notes",
      "description": "Fictional data. Reorder the priorities; the pipeline shows how a release ships."
    },
    "children": [
      {
        "id": "layout-stack",
        "props": {
          "gap": "medium"
        },
        "children": [
          {
            "id": "layout-card",
            "props": {
              "title": {
                "$state": "review"
              }
            },
            "children": [
              {
                "id": "sortable-list",
                "props": {
                  "label": "Release priorities",
                  "itemDetail": "owner",
                  "reorder": {
                    "bind": {
                      "$state": "priorities"
                    },
                    "axis": "vertical"
                  }
                },
                "on": {
                  "move": [
                    {
                      "op": "setState",
                      "state": "review",
                      "value": "Priorities (reordered)"
                    }
                  ]
                }
              }
            ]
          },
          {
            "id": "control-toggle",
            "props": {
              "state": "showPipeline",
              "label": "Show the release pipeline"
            },
            "on": {
              "change": [
                {
                  "op": "setState",
                  "state": "review",
                  "value": "Priorities (pipeline checked)"
                }
              ]
            }
          },
          {
            "id": "layout-card",
            "props": {
              "title": "Release pipeline"
            },
            "when": {
              "op": "eq",
              "left": {
                "op": "var",
                "name": "showPipeline"
              },
              "right": {
                "op": "num",
                "value": 1
              }
            },
            "children": [
              {
                "id": "workflow-graph",
                "props": {
                  "label": "Release pipeline",
                  "mode": "view",
                  "graph": {
                    "version": 1,
                    "cycles": "forbid",
                    "nodeTypes": [
                      {
                        "id": "trigger",
                        "label": "Trigger",
                        "ports": [
                          {
                            "id": "out",
                            "direction": "out",
                            "kind": "flow",
                            "multiple": true
                          }
                        ]
                      },
                      {
                        "id": "step",
                        "label": "Step",
                        "ports": [
                          {
                            "id": "in",
                            "direction": "in",
                            "kind": "flow",
                            "multiple": true
                          },
                          {
                            "id": "out",
                            "direction": "out",
                            "kind": "flow",
                            "multiple": true
                          }
                        ]
                      },
                      {
                        "id": "finish",
                        "label": "Finish",
                        "ports": [
                          {
                            "id": "in",
                            "direction": "in",
                            "kind": "flow",
                            "multiple": true
                          }
                        ]
                      }
                    ],
                    "nodes": [
                      {
                        "id": "merge",
                        "type": "trigger",
                        "label": "Pull request merged",
                        "position": {
                          "x": 0,
                          "y": 0
                        }
                      },
                      {
                        "id": "test",
                        "type": "step",
                        "label": "Run the checks",
                        "position": {
                          "x": 240,
                          "y": 0
                        }
                      },
                      {
                        "id": "notes",
                        "type": "step",
                        "label": "Draft release notes",
                        "position": {
                          "x": 480,
                          "y": 0
                        }
                      },
                      {
                        "id": "ship",
                        "type": "finish",
                        "label": "Post to the team space",
                        "position": {
                          "x": 720,
                          "y": 0
                        }
                      }
                    ],
                    "edges": [
                      {
                        "id": "e1",
                        "from": {
                          "node": "merge",
                          "port": "out"
                        },
                        "to": {
                          "node": "test",
                          "port": "in"
                        }
                      },
                      {
                        "id": "e2",
                        "from": {
                          "node": "test",
                          "port": "out"
                        },
                        "to": {
                          "node": "notes",
                          "port": "in"
                        }
                      },
                      {
                        "id": "e3",
                        "from": {
                          "node": "notes",
                          "port": "out"
                        },
                        "to": {
                          "node": "ship",
                          "port": "in"
                        }
                      }
                    ]
                  }
                }
              }
            ]
          }
        ]
      }
    ]
  }
}
```

Changes are checked 250 ms after you stop typing. Tab leaves the editor.

## Result

Checking the blueprint…

### Diagnostics

The validator is loading…

### Rendered preview

Loading the player…

## How the preview works

- **Parse.** The text must be JSON; a syntax error is reported with its line and column.
- **Validate.** The same checks the player runs: the local-state declarations, the player's binding checks and `validateDraft` from `@texuli/catalog/validate` with the player catalog (component ids, prop schemas, bindings, events and closed actions, block schemas, composition grammar and the untrusted URL policy). Each diagnostic lists its code, its message and its JSON path.
- **Paint or refuse.** With no errors, `<Player>` paints the blueprint at the `untrusted` tier and validates it again. With any error the preview is cleared, never left showing an older result, and the status reads “Not rendered”.

## What is in development

- The player's runtime for the spec 0.3.0 interaction fields (local state in the envelope, `on` actions, `reorder` and workflow graphs) is in development and first published in `@texuli/player` `0.4.0`.
- `@texuli/workflows`, which paints the `workflow-graph` node, is in development and on npm as `0.18.0`; the player's `workflow-graph` painter that uses it ships from the player's `0.4.0` release. The preview shows graphs read-only.
- This page does not run the spec's own structural validator (`validateBlueprint` from `@texuli/spec`); the player's checks above decide what paints.

## For agents

Blueprints are composed, validated and painted live in the browser. The same validation runs through the protocol: an agent drafts a blueprint from catalog components and checks it before anything renders. The live parts run in the browser and are not in this Markdown; the operations below do the same work through the read-only MCP server at https://texuli.com/mcp (no sign-in; see https://texuli.com/auth.md).

MCP operations ([reference](https://github.com/DailybotHQ/texuli/blob/main/packages/tools/docs/ops.md#operations)):

- `blueprint.validate`: Validate a blueprint draft.
- `catalog.search`: Search the component catalog.
- `component.get`: Read a component manifest.
- `catalog.validate`: Validate catalog manifests.

Docs:

- [Component docs for agents (llms.txt)](https://texuli.com/llms/llms.txt)
- [Catalog manifest snapshot (JSON)](https://texuli.com/catalog/catalog.json)
- [@texuli/catalog README](https://github.com/DailybotHQ/texuli/blob/main/packages/catalog/README.md)
- [@texuli/player README](https://github.com/DailybotHQ/texuli/blob/main/packages/player/README.md)
- [@texuli/spec README](https://github.com/DailybotHQ/texuli/blob/main/packages/spec/README.md)
