@cargo-ai/cli 1.0.55 → 1.0.57
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 +1 -1
- package/build/commands/auth/index.d.ts.map +1 -1
- package/build/commands/auth/index.js +25 -5
- package/build/commands/orchestration/asciiBlocks.d.ts +42 -0
- package/build/commands/orchestration/asciiBlocks.d.ts.map +1 -0
- package/build/commands/orchestration/asciiBlocks.js +170 -0
- package/build/commands/orchestration/node.d.ts.map +1 -1
- package/build/commands/orchestration/node.js +131 -18
- package/build/commands/orchestration/nodeDiagram.d.ts +42 -0
- package/build/commands/orchestration/nodeDiagram.d.ts.map +1 -1
- package/build/commands/orchestration/nodeDiagram.js +123 -40
- package/build/commands/orchestration/nodeDiagramAscii.d.ts +32 -0
- package/build/commands/orchestration/nodeDiagramAscii.d.ts.map +1 -0
- package/build/commands/orchestration/nodeDiagramAscii.js +528 -0
- package/build/credentials.d.ts +1 -1
- package/build/credentials.d.ts.map +1 -1
- package/build/credentials.js +1 -1
- package/package.json +2 -2
|
@@ -13,24 +13,117 @@
|
|
|
13
13
|
// * `childrenUuids` order carries the routing semantics (index 0 of a
|
|
14
14
|
// `branch` is the matched path), so edge labels are table-driven rather
|
|
15
15
|
// than inferred from node names.
|
|
16
|
-
|
|
16
|
+
/** Actions that route rather than do work. Shared, so adding one to the
|
|
17
|
+
* platform does not have to be mirrored in each renderer. */
|
|
18
|
+
export const ROUTING_ACTIONS = new Set([
|
|
17
19
|
"branch",
|
|
18
20
|
"filter",
|
|
19
21
|
"switch",
|
|
20
22
|
"split",
|
|
21
23
|
"balance",
|
|
22
24
|
"humanReview",
|
|
23
|
-
];
|
|
25
|
+
]);
|
|
24
26
|
const CODE_ACTIONS = ["python", "script"];
|
|
25
27
|
// ---------------------------------------------------------------------------
|
|
28
|
+
// Graph basics, shared by every renderer
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
export function isStart(node) {
|
|
31
|
+
if (node === undefined)
|
|
32
|
+
return false;
|
|
33
|
+
return node.kind === "native" && node.actionSlug === "start";
|
|
34
|
+
}
|
|
35
|
+
export function isEnd(node) {
|
|
36
|
+
if (node === undefined)
|
|
37
|
+
return false;
|
|
38
|
+
return node.kind === "native" && node.actionSlug === "end";
|
|
39
|
+
}
|
|
40
|
+
export function indexByUuid(nodes) {
|
|
41
|
+
const byUuid = new Map();
|
|
42
|
+
for (const node of nodes) {
|
|
43
|
+
if (typeof node.uuid === "string")
|
|
44
|
+
byUuid.set(node.uuid, node);
|
|
45
|
+
}
|
|
46
|
+
return byUuid;
|
|
47
|
+
}
|
|
48
|
+
/** Where the graph begins — the `start` node, or the first node if it has none. */
|
|
49
|
+
export function findStart(nodes) {
|
|
50
|
+
const start = nodes.find(isStart);
|
|
51
|
+
return start === undefined ? nodes[0] : start;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Whether a user-supplied `--paid` / `--highlight` token names this node.
|
|
55
|
+
* Slugs repeat within a release, so a slug token marks every node carrying it;
|
|
56
|
+
* pass a uuid to mark exactly one.
|
|
57
|
+
*/
|
|
58
|
+
export function matchesNode(node, needles) {
|
|
59
|
+
const slug = node.slug === null ? undefined : node.slug;
|
|
60
|
+
return needles.some((needle) => needle === node.uuid || needle === slug);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A node's outgoing edges, in `childrenUuids` order, labelled by what the
|
|
64
|
+
* routing node means. Shared because this encodes routing *semantics* — index
|
|
65
|
+
* order, and the rule that a fallback pointing at the node's own next step is
|
|
66
|
+
* the same arrow rather than a second one. Two copies would let the two formats
|
|
67
|
+
* draw different graphs from one release.
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* A fallback pointing at the node's own next step: a failure here does not stop
|
|
71
|
+
* the run. It is not a second arrow — it is the same one — so it shows as a mark
|
|
72
|
+
* on the step rather than an edge. Silently dropping it makes a step that
|
|
73
|
+
* survives a provider outage look like one that dies on it, which is the exact
|
|
74
|
+
* misread this command exists to prevent.
|
|
75
|
+
*/
|
|
76
|
+
export function continuesOnFailure(node) {
|
|
77
|
+
const fallback = node.fallbackChildUuid;
|
|
78
|
+
if (typeof fallback !== "string")
|
|
79
|
+
return false;
|
|
80
|
+
return childrenOf(node).includes(fallback);
|
|
81
|
+
}
|
|
82
|
+
/** A node's child slots, in order, including the empty ones. */
|
|
83
|
+
function childrenOf(node) {
|
|
84
|
+
const children = node.childrenUuids;
|
|
85
|
+
return children === null || children === undefined ? [] : children;
|
|
86
|
+
}
|
|
87
|
+
export function outgoingEdges(node, byUuid) {
|
|
88
|
+
const children = childrenOf(node);
|
|
89
|
+
const labels = edgeLabels(node, children.length);
|
|
90
|
+
const edges = [];
|
|
91
|
+
children.forEach((child, index) => {
|
|
92
|
+
if (typeof child === "string" && byUuid.has(child)) {
|
|
93
|
+
edges.push({ to: child, label: labels[index] });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
const fallback = node.fallbackChildUuid;
|
|
97
|
+
if (typeof fallback === "string" &&
|
|
98
|
+
byUuid.has(fallback) &&
|
|
99
|
+
!children.includes(fallback)) {
|
|
100
|
+
edges.push({ to: fallback, label: "on failure", dashed: true });
|
|
101
|
+
}
|
|
102
|
+
return edges;
|
|
103
|
+
}
|
|
104
|
+
/** Structural problems worth saying out loud rather than drawing over. */
|
|
105
|
+
export function graphWarnings(nodes, byUuid, reached) {
|
|
106
|
+
const warnings = [];
|
|
107
|
+
const name = (node) => node.slug === null || node.slug === undefined ? node.uuid : node.slug;
|
|
108
|
+
const orphans = nodes.filter((node) => typeof node.uuid === "string" && !reached.has(node.uuid));
|
|
109
|
+
if (orphans.length > 0) {
|
|
110
|
+
warnings.push(`unreachable from start: ${orphans.map(name).join(", ")} — these nodes never run`);
|
|
111
|
+
}
|
|
112
|
+
const dangling = nodes.filter((node) => childrenOf(node).some((child) => child === null || byUuid.has(child) === false));
|
|
113
|
+
if (dangling.length > 0) {
|
|
114
|
+
warnings.push(`dangling childrenUuids (null or unknown) on: ${dangling.map(name).join(", ")} — the graph stops there`);
|
|
115
|
+
}
|
|
116
|
+
return warnings;
|
|
117
|
+
}
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
26
119
|
// Shapes and labels
|
|
27
120
|
// ---------------------------------------------------------------------------
|
|
28
121
|
function shapeFor(node) {
|
|
29
122
|
const action = node.actionSlug ?? "";
|
|
30
123
|
if (node.kind === "native") {
|
|
31
|
-
if (
|
|
124
|
+
if (isStart(node) || isEnd(node))
|
|
32
125
|
return ["([", "])"];
|
|
33
|
-
if (ROUTING_ACTIONS.
|
|
126
|
+
if (ROUTING_ACTIONS.has(action))
|
|
34
127
|
return ["{", "}"];
|
|
35
128
|
if (CODE_ACTIONS.includes(action))
|
|
36
129
|
return ["[/", "/]"];
|
|
@@ -146,7 +239,7 @@ export function labelFor(node) {
|
|
|
146
239
|
* is the matched path, index 1 the unmatched one. Getting this backwards
|
|
147
240
|
* inverts the diagram's meaning, so it is table-driven, never inferred.
|
|
148
241
|
*/
|
|
149
|
-
function edgeLabels(node, count) {
|
|
242
|
+
export function edgeLabels(node, count) {
|
|
150
243
|
const action = node.kind === "native" ? (node.actionSlug ?? "") : "";
|
|
151
244
|
if (action === "branch")
|
|
152
245
|
return ["yes", "no"];
|
|
@@ -179,9 +272,6 @@ function edgeLabels(node, count) {
|
|
|
179
272
|
// ---------------------------------------------------------------------------
|
|
180
273
|
// Rendering
|
|
181
274
|
// ---------------------------------------------------------------------------
|
|
182
|
-
function matches(node, needles) {
|
|
183
|
-
return needles.some((needle) => needle === node.uuid || needle === (node.slug ?? undefined));
|
|
184
|
-
}
|
|
185
275
|
function subNodes(node) {
|
|
186
276
|
const nested = node.config?.["_nodes"];
|
|
187
277
|
return Array.isArray(nested) && nested.length > 0
|
|
@@ -192,11 +282,7 @@ function renderNodes(nodes, context) {
|
|
|
192
282
|
const warnings = [];
|
|
193
283
|
const highlighted = [];
|
|
194
284
|
const direction = context.direction;
|
|
195
|
-
const byUuid =
|
|
196
|
-
for (const node of nodes) {
|
|
197
|
-
if (typeof node.uuid === "string")
|
|
198
|
-
byUuid.set(node.uuid, node);
|
|
199
|
-
}
|
|
285
|
+
const byUuid = indexByUuid(nodes);
|
|
200
286
|
// Ids come from a breadth-first walk from `start`, so the diagram reads in
|
|
201
287
|
// execution order and is stable across runs. Slugs are never used as ids:
|
|
202
288
|
// they repeat within a single release.
|
|
@@ -204,7 +290,7 @@ function renderNodes(nodes, context) {
|
|
|
204
290
|
const ids = new Map();
|
|
205
291
|
const seen = new Set();
|
|
206
292
|
const queue = [];
|
|
207
|
-
const start = nodes
|
|
293
|
+
const start = findStart(nodes);
|
|
208
294
|
if (start !== undefined)
|
|
209
295
|
queue.push(start.uuid);
|
|
210
296
|
while (queue.length > 0) {
|
|
@@ -236,28 +322,29 @@ function renderNodes(nodes, context) {
|
|
|
236
322
|
if (orphans.length > 0) {
|
|
237
323
|
warnings.push(`unreachable from start: ${orphans.map((node) => node.slug ?? node.uuid).join(", ")} — these nodes never run`);
|
|
238
324
|
}
|
|
325
|
+
// Edges come from the shared walk, so both formats encode routing the same
|
|
326
|
+
// way — index order, and the rule that a fallback pointing at a node's own
|
|
327
|
+
// next step is a ↷ mark rather than a second arrow. Only the id mapping is
|
|
328
|
+
// Mermaid's own.
|
|
239
329
|
const edges = [];
|
|
240
330
|
const dangling = new Set();
|
|
241
331
|
for (const { id, node } of order) {
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
//
|
|
254
|
-
//
|
|
255
|
-
const
|
|
256
|
-
if (
|
|
257
|
-
|
|
258
|
-
if (target !== undefined && !children.includes(fallbackUuid)) {
|
|
259
|
-
edges.push({ from: id, to: target, label: "on failure", dashed: true });
|
|
260
|
-
}
|
|
332
|
+
for (const edge of outgoingEdges(node, byUuid)) {
|
|
333
|
+
const target = ids.get(edge.to);
|
|
334
|
+
if (target === undefined)
|
|
335
|
+
continue;
|
|
336
|
+
edges.push({
|
|
337
|
+
from: id,
|
|
338
|
+
to: target,
|
|
339
|
+
label: edge.label,
|
|
340
|
+
dashed: edge.dashed,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
// `outgoingEdges` drops unusable slots by design; the diagram still has to
|
|
344
|
+
// report them, and it reports the node rather than the slot.
|
|
345
|
+
const hasUnusableSlot = childrenOf(node).some((child) => child === null || byUuid.has(child) === false);
|
|
346
|
+
if (hasUnusableSlot) {
|
|
347
|
+
dangling.add(node.slug === null || node.slug === undefined ? id : node.slug);
|
|
261
348
|
}
|
|
262
349
|
}
|
|
263
350
|
if (dangling.size > 0) {
|
|
@@ -266,14 +353,10 @@ function renderNodes(nodes, context) {
|
|
|
266
353
|
const lines = [];
|
|
267
354
|
for (const { id, node } of order) {
|
|
268
355
|
const [open, close] = shapeFor(node);
|
|
269
|
-
const paid =
|
|
270
|
-
if (
|
|
356
|
+
const paid = matchesNode(node, context.paid) ? "💳 " : "";
|
|
357
|
+
if (matchesNode(node, context.highlight))
|
|
271
358
|
highlighted.push(id);
|
|
272
|
-
|
|
273
|
-
const continuesOnFailure = node.fallbackChildUuid !== null &&
|
|
274
|
-
node.fallbackChildUuid !== undefined &&
|
|
275
|
-
children.includes(node.fallbackChildUuid);
|
|
276
|
-
lines.push(` ${id}${open}"${paid}${labelFor(node)}${continuesOnFailure ? " ↷" : ""}"${close}`);
|
|
359
|
+
lines.push(` ${id}${open}"${paid}${labelFor(node)}${continuesOnFailure(node) ? " ↷" : ""}"${close}`);
|
|
277
360
|
// A group's steps are drawn inside a sub-graph, under an id namespace of
|
|
278
361
|
// their own — `--paid` and `--highlight` apply just as they do out here,
|
|
279
362
|
// since a billing step buried in a loop is exactly the one worth seeing.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { displayWidth } from "./asciiBlocks.js";
|
|
2
|
+
import { type DiagramNode } from "./nodeDiagram.js";
|
|
3
|
+
/**
|
|
4
|
+
* Display names from the integration catalog. A graph stores wire slugs
|
|
5
|
+
* (`apolloio`, `enrichPerson`); the reader knows the product by its name.
|
|
6
|
+
* Optional throughout, so a graph diagrammed offline still renders.
|
|
7
|
+
*/
|
|
8
|
+
export type NameBook = {
|
|
9
|
+
/** integration slug → product name, e.g. `apolloio` → `Apollo.io`. */
|
|
10
|
+
integrations?: Record<string, string>;
|
|
11
|
+
/** integration slug → action slug → action name. */
|
|
12
|
+
actions?: Record<string, Record<string, string>>;
|
|
13
|
+
/** native action slug → action name, e.g. `script` → `JavaScript`. */
|
|
14
|
+
native?: Record<string, string>;
|
|
15
|
+
};
|
|
16
|
+
export type AsciiOptions = {
|
|
17
|
+
title?: string;
|
|
18
|
+
/** Catalog names, so steps read as products rather than as slugs. */
|
|
19
|
+
names?: NameBook;
|
|
20
|
+
/** Node slugs or uuids that bill credits — marked with 💳. */
|
|
21
|
+
paid?: string[];
|
|
22
|
+
/** Node slugs or uuids to mark, e.g. the failing node in a trace. */
|
|
23
|
+
highlight?: string[];
|
|
24
|
+
};
|
|
25
|
+
export { displayWidth };
|
|
26
|
+
export type AsciiResult = {
|
|
27
|
+
diagram: string;
|
|
28
|
+
format: "ascii";
|
|
29
|
+
warnings: string[];
|
|
30
|
+
};
|
|
31
|
+
export declare function renderNodeAscii(nodes: DiagramNode[], options?: AsciiOptions): AsciiResult;
|
|
32
|
+
//# sourceMappingURL=nodeDiagramAscii.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeDiagramAscii.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/nodeDiagramAscii.ts"],"names":[],"mappings":"AA4BA,OAAO,EAEL,YAAY,EAWb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,WAAW,EAQjB,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAkkBF,wBAAgB,eAAe,CAC7B,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,GAAE,YAAiB,GACzB,WAAW,CAiDb"}
|