@controllerai/cli 0.2.0
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/README.md +180 -0
- package/dist/api/client.js +330 -0
- package/dist/api/client.js.map +1 -0
- package/dist/appLinks.js +99 -0
- package/dist/appLinks.js.map +1 -0
- package/dist/argv.js +124 -0
- package/dist/argv.js.map +1 -0
- package/dist/commands/agent.js +813 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/auth.js +327 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/branch.js +441 -0
- package/dist/commands/branch.js.map +1 -0
- package/dist/commands/connect.js +148 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/connection.js +148 -0
- package/dist/commands/connection.js.map +1 -0
- package/dist/commands/data.js +441 -0
- package/dist/commands/data.js.map +1 -0
- package/dist/commands/deps.js +63 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/doctor.js +102 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.js +72 -0
- package/dist/commands/events.js.map +1 -0
- package/dist/commands/exec.js +306 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/expr.js +346 -0
- package/dist/commands/expr.js.map +1 -0
- package/dist/commands/flow.js +447 -0
- package/dist/commands/flow.js.map +1 -0
- package/dist/commands/integration.js +102 -0
- package/dist/commands/integration.js.map +1 -0
- package/dist/commands/node.js +885 -0
- package/dist/commands/node.js.map +1 -0
- package/dist/commands/organize.js +234 -0
- package/dist/commands/organize.js.map +1 -0
- package/dist/commands/run.js +437 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/schema.js +269 -0
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/skills.js +1156 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/trigger.js +992 -0
- package/dist/commands/trigger.js.map +1 -0
- package/dist/commands/workflow.js +503 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/config.js +74 -0
- package/dist/config.js.map +1 -0
- package/dist/context.js +39 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.js +125 -0
- package/dist/index.js.map +1 -0
- package/dist/jsSource.js +32 -0
- package/dist/jsSource.js.map +1 -0
- package/dist/nodeProps.js +177 -0
- package/dist/nodeProps.js.map +1 -0
- package/dist/output.js +85 -0
- package/dist/output.js.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +41 -0
- package/skills/controllerai-agents/SKILL.md +169 -0
- package/skills/controllerai-agents/agents/openai.yaml +4 -0
- package/skills/controllerai-agents/references/instructions-and-versioning.md +76 -0
- package/skills/controllerai-ai-nodes/SKILL.md +83 -0
- package/skills/controllerai-ai-nodes/agents/openai.yaml +4 -0
- package/skills/controllerai-ai-nodes/references/selection-and-testing.md +46 -0
- package/skills/controllerai-data/SKILL.md +121 -0
- package/skills/controllerai-data/agents/openai.yaml +4 -0
- package/skills/controllerai-data/references/data-rails.md +46 -0
- package/skills/controllerai-expressions/SKILL.md +115 -0
- package/skills/controllerai-expressions/agents/openai.yaml +4 -0
- package/skills/controllerai-expressions/references/dsl-and-recipes.md +120 -0
- package/skills/controllerai-flow-control/SKILL.md +132 -0
- package/skills/controllerai-flow-control/agents/openai.yaml +4 -0
- package/skills/controllerai-flow-control/references/patterns.md +61 -0
- package/skills/controllerai-integration-actions/SKILL.md +95 -0
- package/skills/controllerai-integration-actions/agents/openai.yaml +4 -0
- package/skills/controllerai-node-config/SKILL.md +138 -0
- package/skills/controllerai-node-config/agents/openai.yaml +4 -0
- package/skills/controllerai-node-config/references/prop-and-readiness.md +72 -0
- package/skills/controllerai-runs/SKILL.md +109 -0
- package/skills/controllerai-runs/agents/openai.yaml +4 -0
- package/skills/controllerai-runs/references/debugging.md +53 -0
- package/skills/controllerai-start/SKILL.md +44 -0
- package/skills/controllerai-start/agents/openai.yaml +4 -0
- package/skills/controllerai-triggers/SKILL.md +174 -0
- package/skills/controllerai-triggers/agents/openai.yaml +4 -0
- package/skills/controllerai-triggers/references/lifecycle.md +54 -0
- package/skills/controllerai-workflows/SKILL.md +86 -0
- package/skills/controllerai-workflows/agents/openai.yaml +4 -0
- package/skills/controllerai-workflows/references/command-map.md +64 -0
- package/skills/manifest.json +248 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: controllerai-node-config
|
|
3
|
+
description: Discover, initialize, configure, connect, and verify Controller AI workflow nodes. Use when adding an action, selecting an integration component, binding an account, setting node props, enabling optional or dynamic props, choosing provider-backed options, wiring nodes, or fixing a node that is not ready to run.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Controller AI node configuration
|
|
7
|
+
|
|
8
|
+
A node is ready only after its component, connection, dependency-ordered props, wiring, and output type are valid. Treat configuration as a state machine, not a bag of property writes.
|
|
9
|
+
|
|
10
|
+
## Deterministic sequence
|
|
11
|
+
|
|
12
|
+
### 1. Find an exact component
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cai node find "<capability>" --json
|
|
16
|
+
cai node component --node <nodeSlug> --key <nodeKey> --json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Use the returned `nodeSlug` and full `nodeKey`. Do not infer a component key from its display name. If discovery is broad, narrow it with:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cai node search "<integration>" --actions --json
|
|
23
|
+
cai node components "<action>" --node <nodeSlug> --json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Inspect static prop metadata before creating the node. `required`, `remoteOptions`, and `reloadProps` determine configuration order.
|
|
27
|
+
|
|
28
|
+
### 2. Resolve the account
|
|
29
|
+
|
|
30
|
+
If the component requires auth:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cai connection list --node <nodeSlug> --json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- One active connection: use its exact `connectionId`.
|
|
37
|
+
- Several: use an explicit user preference; otherwise ask which account.
|
|
38
|
+
- None: run `cai connection connect <nodeSlug> --wait`, share the printed link with the user, and the command returns automatically the moment they finish connecting (structured timeout otherwise — the link stays valid).
|
|
39
|
+
|
|
40
|
+
Never substitute a connection from a similar slug.
|
|
41
|
+
|
|
42
|
+
### 3. Initialize once
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cai node init \
|
|
46
|
+
--flow <flowId> \
|
|
47
|
+
--node <nodeSlug> \
|
|
48
|
+
--key <nodeKey> \
|
|
49
|
+
--name "<data this node produces>" \
|
|
50
|
+
--connection <connectionId> \
|
|
51
|
+
--after <upstreamNodeId> \
|
|
52
|
+
--json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Omit flags that do not apply. `--after` creates the ordinary main/error wire at creation. Use it when later props need upstream data. Initialization also accepts `--props`, but use it only for static, non-option values already present in the inspected component metadata. Never inline a `remoteOptions` value, a reload selector and its dependents, or a prop that has not materialized yet; initialize first and set those sequentially. Use `--enable-prop <name...>` only for optional props confirmed by component metadata.
|
|
56
|
+
|
|
57
|
+
Capture the returned `nodeId`; do not rediscover it by name.
|
|
58
|
+
|
|
59
|
+
### 4. Follow readiness, not guesses
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
cai node status <nodeId> --json
|
|
63
|
+
cai node props <nodeId> --json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Work through blockers in this order:
|
|
67
|
+
|
|
68
|
+
1. Missing connection
|
|
69
|
+
2. Required selector props with `reloadProps`
|
|
70
|
+
3. Newly revealed required props
|
|
71
|
+
4. Static and remote-option props
|
|
72
|
+
5. Wiring required for expressions
|
|
73
|
+
6. Expressions
|
|
74
|
+
7. Unresolved output type
|
|
75
|
+
|
|
76
|
+
Re-run `node props` after every reload selector or connection change. Dynamic props can appear, disappear, or reset.
|
|
77
|
+
|
|
78
|
+
### 5. Set props safely
|
|
79
|
+
|
|
80
|
+
Static value:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cai node set <nodeId> --prop <exactName> --value '<literal-or-json>' --json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Optional prop:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cai node optional-props <nodeId> --json
|
|
90
|
+
cai node enable-prop <nodeId> --prop <exactName> --json
|
|
91
|
+
cai node props <nodeId> --json
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Remote or dynamic option:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
cai node options <nodeId> --prop <exactName> --query "<specific label>" --json
|
|
98
|
+
cai node set <nodeId> \
|
|
99
|
+
--prop <exactName> \
|
|
100
|
+
--value '<returned value>' \
|
|
101
|
+
--label '<returned label>' \
|
|
102
|
+
--json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
For a remote option, preserve both fields from the same returned option. The label is not cosmetic: the CLI uses it to search providers that do not index opaque IDs, then verifies that the returned value still matches before writing. For a multi-select, pass a JSON array of returned values and one `--label` argument per value, in the same order. The CLI supplies the persisted label shape, chooses the correct expression storage channel, and verifies read-back. If metadata or options cannot be fetched, it fails closed; do not bypass that with a raw API call.
|
|
106
|
+
|
|
107
|
+
For dynamic values, load `controllerai-expressions` and prefer `cai expr set`.
|
|
108
|
+
|
|
109
|
+
### 6. Wire and verify
|
|
110
|
+
|
|
111
|
+
Ordinary outputs:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
cai node connect --flow <flowId> --from <sourceNodeId> --to <targetNodeId> --output main --json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Use `--output error` only for the automatic error path. Router and If/Else outputs require `cai branch connect` from the flow-control skill.
|
|
118
|
+
|
|
119
|
+
Finish with:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
cai node status <nodeId> --json
|
|
123
|
+
cai run node <nodeId> --inputs <values.json> --json
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
If the node has a wired input or consumes `inputs.<name>`, the node test is only an isolated configuration check. Run `cai run flow <flowId> --inputs <values.json> --json` before declaring its upstream expressions verified.
|
|
127
|
+
|
|
128
|
+
Read [references/prop-and-readiness.md](references/prop-and-readiness.md) when a prop is dynamic, option-backed, expression-capable, or unexpectedly absent.
|
|
129
|
+
|
|
130
|
+
## Hard rules
|
|
131
|
+
|
|
132
|
+
- Configure props in returned order; later props may depend on earlier values.
|
|
133
|
+
- Never write a prop absent from `node props`.
|
|
134
|
+
- Enable catalog-only optional props before writing them.
|
|
135
|
+
- Wire before authoring an expression that consumes upstream data.
|
|
136
|
+
- Changing a connection invalidates connection-scoped options; re-read props and options.
|
|
137
|
+
- A successful write is not completion. Require read-back plus `node status`.
|
|
138
|
+
- If output type remains unresolved, perform a realistic development test and inspect the resulting execution. Never fabricate an output schema.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Prop and readiness reference
|
|
2
|
+
|
|
3
|
+
## What `cai node status` means
|
|
4
|
+
|
|
5
|
+
The JSON response reports:
|
|
6
|
+
|
|
7
|
+
- `missingConnection`: an authenticated component has no account bound.
|
|
8
|
+
- `missingRequiredProps`: materialized required props without a value.
|
|
9
|
+
- `pendingReloadProps`: selectors that must be set before dependent props are trustworthy.
|
|
10
|
+
- `outputTypeStatus`: `concrete`, `unresolved`, or `none`. Connection-port wrappers never count as a concrete process output.
|
|
11
|
+
- `readyForExpressions`: connection and required/reload props are complete. The source still must be wired before its binding appears in expression context.
|
|
12
|
+
- `readyForRun`: connection and required/reload props are complete; running may be the step that discovers a concrete output type.
|
|
13
|
+
- `readyForDownstreamExpressions`: the node is runnable and its actual process output type is concrete enough for downstream field bindings.
|
|
14
|
+
- `next`: the CLI's exact next diagnostic command.
|
|
15
|
+
|
|
16
|
+
Follow `next`, then read status again. Do not treat `readyForRun` as proof that downstream fields are typed; require `readyForDownstreamExpressions` for that.
|
|
17
|
+
|
|
18
|
+
For an existing node with a missing connection, a browser handoff alone is not enough. After the user connects, list the compatible accounts, bind the chosen ID, and re-read status:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cai connection connect <nodeSlug>
|
|
22
|
+
cai connection list --node <nodeSlug> --json
|
|
23
|
+
cai node set-connection <nodeId> --connection <connectionId> --json
|
|
24
|
+
cai node status <nodeId> --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Prop channels
|
|
28
|
+
|
|
29
|
+
Use `cai node set`; it selects the persisted shape from live metadata.
|
|
30
|
+
|
|
31
|
+
| Intent | Command input | Persisted channel |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| Static text, JSON text, scalar, object, or list | `--value` | `value` |
|
|
34
|
+
| Dynamic text, JSON text, or custom data | `--js` | `valueJs` |
|
|
35
|
+
| Dynamic non-text prop with expression mode | `--js` | `expressionValueJs` |
|
|
36
|
+
|
|
37
|
+
Do not force a channel with internal fields. `cai node set` and `cai expr set` compile first and verify the actual channel after writing.
|
|
38
|
+
|
|
39
|
+
## Option-backed props
|
|
40
|
+
|
|
41
|
+
Static options are declared in component/prop metadata. Remote options require current connection and earlier prop values.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cai node options <nodeId> --prop <name> --query "<specific search>" --json
|
|
45
|
+
cai node set <nodeId> --prop <name> --value '<option.value>' --label '<option.label>' --json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Pass the value and label from the same live option. Remote providers often search labels rather than opaque values, so omitting `--label` can make a valid copied ID impossible to re-verify. For multi-select, pass a JSON array of returned values plus one `--label` argument per value in matching order. The CLI constructs the required array of `{value,label}` records for read-back/UI compatibility.
|
|
49
|
+
|
|
50
|
+
## Reload selectors
|
|
51
|
+
|
|
52
|
+
A prop with `reloadProps:true` changes the downstream prop schema. Set it statically, wait for the mutation, and immediately re-read:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
cai node set <nodeId> --prop <selector> --value '<value>' --json
|
|
56
|
+
cai node props <nodeId> --json
|
|
57
|
+
cai node status <nodeId> --json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Do not batch dependent values into stale metadata. A provider, model family, spreadsheet, database, or action selector commonly triggers this behavior.
|
|
61
|
+
|
|
62
|
+
## Output type
|
|
63
|
+
|
|
64
|
+
An unresolved output blocks trustworthy downstream field expressions. Resolve it by one of:
|
|
65
|
+
|
|
66
|
+
- Set the component's supported output/data type selector.
|
|
67
|
+
- Run the configured node with representative inputs.
|
|
68
|
+
- Probe an action with `cai run discover` only when its real-world side effects are acceptable.
|
|
69
|
+
|
|
70
|
+
After the run, read `cai node status` and `cai expr context` again. Do not infer fields from an example response alone if the platform did not adopt a concrete type.
|
|
71
|
+
|
|
72
|
+
`cai run node` and `cai run flow` pass the exact completed node-execution ID back to the backend. The backend verifies ownership, workflow, node, component snapshot, and terminal status, then derives the persisted output shape; callers never supply the type name. Adoption updates only that non-static node, so separate instances of generic components such as HTTP can learn different schemas. Inspect `outputTypeAdoption`/`outputTypeAdoptions` in the run result. If it reports `no_observed_output`, use a representative input that returns data and rerun. If it reports `error`, stop and surface that error rather than inventing a schema.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: controllerai-runs
|
|
3
|
+
description: Run and debug Controller AI nodes and flows on the development version — execution history, ports, outputs, skip reasons, and resolved configs. Use when verifying or testing a build, investigating a failed or green-but-wrong run, resolving an unknown output type, checking expression values, or proving what data and configuration reached each node.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Controller AI runs
|
|
7
|
+
|
|
8
|
+
Think "dev run", not "test". The development version is a real environment with its own data store — like an app's dev environment — and there is NO simulation mode: a dev run executes real integration actions (messages send, records change, provider usage is spent). Dev isolation covers the data store only. Running is a required part of building — one successful run is how a dynamic node's output type gets resolved for the next step — so the job is never "avoid running"; it is to mitigate risk before running.
|
|
9
|
+
|
|
10
|
+
## Consequential actions: mitigate with the user, don't refuse
|
|
11
|
+
|
|
12
|
+
Before dev-running an action with external consequences (send, reject, delete, charge), tell the user plainly what will really happen and ask for a safe target:
|
|
13
|
+
|
|
14
|
+
- Email/message sends → "What address/channel can I send the dev run to?" (often the user's own).
|
|
15
|
+
- Record deletes/updates → "Is there a record I can safely use, or shall I create one first and delete that?"
|
|
16
|
+
- People-affecting actions (e.g. reject a candidate) → "Which one is safe to use for this run?"
|
|
17
|
+
|
|
18
|
+
If the user declines running the action, accept it. Then keep the build honest: declare the node's output contract from the provider's documented response —
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cai node declare-output <nodeId> --sample-file shape.json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
— where `shape.json` is a representative response object from the provider's API reference. The contract is marked `declared (unverified)`; the first real completed run verifies and upgrades it automatically. State clearly that it is unverified until then, and make the first live run the explicit verification step. Never silently skip the question and never present an unrun action as verified.
|
|
25
|
+
|
|
26
|
+
## First live run is part of development
|
|
27
|
+
|
|
28
|
+
Publishing and running live is a legitimate, supervised development step — not a process failure. For risky sends, build the safe-audience harness: branch on the `isLiveVersion` data source with If/Else — the false branch targets the developer (own email/channel), the true branch targets the real audience. The first live run under supervision is how remaining problems surface.
|
|
29
|
+
|
|
30
|
+
## Prepare exact run inputs
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cai run inputs <nodeId> --json
|
|
34
|
+
cai run inputs <flowId> --flow --json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Use returned opaque input IDs. A compact input file can be a flat map:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"<inputId>": "representative value"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Do not key test values by a guessed display name.
|
|
46
|
+
|
|
47
|
+
## Run the smallest useful scope
|
|
48
|
+
|
|
49
|
+
Start with a changed node, then run its containing flow:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cai run node <nodeId> --inputs values.json --json
|
|
53
|
+
cai run flow <flowId> --inputs values.json --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`run node` is deliberately isolated: it does not execute wired upstream nodes. Read its `runScope`. If `endToEndValidationRequired` is true, values derived from upstream can be empty even when the selected node is green; do not accept that run as expression proof. `run flow` is the end-to-end check that executes upstream wiring.
|
|
57
|
+
|
|
58
|
+
The CLI waits for a terminal execution state. Capture `workflowExecutionId` and `nodeExecutionId` from the result.
|
|
59
|
+
|
|
60
|
+
For every node test, inspect:
|
|
61
|
+
|
|
62
|
+
- `status` and `errorMessage`
|
|
63
|
+
- `skipReason`
|
|
64
|
+
- `runScope`, especially `upstreamNodesExecuted` and `endToEndValidationRequired`
|
|
65
|
+
- `resolvedConfigs`
|
|
66
|
+
- `outputTypeAdoption`: the server verifies the exact completed `nodeExecutionId`, derives its persisted output shape, and updates only that non-static node. `adopted` or `already_typed` lets the next `node status` converge; `no_observed_output` means the representative run returned no reusable shape. `adoptedNodeIds` must be empty or contain only the tested node; stop if it names a sibling.
|
|
67
|
+
- output shape and values
|
|
68
|
+
|
|
69
|
+
A dynamic prop with a null/empty resolved config is a failure even when status is green. `0` and `false` are valid resolved values.
|
|
70
|
+
|
|
71
|
+
## Debug from the execution tree
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
cai exec tree <workflowExecutionId> --json
|
|
75
|
+
cai exec get <workflowExecutionId> --json
|
|
76
|
+
cai exec flow <flowExecutionId> --json
|
|
77
|
+
cai exec node <nodeExecutionId> --json
|
|
78
|
+
cai exec ports <nodeExecutionId> --json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Use the tree to locate the first unexpected status. Use ports to compare actual inputs, resolved configuration, and outputs at that node. Read [references/debugging.md](references/debugging.md) for the fault-isolation order.
|
|
82
|
+
|
|
83
|
+
## Output discovery
|
|
84
|
+
|
|
85
|
+
Prefer a configured node test. If a component is not yet in the graph, `run discover` creates a scratch node and deletes it after execution:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
cai run discover \
|
|
89
|
+
--node <nodeSlug> \
|
|
90
|
+
--key <nodeKey> \
|
|
91
|
+
--connection <connectionId|none> \
|
|
92
|
+
--props '<json>' \
|
|
93
|
+
--json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This calls the real third-party action and spends usage. For a destructive action, do not probe merely to learn its output — first ask the user for a safe target (see "Consequential actions" above); if they decline, declare the expected shape instead. Use `--keep` only when the user wants the scratch node retained.
|
|
97
|
+
|
|
98
|
+
After successful output discovery, re-read `cai node status` and downstream `cai expr context`; verify the adopted output type is concrete.
|
|
99
|
+
|
|
100
|
+
## Completion gate
|
|
101
|
+
|
|
102
|
+
- The test exercised the changed path with credible values.
|
|
103
|
+
- The first unexpected node, if any, was identified rather than inferred from the final error.
|
|
104
|
+
- All dynamic configs resolved to intended values.
|
|
105
|
+
- Output fields and types match downstream expectations.
|
|
106
|
+
- Branch skips are intentional and error paths are accounted for.
|
|
107
|
+
- A full flow test passes after isolated node fixes.
|
|
108
|
+
- `completed` with an empty or null output is treated as a failure until the output values are read and explained — an empty result usually means a mis-mapped input or an expression that null-propagated silently.
|
|
109
|
+
- The final report cites execution IDs and distinguishes development testing from live verification.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Execution debugging
|
|
2
|
+
|
|
3
|
+
Use this order; it avoids changing a downstream node when the defect is upstream.
|
|
4
|
+
|
|
5
|
+
## 1. Confirm rail and graph
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cai workflow status --json
|
|
9
|
+
cai flow get <flowId> --json
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Manual node/flow tests use development. Trigger replay defaults to the development rail, but both development and live replay can call real providers and create external effects. Live replay additionally requires `--target live --confirm-live`.
|
|
13
|
+
|
|
14
|
+
## 2. Find the first divergence
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
cai exec tree <workflowExecutionId> --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Classify each node as completed, failed, skipped intentionally, skipped unexpectedly, or absent. The first divergence is usually the cause; later failures are often consequences.
|
|
21
|
+
|
|
22
|
+
## 3. Inspect the node boundary
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cai exec ports <nodeExecutionId> --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Check:
|
|
29
|
+
|
|
30
|
+
1. Inputs: did the expected upstream value arrive?
|
|
31
|
+
2. Configs: did each expression resolve, and to the correct type/value?
|
|
32
|
+
3. Outputs: did the component return the promised shape?
|
|
33
|
+
4. Status/error: did the provider or engine reject the call?
|
|
34
|
+
|
|
35
|
+
## 4. Fix by category
|
|
36
|
+
|
|
37
|
+
| Evidence | Likely surface |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| Missing/wrong input | Wiring, branch connection, or test input ID |
|
|
40
|
+
| Null dynamic config | Expression binding, field path, or missing source value |
|
|
41
|
+
| Invalid option/account | Node connection or dependency-ordered props |
|
|
42
|
+
| Provider error | Integration configuration, credentials, quota, or payload |
|
|
43
|
+
| Green node, wrong output | Component choice, output contract, or prompt |
|
|
44
|
+
| Unexpected skip | only-when, branch condition/order, or upstream failure |
|
|
45
|
+
|
|
46
|
+
Re-read metadata/context before editing. Then rerun the smallest failed scope and finally the full flow.
|
|
47
|
+
|
|
48
|
+
## 5. Avoid false confidence
|
|
49
|
+
|
|
50
|
+
- A compile pass does not prove runtime data exists.
|
|
51
|
+
- A node pass does not prove downstream mapping: `run node` does not execute wired upstream nodes. Require `run flow` for any `inputs.<name>` expression.
|
|
52
|
+
- A dev pass does not prove live data or live release state.
|
|
53
|
+
- A top-level completed status does not prove every intended branch ran.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: controllerai-start
|
|
3
|
+
description: Connect, orient, and route work across Controller AI agents and no-code automations. Use when starting a Controller AI coding-agent session, after `cai connect`, or when deciding whether an outcome should be a ready integration action, a workflow, an agent, or a combination.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Start with Controller AI
|
|
7
|
+
|
|
8
|
+
Use the installed `cai` CLI as the supported platform interface. Do not call Controller AI REST or MCP routes directly.
|
|
9
|
+
|
|
10
|
+
## Confirm the setup
|
|
11
|
+
|
|
12
|
+
Run:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cai doctor
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
If authentication is missing, run `cai connect`. If `cai doctor` reports missing, stale, or damaged managed skills, run `cai skills update`, then run `cai doctor` again. Skill updates are setup maintenance, not a step to repeat during every build. Never ask the user to paste a password, provider token, or Controller AI credential into chat.
|
|
19
|
+
|
|
20
|
+
## Route the outcome
|
|
21
|
+
|
|
22
|
+
Identify the deliverable before mutating anything:
|
|
23
|
+
|
|
24
|
+
| Outcome | Load next |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| A user-facing agent that can converse and act | `controllerai-agents` |
|
|
27
|
+
| One ready app operation attached to an agent | `controllerai-integration-actions` and `controllerai-agents` |
|
|
28
|
+
| A multi-step, triggered, stateful, or reusable automation | `controllerai-workflows` plus the relevant workflow skills |
|
|
29
|
+
| An agent with orchestrated capabilities | `controllerai-agents`, then both integration-action and workflow skills as needed |
|
|
30
|
+
|
|
31
|
+
Prefer a ready integration action when one existing operation completes the capability. Use a workflow when the behavior needs multiple steps, transformations, branches, loops, durable data, triggers, custom typed input/output, or reuse outside the agent.
|
|
32
|
+
|
|
33
|
+
If the user's outcome does not reveal whether they want an agent or an automation that runs on an event, ask one short clarifying question. Otherwise proceed with the smallest suitable surface.
|
|
34
|
+
|
|
35
|
+
## Keep rails explicit
|
|
36
|
+
|
|
37
|
+
- Agent Test mode uses the owner's mutable draft, current workflow development heads, current draft knowledge, and live runtime files overlaid by development/test runtime files. Live mode uses the latest published agent version, each workflow's latest live release, frozen published knowledge, and live runtime files only.
|
|
38
|
+
- Agent draft edits require another agent publish to reach Live. Publishing restamps existing live conversations; shared users always receive the latest published version and never the draft.
|
|
39
|
+
- Workflow publishes and direct-action connection/authorization grants are live bindings: a rebind can redirect Live, while revocation or detachment can block Live without another agent publish.
|
|
40
|
+
- Local coding-agent subscriptions cover builder reasoning, not Controller AI hosted-agent runtime usage.
|
|
41
|
+
- Provider actions can send messages, mutate or delete records, and incur provider charges. Decide the per-action confirmation policy before attaching one.
|
|
42
|
+
- Never publish, share with the organization, replay a live trigger, or perform a consequential external test without clear user intent.
|
|
43
|
+
|
|
44
|
+
At completion, report what was created, what is still draft or live, the evidence actually observed, and any connection or user decision still required.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
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.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Controller AI triggers
|
|
7
|
+
|
|
8
|
+
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.
|
|
9
|
+
|
|
10
|
+
## Require a real source decision
|
|
11
|
+
|
|
12
|
+
Determine how the trigger choice was established:
|
|
13
|
+
|
|
14
|
+
- `explicit-in-request`: user named it in the request
|
|
15
|
+
- `user-answer`: user chose after clarification
|
|
16
|
+
- `inferred-from-existing-workflow`: preserving an existing source
|
|
17
|
+
|
|
18
|
+
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.
|
|
19
|
+
|
|
20
|
+
## Discover the exact event
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cai trigger search "<event intent>" --json
|
|
24
|
+
cai trigger search --node <nodeSlug> --events-per-node 50 --json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Copy the exact `nodeSlug` and `eventKey`. Never infer an event key from its display name.
|
|
28
|
+
|
|
29
|
+
If authentication is required:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cai connection list --node <nodeSlug> --json
|
|
33
|
+
cai connection connect <nodeSlug>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Resolve trigger props
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cai trigger props \
|
|
40
|
+
--node <nodeSlug> \
|
|
41
|
+
--event <eventKey> \
|
|
42
|
+
--connection <connectionId> \
|
|
43
|
+
--json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
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 CLI intentionally omits unresolved required option props rather than emitting a plausible placeholder.
|
|
47
|
+
|
|
48
|
+
For each name in `unresolvedOptionProps`, run the complete option command printed by the CLI, or equivalently:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
cai trigger options \
|
|
52
|
+
--node <nodeSlug> \
|
|
53
|
+
--event <eventKey> \
|
|
54
|
+
--prop <propName> \
|
|
55
|
+
--connection <connectionId> \
|
|
56
|
+
--configured '<configuredPropsJson>' \
|
|
57
|
+
--dynamic-props-id <dynamicPropsId> \
|
|
58
|
+
--query "<human option label>" \
|
|
59
|
+
--json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
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.
|
|
63
|
+
|
|
64
|
+
When a selector has `reloadProps`, rerun with its configured values and returned `dynamicPropsId` before creating the trigger.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cai trigger props \
|
|
68
|
+
--node <nodeSlug> \
|
|
69
|
+
--event <eventKey> \
|
|
70
|
+
--connection <connectionId> \
|
|
71
|
+
--configured '<configuredPropsJson>' \
|
|
72
|
+
--dynamic-props-id <dynamicPropsId> \
|
|
73
|
+
--json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
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 CLI prints this complete command; do not shorten it to only `--configured`.
|
|
77
|
+
|
|
78
|
+
Timer values are objects:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{"cron":{"cron":"0 9 * * *","timezone":"America/Chicago"}}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
or
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{"cron":{"intervalSeconds":900}}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Do not discard timezone by passing a bare cron string.
|
|
91
|
+
|
|
92
|
+
## Create and map
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
cai trigger create \
|
|
96
|
+
--flow <targetFlowId> \
|
|
97
|
+
--node <nodeSlug> \
|
|
98
|
+
--event <eventKey> \
|
|
99
|
+
--source-basis <basis> \
|
|
100
|
+
--connection <connectionId> \
|
|
101
|
+
--props '<json>' \
|
|
102
|
+
--dynamic-props-id <id> \
|
|
103
|
+
--json
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Capture all returned IDs. `triggerId` is the canvas ID used for get/rename/toggle/delete. `backendTriggerId` is numeric and used for captured events and replay. They are not interchangeable.
|
|
107
|
+
|
|
108
|
+
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.
|
|
109
|
+
|
|
110
|
+
## Establish a typed sample
|
|
111
|
+
|
|
112
|
+
After sending a representative event to the source:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cai trigger events --trigger <backendTriggerId> --json
|
|
116
|
+
cai trigger event <eventId> --json
|
|
117
|
+
cai trigger select-event --node <triggerNodeId> --event <eventId> --json
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then re-read expression context on downstream nodes. A sample without a platform data type may remain untyped.
|
|
121
|
+
|
|
122
|
+
## Finish trigger setup: disarm test events
|
|
123
|
+
|
|
124
|
+
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:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
cai trigger test-events --id <triggerId> --disallow
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The armed state is sticky: nothing disarms it for you, and dev dispatch and live dispatch are independent gates. A trigger that is armed while the workflow is also live runs ONE real event TWICE — both executions real, both billed. The starkest case is a schedule trigger: armed + enabled + published, the cron fires BOTH dev and live at every interval, forever, with no external event involved — until someone edits and republishes.
|
|
131
|
+
|
|
132
|
+
Keeping a trigger armed alongside live on purpose (side-by-side comparison on real events) is legitimate but uncommon; it is a user decision, never a default.
|
|
133
|
+
|
|
134
|
+
## Verify development, then publish
|
|
135
|
+
|
|
136
|
+
Use `cai run flow` for direct development verification, then replay one captured event through the development trigger path:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
cai trigger replay --trigger <backendTriggerId> --event <eventId> --target dev --json
|
|
140
|
+
cai exec tree <workflowExecutionId> --json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
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.
|
|
144
|
+
|
|
145
|
+
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:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cai trigger list --json
|
|
149
|
+
cai workflow publish --name "<release>" --json
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
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:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
cai workflow publish --name "<release>" --acknowledge-dual-dispatch --json
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Never pass `--acknowledge-dual-dispatch` on your own initiative.
|
|
159
|
+
|
|
160
|
+
Live replay is optional and requires an explicit acknowledgement:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cai trigger replay \
|
|
164
|
+
--trigger <backendTriggerId> \
|
|
165
|
+
--event <eventId> \
|
|
166
|
+
--target live \
|
|
167
|
+
--confirm-live \
|
|
168
|
+
--json
|
|
169
|
+
cai exec tree <workflowExecutionId> --json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
It executes the published workflow, calls live third-party actions, and spends usage. Obtain appropriate user intent before replaying a side-effectful event.
|
|
173
|
+
|
|
174
|
+
Read [references/lifecycle.md](references/lifecycle.md) for trigger state and debugging.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Trigger lifecycle
|
|
2
|
+
|
|
3
|
+
## State sequence
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
source decision
|
|
7
|
+
-> exact node/event discovery
|
|
8
|
+
-> 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
|
|
17
|
+
-> optional live replay
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Skipping capture/sample selection commonly leaves downstream output untyped. Skipping mapping commonly produces a green trigger execution with empty flow inputs.
|
|
21
|
+
|
|
22
|
+
## IDs
|
|
23
|
+
|
|
24
|
+
| ID | Used by |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| Canvas `triggerId` | `trigger get`, `rename`, `toggle`, `delete` |
|
|
27
|
+
| Numeric `backendTriggerId` | `trigger events`, `replay` |
|
|
28
|
+
| `triggerNodeId` | `trigger select-event` |
|
|
29
|
+
| Captured `eventId` | `trigger event`, `select-event`, `replay --event` |
|
|
30
|
+
|
|
31
|
+
Always copy these from CLI output.
|
|
32
|
+
|
|
33
|
+
Development replay is the normal pre-publish check:
|
|
34
|
+
|
|
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 toggle <triggerId>` flips state; it is not a setter. Read `cai trigger list --json` before and after. Do not toggle blindly.
|
|
44
|
+
|
|
45
|
+
## Debugging a missing run
|
|
46
|
+
|
|
47
|
+
1. `cai trigger list --json`: enabled, correct flow, recoverable backend ID.
|
|
48
|
+
2. `cai workflow status --json`: published/active live state.
|
|
49
|
+
3. `cai trigger events --trigger <backendId>`: did ingestion capture the event?
|
|
50
|
+
4. `cai trigger event <eventId>`: does payload match the selected sample?
|
|
51
|
+
5. `cai exec list --json`: did execution start?
|
|
52
|
+
6. `cai exec tree <executionId> --json`: where did it stop?
|
|
53
|
+
|
|
54
|
+
No captured event means source/delivery/configuration. Captured event with no execution means enable/live/ingestion routing. An execution with empty inputs means mapping.
|