@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,441 @@
|
|
|
1
|
+
import { requireContext } from '../context.js';
|
|
2
|
+
import { userError } from '../errors.js';
|
|
3
|
+
import { resolveJsSource } from '../jsSource.js';
|
|
4
|
+
import { emit, printKeyValues, printTable, truncate, warn } from '../output.js';
|
|
5
|
+
import { validationFailed, validationMessage } from './expr.js';
|
|
6
|
+
/**
|
|
7
|
+
* `get_node` returns `routes[]` for a Router and `branches[]` for an If/Else and
|
|
8
|
+
* neither for anything else — so the node record alone decides which tool family
|
|
9
|
+
* to use. The caller never has to declare it.
|
|
10
|
+
*/
|
|
11
|
+
export const readBranchNode = (node) => {
|
|
12
|
+
const nodeId = node?.id ?? '(unknown)';
|
|
13
|
+
const displayName = node?.displayName ?? '';
|
|
14
|
+
if (Array.isArray(node?.routes)) {
|
|
15
|
+
return {
|
|
16
|
+
nodeId,
|
|
17
|
+
displayName,
|
|
18
|
+
family: 'router',
|
|
19
|
+
entries: node.routes.map((r) => ({
|
|
20
|
+
id: r.routeId,
|
|
21
|
+
displayName: r.displayName ?? '',
|
|
22
|
+
kind: 'route',
|
|
23
|
+
conditionJs: r.conditionJs,
|
|
24
|
+
})),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(node?.branches)) {
|
|
28
|
+
return {
|
|
29
|
+
nodeId,
|
|
30
|
+
displayName,
|
|
31
|
+
family: 'ifElse',
|
|
32
|
+
entries: node.branches.map((b) => ({
|
|
33
|
+
id: b.branchId,
|
|
34
|
+
displayName: b.displayName ?? '',
|
|
35
|
+
kind: b.branchKind === 'fallback' ? 'fallback' : 'condition',
|
|
36
|
+
conditionJs: b.conditionJs,
|
|
37
|
+
})),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
throw userError(`Node ${nodeId} is neither a Router nor an If/Else — it has no routes or branches. ` +
|
|
41
|
+
'`cai branch` only applies to registry_flow-router and registry_flow-if-else nodes; ' +
|
|
42
|
+
'wire ordinary nodes with `cai node connect`.', 'NOT_A_BRANCH_NODE');
|
|
43
|
+
};
|
|
44
|
+
const loadBranchNode = async (api, workflowId, nodeId) => readBranchNode(await api.tool(workflowId, 'get_node', { nodeId }));
|
|
45
|
+
const findEntry = (view, id) => {
|
|
46
|
+
const entry = view.entries.find(e => e.id === id);
|
|
47
|
+
if (!entry) {
|
|
48
|
+
throw userError(`No ${view.family === 'router' ? 'route' : 'branch'} "${id}" on node ${view.nodeId}. ` +
|
|
49
|
+
`Known ids: ${view.entries.map(e => e.id).join(', ') || '(none)'} ` +
|
|
50
|
+
'(list them with `cai branch list <nodeId>`).', 'UNKNOWN_ROUTE');
|
|
51
|
+
}
|
|
52
|
+
return entry;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The wire shape for a condition is `string` OR `string[][]` (OR of AND groups).
|
|
56
|
+
* `--js` gives the single-expression form; `--condition-json` gives the grouped
|
|
57
|
+
* form verbatim, so both backend shapes are reachable without inventing a DSL.
|
|
58
|
+
*/
|
|
59
|
+
export const parseConditionJs = (js, conditionJson) => {
|
|
60
|
+
if (js !== undefined && conditionJson !== undefined) {
|
|
61
|
+
throw userError('--js and --condition-json are mutually exclusive.', 'CONFLICTING_CONDITION');
|
|
62
|
+
}
|
|
63
|
+
if (js !== undefined)
|
|
64
|
+
return js;
|
|
65
|
+
if (conditionJson === undefined)
|
|
66
|
+
return undefined;
|
|
67
|
+
let parsed;
|
|
68
|
+
try {
|
|
69
|
+
parsed = JSON.parse(conditionJson);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw userError(`--condition-json is not valid JSON: ${error instanceof Error ? error.message : error}`, 'BAD_CONDITION_JSON');
|
|
73
|
+
}
|
|
74
|
+
if (!Array.isArray(parsed) ||
|
|
75
|
+
parsed.some(row => !Array.isArray(row) || row.some(cell => typeof cell !== 'string'))) {
|
|
76
|
+
throw userError('--condition-json must be string[][] — an array of AND-rows, OR-ed together, ' +
|
|
77
|
+
'e.g. \'[["a > 1","b != \\"x\\""],["c"]]\'.', 'BAD_CONDITION_SHAPE');
|
|
78
|
+
}
|
|
79
|
+
const emptyRow = parsed.findIndex(row => row.length === 0);
|
|
80
|
+
if (emptyRow >= 0) {
|
|
81
|
+
throw userError(`--condition-json row ${emptyRow} is empty. Every AND-row must carry at least one ` +
|
|
82
|
+
'expression (the backend rejects empty rows too).', 'EMPTY_CONDITION_ROW');
|
|
83
|
+
}
|
|
84
|
+
return parsed;
|
|
85
|
+
};
|
|
86
|
+
/** Every individual expression inside a condition, for per-expression validation. */
|
|
87
|
+
export const conditionExpressions = (condition) => typeof condition === 'string' ? [condition] : condition.flat();
|
|
88
|
+
/** Render a condition back as readable source for a table cell. */
|
|
89
|
+
export const conditionText = (condition) => {
|
|
90
|
+
if (condition === undefined)
|
|
91
|
+
return '';
|
|
92
|
+
if (typeof condition === 'string')
|
|
93
|
+
return condition;
|
|
94
|
+
return condition.map(row => row.join(' && ')).join(' || ');
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Compile every expression before writing. The backend also compiles (route
|
|
98
|
+
* conditions go through `normalizeOnlyWhenGroup` → `compileJs`), but validating
|
|
99
|
+
* first means a bad expression cannot half-write, and the compiler error is
|
|
100
|
+
* attributed to the exact expression that produced it.
|
|
101
|
+
*/
|
|
102
|
+
const validateCondition = async (api, workflowId, nodeId, condition) => {
|
|
103
|
+
for (const source of conditionExpressions(condition)) {
|
|
104
|
+
const validation = await api.tool(workflowId, 'validate_expression', {
|
|
105
|
+
js: source,
|
|
106
|
+
nodeId,
|
|
107
|
+
mode: 'onlyWhen',
|
|
108
|
+
});
|
|
109
|
+
if (validationFailed(validation)) {
|
|
110
|
+
throw userError(`Condition did not compile — nothing was written.\n\nexpression: ${source}\n` +
|
|
111
|
+
validationMessage(validation), 'EXPRESSION_COMPILE_ERROR');
|
|
112
|
+
}
|
|
113
|
+
for (const w of validation?.warnings ?? [])
|
|
114
|
+
warn(`${source}: ${String(w)}`);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* `get_flow` omits `sourceHandle` from its edges, so route→edge attribution is
|
|
119
|
+
* not readable from the tool surface. The development-version-state document
|
|
120
|
+
* carries the full edge records (`sourceHandle: "output-<routeId>"`), so wiring
|
|
121
|
+
* is recovered from there. An unwired route is a silent dead end: the run stays
|
|
122
|
+
* green and simply stops.
|
|
123
|
+
*/
|
|
124
|
+
const readWiring = async (api, workflowId, nodeId) => {
|
|
125
|
+
const wiring = new Map();
|
|
126
|
+
const state = await api
|
|
127
|
+
.rest(`/workflow-agent/development-version-state/${workflowId}`)
|
|
128
|
+
.catch(() => null);
|
|
129
|
+
if (!state?.json)
|
|
130
|
+
return wiring;
|
|
131
|
+
let document;
|
|
132
|
+
try {
|
|
133
|
+
document = JSON.parse(state.json);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return wiring;
|
|
137
|
+
}
|
|
138
|
+
for (const flow of document?.flows ?? []) {
|
|
139
|
+
for (const edge of flow?.edges ?? []) {
|
|
140
|
+
if (edge?.source !== nodeId)
|
|
141
|
+
continue;
|
|
142
|
+
const match = /^output-(.+)$/.exec(edge.sourceHandle ?? '');
|
|
143
|
+
if (!match)
|
|
144
|
+
continue;
|
|
145
|
+
wiring.set(match[1], [...(wiring.get(match[1]) ?? []), edge.target]);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return wiring;
|
|
149
|
+
};
|
|
150
|
+
/** Locate the flow containing a node when `--flow` was not supplied. */
|
|
151
|
+
const resolveFlowId = async (api, workflowId, nodeId, explicit) => {
|
|
152
|
+
if (explicit)
|
|
153
|
+
return explicit;
|
|
154
|
+
const flows = await api.tool(workflowId, 'get_flows', {});
|
|
155
|
+
for (const flow of flows ?? []) {
|
|
156
|
+
const detail = await api.tool(workflowId, 'get_flow', {
|
|
157
|
+
flowId: flow.id,
|
|
158
|
+
});
|
|
159
|
+
if ((detail?.nodes ?? []).some(n => n.id === nodeId))
|
|
160
|
+
return flow.id;
|
|
161
|
+
}
|
|
162
|
+
throw userError(`Cannot find the flow containing node ${nodeId}. Pass --flow <flowId> explicitly.`, 'UNRESOLVED_FLOW');
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Loud warnings for the two states that pass every write and then break at
|
|
166
|
+
* publish or at run time.
|
|
167
|
+
*/
|
|
168
|
+
export const branchWarnings = (view, wiring) => {
|
|
169
|
+
const problems = [];
|
|
170
|
+
for (const entry of view.entries) {
|
|
171
|
+
if (entry.kind === 'condition' && entry.conditionJs === undefined) {
|
|
172
|
+
problems.push(`BLANK CONDITION: If/Else branch "${entry.displayName}" (${entry.id}) has no condition. ` +
|
|
173
|
+
'This is not cosmetic — publish and execution both hard-fail with ' +
|
|
174
|
+
`'If/Else node "${view.displayName}" branch "${entry.displayName}" has a blank ` +
|
|
175
|
+
"condition rule'. A freshly added If/Else node ships with exactly this state on its " +
|
|
176
|
+
'default "If" branch. Set one with `cai branch update`.');
|
|
177
|
+
}
|
|
178
|
+
if (entry.kind === 'route' && entry.conditionJs === undefined) {
|
|
179
|
+
problems.push(`NO CONDITION: Router route "${entry.displayName}" (${entry.id}) has no condition. ` +
|
|
180
|
+
'The backend accepts a condition-less route, but there is nothing for the engine to ' +
|
|
181
|
+
'evaluate — the route never selects itself and the branch ends silently.');
|
|
182
|
+
}
|
|
183
|
+
if (!(wiring.get(entry.id) ?? []).length) {
|
|
184
|
+
problems.push(`UNWIRED: ${entry.kind === 'fallback' ? 'Else branch' : entry.kind === 'route' ? 'route' : 'branch'} ` +
|
|
185
|
+
`"${entry.displayName}" (${entry.id}) is not connected to any node. Execution taking ` +
|
|
186
|
+
'this path stops there with a green run and no output. Wire it with ' +
|
|
187
|
+
`\`cai branch connect ${view.nodeId} --route ${entry.id} --to <nodeId>\`.`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return problems;
|
|
191
|
+
};
|
|
192
|
+
export const registerBranch = (program) => {
|
|
193
|
+
const branch = program
|
|
194
|
+
.command('branch')
|
|
195
|
+
.description('Router routes and If/Else branches — create, condition, wire, order');
|
|
196
|
+
branch
|
|
197
|
+
.command('list')
|
|
198
|
+
.argument('<nodeId>', 'Router or If/Else node id')
|
|
199
|
+
.description('Routes/branches in evaluation order, with conditions and wired targets')
|
|
200
|
+
.action(async (nodeId, _opts, command) => {
|
|
201
|
+
const { api, workflowId } = requireContext(command);
|
|
202
|
+
const view = await loadBranchNode(api, workflowId, nodeId);
|
|
203
|
+
const wiring = await readWiring(api, workflowId, nodeId);
|
|
204
|
+
for (const problem of branchWarnings(view, wiring))
|
|
205
|
+
warn(problem);
|
|
206
|
+
const rows = view.entries.map((entry, index) => ({
|
|
207
|
+
order: index,
|
|
208
|
+
id: entry.id,
|
|
209
|
+
displayName: entry.displayName,
|
|
210
|
+
kind: entry.kind,
|
|
211
|
+
conditionJs: entry.conditionJs ?? null,
|
|
212
|
+
targets: wiring.get(entry.id) ?? [],
|
|
213
|
+
}));
|
|
214
|
+
emit({ nodeId: view.nodeId, family: view.family, items: rows, entries: rows }, () => {
|
|
215
|
+
printKeyValues([
|
|
216
|
+
['nodeId', view.nodeId],
|
|
217
|
+
['displayName', view.displayName],
|
|
218
|
+
[
|
|
219
|
+
'family',
|
|
220
|
+
view.family === 'router'
|
|
221
|
+
? 'Router (every match runs)'
|
|
222
|
+
: 'If/Else (first match wins, Else last)',
|
|
223
|
+
],
|
|
224
|
+
]);
|
|
225
|
+
process.stdout.write('\n');
|
|
226
|
+
printTable(['order', 'id', 'name', 'kind', 'condition', 'wired to'], rows.map(r => [
|
|
227
|
+
r.order,
|
|
228
|
+
r.id,
|
|
229
|
+
r.displayName,
|
|
230
|
+
r.kind,
|
|
231
|
+
truncate(conditionText(r.conditionJs ?? undefined), 50) || '(none)',
|
|
232
|
+
r.targets.join(', ') || '(none)',
|
|
233
|
+
]));
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
branch
|
|
237
|
+
.command('add')
|
|
238
|
+
.argument('<nodeId>', 'Router or If/Else node id')
|
|
239
|
+
.option('--name <displayName>', 'route/branch label')
|
|
240
|
+
.option('--js <expr>', 'boolean condition, one expression')
|
|
241
|
+
.option('--js-file <path|->', 'read one boolean condition from a UTF-8 file or stdin')
|
|
242
|
+
.option('--condition-json <json>', 'condition as string[][] — OR of AND-rows')
|
|
243
|
+
.description('Add a Router route or an If/Else condition branch (inserted before Else)')
|
|
244
|
+
.action(async (nodeId, opts, command) => {
|
|
245
|
+
const js = resolveJsSource(opts, { required: false });
|
|
246
|
+
const { api, workflowId } = requireContext(command);
|
|
247
|
+
const view = await loadBranchNode(api, workflowId, nodeId);
|
|
248
|
+
const condition = parseConditionJs(js, opts.conditionJson);
|
|
249
|
+
if (view.family === 'ifElse' && condition === undefined) {
|
|
250
|
+
throw userError('An If/Else condition branch requires a condition — pass --js, --js-file, or ' +
|
|
251
|
+
'--condition-json. ' +
|
|
252
|
+
'Else already exists on every If/Else node, runs when nothing matches, and cannot ' +
|
|
253
|
+
'be given a condition, so a complement condition is never needed.', 'MISSING_CONDITION');
|
|
254
|
+
}
|
|
255
|
+
if (condition !== undefined)
|
|
256
|
+
await validateCondition(api, workflowId, nodeId, condition);
|
|
257
|
+
if (view.family === 'router' && condition === undefined) {
|
|
258
|
+
warn('Adding a Router route with no condition. The write succeeds, but the route has ' +
|
|
259
|
+
'nothing to evaluate and will never select itself — set one with `cai branch update`.');
|
|
260
|
+
}
|
|
261
|
+
const tool = view.family === 'router' ? 'add_router_route' : 'add_if_else_branch';
|
|
262
|
+
const result = await api.mutate(workflowId, () => api.tool(workflowId, tool, {
|
|
263
|
+
nodeId,
|
|
264
|
+
...(opts.name ? { displayName: opts.name } : {}),
|
|
265
|
+
...(condition !== undefined ? { conditionJs: condition } : {}),
|
|
266
|
+
}));
|
|
267
|
+
const newId = result?.routeId ?? result?.branchId;
|
|
268
|
+
emit({ nodeId, family: view.family, id: newId, result }, () => printKeyValues([
|
|
269
|
+
['nodeId', nodeId],
|
|
270
|
+
[view.family === 'router' ? 'routeId' : 'branchId', newId],
|
|
271
|
+
['displayName', opts.name ?? '(default)'],
|
|
272
|
+
['condition', conditionText(condition) || '(none)'],
|
|
273
|
+
]));
|
|
274
|
+
});
|
|
275
|
+
branch
|
|
276
|
+
.command('update')
|
|
277
|
+
.argument('<nodeId>', 'Router or If/Else node id')
|
|
278
|
+
.option('--route <id>', 'route id (Router) or branch id (If/Else)')
|
|
279
|
+
.option('--branch <id>', 'alias for --route')
|
|
280
|
+
.option('--name <displayName>', 'new label')
|
|
281
|
+
.option('--js <expr>', 'new boolean condition, one expression')
|
|
282
|
+
.option('--js-file <path|->', 'read one boolean condition from a UTF-8 file or stdin')
|
|
283
|
+
.option('--condition-json <json>', 'new condition as string[][] — OR of AND-rows')
|
|
284
|
+
.description('Rename a route/branch and/or replace its condition')
|
|
285
|
+
.action(async (nodeId, opts, command) => {
|
|
286
|
+
const js = resolveJsSource(opts, { required: false });
|
|
287
|
+
const { api, workflowId } = requireContext(command);
|
|
288
|
+
const routeId = requireRouteId(opts);
|
|
289
|
+
const view = await loadBranchNode(api, workflowId, nodeId);
|
|
290
|
+
const entry = findEntry(view, routeId);
|
|
291
|
+
const condition = parseConditionJs(js, opts.conditionJson);
|
|
292
|
+
if (opts.name === undefined && condition === undefined) {
|
|
293
|
+
throw userError('Pass --name and/or a condition (--js | --js-file | --condition-json).', 'NOTHING_TO_DO');
|
|
294
|
+
}
|
|
295
|
+
if (entry.kind === 'fallback' && condition !== undefined) {
|
|
296
|
+
throw userError(`"${entry.displayName}" is the Else branch. Else runs when no condition branch ` +
|
|
297
|
+
'matches and cannot be given a condition — it can only be renamed. Add a condition ' +
|
|
298
|
+
'branch instead (`cai branch add`); a manual complement condition is never needed.', 'ELSE_CANNOT_HAVE_CONDITION');
|
|
299
|
+
}
|
|
300
|
+
if (condition !== undefined)
|
|
301
|
+
await validateCondition(api, workflowId, nodeId, condition);
|
|
302
|
+
const tool = view.family === 'router' ? 'update_router_route' : 'update_if_else_branch';
|
|
303
|
+
const idKey = view.family === 'router' ? 'routeId' : 'branchId';
|
|
304
|
+
const result = await api.mutate(workflowId, () => api.tool(workflowId, tool, {
|
|
305
|
+
nodeId,
|
|
306
|
+
[idKey]: routeId,
|
|
307
|
+
...(opts.name !== undefined ? { displayName: opts.name } : {}),
|
|
308
|
+
...(condition !== undefined ? { conditionJs: condition } : {}),
|
|
309
|
+
}));
|
|
310
|
+
emit({
|
|
311
|
+
nodeId,
|
|
312
|
+
[idKey]: routeId,
|
|
313
|
+
displayName: opts.name ?? null,
|
|
314
|
+
condition: condition ?? null,
|
|
315
|
+
result,
|
|
316
|
+
}, () => printKeyValues([
|
|
317
|
+
['nodeId', nodeId],
|
|
318
|
+
[idKey, routeId],
|
|
319
|
+
['displayName', opts.name ?? '(unchanged)'],
|
|
320
|
+
['condition', condition === undefined ? '(unchanged)' : conditionText(condition)],
|
|
321
|
+
]));
|
|
322
|
+
});
|
|
323
|
+
branch
|
|
324
|
+
.command('delete')
|
|
325
|
+
.argument('<nodeId>', 'Router or If/Else node id')
|
|
326
|
+
.option('--route <id>', 'route id (Router) or branch id (If/Else)')
|
|
327
|
+
.option('--branch <id>', 'alias for --route')
|
|
328
|
+
.description('Delete a route/branch and its branch edge')
|
|
329
|
+
.action(async (nodeId, opts, command) => {
|
|
330
|
+
const { api, workflowId } = requireContext(command);
|
|
331
|
+
const routeId = requireRouteId(opts);
|
|
332
|
+
const view = await loadBranchNode(api, workflowId, nodeId);
|
|
333
|
+
const entry = findEntry(view, routeId);
|
|
334
|
+
if (entry.kind === 'fallback') {
|
|
335
|
+
throw userError('Else is required on every If/Else node and cannot be deleted. Delete the If/Else ' +
|
|
336
|
+
'node itself (`cai node delete`) if the fork is no longer wanted.', 'ELSE_REQUIRED');
|
|
337
|
+
}
|
|
338
|
+
const siblings = view.entries.filter(e => e.kind === entry.kind).length;
|
|
339
|
+
if (siblings <= 1) {
|
|
340
|
+
throw userError(`"${entry.displayName}" is the last ${entry.kind === 'route' ? 'route on this Router' : 'condition branch on this If/Else'}. ` +
|
|
341
|
+
'The backend keeps at least one — delete the node itself instead (`cai node delete`).', 'LAST_ROUTE');
|
|
342
|
+
}
|
|
343
|
+
const tool = view.family === 'router' ? 'delete_router_route' : 'delete_if_else_branch';
|
|
344
|
+
const idKey = view.family === 'router' ? 'routeId' : 'branchId';
|
|
345
|
+
const result = await api.mutate(workflowId, () => api.tool(workflowId, tool, { nodeId, [idKey]: routeId }));
|
|
346
|
+
emit({ nodeId, [idKey]: routeId, result }, () => printKeyValues([
|
|
347
|
+
['deleted', routeId],
|
|
348
|
+
['from', nodeId],
|
|
349
|
+
]));
|
|
350
|
+
});
|
|
351
|
+
branch
|
|
352
|
+
.command('connect')
|
|
353
|
+
.argument('<nodeId>', 'Router or If/Else node id')
|
|
354
|
+
.option('--route <id>', 'route id (Router) or branch id (If/Else)')
|
|
355
|
+
.option('--branch <id>', 'alias for --route')
|
|
356
|
+
.requiredOption('--to <nodeId>', 'target node the branch runs')
|
|
357
|
+
.option('--flow <flowId>', 'flow containing both nodes (resolved when omitted)')
|
|
358
|
+
.description('Wire a branch output to a target node — the only way to do it headlessly')
|
|
359
|
+
.action(async (nodeId, opts, command) => {
|
|
360
|
+
const { api, workflowId } = requireContext(command);
|
|
361
|
+
const routeId = requireRouteId(opts);
|
|
362
|
+
const view = await loadBranchNode(api, workflowId, nodeId);
|
|
363
|
+
findEntry(view, routeId);
|
|
364
|
+
const flowId = await resolveFlowId(api, workflowId, nodeId, opts.flow);
|
|
365
|
+
const result = view.family === 'router'
|
|
366
|
+
? await api.mutate(workflowId, () => api.tool(workflowId, 'connect_router_route', {
|
|
367
|
+
flowId,
|
|
368
|
+
routerNodeId: nodeId,
|
|
369
|
+
routeId,
|
|
370
|
+
targetNodeId: opts.to,
|
|
371
|
+
}))
|
|
372
|
+
: await api.mutate(workflowId, () => api.tool(workflowId, 'connect_if_else_branch', {
|
|
373
|
+
flowId,
|
|
374
|
+
ifElseNodeId: nodeId,
|
|
375
|
+
branchId: routeId,
|
|
376
|
+
targetNodeId: opts.to,
|
|
377
|
+
}));
|
|
378
|
+
emit({ nodeId, routeId, targetNodeId: opts.to, flowId, ...result }, () => printKeyValues([
|
|
379
|
+
['from', `${nodeId} (${routeId})`],
|
|
380
|
+
['to', opts.to],
|
|
381
|
+
['flow', flowId],
|
|
382
|
+
['edgeId', result?.edgeId],
|
|
383
|
+
['nodeInputId', result?.nodeInputId],
|
|
384
|
+
]));
|
|
385
|
+
});
|
|
386
|
+
branch
|
|
387
|
+
.command('reorder')
|
|
388
|
+
.argument('<nodeId>', 'If/Else node id')
|
|
389
|
+
.requiredOption('--order <ids>', 'every condition branch id, comma-separated, in new order')
|
|
390
|
+
.description('Reorder If/Else condition branches — first match wins, so order is semantics')
|
|
391
|
+
.action(async (nodeId, opts, command) => {
|
|
392
|
+
const { api, workflowId } = requireContext(command);
|
|
393
|
+
const view = await loadBranchNode(api, workflowId, nodeId);
|
|
394
|
+
if (view.family === 'router') {
|
|
395
|
+
throw userError('Router routes have no evaluation order — every route condition is evaluated ' +
|
|
396
|
+
'independently and every match runs. There is no reorder tool for a Router, and ' +
|
|
397
|
+
'reordering would not change behaviour. Use an If/Else node when exactly one path ' +
|
|
398
|
+
'should run.', 'ROUTER_HAS_NO_ORDER');
|
|
399
|
+
}
|
|
400
|
+
const requested = String(opts.order)
|
|
401
|
+
.split(',')
|
|
402
|
+
.map(s => s.trim())
|
|
403
|
+
.filter(Boolean);
|
|
404
|
+
const conditionIds = view.entries.filter(e => e.kind === 'condition').map(e => e.id);
|
|
405
|
+
const fallback = view.entries.find(e => e.kind === 'fallback');
|
|
406
|
+
if (fallback && requested.includes(fallback.id)) {
|
|
407
|
+
throw userError(`--order must not contain the Else branch (${fallback.id}). Else is always evaluated ` +
|
|
408
|
+
'last and is appended automatically; list only the condition branches.', 'ELSE_IN_ORDER');
|
|
409
|
+
}
|
|
410
|
+
const missing = conditionIds.filter(id => !requested.includes(id));
|
|
411
|
+
const unknown = requested.filter(id => !conditionIds.includes(id));
|
|
412
|
+
const duplicated = requested.filter((id, i) => requested.indexOf(id) !== i);
|
|
413
|
+
if (missing.length || unknown.length || duplicated.length) {
|
|
414
|
+
throw userError('--order must list every condition branch id exactly once.' +
|
|
415
|
+
(missing.length ? `\nmissing: ${missing.join(', ')}` : '') +
|
|
416
|
+
(unknown.length ? `\nnot on this node: ${unknown.join(', ')}` : '') +
|
|
417
|
+
(duplicated.length ? `\nduplicated: ${duplicated.join(', ')}` : ''), 'BAD_ORDER');
|
|
418
|
+
}
|
|
419
|
+
const result = await api.mutate(workflowId, () => api.tool(workflowId, 'reorder_if_else_branches', { nodeId, orderedBranchIds: requested }));
|
|
420
|
+
const names = new Map(view.entries.map(e => [e.id, e.displayName]));
|
|
421
|
+
emit({ nodeId, orderedBranchIds: requested, elseLast: fallback?.id ?? null, result }, () => printTable(['order', 'branchId', 'name'], [
|
|
422
|
+
...requested.map((id, i) => [i, id, names.get(id) ?? '']),
|
|
423
|
+
...(fallback
|
|
424
|
+
? [[requested.length, fallback.id, `${fallback.displayName} (always last)`]]
|
|
425
|
+
: []),
|
|
426
|
+
]));
|
|
427
|
+
});
|
|
428
|
+
};
|
|
429
|
+
/** `--route` and `--branch` are the same argument under two names. */
|
|
430
|
+
const requireRouteId = (opts) => {
|
|
431
|
+
if (opts.route && opts.branch && opts.route !== opts.branch) {
|
|
432
|
+
throw userError('--route and --branch are aliases; pass only one.', 'CONFLICTING_ROUTE_ID');
|
|
433
|
+
}
|
|
434
|
+
const id = opts.route ?? opts.branch;
|
|
435
|
+
if (!id) {
|
|
436
|
+
throw userError('Pass --route <id> (Router) or --branch <id> (If/Else). List them with ' +
|
|
437
|
+
'`cai branch list <nodeId>`.', 'MISSING_ROUTE_ID');
|
|
438
|
+
}
|
|
439
|
+
return id;
|
|
440
|
+
};
|
|
441
|
+
//# sourceMappingURL=branch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch.js","sourceRoot":"","sources":["../../src/commands/branch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { maskToken } from '../config.js';
|
|
2
|
+
import { buildClient } from '../context.js';
|
|
3
|
+
import { CaiError, EXIT, userError } from '../errors.js';
|
|
4
|
+
import { emit, printKeyValues, printTable, warn } from '../output.js';
|
|
5
|
+
import { parseDeviceLoginTimeout, runDeviceLogin, } from './auth.js';
|
|
6
|
+
import { runDoctor } from './doctor.js';
|
|
7
|
+
import { entrySkillPaths, updateSkills } from './skills.js';
|
|
8
|
+
export const isTransientNpxExecution = (entryPath = process.argv[1] ?? '', npmCommand = process.env.npm_command ?? '') => npmCommand === 'exec' || /(?:^|[/\\])_npx(?:[/\\]|$)/.test(entryPath);
|
|
9
|
+
export const connectDeviceLoginOptions = (opts) => ({
|
|
10
|
+
open: opts.open,
|
|
11
|
+
timeout: opts.timeout === undefined ? undefined : parseDeviceLoginTimeout(opts.timeout),
|
|
12
|
+
});
|
|
13
|
+
export const assertConnectVerification = (checks) => {
|
|
14
|
+
const requiredNames = new Set(['Node.js', 'Credential', 'Controller AI API', 'Credential file']);
|
|
15
|
+
const failed = checks.filter(check => requiredNames.has(check.name) && !check.ok);
|
|
16
|
+
const observed = new Set(checks.filter(check => requiredNames.has(check.name)).map(check => check.name));
|
|
17
|
+
for (const name of requiredNames) {
|
|
18
|
+
if (!observed.has(name))
|
|
19
|
+
failed.push({ name, ok: false, detail: 'check did not run' });
|
|
20
|
+
}
|
|
21
|
+
if (failed.length === 0)
|
|
22
|
+
return;
|
|
23
|
+
throw userError(`Controller AI connection verification failed:\n${failed
|
|
24
|
+
.map(check => `- ${check.name}: ${check.detail}`)
|
|
25
|
+
.join('\n')}`, 'CONNECT_VERIFICATION_FAILED');
|
|
26
|
+
};
|
|
27
|
+
export const registerConnect = (program) => {
|
|
28
|
+
program
|
|
29
|
+
.command('connect')
|
|
30
|
+
.description('Install skills, authorize this machine, and verify the complete setup')
|
|
31
|
+
.option('--target <target>', 'auto, agents, codex, claude, cursor, copilot, all, or project', 'auto')
|
|
32
|
+
.option('--project-dir <path>', 'project root for the open-standard project target')
|
|
33
|
+
.option('--force', 'replace existing unmanaged Controller AI skill folders', false)
|
|
34
|
+
.option('--no-open', 'headless/remote mode: print the URL without opening a browser')
|
|
35
|
+
.option('--timeout <seconds>', 'maximum time to wait for browser approval')
|
|
36
|
+
.action(async (opts, command) => {
|
|
37
|
+
const deviceLoginOptions = connectDeviceLoginOptions(opts);
|
|
38
|
+
const transient = isTransientNpxExecution();
|
|
39
|
+
if (transient) {
|
|
40
|
+
warn('This run appears to be transient (`npx … connect`). Your authorization and skills ' +
|
|
41
|
+
'will persist, but the `cai` command may not. For a durable install run: ' +
|
|
42
|
+
'`npm install -g @controllerai/cli`.');
|
|
43
|
+
}
|
|
44
|
+
const skillResult = await updateSkills({
|
|
45
|
+
target: opts.target,
|
|
46
|
+
projectDir: opts.projectDir,
|
|
47
|
+
force: opts.force,
|
|
48
|
+
});
|
|
49
|
+
for (const message of [
|
|
50
|
+
...skillResult.migrationWarnings,
|
|
51
|
+
...skillResult.cleanupWarnings,
|
|
52
|
+
]) {
|
|
53
|
+
warn(message);
|
|
54
|
+
}
|
|
55
|
+
let { config, api } = buildClient(command);
|
|
56
|
+
let authenticated = false;
|
|
57
|
+
if (config.token) {
|
|
58
|
+
authenticated = await api
|
|
59
|
+
.rest('/user/me')
|
|
60
|
+
.then(() => true)
|
|
61
|
+
.catch(error => {
|
|
62
|
+
// A rejected/expired credential should restart authorization. A
|
|
63
|
+
// network or backend failure should remain visible instead of
|
|
64
|
+
// being misreported as a need to log in again.
|
|
65
|
+
if (error instanceof CaiError && error.exitCode === EXIT.auth)
|
|
66
|
+
return false;
|
|
67
|
+
throw error;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (!authenticated) {
|
|
71
|
+
await runDeviceLogin(command, deviceLoginOptions);
|
|
72
|
+
({ config, api } = buildClient(command));
|
|
73
|
+
}
|
|
74
|
+
const checks = await runDoctor(command);
|
|
75
|
+
assertConnectVerification(checks);
|
|
76
|
+
const entries = entrySkillPaths(skillResult);
|
|
77
|
+
const availableSkills = skillResult.available;
|
|
78
|
+
const skillSetVersions = skillResult.availableSkillSetVersions;
|
|
79
|
+
const skillSources = skillResult.availableSkillSources;
|
|
80
|
+
const payload = {
|
|
81
|
+
connected: true,
|
|
82
|
+
apiUrl: config.apiUrl,
|
|
83
|
+
credential: maskToken(config.token),
|
|
84
|
+
skillSetVersion: skillSetVersions.length === 1 ? skillSetVersions[0] : 'mixed',
|
|
85
|
+
skillSetVersions,
|
|
86
|
+
skillSource: skillSources.length === 1 ? skillSources[0] : 'mixed',
|
|
87
|
+
skillSources,
|
|
88
|
+
updateSkillSetVersion: skillResult.updateSkillSetVersion,
|
|
89
|
+
updateSource: skillResult.updateSource,
|
|
90
|
+
availableSkillCount: skillResult.availableSkillCount,
|
|
91
|
+
installedSkillCount: availableSkills.length,
|
|
92
|
+
updatedSkillCount: skillResult.updatedSkillCount,
|
|
93
|
+
retainedSkillCount: skillResult.retainedSkillCount,
|
|
94
|
+
updatedSkills: skillResult.updated,
|
|
95
|
+
retainedSkills: skillResult.retained,
|
|
96
|
+
availableSkills,
|
|
97
|
+
// Compatibility alias: earlier consumers used installedSkills for
|
|
98
|
+
// every available row, including rows retained during an outage.
|
|
99
|
+
installedSkills: availableSkills,
|
|
100
|
+
entrySkillPath: entries[0],
|
|
101
|
+
entrySkillPaths: entries,
|
|
102
|
+
removedLegacyPaths: skillResult.removedLegacyPaths,
|
|
103
|
+
durableCommand: 'npm install -g @controllerai/cli && cai connect',
|
|
104
|
+
checks,
|
|
105
|
+
next: 'Read the entry skill above, then ask: “Would you like to build an agent or an automation?”',
|
|
106
|
+
};
|
|
107
|
+
emit(payload, () => {
|
|
108
|
+
printKeyValues([
|
|
109
|
+
['connected', payload.connected ? 'yes' : 'no'],
|
|
110
|
+
['backend', payload.apiUrl],
|
|
111
|
+
['credential', payload.credential],
|
|
112
|
+
['skill set', payload.skillSetVersion],
|
|
113
|
+
['skill source', payload.skillSource],
|
|
114
|
+
['update skill set', payload.updateSkillSetVersion],
|
|
115
|
+
['update source', payload.updateSource],
|
|
116
|
+
['skills available', payload.availableSkillCount],
|
|
117
|
+
['skills updated', payload.updatedSkillCount],
|
|
118
|
+
['skills retained', payload.retainedSkillCount],
|
|
119
|
+
['durable setup', payload.durableCommand],
|
|
120
|
+
['next', payload.next],
|
|
121
|
+
]);
|
|
122
|
+
process.stdout.write('\nAvailable skills:\n');
|
|
123
|
+
const availableRows = [
|
|
124
|
+
...payload.updatedSkills.map(row => ({ action: 'updated', row })),
|
|
125
|
+
...payload.retainedSkills.map(row => ({ action: 'retained', row })),
|
|
126
|
+
];
|
|
127
|
+
printTable(['action', 'target', 'skill', 'version', 'digest', 'path'], availableRows.map(({ action, row }) => [
|
|
128
|
+
action,
|
|
129
|
+
row.target,
|
|
130
|
+
row.skill,
|
|
131
|
+
row.skillSetVersion,
|
|
132
|
+
row.digest,
|
|
133
|
+
row.skillFile,
|
|
134
|
+
]));
|
|
135
|
+
if (payload.removedLegacyPaths.length > 0) {
|
|
136
|
+
process.stdout.write('\nRemoved legacy managed Codex copies:\n');
|
|
137
|
+
for (const path of payload.removedLegacyPaths)
|
|
138
|
+
process.stdout.write(` ${path}\n`);
|
|
139
|
+
}
|
|
140
|
+
if (payload.entrySkillPaths.length > 0) {
|
|
141
|
+
process.stdout.write('\nRead this entry skill now:\n');
|
|
142
|
+
for (const path of payload.entrySkillPaths)
|
|
143
|
+
process.stdout.write(` ${path}\n`);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}
|