Scaffold Workspace Structure
steps.applyApply a declarative 'Steps' document that scaffolds a whole workspace at once: a space (new, or an existing one you name), optional folders, and one or more sheets (each with attributes/views/peeks). Use this for multi-sheet apps (e.g. a CRM with Contacts + Deals) instead of creating sheets one by one.
Every node has a doc-local 'ref'; cross-references use {"$ref":""}; attributes are targeted by their author-assigned 'code'.
To LINK two sheets (a relation), use dataType "Relation" with options.relatedSheet:{"$ref":""}, or {"$existing":{"sheetId":}} to link to a sheet that already exists in this workspace (id from workspace.structure). Do NOT use "Link" — that is a plain URL field, not a cross-sheet relation.
A count or sum over linked rows: dataType "Rollup" with options {type:"RELATION", relatedAttr:{"$ref":""}, fn:{functionType:"COUNT"}, returnType:"Number"}. A linked row's field: dataType "Mirror" with options {relationAttr:{"$ref":""}, mirroredAttr:{"$ref":"<field of the related sheet, or Title>"}}. Name fields by ref or code, never by id; new sheets only.
Set
isUnique: trueon an attribute whose value identifies a row (an external id, an email): item.create then dedupes on it.On a Status attribute give each option a
bucket("Todo" / "InProgress" / "Complete") so done choices read as done — give every option one.bucketis rejected on Select / Multi-Select.A sheet with no 'folder' lands at the space root. Only set a sheet's folder to a ref you declared in 'folders' — never to a space ref.
dataType values must be canonical Atwork names (e.g. "Short Text", "Long Text", "Number", "Email", "Date", "Select", "Status", "Relation"); a file field is always "File List".
Do NOT include a version or capabilities in the doc — those are handled automatically.
Placement: pass
spaceId(and optionallyfolderId) fromworkspace.structureto install into an EXISTING space. Omit both to create a new space.Optional extras: top-level 'forms' ({ref,name,sheet:{$ref},fields:[{code,required?,label?}]}), 'dashboards' ({ref,name,sheet:{$ref},widgets}), 'pages' ({ref,name,markdown}), 'spaceHome' ({widgets}) and 'seedRows' ({"": [{"": value}]}) for starter rows. Pass a draft from steps.draft unchanged; any other top-level key is an error.
'workflows' use the Steps workflow format from the build skill; a doc with only workflows on existing sheets ({"$existing":{"sheetId":}}) creates no space. Returns the created spaceId, a map of sheet ref -> new sheetId, each workflow's state or error, and the address of every sheet that now takes email.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| doc | Yes | ||
| spaceId | No | Install into this EXISTING space instead of creating a new one. From workspace.structure. | |
| folderId | No | Folder inside that space; defaults to the space root. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| spaceId | No | The space the document was applied to (new or existing) | |
| sheetIds | No | Sheet ref → new sheetId | |
| workflows | No | One per workflow: active = running; error = why it was not created or turned on — tell the user | |
| inboundAddresses | No | Email to this sheet: give the user this address; each email sent to it creates an item |