@controllerai/cli 0.2.18 → 0.2.21

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.
Files changed (45) hide show
  1. package/package.json +6 -4
  2. package/skills/controllerai-agents/SKILL.md +66 -152
  3. package/skills/controllerai-agents/references/instructions-and-versioning.md +32 -34
  4. package/skills/controllerai-ai-nodes/SKILL.md +57 -65
  5. package/skills/controllerai-ai-nodes/references/selection-and-testing.md +44 -26
  6. package/skills/controllerai-data/SKILL.md +65 -118
  7. package/skills/controllerai-data/references/data-rails.md +24 -26
  8. package/skills/controllerai-expressions/SKILL.md +48 -117
  9. package/skills/controllerai-expressions/references/dsl-and-recipes.md +42 -40
  10. package/skills/controllerai-flow-control/SKILL.md +66 -122
  11. package/skills/controllerai-flow-control/references/patterns.md +23 -60
  12. package/skills/controllerai-integration-actions/SKILL.md +47 -75
  13. package/skills/controllerai-node-config/SKILL.md +60 -130
  14. package/skills/controllerai-node-config/references/prop-and-readiness.md +28 -78
  15. package/skills/controllerai-runs/SKILL.md +50 -85
  16. package/skills/controllerai-runs/references/debugging.md +24 -22
  17. package/skills/controllerai-start/SKILL.md +53 -58
  18. package/skills/controllerai-start/references/mcp-tool-map.md +21 -16
  19. package/skills/controllerai-triggers/SKILL.md +62 -159
  20. package/skills/controllerai-triggers/references/lifecycle.md +36 -48
  21. package/skills/controllerai-workflows/SKILL.md +70 -70
  22. package/skills/controllerai-workflows/references/command-map.md +19 -44
  23. package/skills/manifest.json +80 -77
  24. package/skills-mcp/controllerai-agents/SKILL.md +121 -0
  25. package/skills-mcp/controllerai-agents/references/instructions-and-versioning.md +76 -0
  26. package/skills-mcp/controllerai-ai-nodes/SKILL.md +92 -0
  27. package/skills-mcp/controllerai-ai-nodes/references/selection-and-testing.md +66 -0
  28. package/skills-mcp/controllerai-data/SKILL.md +119 -0
  29. package/skills-mcp/controllerai-data/references/data-rails.md +45 -0
  30. package/skills-mcp/controllerai-expressions/SKILL.md +98 -0
  31. package/skills-mcp/controllerai-expressions/references/dsl-and-recipes.md +136 -0
  32. package/skills-mcp/controllerai-flow-control/SKILL.md +114 -0
  33. package/skills-mcp/controllerai-flow-control/references/patterns.md +83 -0
  34. package/skills-mcp/controllerai-integration-actions/SKILL.md +89 -0
  35. package/skills-mcp/controllerai-node-config/SKILL.md +106 -0
  36. package/skills-mcp/controllerai-node-config/references/prop-and-readiness.md +49 -0
  37. package/skills-mcp/controllerai-runs/SKILL.md +88 -0
  38. package/skills-mcp/controllerai-runs/references/debugging.md +53 -0
  39. package/skills-mcp/controllerai-start/SKILL.md +80 -0
  40. package/skills-mcp/controllerai-start/references/mcp-tool-map.md +175 -0
  41. package/skills-mcp/controllerai-triggers/SKILL.md +112 -0
  42. package/skills-mcp/controllerai-triggers/references/lifecycle.md +59 -0
  43. package/skills-mcp/controllerai-workflows/SKILL.md +109 -0
  44. package/skills-mcp/controllerai-workflows/references/command-map.md +1 -0
  45. package/skills-mcp/manifest.json +189 -0
@@ -1,140 +1,68 @@
1
1
  ---
2
2
  name: controllerai-triggers
3
- description: Discover, configure, create, sample, enable, test, and debug Controller AI triggers. Use when working with schedules, webhooks, email or app events, captured sample payloads, trigger-to-flow mappings, replay, or any question about why an automation did or did not start.
3
+ description: Discover, configure, create, capture, map, test, enable and debug Controller AI triggers: schedules, webhooks, email and app events. Use when an automation must start without a chat message, when a captured payload must become typed flow input, when replaying an event, or when asking why an automation did or did not start.
4
4
  ---
5
+ <!-- generated from .claude/skills by cli/scripts/render-skills.mjs; edit the source -->
5
6
 
6
- # Controller AI triggers
7
+ # Triggers
7
8
 
8
- The `cai ...` examples are canonical grammar. Use the transport selected in `controllerai-start` and its MCP tool map; never mix transports in one task.
9
+ ## Use this when
9
10
 
10
- 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.
11
+ - A workflow must start on a schedule, a webhook, an email or an app event.
12
+ - A captured event must become the typed input of a flow, or a trigger's mapping is wrong.
13
+ - A trigger must be paused, resumed, retired or replaced, or a run did not start.
11
14
 
12
- ## Rules that break tasks when skipped
15
+ Flow inputs and mapping expressions belong to `controllerai-expressions`; reading a run belongs to `controllerai-runs`; publishing belongs to `controllerai-workflows`.
13
16
 
14
- - Preserve trigger ID and source during repair; see Create and map.
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.
17
+ ## How it works
20
18
 
21
- ## Require a real source decision
19
+ **One trigger, one flow.** A trigger binds a source (node slug plus exact event key, its connection and props) to exactly one flow, and its payload does not populate that flow by itself: the flow needs declared inputs, and the mapping props live on the trigger canvas's run-subflow node (`runSubflowNodeId`, wired automatically, never connected by hand), one per flow input, synthesized after the inputs exist. Creating the source, capturing and selecting a sample, mapping, testing on development, publishing and verifying live are separate steps.
22
20
 
23
- Determine how the trigger choice was established:
21
+ **Two rails, three switches.** Events are captured from the moment the source exists, and ordinary event execution runs the live release, so a trigger does not run live until the workflow is published; before that it can execute on development only through a replay or armed ambient dispatch. `set-enabled` (enable or disable) is the trigger's definition state and edits development only; the prior live trigger keeps running until an authorized publish. `test-events` (allow or disallow) sets a sticky permission bit for ambient development dispatch: real events then also execute the development canvas. `replay` targets one rail explicitly. The bit survives a disable (`devDispatchArmed` is enabled-and-allowed), and once the workflow is published with the trigger enabled on both rails and routable, every real event can execute on both rails (a schedule every interval), which is why publish refuses an armed trigger unless the user explicitly acknowledges dual dispatch.
24
22
 
25
- - `explicit-in-request`: user named it in the request
26
- - `user-answer`: user chose after clarification
27
- - `inferred-from-existing-workflow`: preserving an existing source
23
+ **Four IDs.** The canvas `triggerId` addresses get, rename, set-enabled, delete and test-events. The numeric `backendTriggerId` addresses captured events and replay. The `triggerNodeId` selects the typed sample. The captured `eventId` addresses event, select-event and replay. Copy them from the responses; they are never interchangeable.
28
24
 
29
- 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.
25
+ **Props are resolved, not guessed.** The props read returns a shape-correct `propsExample`, `readyForCreate`, and `unresolvedOptionProps`; unresolved required option props are omitted rather than filled with a plausible placeholder, and hidden props stay unset (they are provider reload plumbing). Option values are resolved by the options read with the same node, event, connection and configured values. The dynamic schema is identified by the response's `id`, passed back as `dynamicPropsId`; a selector that reloads props can mint a new one, so always pass the latest and keep every earlier configured value on each reload (registry events have no dynamic schema). Timer values are objects, `{"cron":{"cron":"0 9 * * *","timezone":"America/Chicago"}}` or `{"cron":{"intervalSeconds":900}}`, never a bare cron string.
30
26
 
31
- ## Discover the exact event
27
+ **A sample makes the type.** A captured event becomes the trigger node's output type only when it is selected; the mapping props are bound after that, from the re-read expression context, and a payload without a platform data type can stay untyped.
32
28
 
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
- ```
29
+ ## Rules
58
30
 
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.
31
+ 1. **The start condition is the user's decision.** Create a source only with an explicit `--source-basis`: `explicit-in-request`, `user-answer`, or `inferred-from-existing-workflow` when preserving an existing source. The backend rejects an assumption; when the request does not say when the automation runs, ask one focused question first.
32
+ 2. **Copy the exact `nodeSlug` and `eventKey`** from the search result; never derive an event key from its display name, because keys are opaque and display names collide across providers.
33
+ 3. **Ask for the timezone** when the user says "at 9am" without one, and never infer a production cadence from a test sample, whose timing is a test artifact.
34
+ 4. **Repair in place.** Keep the trigger's canvas ID and source when fixing its mapping or readiness; replacing a trigger changes captured IDs and may change a webhook URL, so replace only when the source itself must change, then recapture every ID.
35
+ 5. **Delete a retired start; disable a paused one.** "Stop starting itself", "retire" and "no longer" mean delete: a disabled trigger still exists and can be re-enabled, so it is not retired. Never delete the owning flow to remove a trigger (that destroys the graph and its callers), and pass exactly one state flag.
36
+ 6. **Arm ambient dispatch only on the user's decision, and disarm when setup ends**, including a failed or abandoned setup. Capture needs no arming; arming executes a half-built development flow on real traffic, so explain that before adding the acknowledgement. Keeping both rails armed is an uncommon, explicit user choice, never a default, and routine tests use replay.
37
+ 7. **Never mix the flag families or the acknowledgements.** `--enable|--disable`, `--allow|--disallow`, `--target dev|live`; `--acknowledge-dual-run` only while arming, `--acknowledge-dual-dispatch` only while publishing an armed trigger, `--confirm-live` only for one live replay. Never add an acknowledgement on your own initiative.
38
+ 8. **Audit every trigger before a publish**, not only the one you touched; users forget starts left enabled or armed in other flows.
39
+ 9. **A captured event is not a run.** For create or mapping work, verify received inputs, outputs and effects on a development replay; an event with no execution and an execution with empty inputs are different faults. Read-only diagnosis, a deletion (verified through the list and status) and a user-declined test need no replay.
40
+ 10. **A draft-only request stops at development proof**, and a delete-only or disable-only task needs no replay.
60
41
 
61
- For each name in `unresolvedOptionProps`, run the complete canonical option command returned by the transport, or equivalently:
42
+ ## Recipes
62
43
 
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.
44
+ ### Discover and resolve
78
45
 
79
46
  ```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}}
47
+ cai trigger search "<event intent>" --json
48
+ cai trigger search --node <nodeSlug> --events-per-node 50 --json
49
+ cai trigger props --node <nodeSlug> --event <eventKey> --connection <connectionId> --json
50
+ cai trigger options --node <nodeSlug> --event <eventKey> --prop <propName> --connection <connectionId> --configured '<configuredPropsJson>' --dynamic-props-id <dynamicPropsId> --query "<option label>" --json
51
+ cai trigger props --node <nodeSlug> --event <eventKey> --connection <connectionId> --configured '<configuredPropsJson>' --dynamic-props-id <dynamicPropsId> --json
101
52
  ```
102
53
 
103
- Do not pass a bare cron string or assume a timezone. Ask when the user says "at 9am" without one.
54
+ Omit the connection for a source without auth. Copy the returned option `value`, not its `label`, into the configured props, then re-read the props until `readyForCreate` is true. Use `--page` with the returned context (`--prev-context`) when a search does not find the option. A missing connection is handled as in `controllerai-node-config`: `cai connection list --node <nodeSlug> --json`, then `cai connection connect <nodeSlug> --no-open`.
104
55
 
105
- ## Create and map
56
+ ### Create and map
106
57
 
107
58
  ```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
59
+ cai trigger create --flow <targetFlowId> --node <nodeSlug> --event <eventKey> --source-basis <basis> --connection <connectionId> --props '<json>' --dynamic-props-id <dynamicPropsId> --json
60
+ cai trigger get <triggerId> --json
117
61
  ```
118
62
 
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.
63
+ Capture every returned ID (`triggerId`, `backendTriggerId`, `triggerNodeId`, `runSubflowNodeId`) plus the `webhookUrl` or `emailAddress` when the source has one, and follow `nextSteps` in order: declare the flow inputs, capture and select a sample, then bind one mapping prop per input on the run-subflow node from its re-read expression context. Read-back is `get`; there is no describe command.
120
64
 
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:
65
+ ### Capture and select a sample
138
66
 
139
67
  ```bash
140
68
  cai trigger events --trigger <backendTriggerId> --json
@@ -142,81 +70,56 @@ cai trigger event <eventId> --json
142
70
  cai trigger select-event --node <triggerNodeId> --event <eventId> --json
143
71
  ```
144
72
 
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
73
+ A representative event has to reach the source: through the provider, the returned webhook URL or email address; never invent an endpoint. Inspect the payload before selecting it and re-read the run-subflow node's expression context after selecting.
148
74
 
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:
75
+ ### Arm ambient development dispatch (only on request)
150
76
 
151
77
  ```bash
152
- cai trigger test-events --id <triggerId> --disallow
78
+ cai trigger test-events <triggerId> --allow --acknowledge-dual-run --json
79
+ cai trigger test-events <triggerId> --disallow --json
153
80
  ```
154
81
 
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
82
+ Arming makes every real event also execute the development canvas while it is half built; use it only when the user wants that after hearing it, and disarm at the end of setup.
166
83
 
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`.
84
+ ### Pause, resume, retire
168
85
 
169
86
  ```bash
170
- cai trigger replay --trigger <backendTriggerId> --event <eventId> --target dev --json
171
- cai exec tree <workflowExecutionId> --json
87
+ cai trigger set-enabled <triggerId> --enable --json
88
+ cai trigger set-enabled <triggerId> --disable --json
89
+ cai trigger delete <triggerId> --json
172
90
  ```
173
91
 
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:
92
+ ### Test, audit, publish
179
93
 
180
94
  ```bash
95
+ cai run flow <targetFlowId> --inputs <values.json> --json
96
+ cai trigger replay --trigger <backendTriggerId> --event <eventId> --target dev --json
97
+ cai exec tree <workflowExecutionId> --json
98
+ cai trigger audit --json
181
99
  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
100
  ```
190
101
 
191
- Never pass `--acknowledge-dual-dispatch` on your own initiative.
102
+ Run the target flow directly first, then replay one captured event through the development trigger path; a development replay never dispatches live but still calls real providers and spends usage. `--payload` replays a custom raw payload instead of `--event`. The audit reports coverage, armed development dispatch and double-run risk; the list and get reads show `devCanvasEnabled` at the top level and `deployment.liveCanvasEnabled`, `deployment.inLiveVersion`, `deployment.devDispatchArmed` and `deployment.dualDispatchLive` (live fields are null when no live canvas exists yet: never published, or this trigger added after the last publish). Publish through `controllerai-workflows` only for an authorized live change. A publish refused because a trigger is still armed is the designed backstop: disarm and republish; publishing armed needs the user's informed choice after hearing about double runs and double billing, and only then `cai workflow publish --acknowledge-dual-dispatch --json`.
192
103
 
193
- Live replay is optional and requires an explicit acknowledgement:
104
+ ### Verify live
194
105
 
195
106
  ```bash
196
- cai trigger replay \
197
- --trigger <backendTriggerId> \
198
- --event <eventId> \
199
- --target live \
200
- --confirm-live \
201
- --json
107
+ cai trigger replay --trigger <backendTriggerId> --event <eventId> --target live --confirm-live --json
202
108
  cai exec tree <workflowExecutionId> --json
203
109
  ```
204
110
 
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.
111
+ A live replay executes the published workflow, calls live third-party actions and spends usage; it needs its own authorization and is optional.
208
112
 
209
- ## Before you finish
113
+ ## Verify
210
114
 
211
115
  ```bash
212
116
  cai trigger get <triggerId> --json
213
117
  cai trigger list --json
214
118
  cai workflow status --json
215
- # Only after an authorized create or mapping test:
216
- cai exec tree <workflowExecutionId> --json
217
119
  ```
218
120
 
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.
121
+ The trigger, source, target flow, connection, props and mapping match the request; `devCanvasEnabled` and `deployment.liveCanvasEnabled` / `deployment.inLiveVersion` match the requested rail state; `deployment.devDispatchArmed` is false unless the user chose dual dispatch; for create or mapping work, the development replay's execution tree shows the flow receiving the mapped inputs and producing the expected effect; for a deletion, the list no longer shows the trigger and the status shows what remains live. Read [references/lifecycle.md](references/lifecycle.md) for the state sequence, the ID table and the missing-run diagnosis.
122
+
123
+ ## Report
124
+
125
+ The trigger and its source, the IDs the user needs, whether it is enabled on development and on live, whether ambient dispatch is armed and why, what the development replay proved, and what remains: an unpublished change, a live verification not yet run, or a source decision still open.
@@ -1,71 +1,59 @@
1
+ <!-- generated from .claude/skills by cli/scripts/render-skills.mjs; edit the source -->
1
2
  # Trigger lifecycle
2
3
 
3
4
  ## State sequence
4
5
 
5
6
  ```text
6
- source decision
7
- -> exact node/event discovery
7
+ source decision (basis)
8
+ -> exact node and event
8
9
  -> connection
9
- -> dynamic prop resolution
10
- -> create source + canvas
11
- -> map payload into target flow
12
- -> capture representative event
13
- -> select typed sample
14
- -> test target flow on development
15
- -> replay captured event against development
16
- -> publish workflow
10
+ -> prop and option resolution (latest dynamicPropsId)
11
+ -> create source and canvas trigger (triggerId, backendTriggerId, triggerNodeId, runSubflowNodeId)
12
+ -> declare the flow inputs
13
+ -> capture a representative event, select it
14
+ -> bind one mapping prop per input on the run-subflow node
15
+ -> run the target flow on development
16
+ -> replay the captured event on development
17
+ -> audit every trigger, then authorized publish
17
18
  -> optional live replay
18
19
  ```
19
20
 
20
- Skipping capture/sample selection commonly leaves downstream output untyped. Skipping mapping commonly produces a green trigger execution with empty flow inputs.
21
+ Skipping capture or selection leaves the trigger output untyped. Skipping the mapping produces a green trigger execution with empty flow inputs. Leaving ambient dispatch allowed can produce double runs after publish.
21
22
 
22
23
  ## IDs
23
24
 
24
25
  | ID | Used by |
25
26
  | --- | --- |
26
- | Canvas `triggerId` | `trigger get`, `rename`, `set-enabled`, `delete`, `test-events` |
27
- | Numeric `backendTriggerId` | `trigger events`, `replay` |
28
- | `triggerNodeId` | `trigger select-event` |
29
- | Captured `eventId` | `trigger event`, `select-event`, `replay --event` |
27
+ | Canvas `triggerId` | get, rename, set-enabled, delete, test-events |
28
+ | Numeric `backendTriggerId` | captured events, replay (`--trigger`) |
29
+ | `triggerNodeId` | select-event |
30
+ | `runSubflowNodeId` | the mapping props, one per flow input |
31
+ | Captured `eventId` | event read, select-event, replay |
30
32
 
31
- Always copy these from the transport output.
33
+ Copy them from the responses. A replaced trigger has new IDs and possibly a new webhook URL.
32
34
 
33
- Development replay is the normal pre-publish check:
35
+ ## Switches and acknowledgements
34
36
 
35
- ```bash
36
- cai trigger replay --trigger <backendTriggerId> --event <eventId> --target dev --json
37
- ```
38
-
39
- Use `--target live --confirm-live` only for an intentional post-publish live verification.
40
-
41
- ## Enable/disable
42
-
43
- `cai trigger set-enabled <triggerId> --enable|--disable` sets the requested state idempotently. Pass exactly one state flag.
37
+ | Switch | Flags | Meaning |
38
+ | --- | --- | --- |
39
+ | Definition state | `set-enabled --enable` / `--disable` | Whether the trigger starts its flow; development edit until published |
40
+ | Ambient development dispatch | `test-events --allow --acknowledge-dual-run` / `--disallow` | Real events also execute the development canvas; sticky permission bit, survives disable |
41
+ | Replay rail | `replay --target dev` / `--target live --confirm-live` | Which version one captured event executes |
42
+ | Publish while armed | `workflow publish --acknowledge-dual-dispatch` | User's informed acceptance of double runs and double billing |
44
43
 
45
- MCP: call `trigger_set_enabled` with `enabled: true` or `enabled: false`.
46
-
47
- ## Lifecycle flag families
48
-
49
- ```bash
50
- cai trigger set-enabled <triggerId> --enable|--disable --json
51
- cai trigger test-events <triggerId> --allow [--acknowledge-dual-run] --json
52
- cai trigger test-events <triggerId> --disallow --json
53
- cai trigger replay --trigger <backendTriggerId> --target dev --json
54
- cai trigger replay --trigger <backendTriggerId> --target live --confirm-live --json
55
- cai workflow publish --acknowledge-dual-dispatch --json
56
- ```
44
+ Each acknowledgement belongs to exactly one operation. Arming, publishing armed and live replay are three separate user decisions.
57
45
 
58
- Use enable/disable for the trigger definition, allow/disallow for ambient development capture, and target for replay rail. `--acknowledge-dual-run` applies only while arming. `--acknowledge-dual-dispatch` applies only when publishing an armed trigger. `--confirm-live` applies only to one Live replay. These acknowledgements are not interchangeable.
46
+ ## Lifecycle fields
59
47
 
60
- The allow flag is sticky even when the trigger is disabled. Always disallow after capture or an abandoned setup so later re-enablement cannot silently rearm development dispatch.
48
+ The list and get reads report `devCanvasEnabled` at the top level and, under `deployment`, `liveCanvasEnabled` (null when no live canvas exists: never published, or this trigger was added after the last publish), `inLiveVersion`, `devDispatchArmed` (enabled and allowed) and `dualDispatchLive`; get adds captured event counts and issues. The audit summarizes coverage and double-run risk before a publish and names the disarm step for each armed trigger.
61
49
 
62
- ## Debugging a missing run
50
+ ## Missing-run diagnosis
63
51
 
64
- 1. `cai trigger list --json`: enabled, correct flow, recoverable backend ID.
65
- 2. `cai workflow status --json`: published/active live state.
66
- 3. `cai trigger events --trigger <backendId>`: did ingestion capture the event?
67
- 4. `cai trigger event <eventId>`: does payload match the selected sample?
68
- 5. `cai exec list --json`: did execution start?
69
- 6. `cai exec tree <executionId> --json`: where did it stop?
52
+ 1. The trigger list: enabled, correct flow, recoverable backend ID?
53
+ 2. The workflow status: published, and is the live version active?
54
+ 3. The captured events for the backend trigger ID: did ingestion capture the event?
55
+ 4. The event read: does the payload match the selected sample?
56
+ 5. The execution list: did an execution start?
57
+ 6. The execution tree: where did it stop?
70
58
 
71
- No captured event means source/delivery/configuration. Captured event with no execution means enable/live/ingestion routing. An execution with empty inputs means mapping.
59
+ No captured event points to the source, delivery or configuration. A captured event with no execution points to enablement, publish state or ingestion routing. An execution with empty inputs points to the mapping. Development works but live does not: compare the enabled state and the published configuration, and remember that live runs read the live data store.