@culvii/cli 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMMANDS.md +1 -1
- package/USAGE.md +4 -3
- package/dist/{DeployView-I4Y55LV4.js → DeployView-D4UEXMDJ.js} +1 -1
- package/dist/{HelpView-ZMOAJNYC.js → HelpView-E7HS4SVF.js} +1 -1
- package/dist/{WhoamiView-VHDXFFLX.js → WhoamiView-TKSYSHQ2.js} +1 -1
- package/dist/{WorkspaceView-RNFALIPM.js → WorkspaceView-ID7ZMBHV.js} +1 -1
- package/dist/chunk-IPETC2TK.js +3 -0
- package/dist/index.js +27 -676
- package/dist/lib/evaluator.js +2 -2
- package/dist/login-OGOHEHFE.js +39 -0
- package/dist/{logout-VOWHM2QB.js → logout-BRUJBFUK.js} +1 -1
- package/dist/skill-bundle-7KYK5GBL.js +1377 -0
- package/package.json +9 -5
- package/skills/culvii/.culvii-skill.json +59 -0
- package/skills/culvii/SKILL.md +73 -0
- package/skills/culvii/agents/openai.yaml +4 -0
- package/skills/culvii/examples/agent-workflow.culvii.ts +24 -0
- package/skills/culvii/examples/complete-workflow.culvii.ts +37 -0
- package/skills/culvii/examples/output-surface.culvii.ts +45 -0
- package/skills/culvii/examples/wait-surface.culvii.ts +24 -0
- package/skills/culvii/references/agents.md +29 -0
- package/skills/culvii/references/authoring-files.md +21 -0
- package/skills/culvii/references/cli-guide.md +22 -0
- package/skills/culvii/references/cli-reference.md +184 -0
- package/skills/culvii/references/feedback-cycle.md +43 -0
- package/skills/culvii/references/integrations.md +13 -0
- package/skills/culvii/references/kit-api.md +35 -0
- package/skills/culvii/references/node-core-agent.md +27 -0
- package/skills/culvii/references/node-core-browser-automation.md +53 -0
- package/skills/culvii/references/node-core-code.md +28 -0
- package/skills/culvii/references/node-core-http.md +42 -0
- package/skills/culvii/references/node-core-if.md +26 -0
- package/skills/culvii/references/node-core-jwt.md +31 -0
- package/skills/culvii/references/node-core-set.md +24 -0
- package/skills/culvii/references/node-cron-trigger.md +25 -0
- package/skills/culvii/references/node-elasticsearch.md +39 -0
- package/skills/culvii/references/node-gmail-trigger.md +44 -0
- package/skills/culvii/references/node-gmail.md +57 -0
- package/skills/culvii/references/node-google-calendar.md +51 -0
- package/skills/culvii/references/node-google-docs.md +46 -0
- package/skills/culvii/references/node-manual-trigger.md +24 -0
- package/skills/culvii/references/node-microsoft-outlook-trigger.md +41 -0
- package/skills/culvii/references/node-microsoft-outlook.md +55 -0
- package/skills/culvii/references/node-microsoft-sharepoint.md +40 -0
- package/skills/culvii/references/node-s3.md +40 -0
- package/skills/culvii/references/node-slack-trigger.md +40 -0
- package/skills/culvii/references/node-slack.md +38 -0
- package/skills/culvii/references/node-twilio.md +39 -0
- package/skills/culvii/references/node-wait-timer.md +24 -0
- package/skills/culvii/references/node-webhook-trigger.md +24 -0
- package/skills/culvii/references/nodes-index.md +27 -0
- package/skills/culvii/references/runtime-values.md +36 -0
- package/skills/culvii/references/surface-authoring.md +27 -0
- package/skills/culvii/references/surface-display.md +390 -0
- package/skills/culvii/references/surface-feedback.md +41 -0
- package/skills/culvii/references/surface-input-actions.md +143 -0
- package/skills/culvii/references/surface-layout.md +97 -0
- package/skills/culvii/references/validation.md +18 -0
- package/skills/culvii/references/workflows.md +30 -0
- package/dist/chunk-LD5ISISS.js +0 -3
- package/dist/login-4VBBCK4V.js +0 -36
- /package/dist/{chunk-5NBKYMD7.js → chunk-56C3DFV2.js} +0 -0
- /package/dist/{chunk-JFIFRAAR.js → chunk-RS5GDTRN.js} +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# microsoftSharepoint
|
|
2
|
+
|
|
3
|
+
- Type ID: `microsoftSharepoint`
|
|
4
|
+
- Kind: `action`
|
|
5
|
+
- Credentials: required as `credentials: { name, id }`
|
|
6
|
+
- Feedback mock: required
|
|
7
|
+
|
|
8
|
+
Resolve the credential through [integration selection](integrations.md); never ask the user to copy a credential ID.
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
- `resource`: options; required
|
|
13
|
+
- Values: `sharepointItem`, `sharepointList`
|
|
14
|
+
- `operation`: options; required; when resource=sharepointItem
|
|
15
|
+
- Values: `getMany`, `getOne`, `create`, `update`, `delete`
|
|
16
|
+
- `siteId`: options; required; when resource=sharepointItem
|
|
17
|
+
- `listId`: options; required; when resource=sharepointItem
|
|
18
|
+
- `limit`: number; optional; when resource=sharepointItem, operation=getMany
|
|
19
|
+
- `returnFields`: string; optional; when resource=sharepointItem, operation=getMany|getOne
|
|
20
|
+
- `itemId`: string; required; when resource=sharepointItem, operation=getOne|update|delete
|
|
21
|
+
- `contentTypeId`: options; required; when resource=sharepointItem, operation=create|update
|
|
22
|
+
- `fields`: resourceMapper; required; when resource=sharepointItem, operation=create|update
|
|
23
|
+
- `operation`: options; required; when resource=sharepointList
|
|
24
|
+
- Values: `getMany`
|
|
25
|
+
- `siteId`: options; required; when resource=sharepointList
|
|
26
|
+
- `pauseAfterExecution`: boolean; optional
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
new Step({
|
|
32
|
+
id: 'microsoft-sharepoint',
|
|
33
|
+
name: 'microsoftSharepoint',
|
|
34
|
+
type: 'microsoftSharepoint',
|
|
35
|
+
credentials: { name: 'Stored credential', id: 'credential-id' },
|
|
36
|
+
params: { /* use the required props and conditional values above */ },
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Further reading: [Culvii microsoftSharepoint node](https://culvii.com/docs/nodes/microsoft-sharepoint/).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# s3
|
|
2
|
+
|
|
3
|
+
- Type ID: `s3`
|
|
4
|
+
- Kind: `action`
|
|
5
|
+
- Credentials: required as `credentials: { name, id }`
|
|
6
|
+
- Feedback mock: required
|
|
7
|
+
|
|
8
|
+
Resolve the credential through [integration selection](integrations.md); never ask the user to copy a credential ID.
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
- `resource`: options; required
|
|
13
|
+
- Values: `object`
|
|
14
|
+
- `operation`: options; required; when resource=object
|
|
15
|
+
- Values: `upload`, `get`
|
|
16
|
+
- `bucketName`: string; required; when resource=object, operation=upload
|
|
17
|
+
- `objectKey`: string; required; when resource=object, operation=upload
|
|
18
|
+
- `binaryPropertyName`: string; required; when resource=object, operation=upload
|
|
19
|
+
- `skipIfNoBinaryData`: boolean; optional; when resource=object, operation=upload
|
|
20
|
+
- `bucketName`: string; required; when resource=object, operation=get
|
|
21
|
+
- `objectKey`: string; required; when resource=object, operation=get
|
|
22
|
+
- `binaryPropertyName`: string; required; when resource=object, operation=get
|
|
23
|
+
- `returnBinaryData`: boolean; optional; when resource=object, operation=get
|
|
24
|
+
- `generateDownloadUrl`: boolean; optional; when resource=object, operation=get
|
|
25
|
+
- `downloadUrlExpiresIn`: number; optional; when resource=object, operation=get, generateDownloadUrl=true
|
|
26
|
+
- `pauseAfterExecution`: boolean; optional
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
new Step({
|
|
32
|
+
id: 's3',
|
|
33
|
+
name: 's3',
|
|
34
|
+
type: 's3',
|
|
35
|
+
credentials: { name: 'Stored credential', id: 'credential-id' },
|
|
36
|
+
params: { /* use the required props and conditional values above */ },
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Further reading: [Culvii s3 node](https://culvii.com/docs/nodes/s3/).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# slackTrigger
|
|
2
|
+
|
|
3
|
+
- Type ID: `slackTrigger`
|
|
4
|
+
- Kind: `trigger`
|
|
5
|
+
- Credentials: required as `credentials: { name, id }`
|
|
6
|
+
- Feedback mock: required
|
|
7
|
+
|
|
8
|
+
Resolve the credential through [integration selection](integrations.md); never ask the user to copy a credential ID.
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
- `pollIntervalMs`: number; required
|
|
13
|
+
- `event`: options; required
|
|
14
|
+
- Values: `messagePosted`
|
|
15
|
+
- `channelId`: string; required
|
|
16
|
+
- `output`: options; optional
|
|
17
|
+
- Values: `simple`, `raw`
|
|
18
|
+
- `filters`: object; optional
|
|
19
|
+
- `userId`: string; optional
|
|
20
|
+
- `textContains`: string; optional
|
|
21
|
+
- `excludeBots`: boolean; optional
|
|
22
|
+
- `subtype`: string; optional
|
|
23
|
+
- `options`: object; optional
|
|
24
|
+
- `maxMessages`: number; optional
|
|
25
|
+
- `includeThreadReplies`: boolean; optional
|
|
26
|
+
- `pauseAfterExecution`: boolean; optional
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
new Step({
|
|
32
|
+
id: 'slack-trigger',
|
|
33
|
+
name: 'slackTrigger',
|
|
34
|
+
type: 'slackTrigger',
|
|
35
|
+
credentials: { name: 'Stored credential', id: 'credential-id' },
|
|
36
|
+
params: { /* use the required props and conditional values above */ },
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Further reading: [Culvii slackTrigger node](https://culvii.com/docs/nodes/triggers/slack-trigger/).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# slack
|
|
2
|
+
|
|
3
|
+
- Type ID: `slack`
|
|
4
|
+
- Kind: `action`
|
|
5
|
+
- Credentials: required as `credentials: { name, id }`
|
|
6
|
+
- Feedback mock: required
|
|
7
|
+
|
|
8
|
+
Resolve the credential through [integration selection](integrations.md); never ask the user to copy a credential ID.
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
- `resource`: options; required
|
|
13
|
+
- Values: `message`
|
|
14
|
+
- `operation`: options; required; when resource=message
|
|
15
|
+
- Values: `send`
|
|
16
|
+
- `channel`: string; required; when resource=message, operation=send
|
|
17
|
+
- `text`: string; required; when resource=message, operation=send
|
|
18
|
+
- `additionalFields`: object; optional; when resource=message, operation=send
|
|
19
|
+
- `thread_ts`: string; optional
|
|
20
|
+
- `mrkdwn`: boolean; optional
|
|
21
|
+
- `link_names`: boolean; optional
|
|
22
|
+
- `unfurl_links`: boolean; optional
|
|
23
|
+
- `unfurl_media`: boolean; optional
|
|
24
|
+
- `pauseAfterExecution`: boolean; optional
|
|
25
|
+
|
|
26
|
+
## Example
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
new Step({
|
|
30
|
+
id: 'slack',
|
|
31
|
+
name: 'slack',
|
|
32
|
+
type: 'slack',
|
|
33
|
+
credentials: { name: 'Stored credential', id: 'credential-id' },
|
|
34
|
+
params: { /* use the required props and conditional values above */ },
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Further reading: [Culvii slack node](https://culvii.com/docs/nodes/slack/).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# twilio
|
|
2
|
+
|
|
3
|
+
- Type ID: `twilio`
|
|
4
|
+
- Kind: `action`
|
|
5
|
+
- Credentials: required as `credentials: { name, id }`
|
|
6
|
+
- Feedback mock: required
|
|
7
|
+
|
|
8
|
+
Resolve the credential through [integration selection](integrations.md); never ask the user to copy a credential ID.
|
|
9
|
+
|
|
10
|
+
## Props
|
|
11
|
+
|
|
12
|
+
- `resource`: options; optional
|
|
13
|
+
- Values: `call`
|
|
14
|
+
- `operation`: options; optional; when resource=call
|
|
15
|
+
- Values: `makeCall`
|
|
16
|
+
- `fromNumber`: string; required; when resource=call, operation=makeCall
|
|
17
|
+
- `toNumber`: string; required; when resource=call, operation=makeCall
|
|
18
|
+
- `sayList`: array; required; when resource=call, operation=makeCall
|
|
19
|
+
- `noResponseSayList`: array; optional; when resource=call, operation=makeCall
|
|
20
|
+
- `positiveResponseSayList`: array; optional; when resource=call, operation=makeCall
|
|
21
|
+
- `negativeResponseSayList`: array; optional; when resource=call, operation=makeCall
|
|
22
|
+
- `positiveResponse`: number; required; when resource=call, operation=makeCall
|
|
23
|
+
- `speechRate`: string; optional; when resource=call, operation=makeCall
|
|
24
|
+
- `record`: boolean; optional; when resource=call, operation=makeCall
|
|
25
|
+
- `pauseAfterExecution`: boolean; optional
|
|
26
|
+
|
|
27
|
+
## Example
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
new Step({
|
|
31
|
+
id: 'twilio',
|
|
32
|
+
name: 'twilio',
|
|
33
|
+
type: 'twilio',
|
|
34
|
+
credentials: { name: 'Stored credential', id: 'credential-id' },
|
|
35
|
+
params: { /* use the required props and conditional values above */ },
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Further reading: [Culvii twilio node](https://culvii.com/docs/nodes/twilio/).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# waitTimer
|
|
2
|
+
|
|
3
|
+
- Type ID: `waitTimer`
|
|
4
|
+
- Kind: `action`
|
|
5
|
+
- Credentials: not required
|
|
6
|
+
- Feedback mock: not required
|
|
7
|
+
|
|
8
|
+
## Props
|
|
9
|
+
|
|
10
|
+
- `resumeIn`: number; required
|
|
11
|
+
- `pauseAfterExecution`: boolean; optional
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
new Step({
|
|
17
|
+
id: 'wait-timer',
|
|
18
|
+
name: 'waitTimer',
|
|
19
|
+
type: 'waitTimer',
|
|
20
|
+
params: { /* use the required props and conditional values above */ },
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Further reading: [Culvii waitTimer node](https://culvii.com/docs/nodes/wait-timer/).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# webhookTrigger
|
|
2
|
+
|
|
3
|
+
- Type ID: `webhookTrigger`
|
|
4
|
+
- Kind: `trigger`
|
|
5
|
+
- Credentials: not required
|
|
6
|
+
- Feedback mock: not required
|
|
7
|
+
|
|
8
|
+
## Props
|
|
9
|
+
|
|
10
|
+
- `method`: string; required
|
|
11
|
+
- `pauseAfterExecution`: boolean; optional
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
new Step({
|
|
17
|
+
id: 'webhook-trigger',
|
|
18
|
+
name: 'webhookTrigger',
|
|
19
|
+
type: 'webhookTrigger',
|
|
20
|
+
params: { /* use the required props and conditional values above */ },
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Further reading: [Culvii webhookTrigger node](https://culvii.com/docs/nodes/triggers/webhook-trigger/).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Node index
|
|
2
|
+
|
|
3
|
+
Generated from `GENERATED_NODE_DEFINITIONS`. Open the exact node page before authoring its params.
|
|
4
|
+
|
|
5
|
+
- [`core.agent`](node-core-agent.md) — action
|
|
6
|
+
- [`core.browserAutomation`](node-core-browser-automation.md) — action; feedback mock required
|
|
7
|
+
- [`core.code`](node-core-code.md) — action
|
|
8
|
+
- [`core.http`](node-core-http.md) — action; feedback mock required
|
|
9
|
+
- [`core.if`](node-core-if.md) — action
|
|
10
|
+
- [`core.jwt`](node-core-jwt.md) — action
|
|
11
|
+
- [`core.set`](node-core-set.md) — action
|
|
12
|
+
- [`cronTrigger`](node-cron-trigger.md) — trigger
|
|
13
|
+
- [`elasticsearch`](node-elasticsearch.md) — action; credentials required; feedback mock required
|
|
14
|
+
- [`gmail`](node-gmail.md) — action; credentials required; feedback mock required
|
|
15
|
+
- [`gmailTrigger`](node-gmail-trigger.md) — trigger; credentials required; feedback mock required
|
|
16
|
+
- [`googleCalendar`](node-google-calendar.md) — action; credentials required; feedback mock required
|
|
17
|
+
- [`googleDocs`](node-google-docs.md) — action; credentials required; feedback mock required
|
|
18
|
+
- [`manualTrigger`](node-manual-trigger.md) — trigger
|
|
19
|
+
- [`microsoftOutlook`](node-microsoft-outlook.md) — action; credentials required; feedback mock required
|
|
20
|
+
- [`microsoftOutlookTrigger`](node-microsoft-outlook-trigger.md) — trigger; credentials required; feedback mock required
|
|
21
|
+
- [`microsoftSharepoint`](node-microsoft-sharepoint.md) — action; credentials required; feedback mock required
|
|
22
|
+
- [`s3`](node-s3.md) — action; credentials required; feedback mock required
|
|
23
|
+
- [`slack`](node-slack.md) — action; credentials required; feedback mock required
|
|
24
|
+
- [`slackTrigger`](node-slack-trigger.md) — trigger; credentials required; feedback mock required
|
|
25
|
+
- [`twilio`](node-twilio.md) — action; credentials required; feedback mock required
|
|
26
|
+
- [`waitTimer`](node-wait-timer.md) — action
|
|
27
|
+
- [`webhookTrigger`](node-webhook-trigger.md) — trigger
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Runtime values
|
|
2
|
+
|
|
3
|
+
Workflow expressions and surface bindings are different languages. Do not mix them.
|
|
4
|
+
|
|
5
|
+
## Workflow expressions
|
|
6
|
+
|
|
7
|
+
Step params are resolved recursively through nested objects and arrays. A value consisting entirely of an expression preserves its runtime type; interpolation inside other text always returns a string.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
params: { values: {
|
|
11
|
+
object: "={{ $('Prepare').json.payload }}",
|
|
12
|
+
nested: { ids: ["={{ $('Prepare').json.id }}", '={{ $system.execId }}'] },
|
|
13
|
+
message: "Account {{ $('Prepare').json.account }} is ready",
|
|
14
|
+
} }
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Selectors:
|
|
18
|
+
|
|
19
|
+
- `$json.field` or `json.field`: current input.
|
|
20
|
+
- `$('Step Name').json.field`: named step, default port and item index.
|
|
21
|
+
- `$('Step Name:port')[2].json.field`: named port and index.
|
|
22
|
+
- `$system.execId`, `$system.workflowId`, `$system.node.id`: execution metadata.
|
|
23
|
+
|
|
24
|
+
The `.json` segment after a named step is optional. Use step names, not IDs. Expressions are selectors, not JavaScript.
|
|
25
|
+
|
|
26
|
+
## Surface bindings
|
|
27
|
+
|
|
28
|
+
A binding is an object such as `{ path: '/$output/Prepare/main/0/0/account', default: 'Unknown', format: 'text' }`. Its `path` is a JSON Pointer rooted at:
|
|
29
|
+
|
|
30
|
+
- `$output`: current surfaced step output.
|
|
31
|
+
- `$input`: ancestor step output.
|
|
32
|
+
- `$exec`: execution metadata.
|
|
33
|
+
- `$binary`: safe binary descriptors, not raw bytes.
|
|
34
|
+
- `$form`: wait-surface form state only.
|
|
35
|
+
|
|
36
|
+
Output/input/binary paths use `/<root>/<step name>/<port>/<output index>/<item index>/...`. Escape `~` as `~0` and `/` as `~1` in every JSON Pointer segment. A real `null` is not replaced by `default`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Surface authoring
|
|
2
|
+
|
|
3
|
+
Choose components from the use case and expected node data, then verify every prop in the generated catalog pages.
|
|
4
|
+
|
|
5
|
+
For workflow-attached surfaces, make selection, validation, preview, and approval decisions through [surface configuration and visual approval](surface-feedback.md).
|
|
6
|
+
|
|
7
|
+
- Objects: `KeyValue`; wrap important groups in `Card` or `Section`.
|
|
8
|
+
- Arrays: `Table` for comparable records, or repeated domain cards composed with layout components.
|
|
9
|
+
- Metrics: `Stat`, `Money`, `Duration`, or `Timestamp`.
|
|
10
|
+
- Files: `FileChip` bound through `$binary`.
|
|
11
|
+
- Human decisions: a wait `Form` with input components and `Button`, or `ApproveRejectBar`.
|
|
12
|
+
- Raw/debug values: `JsonInspector` or `Code`.
|
|
13
|
+
|
|
14
|
+
A definition uses `schema: 'kit.ui/v1'`, a root component ID, a flat component document list, and an optional wait form. `root` and `children` contain IDs. Never embed a component object directly inside `children`.
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
definition: {
|
|
18
|
+
schema: 'kit.ui/v1', root: 'outer', components: [
|
|
19
|
+
{ id: 'outer', type: 'Stack', children: ['card'] },
|
|
20
|
+
{ id: 'card', type: 'Card', props: { title: 'Result' }, children: ['inner'] },
|
|
21
|
+
{ id: 'inner', type: 'Stack', children: ['status'] },
|
|
22
|
+
{ id: 'status', type: 'StatusPill', props: { status: { path: '/$output/Run/main/0/0/status' } } },
|
|
23
|
+
],
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Recursive Stack/Card/Section graphs are valid up to platform depth 12. Recursive prop schemas are also supported. Component IDs must be unique, reachable from the root, and referenced once according to each component's child mode. The complete catalog is split into [layout](surface-layout.md), [display](surface-display.md), and [input/actions](surface-input-actions.md).
|