@sweny-ai/core 0.1.77 → 0.1.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +11 -5
- package/dist/browser.js +11 -11
- package/dist/claude.d.ts +16 -0
- package/dist/claude.js +98 -9
- package/dist/cli/config.d.ts +22 -0
- package/dist/cli/config.js +56 -9
- package/dist/cli/main.d.ts +1 -1
- package/dist/cli/main.js +56 -57
- package/dist/cli/marketplace.js +35 -9
- package/dist/cli/publish.d.ts +10 -0
- package/dist/cli/publish.js +22 -14
- package/dist/loader.d.ts +40 -0
- package/dist/loader.js +73 -0
- package/dist/mcp-catalog.d.ts +47 -0
- package/dist/mcp-catalog.js +304 -0
- package/dist/mcp.d.ts +6 -9
- package/dist/mcp.js +24 -314
- package/dist/schema.d.ts +183 -151
- package/dist/schema.js +49 -7
- package/dist/skills/custom-loader.d.ts +40 -0
- package/dist/skills/custom-loader.js +107 -32
- package/dist/skills/index.d.ts +13 -1
- package/dist/skills/index.js +12 -3
- package/dist/studio.js +4 -1
- package/dist/templates.d.ts +29 -8
- package/dist/templates.js +30 -20
- package/dist/types.d.ts +12 -0
- package/dist/verify.js +42 -4
- package/package.json +8 -4
- package/dist/__tests__/cascade.test.d.ts +0 -11
- package/dist/__tests__/cascade.test.js +0 -452
- package/dist/__tests__/claude.test.d.ts +0 -1
- package/dist/__tests__/claude.test.js +0 -427
- package/dist/__tests__/custom-loader.test.d.ts +0 -1
- package/dist/__tests__/custom-loader.test.js +0 -116
- package/dist/__tests__/executor.test.d.ts +0 -1
- package/dist/__tests__/executor.test.js +0 -1635
- package/dist/__tests__/integration/datadog.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/datadog.integration.test.js +0 -23
- package/dist/__tests__/integration/e2e-workflow.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/e2e-workflow.integration.test.js +0 -75
- package/dist/__tests__/integration/github.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/github.integration.test.js +0 -37
- package/dist/__tests__/integration/harness.d.ts +0 -24
- package/dist/__tests__/integration/harness.js +0 -34
- package/dist/__tests__/integration/linear.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/linear.integration.test.js +0 -15
- package/dist/__tests__/integration/sentry.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/sentry.integration.test.js +0 -20
- package/dist/__tests__/integration/slack.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/slack.integration.test.js +0 -22
- package/dist/__tests__/integration/sources.integration.test.d.ts +0 -1
- package/dist/__tests__/integration/sources.integration.test.js +0 -123
- package/dist/__tests__/publish.test.d.ts +0 -1
- package/dist/__tests__/publish.test.js +0 -180
- package/dist/__tests__/requires.test.d.ts +0 -1
- package/dist/__tests__/requires.test.js +0 -82
- package/dist/__tests__/retry.test.d.ts +0 -1
- package/dist/__tests__/retry.test.js +0 -213
- package/dist/__tests__/schema.test.d.ts +0 -1
- package/dist/__tests__/schema.test.js +0 -600
- package/dist/__tests__/skill-config-integration.test.d.ts +0 -1
- package/dist/__tests__/skill-config-integration.test.js +0 -204
- package/dist/__tests__/skills-index.test.d.ts +0 -1
- package/dist/__tests__/skills-index.test.js +0 -119
- package/dist/__tests__/skills.test.d.ts +0 -1
- package/dist/__tests__/skills.test.js +0 -565
- package/dist/__tests__/spec-conformance.test.d.ts +0 -18
- package/dist/__tests__/spec-conformance.test.js +0 -1084
- package/dist/__tests__/studio.test.d.ts +0 -1
- package/dist/__tests__/studio.test.js +0 -403
- package/dist/__tests__/templates.test.d.ts +0 -1
- package/dist/__tests__/templates.test.js +0 -49
- package/dist/__tests__/testing.test.d.ts +0 -1
- package/dist/__tests__/testing.test.js +0 -242
- package/dist/__tests__/verify.test.d.ts +0 -1
- package/dist/__tests__/verify.test.js +0 -517
- package/dist/__tests__/version-consistency.test.d.ts +0 -1
- package/dist/__tests__/version-consistency.test.js +0 -312
- package/dist/__tests__/workflow-builder.test.d.ts +0 -1
- package/dist/__tests__/workflow-builder.test.js +0 -110
- package/dist/__tests__/workflow-yaml.test.d.ts +0 -1
- package/dist/__tests__/workflow-yaml.test.js +0 -201
- package/dist/cli/__tests__/diagram.test.d.ts +0 -1
- package/dist/cli/__tests__/diagram.test.js +0 -225
- package/dist/cli/__tests__/report-cloud.test.d.ts +0 -1
- package/dist/cli/__tests__/report-cloud.test.js +0 -165
- package/dist/cli/__tests__/upgrade.test.d.ts +0 -1
- package/dist/cli/__tests__/upgrade.test.js +0 -317
- package/dist/cli/__tests__/version-check.test.d.ts +0 -1
- package/dist/cli/__tests__/version-check.test.js +0 -209
- package/dist/cli/config.test.d.ts +0 -1
- package/dist/cli/config.test.js +0 -200
- package/dist/cli/credentials.test.d.ts +0 -1
- package/dist/cli/credentials.test.js +0 -172
- package/dist/cli/e2e.test.d.ts +0 -1
- package/dist/cli/e2e.test.js +0 -690
- package/dist/cli/marketplace.test.d.ts +0 -1
- package/dist/cli/marketplace.test.js +0 -355
- package/dist/cli/new.test.d.ts +0 -1
- package/dist/cli/new.test.js +0 -1043
- package/dist/cli/output.test.d.ts +0 -1
- package/dist/cli/output.test.js +0 -180
- package/dist/cli/publish.test.d.ts +0 -1
- package/dist/cli/publish.test.js +0 -610
- package/dist/cli/renderer.test.d.ts +0 -1
- package/dist/cli/renderer.test.js +0 -302
- package/dist/executor.test.d.ts +0 -1
- package/dist/executor.test.js +0 -618
- package/dist/mcp.test.d.ts +0 -1
- package/dist/mcp.test.js +0 -735
- package/dist/mermaid.test.d.ts +0 -1
- package/dist/mermaid.test.js +0 -256
- package/dist/sources.test.d.ts +0 -1
- package/dist/sources.test.js +0 -265
- package/dist/sources.validation.test.d.ts +0 -12
- package/dist/sources.validation.test.js +0 -380
- package/dist/workflow-builder.test.d.ts +0 -1
- package/dist/workflow-builder.test.js +0 -123
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
-
import { DagRenderer, stripAnsi } from "./renderer.js";
|
|
3
|
-
const testWorkflow = {
|
|
4
|
-
id: "test",
|
|
5
|
-
name: "Test Workflow",
|
|
6
|
-
description: "A simple test workflow",
|
|
7
|
-
nodes: {
|
|
8
|
-
gather: { name: "Gather Context", instruction: "Gather", skills: [] },
|
|
9
|
-
investigate: { name: "Investigate", instruction: "Investigate", skills: [] },
|
|
10
|
-
report: { name: "Report", instruction: "Report", skills: [] },
|
|
11
|
-
},
|
|
12
|
-
edges: [
|
|
13
|
-
{ from: "gather", to: "investigate" },
|
|
14
|
-
{ from: "investigate", to: "report" },
|
|
15
|
-
],
|
|
16
|
-
entry: "gather",
|
|
17
|
-
};
|
|
18
|
-
describe("DagRenderer", () => {
|
|
19
|
-
let renderer;
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
renderer = new DagRenderer(testWorkflow, { animate: false });
|
|
22
|
-
});
|
|
23
|
-
it("starts all nodes in pending state", () => {
|
|
24
|
-
expect(renderer.getNodeState("gather")).toBe("pending");
|
|
25
|
-
expect(renderer.getNodeState("investigate")).toBe("pending");
|
|
26
|
-
expect(renderer.getNodeState("report")).toBe("pending");
|
|
27
|
-
});
|
|
28
|
-
it("tracks node state: pending → running on node:enter", () => {
|
|
29
|
-
const event = { type: "node:enter", node: "gather", instruction: "Gather" };
|
|
30
|
-
renderer.update(event);
|
|
31
|
-
expect(renderer.getNodeState("gather")).toBe("running");
|
|
32
|
-
expect(renderer.getNodeState("investigate")).toBe("pending");
|
|
33
|
-
});
|
|
34
|
-
it("tracks node state: running → completed on node:exit success", () => {
|
|
35
|
-
renderer.update({ type: "node:enter", node: "gather", instruction: "Gather" });
|
|
36
|
-
renderer.update({
|
|
37
|
-
type: "node:exit",
|
|
38
|
-
node: "gather",
|
|
39
|
-
result: { status: "success", data: {}, toolCalls: [] },
|
|
40
|
-
});
|
|
41
|
-
expect(renderer.getNodeState("gather")).toBe("completed");
|
|
42
|
-
});
|
|
43
|
-
it("tracks node state: running → failed on node:exit failed", () => {
|
|
44
|
-
renderer.update({ type: "node:enter", node: "gather", instruction: "Gather" });
|
|
45
|
-
renderer.update({
|
|
46
|
-
type: "node:exit",
|
|
47
|
-
node: "gather",
|
|
48
|
-
result: { status: "failed", data: {}, toolCalls: [] },
|
|
49
|
-
});
|
|
50
|
-
expect(renderer.getNodeState("gather")).toBe("failed");
|
|
51
|
-
});
|
|
52
|
-
it("tracks failed nodes", () => {
|
|
53
|
-
renderer.update({ type: "node:enter", node: "investigate", instruction: "Investigate" });
|
|
54
|
-
renderer.update({
|
|
55
|
-
type: "node:exit",
|
|
56
|
-
node: "investigate",
|
|
57
|
-
result: { status: "failed", data: { error: "timeout" }, toolCalls: [] },
|
|
58
|
-
});
|
|
59
|
-
expect(renderer.getNodeState("investigate")).toBe("failed");
|
|
60
|
-
});
|
|
61
|
-
it("counts tool calls per node", () => {
|
|
62
|
-
expect(renderer.getToolCallCount("gather")).toBe(0);
|
|
63
|
-
renderer.update({ type: "node:enter", node: "gather", instruction: "Gather" });
|
|
64
|
-
renderer.update({ type: "tool:call", node: "gather", tool: "search", input: {} });
|
|
65
|
-
renderer.update({ type: "tool:call", node: "gather", tool: "fetch", input: {} });
|
|
66
|
-
expect(renderer.getToolCallCount("gather")).toBe(2);
|
|
67
|
-
expect(renderer.getToolCallCount("investigate")).toBe(0);
|
|
68
|
-
});
|
|
69
|
-
it("counts tool calls across multiple nodes independently", () => {
|
|
70
|
-
renderer.update({ type: "node:enter", node: "gather", instruction: "Gather" });
|
|
71
|
-
renderer.update({ type: "tool:call", node: "gather", tool: "search", input: {} });
|
|
72
|
-
renderer.update({ type: "node:exit", node: "gather", result: { status: "success", data: {}, toolCalls: [] } });
|
|
73
|
-
renderer.update({ type: "node:enter", node: "investigate", instruction: "Investigate" });
|
|
74
|
-
renderer.update({ type: "tool:call", node: "investigate", tool: "read", input: {} });
|
|
75
|
-
renderer.update({ type: "tool:call", node: "investigate", tool: "write", input: {} });
|
|
76
|
-
renderer.update({ type: "tool:call", node: "investigate", tool: "run", input: {} });
|
|
77
|
-
expect(renderer.getToolCallCount("gather")).toBe(1);
|
|
78
|
-
expect(renderer.getToolCallCount("investigate")).toBe(3);
|
|
79
|
-
});
|
|
80
|
-
it("renders to string without crashing", () => {
|
|
81
|
-
const output = renderer.renderToString();
|
|
82
|
-
expect(typeof output).toBe("string");
|
|
83
|
-
expect(output.length).toBeGreaterThan(0);
|
|
84
|
-
});
|
|
85
|
-
it("output contains all node names", () => {
|
|
86
|
-
const output = renderer.renderToString();
|
|
87
|
-
expect(output).toContain("Gather Context");
|
|
88
|
-
expect(output).toContain("Investigate");
|
|
89
|
-
expect(output).toContain("Report");
|
|
90
|
-
});
|
|
91
|
-
it("topological order starts from entry node", () => {
|
|
92
|
-
const output = renderer.renderToString();
|
|
93
|
-
const gatherIdx = output.indexOf("Gather Context");
|
|
94
|
-
const investigateIdx = output.indexOf("Investigate");
|
|
95
|
-
const reportIdx = output.indexOf("Report");
|
|
96
|
-
expect(gatherIdx).toBeLessThan(investigateIdx);
|
|
97
|
-
expect(investigateIdx).toBeLessThan(reportIdx);
|
|
98
|
-
});
|
|
99
|
-
it("shows running status icon for active node", () => {
|
|
100
|
-
renderer.update({ type: "node:enter", node: "gather", instruction: "Gather" });
|
|
101
|
-
const output = renderer.renderToString();
|
|
102
|
-
// ◉ is the running icon
|
|
103
|
-
expect(output).toContain("◉");
|
|
104
|
-
});
|
|
105
|
-
it("shows completed status icon for finished node", () => {
|
|
106
|
-
renderer.update({ type: "node:enter", node: "gather", instruction: "Gather" });
|
|
107
|
-
renderer.update({
|
|
108
|
-
type: "node:exit",
|
|
109
|
-
node: "gather",
|
|
110
|
-
result: { status: "success", data: {}, toolCalls: [] },
|
|
111
|
-
});
|
|
112
|
-
const output = renderer.renderToString();
|
|
113
|
-
// ● is the completed icon
|
|
114
|
-
expect(output).toContain("●");
|
|
115
|
-
});
|
|
116
|
-
it("shows failed status icon for failed node", () => {
|
|
117
|
-
renderer.update({ type: "node:enter", node: "gather", instruction: "Gather" });
|
|
118
|
-
renderer.update({
|
|
119
|
-
type: "node:exit",
|
|
120
|
-
node: "gather",
|
|
121
|
-
result: { status: "failed", data: {}, toolCalls: [] },
|
|
122
|
-
});
|
|
123
|
-
const output = renderer.renderToString();
|
|
124
|
-
// ✕ is the failed icon
|
|
125
|
-
expect(output).toContain("✕");
|
|
126
|
-
});
|
|
127
|
-
it("returns pending state for unknown node id", () => {
|
|
128
|
-
expect(renderer.getNodeState("nonexistent")).toBe("pending");
|
|
129
|
-
});
|
|
130
|
-
it("returns 0 tool calls for unknown node id", () => {
|
|
131
|
-
expect(renderer.getToolCallCount("nonexistent")).toBe(0);
|
|
132
|
-
});
|
|
133
|
-
it("includes a legend in the output", () => {
|
|
134
|
-
const output = renderer.renderToString();
|
|
135
|
-
// Legend should mention at least pending and completed
|
|
136
|
-
expect(output).toContain("○");
|
|
137
|
-
expect(output).toContain("●");
|
|
138
|
-
});
|
|
139
|
-
it("handles workflow:start event without crashing", () => {
|
|
140
|
-
const event = { type: "workflow:start", workflow: "test" };
|
|
141
|
-
expect(() => renderer.update(event)).not.toThrow();
|
|
142
|
-
});
|
|
143
|
-
it("handles workflow:end event without crashing", () => {
|
|
144
|
-
const event = {
|
|
145
|
-
type: "workflow:end",
|
|
146
|
-
results: {
|
|
147
|
-
gather: { status: "success", data: {}, toolCalls: [] },
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
expect(() => renderer.update(event)).not.toThrow();
|
|
151
|
-
});
|
|
152
|
-
it("handles route event without crashing", () => {
|
|
153
|
-
const event = { type: "route", from: "gather", to: "investigate", reason: "next" };
|
|
154
|
-
expect(() => renderer.update(event)).not.toThrow();
|
|
155
|
-
});
|
|
156
|
-
describe("uniform box widths", () => {
|
|
157
|
-
const mixedWidthWorkflow = {
|
|
158
|
-
id: "mixed",
|
|
159
|
-
name: "Mixed Width Workflow",
|
|
160
|
-
description: "Nodes with varying name lengths",
|
|
161
|
-
nodes: {
|
|
162
|
-
a: { name: "A", instruction: "Short", skills: [] },
|
|
163
|
-
b: { name: "Gather Context and Analyze", instruction: "Long name", skills: [] },
|
|
164
|
-
c: { name: "Report", instruction: "Medium", skills: [] },
|
|
165
|
-
},
|
|
166
|
-
edges: [
|
|
167
|
-
{ from: "a", to: "b" },
|
|
168
|
-
{ from: "b", to: "c" },
|
|
169
|
-
],
|
|
170
|
-
entry: "a",
|
|
171
|
-
};
|
|
172
|
-
it("all top-border lines have the same width", () => {
|
|
173
|
-
const r = new DagRenderer(mixedWidthWorkflow, { animate: false });
|
|
174
|
-
const output = stripAnsi(r.renderToString());
|
|
175
|
-
const topLines = output.split("\n").filter((l) => l.includes("┌") && l.includes("┐"));
|
|
176
|
-
expect(topLines.length).toBe(3);
|
|
177
|
-
const widths = topLines.map((l) => l.trim().length);
|
|
178
|
-
expect(new Set(widths).size).toBe(1); // all same width
|
|
179
|
-
});
|
|
180
|
-
it("output contains ▼ arrowhead on non-first boxes", () => {
|
|
181
|
-
const r = new DagRenderer(mixedWidthWorkflow, { animate: false });
|
|
182
|
-
const output = stripAnsi(r.renderToString());
|
|
183
|
-
expect(output).toContain("▼");
|
|
184
|
-
});
|
|
185
|
-
it("▼ is positioned between box borders", () => {
|
|
186
|
-
const r = new DagRenderer(mixedWidthWorkflow, { animate: false });
|
|
187
|
-
const output = stripAnsi(r.renderToString());
|
|
188
|
-
const arrowLines = output.split("\n").filter((l) => l.includes("▼"));
|
|
189
|
-
for (const line of arrowLines) {
|
|
190
|
-
// ▼ should be inside a top border: ┌───▼───┐
|
|
191
|
-
expect(line).toMatch(/┌─*▼─*┐/);
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
it("bottom of non-terminal boxes has centered ┬", () => {
|
|
195
|
-
const r = new DagRenderer(mixedWidthWorkflow, { animate: false });
|
|
196
|
-
const output = stripAnsi(r.renderToString());
|
|
197
|
-
const bottomLinesWithT = output.split("\n").filter((l) => l.includes("┬"));
|
|
198
|
-
// A and B are non-terminal, so 2 lines with ┬
|
|
199
|
-
expect(bottomLinesWithT.length).toBe(2);
|
|
200
|
-
for (const line of bottomLinesWithT) {
|
|
201
|
-
expect(line).toMatch(/└─*┬─*┘/);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
it("vertical connector uses centered │", () => {
|
|
205
|
-
const r = new DagRenderer(mixedWidthWorkflow, { animate: false });
|
|
206
|
-
const output = stripAnsi(r.renderToString());
|
|
207
|
-
// Find lines that are purely vertical connectors (between boxes)
|
|
208
|
-
const lines = output.split("\n");
|
|
209
|
-
const connectorLines = lines.filter((l) => l.trim() === "│");
|
|
210
|
-
expect(connectorLines.length).toBeGreaterThan(0);
|
|
211
|
-
// The │ should be centered relative to the box width
|
|
212
|
-
const topLine = lines.find((l) => l.includes("┌") && l.includes("┐"));
|
|
213
|
-
const tIdx = topLine.indexOf("┌");
|
|
214
|
-
const boxWidth = topLine.lastIndexOf("┐") - tIdx + 1;
|
|
215
|
-
const expectedCol = tIdx + Math.floor(boxWidth / 2);
|
|
216
|
-
for (const cl of connectorLines) {
|
|
217
|
-
expect(cl.indexOf("│")).toBe(expectedCol);
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
describe("branching layout", () => {
|
|
222
|
-
const branchingWorkflow = {
|
|
223
|
-
id: "triage",
|
|
224
|
-
name: "Triage Test",
|
|
225
|
-
description: "A branching workflow",
|
|
226
|
-
nodes: {
|
|
227
|
-
gather: { name: "Gather Context", instruction: "Gather", skills: [] },
|
|
228
|
-
investigate: { name: "Investigate", instruction: "Investigate", skills: [] },
|
|
229
|
-
create_ticket: { name: "Create Ticket", instruction: "Create", skills: [] },
|
|
230
|
-
skip: { name: "Skip", instruction: "Skip", skills: [] },
|
|
231
|
-
notify: { name: "Notify", instruction: "Notify", skills: [] },
|
|
232
|
-
},
|
|
233
|
-
edges: [
|
|
234
|
-
{ from: "gather", to: "investigate" },
|
|
235
|
-
{ from: "investigate", to: "create_ticket" },
|
|
236
|
-
{ from: "investigate", to: "skip" },
|
|
237
|
-
{ from: "create_ticket", to: "notify" },
|
|
238
|
-
],
|
|
239
|
-
entry: "gather",
|
|
240
|
-
};
|
|
241
|
-
it("output contains both branch children", () => {
|
|
242
|
-
const r = new DagRenderer(branchingWorkflow, { animate: false });
|
|
243
|
-
const output = stripAnsi(r.renderToString());
|
|
244
|
-
expect(output).toContain("Create Ticket");
|
|
245
|
-
expect(output).toContain("Skip");
|
|
246
|
-
});
|
|
247
|
-
it("output contains ┴ fork character", () => {
|
|
248
|
-
const r = new DagRenderer(branchingWorkflow, { animate: false });
|
|
249
|
-
const output = stripAnsi(r.renderToString());
|
|
250
|
-
expect(output).toContain("┴");
|
|
251
|
-
});
|
|
252
|
-
it("state tracking works through branches", () => {
|
|
253
|
-
const r = new DagRenderer(branchingWorkflow, { animate: false });
|
|
254
|
-
r.update({ type: "node:enter", node: "gather", instruction: "Gather" });
|
|
255
|
-
r.update({ type: "node:exit", node: "gather", result: { status: "success", data: {}, toolCalls: [] } });
|
|
256
|
-
r.update({ type: "node:enter", node: "investigate", instruction: "Investigate" });
|
|
257
|
-
r.update({ type: "node:exit", node: "investigate", result: { status: "success", data: {}, toolCalls: [] } });
|
|
258
|
-
r.update({ type: "node:enter", node: "create_ticket", instruction: "Create" });
|
|
259
|
-
expect(r.getNodeState("gather")).toBe("completed");
|
|
260
|
-
expect(r.getNodeState("investigate")).toBe("completed");
|
|
261
|
-
expect(r.getNodeState("create_ticket")).toBe("running");
|
|
262
|
-
expect(r.getNodeState("skip")).toBe("pending");
|
|
263
|
-
expect(r.getNodeState("notify")).toBe("pending");
|
|
264
|
-
});
|
|
265
|
-
it("topological order: Gather before Investigate before Notify", () => {
|
|
266
|
-
const r = new DagRenderer(branchingWorkflow, { animate: false });
|
|
267
|
-
const output = stripAnsi(r.renderToString());
|
|
268
|
-
const gatherIdx = output.indexOf("Gather Context");
|
|
269
|
-
const investigateIdx = output.indexOf("Investigate");
|
|
270
|
-
const notifyIdx = output.indexOf("Notify");
|
|
271
|
-
expect(gatherIdx).toBeLessThan(investigateIdx);
|
|
272
|
-
expect(investigateIdx).toBeLessThan(notifyIdx);
|
|
273
|
-
});
|
|
274
|
-
it("falls back to sequential for 3+ children", () => {
|
|
275
|
-
const tripleWorkflow = {
|
|
276
|
-
id: "triple",
|
|
277
|
-
name: "Triple Branch",
|
|
278
|
-
description: "Three-way branch",
|
|
279
|
-
nodes: {
|
|
280
|
-
start: { name: "Start", instruction: "Start", skills: [] },
|
|
281
|
-
a: { name: "Branch A", instruction: "A", skills: [] },
|
|
282
|
-
b: { name: "Branch B", instruction: "B", skills: [] },
|
|
283
|
-
c: { name: "Branch C", instruction: "C", skills: [] },
|
|
284
|
-
},
|
|
285
|
-
edges: [
|
|
286
|
-
{ from: "start", to: "a" },
|
|
287
|
-
{ from: "start", to: "b" },
|
|
288
|
-
{ from: "start", to: "c" },
|
|
289
|
-
],
|
|
290
|
-
entry: "start",
|
|
291
|
-
};
|
|
292
|
-
const r = new DagRenderer(tripleWorkflow, { animate: false });
|
|
293
|
-
const output = stripAnsi(r.renderToString());
|
|
294
|
-
// Should NOT have ┴ fork — sequential fallback
|
|
295
|
-
expect(output).not.toContain("┴");
|
|
296
|
-
// But all branches are present
|
|
297
|
-
expect(output).toContain("Branch A");
|
|
298
|
-
expect(output).toContain("Branch B");
|
|
299
|
-
expect(output).toContain("Branch C");
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
});
|
package/dist/executor.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|