Motion operations
7 operations named motion.*. Every one runs in a batch through apply_ops, dry_run_ops, the CLI or the admin.
| Operation | What it does | Permission | Confirmation |
|---|---|---|---|
| motion.read | motion.read with scene validation and page ownership. | site.read | none |
| motion.replace | motion.replace with scene validation and page ownership. | site.edit | none |
| motion.delete | motion.delete with scene validation and page ownership. | site.edit | destructive |
| motion.listRecipes | List the scene recipes a page can apply: the built-in recipes first, then the site's own. | site.read | none |
| motion.applyRecipe | Build a recipe's scenes on a page from its knobs (a knob left out takes its default; an element knob such as target has none and must be given) and replace the page's scenes built by the same recipe on the same target. | site.edit | none |
| motion.saveRecipe | Save scenes of a page that one recipe built as a site recipe (site:<key>): the scenes, their source recipe and its knobs, under a label in Italian and English. | site.edit | none |
| motion.diagnose | Explain why a page's scenes would not play as authored: one finding per problem, each with a reason code (target-missing, target-ambiguous, stateful-target, overlap, empty-range, hidden-at-rest, never-matches), the scene and the node ref it concerns. | site.read | none |
motion.read
motion.read with scene validation and page ownership.
Example input
{
"pageId": "6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f"
}Input
| Field | Type | Required | Notes |
|---|---|---|---|
| pageId | string | yes | At least 1 character. At most 36 characters. |
Output
| Field | Type | Required | Notes |
|---|---|---|---|
| scenes | array of object | yes | |
| scenes[].id | string | yes | At least 1 character. At most 36 characters. |
| scenes[].pageId | string | yes | At least 1 character. At most 36 characters. |
| scenes[].versionId | string | yes | At least 1 character. At most 50 characters. |
| scenes[].trigger | object | object | object | object | object | object | yes | |
| scenes[].entries | array of object | yes | At most 100 items. |
| scenes[].conditions | object | no | |
| scenes[].actions | array of object | object | no | At most 20 items. |
| scenes[].seed | integer | no | At least 0. At most 4294967295. |
| scenes[].pushBy | object | no | |
| scenes[].recipe | object | no | |
| scenes[].disabled | boolean | no | |
| scenes[].defaults | object | no |
Fields nested deeper are in the output schema that discover_operations answers with outputSchemas: true.
Try it
yarn splash motion.read '{"pageId":"6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f"}' --dry-runmotion.replace
motion.replace with scene validation and page ownership.
Example input
{
"pageId": "6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f",
"scenes": []
}Input
| Field | Type | Required | Notes |
|---|---|---|---|
| pageId | string | yes | At least 1 character. At most 36 characters. |
| scenes | array of object | yes | |
| scenes[].id | string | yes | At least 1 character. At most 36 characters. |
| scenes[].pageId | string | yes | At least 1 character. At most 36 characters. |
| scenes[].versionId | string | yes | At least 1 character. At most 50 characters. |
| scenes[].trigger | object | object | object | object | object | object | yes | |
| scenes[].entries | array of object | yes | At most 100 items. |
| scenes[].conditions | object | no | |
| scenes[].actions | array of object | object | no | At most 20 items. |
| scenes[].seed | integer | no | At least 0. At most 4294967295. |
| scenes[].pushBy | object | no | |
| scenes[].recipe | object | no | |
| scenes[].disabled | boolean | no | |
| scenes[].defaults | object | no |
{
"type": "object",
"properties": {
"pageId": {
"$ref": "#/$defs/__schema0"
},
"scenes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/__schema0"
},
"pageId": {
"$ref": "#/$defs/__schema0"
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 50
},
"trigger": {
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "scroll"
},
"anchor": {
"anyOf": [
{
"$ref": "#/$defs/__schema1"
},
{
"type": "string",
"const": "viewport"
}
]
},
"start": {
"$ref": "#/$defs/__schema3"
},
"end": {
"$ref": "#/$defs/__schema3"
},
"endAnchor": {
"$ref": "#/$defs/__schema1"
},
"scrub": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number",
"minimum": 0,
"maximum": 10
}
]
},
"pin": {
"type": "boolean"
}
},
"required": [
"type",
"anchor",
"start"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "intersection"
},
"anchor": {
"$ref": "#/$defs/__schema1"
},
"threshold": {
"anyOf": [
{
"$ref": "#/$defs/__schema5"
},
{
"minItems": 1,
"maxItems": 10,
"type": "array",
"items": {
"$ref": "#/$defs/__schema5"
}
}
]
},
"once": {
"type": "boolean"
}
},
"required": [
"type",
"anchor"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "event"
},
"event": {
"type": "string",
"enum": [
"load",
"click",
"hover"
]
},
"source": {
"anyOf": [
{
"$ref": "#/$defs/__schema1"
},
{
"type": "string",
"const": "page"
}
]
},
"once": {
"type": "boolean"
}
},
"required": [
"type",
"event",
"source"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "first-interaction"
},
"inputs": {
"minItems": 1,
"maxItems": 4,
"type": "array",
"items": {
"$ref": "#/$defs/__schema6"
}
},
"keys": {
"maxItems": 20,
"type": "array",
"items": {
"$ref": "#/$defs/__schema7"
}
},
"lockScroll": {
"type": "boolean"
},
"timeoutMs": {
"type": "integer",
"minimum": 0,
"maximum": 600000
},
"replay": {
"type": "string",
"enum": [
"session",
"always"
]
}
},
"required": [
"type",
"inputs",
"timeoutMs",
"replay"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "section-active"
},
"anchor": {
"type": "string",
"pattern": "^[a-z][a-z0-9-]{0,63}$"
}
},
"required": [
"type",
"anchor"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "surface-under"
},
"probe": {
"$ref": "#/$defs/__schema1"
},
"is": {
"minItems": 1,
"maxItems": 3,
"type": "array",
"items": {
"$ref": "#/$defs/__schema8"
}
}
},
"required": [
"type",
"probe",
"is"
],
"additionalProperties": false
}
]
},
"entries": {
"maxItems": 100,
"type": "array",
"items": {
"$ref": "#/$defs/__schema9"
}
},
"conditions": {
"type": "object",
"properties": {
"minBreakpoint": {
"type": "string",
"enum": [
"sm",
"md",
"lg",
"xl"
]
},
"maxBreakpoint": {
"type": "string",
"enum": [
"sm",
"md",
"lg",
"xl"
]
},
"hover": {
"type": "string",
"enum": [
"none",
"hover"
]
}
},
"additionalProperties": false
},
"actions": {
"maxItems": 20,
"type": "array",
"items": {
"$ref": "#/$defs/__schema17"
}
},
"seed": {
"type": "integer",
"minimum": 0,
"maximum": 4294967295
},
"pushBy": {
"type": "object",
"properties": {
"by": {
"$ref": "#/$defs/__schema1"
},
"gap": {
"$ref": "#/$defs/__schema4"
},
"target": {
"$ref": "#/$defs/__schema1"
}
},
"required": [
"by",
"gap"
],
"additionalProperties": false
},
"recipe": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^(?:site:)?[a-z][a-z0-9-]{0,63}$"
},
"knobs": {
"type": "object",
"propertyNames": {
"type": "string",
"pattern": "^[a-z][a-zA-Z0-9]{0,39}$"
},
"additionalProperties": {
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"maxLength": 200
},
{
"type": "boolean"
},
{
"$ref": "#/$defs/__schema18"
},
{
"$ref": "#/$defs/__schema1"
},
{
"type": "object",
"propertyNames": {
"$ref": "#/$defs/__schema13"
},
"additionalProperties": {
"$ref": "#/$defs/__schema18"
}
}
]
}
},
"custom": {
"type": "boolean"
}
},
"required": [
"id",
"knobs",
"custom"
],
"additionalProperties": false
},
"disabled": {
"type": "boolean"
},
"defaults": {
"type": "object",
"properties": {
"duration": {
"$ref": "#/$defs/__schema14"
},
"easing": {
"$ref": "#/$defs/__schema15"
},
"reducedMotion": {
"$ref": "#/$defs/__schema16"
}
},
"additionalProperties": false
}
},
"required": [
"id",
"pageId",
"versionId",
"trigger",
"entries"
],
"additionalProperties": false
}
}
},
"required": [
"pageId",
"scenes"
],
"additionalProperties": false,
"$defs": {
"__schema0": {
"type": "string",
"minLength": 1,
"maxLength": 36
},
"__schema1": {
"type": "object",
"properties": {
"nodeId": {
"type": "string",
"pattern": "^[0-9a-z]{8}(?:\\.[0-9a-z]{8}){0,3}$"
},
"part": {
"default": "root",
"$ref": "#/$defs/__schema2"
},
"region": {
"type": "string",
"enum": [
"header",
"footer"
]
}
},
"required": [
"nodeId"
],
"additionalProperties": false
},
"__schema2": {
"type": "string",
"maxLength": 50,
"pattern": "^[a-z][a-z0-9-]*$"
},
"__schema3": {
"type": "object",
"properties": {
"edge": {
"type": "string",
"enum": [
"top",
"center",
"bottom"
]
},
"viewport": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"offset": {
"$ref": "#/$defs/__schema4"
},
"belowHeader": {
"type": "boolean",
"const": true
}
},
"required": [
"edge",
"viewport"
],
"additionalProperties": false
},
"__schema4": {
"type": "object",
"properties": {
"value": {
"type": "number",
"minimum": -10000,
"maximum": 10000
},
"unit": {
"type": "string",
"enum": [
"vh",
"px"
]
}
},
"required": [
"value",
"unit"
],
"additionalProperties": false
},
"__schema5": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"__schema6": {
"type": "string",
"enum": [
"wheel",
"touch",
"click",
"key"
]
},
"__schema7": {
"type": "string",
"minLength": 1,
"maxLength": 20
},
"__schema8": {
"type": "string",
"enum": [
"light",
"dark",
"media"
]
},
"__schema9": {
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/__schema0"
},
"sceneId": {
"$ref": "#/$defs/__schema0"
},
"target": {
"$ref": "#/$defs/__schema1"
},
"keyframes": {
"maxItems": 20,
"type": "array",
"items": {
"$ref": "#/$defs/__schema10"
}
},
"moveInto": {
"type": "object",
"properties": {
"into": {
"$ref": "#/$defs/__schema1"
},
"scale": {
"type": "string",
"enum": [
"fit",
"keep"
]
},
"align": {
"type": "string",
"enum": [
"center",
"start"
]
},
"perBreakpoint": {
"type": "object",
"propertyNames": {
"type": "string",
"enum": [
"sm",
"md",
"lg",
"xl"
]
},
"additionalProperties": {
"type": "object",
"properties": {
"scale": {
"type": "string",
"enum": [
"fit",
"keep"
]
}
},
"required": [
"scale"
],
"additionalProperties": false
}
}
},
"required": [
"into",
"scale"
],
"additionalProperties": false
},
"effect": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"const": "flicker"
},
"part": {
"$ref": "#/$defs/__schema2"
},
"ratio": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"min": {
"type": "integer",
"minimum": 0,
"maximum": 1000
},
"settle": {
"type": "string",
"enum": [
"on",
"off"
]
}
},
"required": [
"kind",
"part"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"const": "assemble"
},
"part": {
"$ref": "#/$defs/__schema2"
}
},
"required": [
"kind",
"part"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"const": "typeErase"
},
"words": {
"type": "object",
"propertyNames": {
"type": "string",
"pattern": "^[a-z][a-z0-9-]{0,63}$"
},
"additionalProperties": {
"anyOf": [
{
"$ref": "#/$defs/__schema12"
},
{
"type": "object",
"propertyNames": {
"$ref": "#/$defs/__schema13"
},
"additionalProperties": {
"$ref": "#/$defs/__schema12"
}
}
]
}
},
"typeMs": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 2000
},
"eraseMs": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 2000
}
},
"required": [
"kind",
"words"
],
"additionalProperties": false
}
]
},
"position": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "absolute"
},
"ms": {
"type": "number",
"minimum": 0,
"maximum": 600000
}
},
"required": [
"type",
"ms"
],
"additionalProperties": false
},
"duration": {
"$ref": "#/$defs/__schema14"
},
"easing": {
"$ref": "#/$defs/__schema15"
},
"stagger": {
"type": "integer",
"minimum": 0,
"maximum": 10000
},
"reducedMotion": {
"$ref": "#/$defs/__schema16"
}
},
"required": [
"id",
"sceneId",
"target",
"keyframes",
"position"
],
"additionalProperties": false
},
"__schema10": {
"type": "object",
"properties": {
"offset": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"transform": {
"type": "object",
"properties": {
"x": {
"$ref": "#/$defs/__schema11"
},
"y": {
"$ref": "#/$defs/__schema11"
},
"scale": {
"type": "number"
},
"rotate": {
"$ref": "#/$defs/__schema11"
}
},
"additionalProperties": false
},
"blur": {
"$ref": "#/$defs/__schema11"
},
"clipPath": {
"$ref": "#/$defs/__schema11"
},
"color": {
"$ref": "#/$defs/__schema11"
},
"backgroundColor": {
"$ref": "#/$defs/__schema11"
},
"vars": {
"type": "object",
"propertyNames": {
"type": "string",
"pattern": "^--[a-z0-9-]+$"
},
"additionalProperties": {
"$ref": "#/$defs/__schema11"
}
}
},
"required": [
"offset"
],
"additionalProperties": false
},
"__schema11": {
"type": "string",
"minLength": 1,
"maxLength": 500
},
"__schema12": {
"type": "string",
"maxLength": 80
},
"__schema13": {
"type": "string",
"pattern": "^[a-z]{2,3}(?:-[A-Z][a-z]{3})?(?:-(?:[A-Z]{2}|\\d{3}))?$"
},
"__schema14": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 600000
},
{
"type": "string",
"maxLength": 100
}
]
},
"__schema15": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "string",
"minLength": 1,
"maxLength": 100
}
]
},
"__schema16": {
"type": "string",
"enum": [
"skip",
"fade-only",
"instant"
]
},
"__schema17": {
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "set-state"
},
"target": {
"$ref": "#/$defs/__schema1"
},
"state": {
"$ref": "#/$defs/__schema2"
}
},
"required": [
"type",
"target",
"state"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "threshold"
},
"target": {
"$ref": "#/$defs/__schema1"
},
"state": {
"$ref": "#/$defs/__schema2"
},
"clear": {
"type": "boolean"
},
"when": {
"anyOf": [
{
"type": "object",
"properties": {
"progress": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"progress"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"scrollY": {
"$ref": "#/$defs/__schema4"
}
},
"required": [
"scrollY"
],
"additionalProperties": false
}
]
}
},
"required": [
"type",
"target",
"state",
"when"
],
"additionalProperties": false
}
]
},
"__schema18": {
"maxItems": 50,
"type": "array",
"items": {
"$ref": "#/$defs/__schema19"
}
},
"__schema19": {
"type": "string",
"maxLength": 200
}
}
}Output
| Field | Type | Required | Notes |
|---|---|---|---|
| success | true | yes |
Try it
yarn splash motion.replace '{"pageId":"6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f","scenes":[]}' --dry-runmotion.delete
motion.delete with scene validation and page ownership.
Example input
{
"pageId": "6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f",
"sceneId": "scene-1"
}Input
| Field | Type | Required | Notes |
|---|---|---|---|
| pageId | string | yes | At least 1 character. At most 36 characters. |
| sceneId | string | yes | At least 1 character. At most 36 characters. |
Output
| Field | Type | Required | Notes |
|---|---|---|---|
| success | true | yes |
Needs confirmed: ["destructive"] on the batch, which the single-operation CLI form does not set: put it in a batch file and run yarn splash apply <file> --dry-run.
motion.listRecipes
List the scene recipes a page can apply: the built-in recipes first, then the site's own. Each has a label and a description in Italian and English, and two to four knobs (a number, a choice, a list of words, a node or a distance in screens) with working defaults.
Example input
{}Input
The input is a record; see the schema below.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Output
| Field | Type | Required | Notes |
|---|---|---|---|
| recipes | array of object | yes | |
| recipes[].id | string | yes | |
| recipes[].label | object | yes | |
| recipes[].description | object | yes | |
| recipes[].source | string | yes | One of "built-in", "site". |
| recipes[].knobs | array of object | object | object | object | object | yes | At most 8 items. |
Fields nested deeper are in the output schema that discover_operations answers with outputSchemas: true.
Try it
yarn splash motion.listRecipes '{}' --dry-runmotion.applyRecipe
Build a recipe's scenes on a page from its knobs (a knob left out takes its default; an element knob such as target has none and must be given) and replace the page's scenes built by the same recipe on the same target. The scenes carry the recipe meta (recipe: { id, knobs, custom: false }) and are validated like motion.replace. The snap recipe writes the page's scroll setting instead, so its batch also needs the pages base revision. An unknown recipe is 404 recipe_not_found; refused knobs are 422 recipe_knobs_invalid.
Example input
{
"pageId": "6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f",
"recipeId": "dock",
"knobs": {
"target": {
"nodeId": "mark0001",
"part": "root"
},
"slot": {
"nodeId": "logo0001",
"part": "root",
"region": "header"
},
"start": 0.95,
"duration": 0.75
}
}Input
| Field | Type | Required | Notes |
|---|---|---|---|
| pageId | string | yes | At least 1 character. At most 36 characters. |
| recipeId | string | yes | |
| knobs | record of number | string | boolean | array of string | object | record of array of value | no |
Output
| Field | Type | Required | Notes |
|---|---|---|---|
| scenes | array of object | yes | |
| scenes[].id | string | yes | At least 1 character. At most 36 characters. |
| scenes[].pageId | string | yes | At least 1 character. At most 36 characters. |
| scenes[].versionId | string | yes | At least 1 character. At most 50 characters. |
| scenes[].trigger | object | object | object | object | object | object | yes | |
| scenes[].entries | array of object | yes | At most 100 items. |
| scenes[].conditions | object | no | |
| scenes[].actions | array of object | object | no | At most 20 items. |
| scenes[].seed | integer | no | At least 0. At most 4294967295. |
| scenes[].pushBy | object | no | |
| scenes[].recipe | object | no | |
| scenes[].disabled | boolean | no | |
| scenes[].defaults | object | no |
Fields nested deeper are in the output schema that discover_operations answers with outputSchemas: true.
Try it
yarn splash motion.applyRecipe '{"pageId":"6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f","recipeId":"dock","knobs":{"target":{"nodeId":"mark0001","part":"root"},"slot":{"nodeId":"logo0001","part":"root","region":"header"},"start":0.95,"duration":0.75}}' --dry-runmotion.saveRecipe
Save scenes of a page that one recipe built as a site recipe (site:<key>): the scenes, their source recipe and its knobs, under a label in Italian and English. A site recipe has no knobs of its own; applying it writes its scenes again.
Example input
{
"pageId": "6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f",
"sceneIds": [
"scene-1"
],
"label": {
"it": "Logo che si aggancia",
"en": "Docking logo"
}
}Input
| Field | Type | Required | Notes |
|---|---|---|---|
| pageId | string | yes | At least 1 character. At most 36 characters. |
| sceneIds | array of string | yes | At least 1 item. At most 20 items. |
| label | object | yes | |
| label.it | string | yes | At least 1 character. At most 120 characters. |
| label.en | string | yes | At least 1 character. At most 120 characters. |
| description | object | no | |
| description.it | string | yes | At least 1 character. At most 120 characters. |
| description.en | string | yes | At least 1 character. At most 120 characters. |
Output
| Field | Type | Required | Notes |
|---|---|---|---|
| id | string | yes | |
| label | object | yes | |
| label.it | string | yes | At least 1 character. At most 120 characters. |
| label.en | string | yes | At least 1 character. At most 120 characters. |
| description | object | yes | |
| description.it | string | yes | At least 1 character. At most 120 characters. |
| description.en | string | yes | At least 1 character. At most 120 characters. |
| source | string | yes | One of "built-in", "site". |
| knobs | array of object | object | object | object | object | yes | At most 8 items. |
Try it
yarn splash motion.saveRecipe '{"pageId":"6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f","sceneIds":["scene-1"],"label":{"it":"Logo che si aggancia","en":"Docking logo"}}' --dry-runmotion.diagnose
Explain why a page's scenes would not play as authored: one finding per problem, each with a reason code (target-missing, target-ambiguous, stateful-target, overlap, empty-range, hidden-at-rest, never-matches), the scene and the node ref it concerns.
Example input
{
"pageId": "6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f"
}Input
| Field | Type | Required | Notes |
|---|---|---|---|
| pageId | string | yes | At least 1 character. At most 36 characters. |
Output
| Field | Type | Required | Notes |
|---|---|---|---|
| findings | array of object | yes | |
| findings[].sceneId | string | yes | At least 1 character. At most 36 characters. |
| findings[].code | string | yes | One of "target-missing", "target-ambiguous", "stateful-target", "overlap", "empty-range", "hidden-at-rest", "never-matches". |
| findings[].ref | object | no | |
| findings[].message | string | yes | At least 1 character. At most 500 characters. |
Fields nested deeper are in the output schema that discover_operations answers with outputSchemas: true.
Try it
yarn splash motion.diagnose '{"pageId":"6f1d2c3b-4a59-4e8d-9c7b-1a2b3c4d5e6f"}' --dry-runGenerated from the operation registry and the MCP tool catalogue (source 50a582a74dcfa6cf).
Something wrong on this page? Write to docs@librettocms.com.