@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.
Files changed (119) hide show
  1. package/dist/browser.d.ts +11 -5
  2. package/dist/browser.js +11 -11
  3. package/dist/claude.d.ts +16 -0
  4. package/dist/claude.js +98 -9
  5. package/dist/cli/config.d.ts +22 -0
  6. package/dist/cli/config.js +56 -9
  7. package/dist/cli/main.d.ts +1 -1
  8. package/dist/cli/main.js +56 -57
  9. package/dist/cli/marketplace.js +35 -9
  10. package/dist/cli/publish.d.ts +10 -0
  11. package/dist/cli/publish.js +22 -14
  12. package/dist/loader.d.ts +40 -0
  13. package/dist/loader.js +73 -0
  14. package/dist/mcp-catalog.d.ts +47 -0
  15. package/dist/mcp-catalog.js +304 -0
  16. package/dist/mcp.d.ts +6 -9
  17. package/dist/mcp.js +24 -314
  18. package/dist/schema.d.ts +183 -151
  19. package/dist/schema.js +49 -7
  20. package/dist/skills/custom-loader.d.ts +40 -0
  21. package/dist/skills/custom-loader.js +107 -32
  22. package/dist/skills/index.d.ts +13 -1
  23. package/dist/skills/index.js +12 -3
  24. package/dist/studio.js +4 -1
  25. package/dist/templates.d.ts +29 -8
  26. package/dist/templates.js +30 -20
  27. package/dist/types.d.ts +12 -0
  28. package/dist/verify.js +42 -4
  29. package/package.json +8 -4
  30. package/dist/__tests__/cascade.test.d.ts +0 -11
  31. package/dist/__tests__/cascade.test.js +0 -452
  32. package/dist/__tests__/claude.test.d.ts +0 -1
  33. package/dist/__tests__/claude.test.js +0 -427
  34. package/dist/__tests__/custom-loader.test.d.ts +0 -1
  35. package/dist/__tests__/custom-loader.test.js +0 -116
  36. package/dist/__tests__/executor.test.d.ts +0 -1
  37. package/dist/__tests__/executor.test.js +0 -1635
  38. package/dist/__tests__/integration/datadog.integration.test.d.ts +0 -1
  39. package/dist/__tests__/integration/datadog.integration.test.js +0 -23
  40. package/dist/__tests__/integration/e2e-workflow.integration.test.d.ts +0 -1
  41. package/dist/__tests__/integration/e2e-workflow.integration.test.js +0 -75
  42. package/dist/__tests__/integration/github.integration.test.d.ts +0 -1
  43. package/dist/__tests__/integration/github.integration.test.js +0 -37
  44. package/dist/__tests__/integration/harness.d.ts +0 -24
  45. package/dist/__tests__/integration/harness.js +0 -34
  46. package/dist/__tests__/integration/linear.integration.test.d.ts +0 -1
  47. package/dist/__tests__/integration/linear.integration.test.js +0 -15
  48. package/dist/__tests__/integration/sentry.integration.test.d.ts +0 -1
  49. package/dist/__tests__/integration/sentry.integration.test.js +0 -20
  50. package/dist/__tests__/integration/slack.integration.test.d.ts +0 -1
  51. package/dist/__tests__/integration/slack.integration.test.js +0 -22
  52. package/dist/__tests__/integration/sources.integration.test.d.ts +0 -1
  53. package/dist/__tests__/integration/sources.integration.test.js +0 -123
  54. package/dist/__tests__/publish.test.d.ts +0 -1
  55. package/dist/__tests__/publish.test.js +0 -180
  56. package/dist/__tests__/requires.test.d.ts +0 -1
  57. package/dist/__tests__/requires.test.js +0 -82
  58. package/dist/__tests__/retry.test.d.ts +0 -1
  59. package/dist/__tests__/retry.test.js +0 -213
  60. package/dist/__tests__/schema.test.d.ts +0 -1
  61. package/dist/__tests__/schema.test.js +0 -600
  62. package/dist/__tests__/skill-config-integration.test.d.ts +0 -1
  63. package/dist/__tests__/skill-config-integration.test.js +0 -204
  64. package/dist/__tests__/skills-index.test.d.ts +0 -1
  65. package/dist/__tests__/skills-index.test.js +0 -119
  66. package/dist/__tests__/skills.test.d.ts +0 -1
  67. package/dist/__tests__/skills.test.js +0 -565
  68. package/dist/__tests__/spec-conformance.test.d.ts +0 -18
  69. package/dist/__tests__/spec-conformance.test.js +0 -1084
  70. package/dist/__tests__/studio.test.d.ts +0 -1
  71. package/dist/__tests__/studio.test.js +0 -403
  72. package/dist/__tests__/templates.test.d.ts +0 -1
  73. package/dist/__tests__/templates.test.js +0 -49
  74. package/dist/__tests__/testing.test.d.ts +0 -1
  75. package/dist/__tests__/testing.test.js +0 -242
  76. package/dist/__tests__/verify.test.d.ts +0 -1
  77. package/dist/__tests__/verify.test.js +0 -517
  78. package/dist/__tests__/version-consistency.test.d.ts +0 -1
  79. package/dist/__tests__/version-consistency.test.js +0 -312
  80. package/dist/__tests__/workflow-builder.test.d.ts +0 -1
  81. package/dist/__tests__/workflow-builder.test.js +0 -110
  82. package/dist/__tests__/workflow-yaml.test.d.ts +0 -1
  83. package/dist/__tests__/workflow-yaml.test.js +0 -201
  84. package/dist/cli/__tests__/diagram.test.d.ts +0 -1
  85. package/dist/cli/__tests__/diagram.test.js +0 -225
  86. package/dist/cli/__tests__/report-cloud.test.d.ts +0 -1
  87. package/dist/cli/__tests__/report-cloud.test.js +0 -165
  88. package/dist/cli/__tests__/upgrade.test.d.ts +0 -1
  89. package/dist/cli/__tests__/upgrade.test.js +0 -317
  90. package/dist/cli/__tests__/version-check.test.d.ts +0 -1
  91. package/dist/cli/__tests__/version-check.test.js +0 -209
  92. package/dist/cli/config.test.d.ts +0 -1
  93. package/dist/cli/config.test.js +0 -200
  94. package/dist/cli/credentials.test.d.ts +0 -1
  95. package/dist/cli/credentials.test.js +0 -172
  96. package/dist/cli/e2e.test.d.ts +0 -1
  97. package/dist/cli/e2e.test.js +0 -690
  98. package/dist/cli/marketplace.test.d.ts +0 -1
  99. package/dist/cli/marketplace.test.js +0 -355
  100. package/dist/cli/new.test.d.ts +0 -1
  101. package/dist/cli/new.test.js +0 -1043
  102. package/dist/cli/output.test.d.ts +0 -1
  103. package/dist/cli/output.test.js +0 -180
  104. package/dist/cli/publish.test.d.ts +0 -1
  105. package/dist/cli/publish.test.js +0 -610
  106. package/dist/cli/renderer.test.d.ts +0 -1
  107. package/dist/cli/renderer.test.js +0 -302
  108. package/dist/executor.test.d.ts +0 -1
  109. package/dist/executor.test.js +0 -618
  110. package/dist/mcp.test.d.ts +0 -1
  111. package/dist/mcp.test.js +0 -735
  112. package/dist/mermaid.test.d.ts +0 -1
  113. package/dist/mermaid.test.js +0 -256
  114. package/dist/sources.test.d.ts +0 -1
  115. package/dist/sources.test.js +0 -265
  116. package/dist/sources.validation.test.d.ts +0 -12
  117. package/dist/sources.validation.test.js +0 -380
  118. package/dist/workflow-builder.test.d.ts +0 -1
  119. 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
- });
@@ -1 +0,0 @@
1
- export {};