@controllerai/cli 0.2.17 → 0.2.20
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/dist/api/client.js +32 -0
- package/dist/api/client.js.map +1 -1
- package/dist/commands/agent.js +101 -8
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/expr.js +3 -10
- package/dist/commands/expr.js.map +1 -1
- package/dist/commands/file.js +11 -1
- package/dist/commands/file.js.map +1 -1
- package/dist/commands/integration.js +8 -2
- package/dist/commands/integration.js.map +1 -1
- package/dist/commands/workflow.js +29 -6
- package/dist/commands/workflow.js.map +1 -1
- package/dist/errors.js +5 -2
- package/dist/errors.js.map +1 -1
- package/package.json +1 -1
- package/skills/controllerai-agents/SKILL.md +25 -192
- package/skills/controllerai-agents/references/command-reference.md +205 -0
- package/skills/controllerai-ai-nodes/SKILL.md +11 -92
- package/skills/controllerai-ai-nodes/references/command-reference.md +98 -0
- package/skills/controllerai-data/SKILL.md +34 -159
- package/skills/controllerai-data/references/command-reference.md +177 -0
- package/skills/controllerai-expressions/SKILL.md +29 -151
- package/skills/controllerai-expressions/references/command-reference.md +166 -0
- package/skills/controllerai-expressions/references/dsl-and-recipes.md +1 -1
- package/skills/controllerai-flow-control/SKILL.md +21 -160
- package/skills/controllerai-flow-control/references/command-reference.md +171 -0
- package/skills/controllerai-integration-actions/SKILL.md +11 -112
- package/skills/controllerai-integration-actions/references/command-reference.md +118 -0
- package/skills/controllerai-node-config/SKILL.md +18 -178
- package/skills/controllerai-node-config/references/command-reference.md +186 -0
- package/skills/controllerai-runs/SKILL.md +25 -117
- package/skills/controllerai-runs/references/command-reference.md +113 -0
- package/skills/controllerai-start/SKILL.md +36 -67
- package/skills/controllerai-start/references/mcp-tool-map.md +6 -0
- package/skills/controllerai-triggers/SKILL.md +16 -210
- package/skills/controllerai-triggers/references/command-reference.md +215 -0
- package/skills/controllerai-workflows/SKILL.md +24 -104
- package/skills/controllerai-workflows/references/command-reference.md +118 -0
- package/skills/manifest.json +120 -60
|
@@ -1,222 +1,28 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: controllerai-triggers
|
|
3
|
-
description:
|
|
3
|
+
description: Build and verify Controller AI event-driven workflows using schedules, webhooks, email and integration events. Use for trigger discovery, configuration, samples, event mapping, replay and enabling live execution.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Run workflows from events
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
A trigger captures a schedule, webhook, email or integration event and maps it into a flow's typed inputs. It lets the same reusable processing run without a chat message. The trigger configuration, captured samples and execution state are separate concerns.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Build the event path
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
1. Discover the trigger component and inspect its properties, authorization and output schema.
|
|
13
|
+
2. Create/select the destination flow and define the inputs it needs.
|
|
14
|
+
3. Configure the trigger using the exact component identity. Choose selectors before dependent properties and bind any required connection.
|
|
15
|
+
4. Capture a representative event. Use the returned webhook URL, trigger email address or provider action; do not invent an endpoint.
|
|
16
|
+
5. Inspect/select the captured sample and map its fields into flow inputs using the actual expression context.
|
|
17
|
+
6. Replay the sample on development and verify received inputs, flow outputs and expected record or external effects.
|
|
18
|
+
7. When live operation is authorized, publish the workflow, enable the trigger as needed and verify an actual live event.
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
- Delete a retired start; disable a reversible pause. See Remove or disable an automatic start.
|
|
16
|
-
- Lifecycle uses `--enable|--disable`; test events use `--allow|--disallow`. See Remove or disable an automatic start and Finish trigger setup.
|
|
17
|
-
- Disarm capture when setup ends; see Finish trigger setup.
|
|
18
|
-
- Lifecycle edits are development-only; publish only for Live. See Verify development, then publish.
|
|
19
|
-
- Replay with `--target dev`; Live also requires `--confirm-live`. See Verify development, then publish.
|
|
20
|
+
Use `trigger_set_enabled` for a reversible pause/resume and `trigger_delete` to remove a retired trigger. Capture can exist before publication; publication controls the live executable definition. Replaying an event can perform real external actions, so use the existing authorization and intended test scope. A recorded event is not proof the flow executed.
|
|
20
21
|
|
|
21
|
-
##
|
|
22
|
+
## Diagnose by stage
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
If there is no event, inspect trigger identity, connection, registration and the source action. If the event exists but inputs are wrong, inspect selected sample and mappings. If the flow starts but fails, follow the execution ID with `controllerai-runs`. Inspect enabled state and published configuration when development works but live does not.
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
- `user-answer`: user chose after clarification
|
|
27
|
-
- `inferred-from-existing-workflow`: preserving an existing source
|
|
26
|
+
Schedules need an explicit timezone and intended cadence. Follow the user's cadence; do not infer a production schedule from a test sample. Avoid duplicate triggers while debugging: keep the original trigger and event IDs.
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
## Discover the exact event
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
cai trigger search "<event intent>" --json
|
|
35
|
-
cai trigger search --node <nodeSlug> --events-per-node 50 --json
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Copy the exact `nodeSlug` and `eventKey`. Never infer an event key from its display name.
|
|
39
|
-
|
|
40
|
-
If authentication is required:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
cai connection list --node <nodeSlug> --json
|
|
44
|
-
cai connection connect <nodeSlug>
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
MCP: call `connection_connect_url`; it returns the URL immediately and has no `open` or `wait` parameter.
|
|
48
|
-
|
|
49
|
-
## Resolve trigger props
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
cai trigger props \
|
|
53
|
-
--node <nodeSlug> \
|
|
54
|
-
--event <eventKey> \
|
|
55
|
-
--connection <connectionId> \
|
|
56
|
-
--json
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Use the returned shape-correct `propsExample` as a starting point. Hidden props remain unset. `readyForCreate` must be true before using it in `trigger create`; the response intentionally omits unresolved required option props rather than emitting a plausible placeholder.
|
|
60
|
-
|
|
61
|
-
For each name in `unresolvedOptionProps`, run the complete canonical option command returned by the transport, or equivalently:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
cai trigger options \
|
|
65
|
-
--node <nodeSlug> \
|
|
66
|
-
--event <eventKey> \
|
|
67
|
-
--prop <propName> \
|
|
68
|
-
--connection <connectionId> \
|
|
69
|
-
--configured '<configuredPropsJson>' \
|
|
70
|
-
--dynamic-props-id <dynamicPropsId> \
|
|
71
|
-
--query "<human option label>" \
|
|
72
|
-
--json
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Copy the exact returned `value`, not its display `label`, into `--configured`, then rerun `trigger props`. Use `--page` and returned `context` via `--prev-context` only when search is unavailable.
|
|
76
|
-
|
|
77
|
-
When a selector has `reloadProps`, rerun with its configured values and returned `dynamicPropsId` before creating the trigger.
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
cai trigger props \
|
|
81
|
-
--node <nodeSlug> \
|
|
82
|
-
--event <eventKey> \
|
|
83
|
-
--connection <connectionId> \
|
|
84
|
-
--configured '<configuredPropsJson>' \
|
|
85
|
-
--dynamic-props-id <dynamicPropsId> \
|
|
86
|
-
--json
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Keep the same node, event, connection, and configured values on every reload, but always pass the LATEST `dynamicPropsId` the backend returned — a reload can mint a new ID, and reusing a stale one resolves against a stale schema. The response provides the complete canonical command; do not shorten it to only `--configured`.
|
|
90
|
-
|
|
91
|
-
Timer values are objects:
|
|
92
|
-
|
|
93
|
-
```json
|
|
94
|
-
{"cron":{"cron":"0 9 * * *","timezone":"America/Chicago"}}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
or
|
|
98
|
-
|
|
99
|
-
```json
|
|
100
|
-
{"cron":{"intervalSeconds":900}}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Do not pass a bare cron string or assume a timezone. Ask when the user says "at 9am" without one.
|
|
104
|
-
|
|
105
|
-
## Create and map
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
cai trigger create \
|
|
109
|
-
--flow <targetFlowId> \
|
|
110
|
-
--node <nodeSlug> \
|
|
111
|
-
--event <eventKey> \
|
|
112
|
-
--source-basis <basis> \
|
|
113
|
-
--connection <connectionId> \
|
|
114
|
-
--props '<json>' \
|
|
115
|
-
--dynamic-props-id <id> \
|
|
116
|
-
--json
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Capture all returned IDs. `triggerId` is the canvas ID used for get/rename/set-enabled/delete/test-events. `backendTriggerId` is numeric and used for captured events and replay. They are not interchangeable.
|
|
120
|
-
|
|
121
|
-
When repairing an existing trigger, preserve its canvas ID and source. Repair its mapping in place; do not delete and recreate it merely to clear readiness. Replacement changes captured IDs and may change a webhook URL. Replace only when the requested source itself must change, then recapture every returned ID.
|
|
122
|
-
|
|
123
|
-
Read a single trigger back with `cai trigger get <triggerId> --json` — the full record: node, event, connection, props, lifecycle. Read-back is always `get`; the CLI has no `describe` read command anywhere (`cai workflow set-description` is a setter).
|
|
124
|
-
|
|
125
|
-
Follow returned `nextSteps` in order. Trigger payload does not automatically populate the target flow; define flow inputs, relink the run-subflow node if needed, and configure its mapping props.
|
|
126
|
-
|
|
127
|
-
## Remove or disable an automatic start
|
|
128
|
-
|
|
129
|
-
`cai trigger delete <triggerId>` removes the automatic start from the development canvas; use it when the start should no longer exist. Never delete its owning flow merely to remove the trigger. `cai trigger set-enabled <triggerId> --enable|--disable` changes the enabled state reversibly and idempotently; pass exactly one state flag.
|
|
130
|
-
|
|
131
|
-
MCP: call `trigger_set_enabled` with `enabled: true` or `enabled: false`.
|
|
132
|
-
|
|
133
|
-
Both are development edits. Publish only for an authorized Live change; otherwise the prior Live trigger remains active.
|
|
134
|
-
|
|
135
|
-
## Establish a typed sample
|
|
136
|
-
|
|
137
|
-
After sending a representative event to the source:
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
cai trigger events --trigger <backendTriggerId> --json
|
|
141
|
-
cai trigger event <eventId> --json
|
|
142
|
-
cai trigger select-event --node <triggerNodeId> --event <eventId> --json
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Then re-read expression context on downstream nodes. A sample without a platform data type may remain untyped.
|
|
146
|
-
|
|
147
|
-
## Finish trigger setup: disarm test events
|
|
148
|
-
|
|
149
|
-
Armed test events let real events reach the DEV version while you set the trigger up. They exist for one purpose: capturing the real data shape so it becomes the trigger node's output type. Arming is the START of trigger setup; **disarming is how trigger setup ENDS.** Once the shape is captured, selected, and typed, turn it off — also when a build fails or is abandoned midway:
|
|
150
|
-
|
|
151
|
-
```bash
|
|
152
|
-
cai trigger test-events --id <triggerId> --disallow
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
MCP: call `trigger_test_events_set` with `allowed: false`, or `allowed: true` to arm it.
|
|
156
|
-
|
|
157
|
-
Do not mix the flag families. `set-enabled` takes `--enable` or `--disable`; `test-events` takes `--allow` or `--disallow`; replay takes `--target dev` or `--target live`, with `--confirm-live` for Live.
|
|
158
|
-
|
|
159
|
-
The acknowledgements are distinct: `--acknowledge-dual-run` applies only while arming, `--acknowledge-dual-dispatch` only while publishing an armed trigger, and `--confirm-live` only to one Live replay.
|
|
160
|
-
|
|
161
|
-
Arming is sticky and independent from enablement. Armed plus live dispatch runs each real event twice; a schedule does so every interval. Disabling does not clear the allow flag, so always disallow after capture.
|
|
162
|
-
|
|
163
|
-
Keeping both rails armed is an uncommon user decision, never a default.
|
|
164
|
-
|
|
165
|
-
## Verify development, then publish
|
|
166
|
-
|
|
167
|
-
Use `cai run flow` for direct development verification, then replay one captured event through the development trigger path. MCP `run_flow` calls take `waitSeconds`.
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
cai trigger replay --trigger <backendTriggerId> --event <eventId> --target dev --json
|
|
171
|
-
cai exec tree <workflowExecutionId> --json
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
A development replay never dispatches live, but nodes still call real providers and can create side effects or spend usage. Publish only after mappings and development behavior pass.
|
|
175
|
-
|
|
176
|
-
A draft-only request stops after development proof. Do not publish merely because the trigger is ready.
|
|
177
|
-
|
|
178
|
-
Before publishing, audit EVERY trigger in the workflow — not just the one you worked on. Users forget triggers left enabled or armed in other flows. Read each row's lifecycle fields from `cai trigger list --json` (`devCanvasEnabled`, `deployment.liveCanvasEnabled`, `deployment.inLiveVersion`, `deployment.devDispatchArmed`, `deployment.dualDispatchLive`) and confirm with the user which triggers should be starting this workflow live:
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
cai trigger list --json
|
|
182
|
-
cai workflow publish --name "<release>" --json
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
If publish fails because a trigger still has test events armed, that error is the designed backstop, not a malfunction: trigger setup was never finished. The normal resolution is to disarm and republish. Publishing WITH an armed trigger requires the user's explicit, informed choice — explain the double-run and double-billing consequence first, then pass the intent flag:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
cai workflow publish --name "<release>" --acknowledge-dual-dispatch --json
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Never pass `--acknowledge-dual-dispatch` on your own initiative.
|
|
192
|
-
|
|
193
|
-
Live replay is optional and requires an explicit acknowledgement:
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
cai trigger replay \
|
|
197
|
-
--trigger <backendTriggerId> \
|
|
198
|
-
--event <eventId> \
|
|
199
|
-
--target live \
|
|
200
|
-
--confirm-live \
|
|
201
|
-
--json
|
|
202
|
-
cai exec tree <workflowExecutionId> --json
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
It executes the published workflow, calls live third-party actions, and spends usage. Obtain appropriate user intent before replaying a side-effectful event.
|
|
206
|
-
|
|
207
|
-
Read [references/lifecycle.md](references/lifecycle.md) for trigger state and debugging.
|
|
208
|
-
|
|
209
|
-
## Before you finish
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
cai trigger get <triggerId> --json
|
|
213
|
-
cai trigger list --json
|
|
214
|
-
cai workflow status --json
|
|
215
|
-
# Only after an authorized create or mapping test:
|
|
216
|
-
cai exec tree <workflowExecutionId> --json
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
- Read-back must retain the intended trigger, source, target flow, connection, props, and mapping.
|
|
220
|
-
- `devCanvasEnabled`, `liveCanvasEnabled`, and `inLiveVersion` must match the requested rail state.
|
|
221
|
-
- `devDispatchArmed` must be false unless the user explicitly chose dual dispatch; report `dualDispatchLive`.
|
|
222
|
-
- For authorized create/mapping work, the development test must produce the expected tree. Never replay for delete/disable-only work. Live replay needs separate authorization.
|
|
28
|
+
Commands: [reference](references/command-reference.md). Capture, replay and lifecycle details: [lifecycle](references/lifecycle.md).
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Controller AI triggers
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
A trigger targets exactly one flow. Its source may capture events before publish, but ordinary event execution uses the live workflow. Creating the source is therefore separate from mapping, development testing, publishing, and live replay.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
- Preserve trigger ID and source during repair; see Create and map.
|
|
8
|
+
- Delete a retired start; disable a reversible pause. See Remove or disable an automatic start.
|
|
9
|
+
- Lifecycle uses `--enable|--disable`; test events use `--allow|--disallow`. See Remove or disable an automatic start and Finish trigger setup.
|
|
10
|
+
- Disarm capture when setup ends; see Finish trigger setup.
|
|
11
|
+
- Lifecycle edits are development-only; publish only for Live. See Verify development, then publish.
|
|
12
|
+
- Replay with `--target dev`; Live also requires `--confirm-live`. See Verify development, then publish.
|
|
13
|
+
|
|
14
|
+
## Require a real source decision
|
|
15
|
+
|
|
16
|
+
Determine how the trigger choice was established:
|
|
17
|
+
|
|
18
|
+
- `explicit-in-request`: user named it in the request
|
|
19
|
+
- `user-answer`: user chose after clarification
|
|
20
|
+
- `inferred-from-existing-workflow`: preserving an existing source
|
|
21
|
+
|
|
22
|
+
Do not use `assumption`; the backend rejects it. If the request does not determine when the automation runs, ask one focused question before creating a source.
|
|
23
|
+
|
|
24
|
+
## Discover the exact event
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cai trigger search "<event intent>" --json
|
|
28
|
+
cai trigger search --node <nodeSlug> --events-per-node 50 --json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Copy the exact `nodeSlug` and `eventKey`. Never infer an event key from its display name.
|
|
32
|
+
|
|
33
|
+
If authentication is required:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cai connection list --node <nodeSlug> --json
|
|
37
|
+
cai connection connect <nodeSlug>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
MCP: call `connection_connect_url`; it returns the URL immediately and has no `open` or `wait` parameter.
|
|
41
|
+
|
|
42
|
+
## Resolve trigger props
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cai trigger props \
|
|
46
|
+
--node <nodeSlug> \
|
|
47
|
+
--event <eventKey> \
|
|
48
|
+
--connection <connectionId> \
|
|
49
|
+
--json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Use the returned shape-correct `propsExample` as a starting point. Hidden props remain unset. `readyForCreate` must be true before using it in `trigger create`; the response intentionally omits unresolved required option props rather than emitting a plausible placeholder.
|
|
53
|
+
|
|
54
|
+
For each name in `unresolvedOptionProps`, run the complete canonical option command returned by the transport, or equivalently:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cai trigger options \
|
|
58
|
+
--node <nodeSlug> \
|
|
59
|
+
--event <eventKey> \
|
|
60
|
+
--prop <propName> \
|
|
61
|
+
--connection <connectionId> \
|
|
62
|
+
--configured '<configuredPropsJson>' \
|
|
63
|
+
--dynamic-props-id <dynamicPropsId> \
|
|
64
|
+
--query "<human option label>" \
|
|
65
|
+
--json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Copy the exact returned `value`, not its display `label`, into `--configured`, then rerun `trigger props`. Use `--page` and returned `context` via `--prev-context` only when search is unavailable.
|
|
69
|
+
|
|
70
|
+
When a selector has `reloadProps`, rerun with its configured values and returned `dynamicPropsId` before creating the trigger.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cai trigger props \
|
|
74
|
+
--node <nodeSlug> \
|
|
75
|
+
--event <eventKey> \
|
|
76
|
+
--connection <connectionId> \
|
|
77
|
+
--configured '<configuredPropsJson>' \
|
|
78
|
+
--dynamic-props-id <dynamicPropsId> \
|
|
79
|
+
--json
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Keep the same node, event, connection, and configured values on every reload, but always pass the LATEST `dynamicPropsId` the backend returned — a reload can mint a new ID, and reusing a stale one resolves against a stale schema. The response provides the complete canonical command; do not shorten it to only `--configured`.
|
|
83
|
+
|
|
84
|
+
Timer values are objects:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{"cron":{"cron":"0 9 * * *","timezone":"America/Chicago"}}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
or
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{"cron":{"intervalSeconds":900}}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Do not pass a bare cron string or assume a timezone. Ask when the user says "at 9am" without one.
|
|
97
|
+
|
|
98
|
+
## Create and map
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
cai trigger create \
|
|
102
|
+
--flow <targetFlowId> \
|
|
103
|
+
--node <nodeSlug> \
|
|
104
|
+
--event <eventKey> \
|
|
105
|
+
--source-basis <basis> \
|
|
106
|
+
--connection <connectionId> \
|
|
107
|
+
--props '<json>' \
|
|
108
|
+
--dynamic-props-id <id> \
|
|
109
|
+
--json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Capture all returned IDs. `triggerId` is the canvas ID used for get/rename/set-enabled/delete/test-events. `backendTriggerId` is numeric and used for captured events and replay. They are not interchangeable.
|
|
113
|
+
|
|
114
|
+
When repairing an existing trigger, preserve its canvas ID and source. Repair its mapping in place; do not delete and recreate it merely to clear readiness. Replacement changes captured IDs and may change a webhook URL. Replace only when the requested source itself must change, then recapture every returned ID.
|
|
115
|
+
|
|
116
|
+
Read a single trigger back with `cai trigger get <triggerId> --json` — the full record: node, event, connection, props, lifecycle. Read-back is always `get`; the CLI has no `describe` read command anywhere (`cai workflow set-description` is a setter).
|
|
117
|
+
|
|
118
|
+
Follow returned `nextSteps` in order. Trigger payload does not automatically populate the target flow; define flow inputs, relink the run-subflow node if needed, and configure its mapping props.
|
|
119
|
+
|
|
120
|
+
## Remove or disable an automatic start
|
|
121
|
+
|
|
122
|
+
`cai trigger delete <triggerId>` removes the automatic start from the development canvas; use it when the start should no longer exist. Never delete its owning flow merely to remove the trigger. `cai trigger set-enabled <triggerId> --enable|--disable` changes the enabled state reversibly and idempotently; pass exactly one state flag.
|
|
123
|
+
|
|
124
|
+
MCP: call `trigger_set_enabled` with `enabled: true` or `enabled: false`.
|
|
125
|
+
|
|
126
|
+
Both are development edits. Publish only for an authorized Live change; otherwise the prior Live trigger remains active.
|
|
127
|
+
|
|
128
|
+
## Establish a typed sample
|
|
129
|
+
|
|
130
|
+
After sending a representative event to the source:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
cai trigger events --trigger <backendTriggerId> --json
|
|
134
|
+
cai trigger event <eventId> --json
|
|
135
|
+
cai trigger select-event --node <triggerNodeId> --event <eventId> --json
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Then re-read expression context on downstream nodes. A sample without a platform data type may remain untyped.
|
|
139
|
+
|
|
140
|
+
## Finish trigger setup: disarm test events
|
|
141
|
+
|
|
142
|
+
Armed test events let real events reach the DEV version while you set the trigger up. They exist for one purpose: capturing the real data shape so it becomes the trigger node's output type. Arming is the START of trigger setup; **disarming is how trigger setup ENDS.** Once the shape is captured, selected, and typed, turn it off — also when a build fails or is abandoned midway:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
cai trigger test-events --id <triggerId> --disallow
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
MCP: call `trigger_test_events_set` with `allowed: false`, or `allowed: true` to arm it.
|
|
149
|
+
|
|
150
|
+
Do not mix the flag families. `set-enabled` takes `--enable` or `--disable`; `test-events` takes `--allow` or `--disallow`; replay takes `--target dev` or `--target live`, with `--confirm-live` for Live.
|
|
151
|
+
|
|
152
|
+
The acknowledgements are distinct: `--acknowledge-dual-run` applies only while arming, `--acknowledge-dual-dispatch` only while publishing an armed trigger, and `--confirm-live` only to one Live replay.
|
|
153
|
+
|
|
154
|
+
Arming is sticky and independent from enablement. Armed plus live dispatch runs each real event twice; a schedule does so every interval. Disabling does not clear the allow flag, so always disallow after capture.
|
|
155
|
+
|
|
156
|
+
Keeping both rails armed is an uncommon user decision, never a default.
|
|
157
|
+
|
|
158
|
+
## Verify development, then publish
|
|
159
|
+
|
|
160
|
+
Use `cai run flow` for direct development verification, then replay one captured event through the development trigger path. MCP `run_flow` calls take `waitSeconds`.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cai trigger replay --trigger <backendTriggerId> --event <eventId> --target dev --json
|
|
164
|
+
cai exec tree <workflowExecutionId> --json
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
A development replay never dispatches live, but nodes still call real providers and can create side effects or spend usage. Publish only after mappings and development behavior pass.
|
|
168
|
+
|
|
169
|
+
A draft-only request stops after development proof. Do not publish merely because the trigger is ready.
|
|
170
|
+
|
|
171
|
+
Before publishing, audit EVERY trigger in the workflow — not just the one you worked on. Users forget triggers left enabled or armed in other flows. Read each row's lifecycle fields from `cai trigger list --json` (`devCanvasEnabled`, `deployment.liveCanvasEnabled`, `deployment.inLiveVersion`, `deployment.devDispatchArmed`, `deployment.dualDispatchLive`) and confirm with the user which triggers should be starting this workflow live:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
cai trigger list --json
|
|
175
|
+
cai workflow publish --name "<release>" --json
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
If publish fails because a trigger still has test events armed, that error is the designed backstop, not a malfunction: trigger setup was never finished. The normal resolution is to disarm and republish. Publishing WITH an armed trigger requires the user's explicit, informed choice — explain the double-run and double-billing consequence first, then pass the intent flag:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
cai workflow publish --name "<release>" --acknowledge-dual-dispatch --json
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Never pass `--acknowledge-dual-dispatch` on your own initiative.
|
|
185
|
+
|
|
186
|
+
Live replay is optional and requires an explicit acknowledgement:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
cai trigger replay \
|
|
190
|
+
--trigger <backendTriggerId> \
|
|
191
|
+
--event <eventId> \
|
|
192
|
+
--target live \
|
|
193
|
+
--confirm-live \
|
|
194
|
+
--json
|
|
195
|
+
cai exec tree <workflowExecutionId> --json
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
It executes the published workflow, calls live third-party actions, and spends usage. Obtain appropriate user intent before replaying a side-effectful event.
|
|
199
|
+
|
|
200
|
+
Read [lifecycle.md](lifecycle.md) for trigger state and debugging.
|
|
201
|
+
|
|
202
|
+
## Before you finish
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
cai trigger get <triggerId> --json
|
|
206
|
+
cai trigger list --json
|
|
207
|
+
cai workflow status --json
|
|
208
|
+
# Only after an authorized create or mapping test:
|
|
209
|
+
cai exec tree <workflowExecutionId> --json
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
- Read-back must retain the intended trigger, source, target flow, connection, props, and mapping.
|
|
213
|
+
- `devCanvasEnabled`, `liveCanvasEnabled`, and `inLiveVersion` must match the requested rail state.
|
|
214
|
+
- `devDispatchArmed` must be false unless the user explicitly chose dual dispatch; report `dualDispatchLive`.
|
|
215
|
+
- For authorized create/mapping work, the development test must produce the expected tree. Never replay for delete/disable-only work. Live replay needs separate authorization.
|
|
@@ -1,126 +1,46 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: controllerai-workflows
|
|
3
|
-
description: Build, inspect,
|
|
3
|
+
description: Build, inspect, repair, test and publish Controller AI workflows: typed callable flows, deterministic actions, branching, durable workflow data and triggers. Use for automations or an agent-callable application backend.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Controller AI workflows
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
A workflow groups **flows**, **custom schemas**, **data collections** and **triggers**. A flow is one callable function with typed inputs and outputs; its connected nodes implement the function. Several flows can share the workflow's data store and call one another.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Flows are useful as API-like tools for agents. For example one “Investor CRM” workflow can expose create/get/update/delete/search flows for contacts, companies, deals and activities, plus a contact history view. An agent chooses a tool; the flow enforces its contract and performs the work.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
- Repair the selected workflow and flow instead of creating replacements; see Build protocol.
|
|
14
|
-
- Keep workflow, flow, node, input, and output IDs distinct; see Lifecycle rules.
|
|
15
|
-
- Preserve contract fields in place and refresh their dependents; see Lifecycle rules.
|
|
16
|
-
- Use save, history, and restore for recovery instead of rebuilding; see Lifecycle rules.
|
|
17
|
-
- Treat validation counts as status; prove the requested rail and stop. See Lifecycle rules and Before you finish.
|
|
12
|
+
## Start with the contract
|
|
18
13
|
|
|
19
|
-
|
|
14
|
+
Define each flow's inputs, outputs and failure behavior. Keep one operation per agent tool when that makes selection clearer than a giant operation dispatcher. Choose useful names and descriptions: “Search contacts by name, owner, tags and status” tells an agent when to call it.
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
cai auth status --json
|
|
23
|
-
cai workflow list --json
|
|
24
|
-
cai use <workflowId>
|
|
25
|
-
cai workflow status --json
|
|
26
|
-
```
|
|
16
|
+
Create the workflow, then explicitly create the first flow. `workflow_outline` provides a compact inventory; `flow_get` provides a flow's contracts, graph and configured values. Workflow IDs, flow IDs and node IDs are different identities.
|
|
27
17
|
|
|
28
|
-
|
|
18
|
+
Before changing an existing workflow, read its outline and the affected flow. Repair the existing IDs instead of creating replacements. For a substantial rewrite, save a named checkpoint. Restore rolls back the definition, not record changes or external effects.
|
|
29
19
|
|
|
30
|
-
|
|
20
|
+
## Assemble and test
|
|
31
21
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
1. Create any custom schemas and flow inputs/outputs first.
|
|
23
|
+
2. Discover actions and add nodes in execution order. Configure the type or action selector before dependent props; reload props if the selector changes.
|
|
24
|
+
3. Bind expressions using current `expr_context` names. Wire the source output to the destination so it appears in `inputs`.
|
|
25
|
+
4. Use a Return node to map promised flow outputs. Merely declaring an output does not populate it.
|
|
26
|
+
5. Test a complete development path with explicit representative input. Check the returned contract and same-environment data changes.
|
|
27
|
+
6. Apply the proven pattern to additional paths. Batch independent configuration when the available tool supports it; do not combine operations whose IDs depend on earlier responses.
|
|
28
|
+
7. Layout each changed flow, validate the saved workflow, and re-read its outline.
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
Use `controllerai-node-config` for action configuration, `controllerai-expressions` for computed values, `controllerai-flow-control` for routing/loops, `controllerai-data` for storage and `controllerai-runs` for execution evidence.
|
|
37
31
|
|
|
38
|
-
|
|
32
|
+
## Files and agents
|
|
39
33
|
|
|
40
|
-
|
|
34
|
+
A chat attachment is handled by a user-facing agent. For CSV enrichment, make a per-row flow accepting `investorName` and optional `company`, returning normalized contact information and evidence. The agent reads and writes the CSV. The native Create File action can generate files; it does not imply a native CSV reader/upload trigger.
|
|
41
35
|
|
|
42
|
-
|
|
36
|
+
For an agent tool, attach the tested flow with `agent_tool_workflow_add`. Its flow inputs and outputs are the tool contract. For unattended operation, add a trigger and map its event into these same inputs.
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
cai workflow outline --json
|
|
46
|
-
```
|
|
38
|
+
## Release and recovery
|
|
47
39
|
|
|
48
|
-
|
|
40
|
+
Graph edits affect development. Publishing creates the workflow's live release; attached live agents follow its latest release without another agent publish. The development/live record stores remain separate.
|
|
49
41
|
|
|
50
|
-
|
|
42
|
+
Use the user's existing authorization when deciding whether to publish. If publication is authorized, fix validation errors, publish, then verify Live. For a draft-only request, deliver the tested draft and its link.
|
|
51
43
|
|
|
52
|
-
|
|
53
|
-
2. Inspect the current workflow before editing: `cai workflow outline`, then `cai flow get <flowId>`. Repair those IDs; do not create replacements for a repair.
|
|
54
|
-
3. Create or select a flow. Define flow inputs and outputs before nodes that derive props from them.
|
|
55
|
-
4. Build in execution order. After each material change, read it back with the corresponding `get`, `props`, `status`, or `list` command.
|
|
56
|
-
5. Run `cai flow layout <flowId>` once per changed flow as the LAST step after a headless build or any batch of structural edits (adds, deletes, rewires) — add-time placement avoids overlap, but only layout produces clean left-to-right columns. An open builder adopts your layout automatically.
|
|
57
|
-
6. Test on the development rail. Debug every failed or suspicious node; a green top-level status alone is insufficient.
|
|
58
|
-
7. Re-read `cai workflow status`. Publish only when the user asked for a live change or clearly authorized deployment.
|
|
44
|
+
On a state conflict, re-read the current saved version and reapply the intended change. Do not overwrite a newer graph with an old document. Report validation issues by their practical effect and inspect empty results where data was expected.
|
|
59
45
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
## Route specialized work
|
|
63
|
-
|
|
64
|
-
Load the narrow skill when the task reaches that surface:
|
|
65
|
-
|
|
66
|
-
- Node discovery, initialization, connections, props, or wiring: `controllerai-node-config`
|
|
67
|
-
- Dynamic values or conditions: `controllerai-expressions`
|
|
68
|
-
- Router, If/Else, loops, joins, or subflows: `controllerai-flow-control`
|
|
69
|
-
- Test execution or debugging: `controllerai-runs`
|
|
70
|
-
- Scheduled, webhook, or integration events: `controllerai-triggers`
|
|
71
|
-
- Schemas or records: `controllerai-data`
|
|
72
|
-
- Ask AI or Agent nodes: `controllerai-ai-nodes`
|
|
73
|
-
- User-facing agents and their workflow tools: `controllerai-agents`
|
|
74
|
-
|
|
75
|
-
## Lifecycle rules
|
|
76
|
-
|
|
77
|
-
- All graph edits target development. Live remains unchanged until `cai workflow publish`.
|
|
78
|
-
- Email verification is not a publishing prerequisite. An unclaimed agent-created account may publish; email claiming only raises its monthly usage cap and enables account recovery.
|
|
79
|
-
- On the CLI, prefer `--json` for decisions and IDs; human tables are for presentation. MCP tools return typed JSON. If human output looks odd, re-run the same read with `--json` before acting.
|
|
80
|
-
- A workflow contains flows; a flow is one canvas. Do not confuse their IDs.
|
|
81
|
-
- For flow inputs, pass a human `--display` label and use the current binding from `flow get` (`jsBinding`) or `workflow outline` (`binding`). Rename an existing contract input or output in place; do not delete and recreate it. After any rename or deletion, re-read the flow and repair every expression and subflow mapping before validation or execution. `legacyBinding` is diagnostic-only.
|
|
82
|
-
- Name nodes after the data they produce. Downstream input bindings are seeded from that name when wired.
|
|
83
|
-
- Use `cai workflow save --name "<checkpoint>"` before a risky rewrite. Named saves and state renames work on every plan.
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
cai workflow history --json
|
|
87
|
-
cai workflow history --group <groupId> --json
|
|
88
|
-
cai workflow restore --state <stateId> --json
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
- **Use version history for recovery.** Each save is a state. History retention is unlimited on Free, Max, and custom plans and 90 days on Pro/Starter; restore eligibility is 7 days on Free, 90 on Pro/Starter, and unlimited on Max/custom. Expand groups to capture state IDs. Restore rolls back the definition only; records and external effects remain.
|
|
92
|
-
- **Validate after structural edits and before publish.** Fix every listed prop, wire, expression, type, subflow, branch, and trigger error. Publish refuses errors; use `--acknowledge-validation-errors` only after explicit approval of the listed issues. Flow deletion also removes its contract, graph, and triggers and breaks callers; validation shows each break.
|
|
93
|
-
- Treat validation warning and error counts as status only. Never write them or their messages into unrelated workflow properties.
|
|
94
|
-
- On a conflict, re-read current state and reapply intent. Do not replay stale IDs or whole documents.
|
|
95
|
-
- Never delete a workflow without the user's explicit intent; the CLI requires `--yes` but that is not a substitute for authorization. MCP: `workflow_delete` has no `yes` parameter, but still requires the same explicit intent. `cai workflow delete` tears down deployed triggers and soft-deletes the workflow row. Historical workflow/version data remains stored, but there is currently no restore command for the deleted row.
|
|
96
|
-
- **Check dependencies before shared-resource changes.** `cai deps` shows attached agents, workflow callers, and connections; `cai deps --account` maps the account. Deleting a workflow with agent dependents is refused server-side, and `--force` is a deprecated, inert compatibility flag. Detach draft tools with `cai agent remove-tool <agentId> --tool <toolId>`. If still LIVE, use `cai agent publish <agentId>` after explicit approval. A dependent agent publish or delete is its own live/destructive decision. Then retry deletion.
|
|
97
|
-
- **Use the account feed only for recorded history.** Filter `cai events` by type, time, workflow, and cursor. It omits deletions, settings, member removals, and labels. For an unrecorded past change, say it is not recorded and change nothing; names and current state are not proof.
|
|
98
|
-
- **Share real product links.** Relevant publish, development run, agent, connection, workflow get/status, and agent get outputs include `appUrl` when known. Share returned links; never guess one. MCP `connection_connect_url` returns its link immediately.
|
|
99
|
-
- Never silently weaken the request to make a test pass. Report an unsupported capability or ask about a real product decision.
|
|
100
|
-
|
|
101
|
-
## Before you finish
|
|
102
|
-
|
|
103
|
-
Before claiming success, verify all of the following:
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
cai workflow outline --json
|
|
107
|
-
cai workflow validate --json
|
|
108
|
-
cai workflow status --json
|
|
109
|
-
cai flow get <flowId> --json
|
|
110
|
-
cai run flow <flowId> --inputs <values.json> --json
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
MCP: pass the parsed values in `inputs` and set `waitSeconds` on `run_flow`.
|
|
114
|
-
|
|
115
|
-
Then confirm:
|
|
116
|
-
|
|
117
|
-
- **`cai workflow validate` reports `errors: 0`.** Every error is fixed, or explicitly reported to the user with what it breaks — never summarized away, never called cosmetic. A red canvas and a "done" claim cannot coexist.
|
|
118
|
-
- Required node connections and props are complete.
|
|
119
|
-
- Expressions compiled and their resolved configs are non-null.
|
|
120
|
-
- Expected branch or error paths were exercised where practical.
|
|
121
|
-
- Flow outputs contain the promised values.
|
|
122
|
-
- The reported live/dev state matches what the user asked for.
|
|
123
|
-
- Final outline inventory matches the request. Remove only scratch schemas, flows, nodes, and triggers created during abandoned attempts.
|
|
124
|
-
- After fixing requested blockers and testing each changed path once, stop. Do not redesign for non-blocking warnings.
|
|
125
|
-
|
|
126
|
-
State what was built, what was tested, whether it was published, and any user-owned connection or product choice still pending.
|
|
46
|
+
Detailed CLI/MCP sequences and lifecycle operations: [command reference](references/command-reference.md). Multi-domain command lookup: [command map](references/command-map.md).
|