@arbidocs/blocks 0.4.74 → 0.4.76

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 (84) hide show
  1. package/README.md +2 -1
  2. package/dist/agents/index.cjs +267 -254
  3. package/dist/agents/index.js +5 -4
  4. package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
  5. package/dist/agents/tasks/WorkflowThreadStrip.d.ts +38 -1
  6. package/dist/agents/tasks/index.d.ts +2 -1
  7. package/dist/agents/tasks/linkedRuns.d.ts +31 -0
  8. package/dist/agents/workflows/index.d.ts +1 -1
  9. package/dist/agents/workflows/planSteps.d.ts +3 -1
  10. package/dist/agents/workflows/types.d.ts +27 -0
  11. package/dist/{chunk-YWYVIQ7T.js → chunk-22P5KNIM.js} +24 -4
  12. package/dist/chunk-22P5KNIM.js.map +1 -0
  13. package/dist/{chunk-5LP54CWR.cjs → chunk-7FKARMA3.cjs} +175 -69
  14. package/dist/chunk-7FKARMA3.cjs.map +1 -0
  15. package/dist/{chunk-IA7RTPT3.cjs → chunk-IXALYQT7.cjs} +2 -200
  16. package/dist/chunk-IXALYQT7.cjs.map +1 -0
  17. package/dist/chunk-NUNKSZKU.js +203 -0
  18. package/dist/chunk-NUNKSZKU.js.map +1 -0
  19. package/dist/{chunk-6OL5S7MJ.cjs → chunk-NYBIKDWI.cjs} +5 -2
  20. package/dist/chunk-NYBIKDWI.cjs.map +1 -0
  21. package/dist/{chunk-D46ZAPEE.js → chunk-R3PDNQYT.js} +5 -2
  22. package/dist/chunk-R3PDNQYT.js.map +1 -0
  23. package/dist/{chunk-KOSGX3UK.js → chunk-TKB7TVMW.js} +134 -30
  24. package/dist/chunk-TKB7TVMW.js.map +1 -0
  25. package/dist/chunk-V4ISCZJ7.cjs +207 -0
  26. package/dist/chunk-V4ISCZJ7.cjs.map +1 -0
  27. package/dist/{chunk-P2RBE3FD.cjs → chunk-VYRKO3XU.cjs} +24 -3
  28. package/dist/chunk-VYRKO3XU.cjs.map +1 -0
  29. package/dist/{chunk-BUHKUKKB.js → chunk-ZPLG7QYF.js} +4 -199
  30. package/dist/chunk-ZPLG7QYF.js.map +1 -0
  31. package/dist/connect/index.cjs +9 -9
  32. package/dist/connect/index.js +2 -2
  33. package/dist/databases/DatabaseColumnDialog.d.ts +43 -0
  34. package/dist/databases/DatabaseList.d.ts +28 -0
  35. package/dist/databases/DatabaseTable.d.ts +38 -0
  36. package/dist/databases/DatabaseToolbar.d.ts +38 -0
  37. package/dist/databases/NewDatabaseDialog.d.ts +25 -0
  38. package/dist/databases/SelectCellEditor.d.ts +6 -0
  39. package/dist/databases/SelectChip.d.ts +4 -0
  40. package/dist/databases/column-types.d.ts +58 -0
  41. package/dist/databases/databaseColumns.d.ts +28 -0
  42. package/dist/databases/index.cjs +1081 -0
  43. package/dist/databases/index.cjs.map +1 -0
  44. package/dist/databases/index.d.ts +13 -0
  45. package/dist/databases/index.js +1055 -0
  46. package/dist/databases/index.js.map +1 -0
  47. package/dist/facts/index.cjs +8 -7
  48. package/dist/facts/index.cjs.map +1 -1
  49. package/dist/facts/index.js +4 -3
  50. package/dist/facts/index.js.map +1 -1
  51. package/dist/files/index.cjs +15 -14
  52. package/dist/files/index.cjs.map +1 -1
  53. package/dist/files/index.js +5 -3
  54. package/dist/files/index.js.map +1 -1
  55. package/dist/home/index.cjs +1 -1
  56. package/dist/home/index.js +1 -1
  57. package/dist/index.cjs +508 -495
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.js +9 -8
  60. package/dist/index.js.map +1 -1
  61. package/dist/shell/ActionCluster.d.ts +3 -1
  62. package/dist/shell/index.cjs +46 -46
  63. package/dist/shell/index.js +2 -2
  64. package/dist/studio/index.cjs +1 -1
  65. package/dist/studio/index.js +1 -1
  66. package/dist/workflow-canvas/SignalsEditor.d.ts +41 -0
  67. package/dist/workflow-canvas/StepInspector.d.ts +4 -1
  68. package/dist/workflow-canvas/TriggerInspector.d.ts +11 -2
  69. package/dist/workflow-canvas/WorkflowBuilder.d.ts +7 -2
  70. package/dist/workflow-canvas/index.cjs +445 -150
  71. package/dist/workflow-canvas/index.cjs.map +1 -1
  72. package/dist/workflow-canvas/index.d.ts +2 -1
  73. package/dist/workflow-canvas/index.js +412 -124
  74. package/dist/workflow-canvas/index.js.map +1 -1
  75. package/dist/workflow-canvas/trigger.d.ts +20 -1
  76. package/package.json +9 -4
  77. package/dist/chunk-5LP54CWR.cjs.map +0 -1
  78. package/dist/chunk-6OL5S7MJ.cjs.map +0 -1
  79. package/dist/chunk-BUHKUKKB.js.map +0 -1
  80. package/dist/chunk-D46ZAPEE.js.map +0 -1
  81. package/dist/chunk-IA7RTPT3.cjs.map +0 -1
  82. package/dist/chunk-KOSGX3UK.js.map +0 -1
  83. package/dist/chunk-P2RBE3FD.cjs.map +0 -1
  84. package/dist/chunk-YWYVIQ7T.js.map +0 -1
@@ -2,24 +2,25 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkMUMH3Z6K_cjs = require('../chunk-MUMH3Z6K.cjs');
5
- var chunk5LP54CWR_cjs = require('../chunk-5LP54CWR.cjs');
5
+ var chunk7FKARMA3_cjs = require('../chunk-7FKARMA3.cjs');
6
6
  require('../chunk-YJQVLVBJ.cjs');
7
7
  require('../chunk-ZW6FPIFC.cjs');
8
- var chunkP2RBE3FD_cjs = require('../chunk-P2RBE3FD.cjs');
8
+ var chunkVYRKO3XU_cjs = require('../chunk-VYRKO3XU.cjs');
9
9
  require('../chunk-7RGLTF76.cjs');
10
10
  require('../chunk-3AFWGEDJ.cjs');
11
11
  require('../chunk-VFUWWH52.cjs');
12
12
  require('../chunk-DETZZBG2.cjs');
13
- require('../chunk-IA7RTPT3.cjs');
13
+ require('../chunk-V4ISCZJ7.cjs');
14
14
  require('../chunk-2EI7NCUA.cjs');
15
+ require('../chunk-IXALYQT7.cjs');
15
16
  require('../chunk-Z5VUZ6YD.cjs');
16
17
  require('../chunk-7D737FLE.cjs');
17
18
  require('../chunk-OB5F4577.cjs');
19
+ require('../chunk-C54XEN5T.cjs');
18
20
  require('../chunk-B4SRYJLM.cjs');
19
21
  require('../chunk-7UTB4PHM.cjs');
20
22
  require('../chunk-FX3K6LNZ.cjs');
21
23
  require('../chunk-PPCATBOY.cjs');
22
- require('../chunk-C54XEN5T.cjs');
23
24
  require('../chunk-KDG6FER6.cjs');
24
25
  require('../chunk-ULWRNGGE.cjs');
25
26
  require('../chunk-MHVNT4J3.cjs');
@@ -47,11 +48,11 @@ function withSteps(workflow, steps, layout) {
47
48
  const run = workflow.run.kind === "steps" ? workflow.run : { kind: "steps", steps: [] };
48
49
  return {
49
50
  ...workflow,
50
- run: { ...run, steps: chunkP2RBE3FD_cjs.orderSteps(steps), layout: layout ?? run.layout }
51
+ run: { ...run, steps: chunkVYRKO3XU_cjs.orderSteps(steps), layout: layout ?? run.layout }
51
52
  };
52
53
  }
53
54
  var layoutOf = (workflow) => workflow.run.kind === "steps" && workflow.run.layout || {};
54
- var explicit = (steps) => steps.map((s) => ({ ...s, after: chunkP2RBE3FD_cjs.stepDependencies(steps, s.id) }));
55
+ var explicit = (steps) => steps.map((s) => ({ ...s, after: chunkVYRKO3XU_cjs.stepDependencies(steps, s.id) }));
55
56
  function stepIdFor(steps, title) {
56
57
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/^[^a-z]+/, "") || "step";
57
58
  const taken = new Set(steps.map((s) => s.id));
@@ -79,7 +80,7 @@ function blankStep(kind, id, title) {
79
80
  }
80
81
  }
81
82
  function addStep(workflow, kind, options = {}) {
82
- const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
83
+ const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
83
84
  const title = options.title ?? DEFAULT_TITLES[kind];
84
85
  const id = stepIdFor(steps, title);
85
86
  const step = { ...blankStep(kind, id, title), after: options.after ? [options.after] : [] };
@@ -88,7 +89,7 @@ function addStep(workflow, kind, options = {}) {
88
89
  return { workflow: withSteps(workflow, [...steps, step], layout), id };
89
90
  }
90
91
  function removeStep(workflow, id) {
91
- const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
92
+ const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
92
93
  const removed = steps.find((s) => s.id === id);
93
94
  if (!removed) return workflow;
94
95
  const bridged = steps.filter((s) => s.id !== id).map(
@@ -101,8 +102,8 @@ function removeStep(workflow, id) {
101
102
  return withSteps(workflow, bridged, layout);
102
103
  }
103
104
  function connectSteps(workflow, from, to) {
104
- const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
105
- if (from === to || !steps.some((s) => s.id === from) || chunkP2RBE3FD_cjs.dependsOn(steps, from, to)) {
105
+ const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
106
+ if (from === to || !steps.some((s) => s.id === from) || chunkVYRKO3XU_cjs.dependsOn(steps, from, to)) {
106
107
  return workflow;
107
108
  }
108
109
  return withSteps(
@@ -112,16 +113,16 @@ function connectSteps(workflow, from, to) {
112
113
  )
113
114
  );
114
115
  }
115
- var wouldCycle = (workflow, from, to) => from === to || chunkP2RBE3FD_cjs.dependsOn(chunkP2RBE3FD_cjs.workflowSteps(workflow), from, to);
116
+ var wouldCycle = (workflow, from, to) => from === to || chunkVYRKO3XU_cjs.dependsOn(chunkVYRKO3XU_cjs.workflowSteps(workflow), from, to);
116
117
  function disconnectSteps(workflow, from, to) {
117
- const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
118
+ const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
118
119
  return withSteps(
119
120
  workflow,
120
121
  steps.map((s) => s.id === to ? { ...s, after: (s.after ?? []).filter((d) => d !== from) } : s)
121
122
  );
122
123
  }
123
124
  function updateStep(workflow, id, patch) {
124
- const steps = explicit(chunkP2RBE3FD_cjs.workflowSteps(workflow));
125
+ const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
125
126
  return withSteps(
126
127
  workflow,
127
128
  steps.map(
@@ -135,7 +136,7 @@ var renameIn = (text, from, to) => text.replace(
135
136
  );
136
137
  function renameInput(workflow, from, to) {
137
138
  if (from === to) return workflow;
138
- const steps = chunkP2RBE3FD_cjs.workflowSteps(workflow).map((s) => {
139
+ const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow).map((s) => {
139
140
  if (s.kind === "agent")
140
141
  return {
141
142
  ...s,
@@ -149,13 +150,13 @@ function renameInput(workflow, from, to) {
149
150
  return withSteps(workflow, steps);
150
151
  }
151
152
  function moveStep(workflow, id, position) {
152
- return withSteps(workflow, chunkP2RBE3FD_cjs.workflowSteps(workflow), { ...layoutOf(workflow), [id]: position });
153
+ return withSteps(workflow, chunkVYRKO3XU_cjs.workflowSteps(workflow), { ...layoutOf(workflow), [id]: position });
153
154
  }
154
155
  var COLUMN = 300;
155
156
  var ROW = 140;
156
157
  function autoLayout(steps) {
157
158
  const layout = {};
158
- chunkP2RBE3FD_cjs.stepLevels(steps).forEach(
159
+ chunkVYRKO3XU_cjs.stepLevels(steps).forEach(
159
160
  (level, x) => level.forEach((s, y) => {
160
161
  layout[s.id] = { x: x * COLUMN, y: (y - (level.length - 1) / 2) * ROW };
161
162
  })
@@ -163,9 +164,225 @@ function autoLayout(steps) {
163
164
  return layout;
164
165
  }
165
166
  function layoutWithDefaults(workflow) {
166
- const auto = autoLayout(chunkP2RBE3FD_cjs.workflowSteps(workflow));
167
+ const auto = autoLayout(chunkVYRKO3XU_cjs.workflowSteps(workflow));
167
168
  return { ...auto, ...layoutOf(workflow) };
168
169
  }
170
+ var DEFAULT_SIGNALS_EDITOR_LABELS = {
171
+ heading: "When done, signal\u2026",
172
+ hint: "Another workflow can start on a signal (\u201CWhen a step signals\u201D), as its own thread linked to this one.",
173
+ add: "Add signal",
174
+ name: "Signal",
175
+ namePlaceholder: "e.g. risk-high",
176
+ when: "When",
177
+ always: "Whenever it is done",
178
+ fieldEquals: "A field equals",
179
+ answerContains: "The answer contains",
180
+ answerMatches: "The answer matches (regex)",
181
+ approved: "It is approved",
182
+ field: "Field",
183
+ value: "Value",
184
+ phrase: "Phrase",
185
+ phrasePlaceholder: "e.g. Risk rating: High",
186
+ pattern: "Pattern",
187
+ remove: "Remove signal"
188
+ };
189
+ function signalConditions(kind) {
190
+ switch (kind) {
191
+ case "form":
192
+ return ["always", "field"];
193
+ case "agent":
194
+ return ["always", "contains", "matches"];
195
+ case "review":
196
+ return ["approved", "always"];
197
+ default:
198
+ return ["always"];
199
+ }
200
+ }
201
+ function conditionOf(when) {
202
+ if (!when) return "always";
203
+ if ("field" in when) return "field";
204
+ if ("contains" in when) return "contains";
205
+ if ("matches" in when) return "matches";
206
+ return "approved";
207
+ }
208
+ function signalSlug(text) {
209
+ return text.toLowerCase().replace(/[^a-z0-9_.-]+/g, "-").replace(/^[^a-z0-9]+/, "").slice(0, 64);
210
+ }
211
+ function startCondition(kind, step) {
212
+ switch (kind) {
213
+ case "field":
214
+ return { field: step.kind === "form" ? step.inputs[0]?.name ?? "" : "", equals: "" };
215
+ case "contains":
216
+ return { contains: "" };
217
+ case "matches":
218
+ return { matches: "" };
219
+ case "approved":
220
+ return { approved: true };
221
+ default:
222
+ return void 0;
223
+ }
224
+ }
225
+ function newSignal(step, taken) {
226
+ const base = signalSlug(step.id) || "signal";
227
+ let name = `${base}-done`;
228
+ let n = 2;
229
+ while (taken.includes(name)) name = `${base}-done-${n++}`;
230
+ const when = startCondition(signalConditions(step.kind)[0], step);
231
+ return when ? { name, when } : { name };
232
+ }
233
+ var selectClass = "flex h-8 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
234
+ function SignalsEditor({
235
+ step,
236
+ onChange,
237
+ labels,
238
+ testId = "signals-editor"
239
+ }) {
240
+ const l = { ...DEFAULT_SIGNALS_EDITOR_LABELS, ...labels };
241
+ const signals = step.signals ?? [];
242
+ const conditions = signalConditions(step.kind);
243
+ const conditionLabel = {
244
+ always: l.always,
245
+ field: l.fieldEquals,
246
+ contains: l.answerContains,
247
+ matches: l.answerMatches,
248
+ approved: l.approved
249
+ };
250
+ const emit = (next) => onChange(next.length ? next : void 0);
251
+ const set = (i, signal) => emit(signals.map((s, j) => j === i ? signal : s));
252
+ const fields = step.kind === "form" ? step.inputs : [];
253
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", "data-testid": testId, children: [
254
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.heading }),
255
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
256
+ signals.map((signal, i) => {
257
+ const condition = conditionOf(signal.when);
258
+ const when = signal.when;
259
+ return /* @__PURE__ */ jsxRuntime.jsxs(
260
+ "div",
261
+ {
262
+ className: ui.cn(
263
+ "space-y-1.5 rounded-md border p-2",
264
+ chunkVYRKO3XU_cjs.isIncompleteSignal(signal) ? "border-destructive/50" : "border-border"
265
+ ),
266
+ "data-incomplete": chunkVYRKO3XU_cjs.isIncompleteSignal(signal) || void 0,
267
+ "data-testid": `${testId}-${i}`,
268
+ children: [
269
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
270
+ /* @__PURE__ */ jsxRuntime.jsx(
271
+ ui.Input,
272
+ {
273
+ value: signal.name,
274
+ "aria-label": l.name,
275
+ placeholder: l.namePlaceholder,
276
+ onChange: (e) => set(i, { ...signal, name: signalSlug(e.target.value) }),
277
+ className: "h-8 font-mono text-xs",
278
+ "data-testid": `${testId}-${i}-name`
279
+ }
280
+ ),
281
+ /* @__PURE__ */ jsxRuntime.jsx(
282
+ "button",
283
+ {
284
+ type: "button",
285
+ "aria-label": l.remove,
286
+ onClick: () => emit(signals.filter((_, j) => j !== i)),
287
+ "data-testid": `${testId}-${i}-remove`,
288
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4 text-muted-foreground" })
289
+ }
290
+ )
291
+ ] }),
292
+ /* @__PURE__ */ jsxRuntime.jsx(
293
+ "select",
294
+ {
295
+ "aria-label": l.when,
296
+ className: selectClass,
297
+ value: condition,
298
+ onChange: (e) => {
299
+ const nextWhen = startCondition(e.target.value, step);
300
+ set(i, nextWhen ? { name: signal.name, when: nextWhen } : { name: signal.name });
301
+ },
302
+ "data-testid": `${testId}-${i}-when`,
303
+ children: [...conditions, ...conditions.includes(condition) ? [] : [condition]].map(
304
+ (c) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: c, children: conditionLabel[c] }, c)
305
+ )
306
+ }
307
+ ),
308
+ when && "field" in when && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
309
+ /* @__PURE__ */ jsxRuntime.jsxs(
310
+ "select",
311
+ {
312
+ "aria-label": l.field,
313
+ className: ui.cn(selectClass, "flex-1"),
314
+ value: when.field,
315
+ onChange: (e) => set(i, { ...signal, when: { ...when, field: e.target.value } }),
316
+ "data-testid": `${testId}-${i}-field`,
317
+ children: [
318
+ fields.map((f) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: f.name, children: f.label }, f.name)),
319
+ !fields.some((f) => f.name === when.field) && /* @__PURE__ */ jsxRuntime.jsx("option", { value: when.field, children: when.field || "\u2014" })
320
+ ]
321
+ }
322
+ ),
323
+ /* @__PURE__ */ jsxRuntime.jsx(
324
+ ui.Input,
325
+ {
326
+ "aria-label": l.value,
327
+ placeholder: l.value,
328
+ value: String(when.equals),
329
+ onChange: (e) => set(i, { ...signal, when: { ...when, equals: e.target.value } }),
330
+ className: "h-8 flex-1",
331
+ "data-testid": `${testId}-${i}-equals`
332
+ }
333
+ )
334
+ ] }),
335
+ when && "contains" in when && /* @__PURE__ */ jsxRuntime.jsx(
336
+ ui.Input,
337
+ {
338
+ "aria-label": l.phrase,
339
+ placeholder: l.phrasePlaceholder,
340
+ value: when.contains,
341
+ onChange: (e) => set(i, { ...signal, when: { contains: e.target.value } }),
342
+ className: "h-8",
343
+ "data-testid": `${testId}-${i}-contains`
344
+ }
345
+ ),
346
+ when && "matches" in when && /* @__PURE__ */ jsxRuntime.jsx(
347
+ ui.Input,
348
+ {
349
+ "aria-label": l.pattern,
350
+ placeholder: "risk rating:\\s*high",
351
+ value: when.matches,
352
+ onChange: (e) => set(i, { ...signal, when: { matches: e.target.value } }),
353
+ className: "h-8 font-mono text-xs",
354
+ "data-testid": `${testId}-${i}-matches`
355
+ }
356
+ )
357
+ ]
358
+ },
359
+ i
360
+ );
361
+ }),
362
+ /* @__PURE__ */ jsxRuntime.jsxs(
363
+ ui.Button,
364
+ {
365
+ variant: "outline",
366
+ size: "sm",
367
+ onClick: () => emit([
368
+ ...signals,
369
+ newSignal(
370
+ step,
371
+ signals.map((s) => s.name)
372
+ )
373
+ ]),
374
+ "data-testid": `${testId}-add`,
375
+ children: [
376
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "size-4" }),
377
+ " ",
378
+ l.add
379
+ ]
380
+ }
381
+ )
382
+ ] }),
383
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: l.hint })
384
+ ] });
385
+ }
169
386
  var DEFAULT_STEP_INSPECTOR_LABELS = {
170
387
  workflow: "Workflow",
171
388
  title: "Title",
@@ -198,7 +415,7 @@ var DEFAULT_STEP_INSPECTOR_LABELS = {
198
415
  deleteStep: "Delete step"
199
416
  };
200
417
  var FIELD_TYPES = ["text", "longtext", "boolean", "number", "date", "scope"];
201
- var selectClass = "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
418
+ var selectClass2 = "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
202
419
  function Field({ label, children, hint }) {
203
420
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
204
421
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: label }),
@@ -220,10 +437,11 @@ function StepInspector({
220
437
  onSelect,
221
438
  workflows = [],
222
439
  labels,
440
+ signalLabels,
223
441
  testId = "step-inspector"
224
442
  }) {
225
443
  const l = { ...DEFAULT_STEP_INSPECTOR_LABELS, ...labels };
226
- const steps = chunkP2RBE3FD_cjs.workflowSteps(workflow);
444
+ const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
227
445
  const step = steps.find((s) => s.id === stepId);
228
446
  const run = workflow.run.kind === "steps" ? workflow.run : void 0;
229
447
  if (!step || !run) {
@@ -248,7 +466,7 @@ function StepInspector({
248
466
  ] });
249
467
  }
250
468
  const patch = (p) => onChange(updateStep(workflow, step.id, p));
251
- const deps = chunkP2RBE3FD_cjs.stepDependencies(steps, step.id);
469
+ const deps = chunkVYRKO3XU_cjs.stepDependencies(steps, step.id);
252
470
  const titleOf = (id) => steps.find((s) => s.id === id)?.title ?? id;
253
471
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", "data-testid": `${testId}-step`, children: [
254
472
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
@@ -337,7 +555,7 @@ function StepInspector({
337
555
  {
338
556
  step,
339
557
  workflows,
340
- fields: chunkP2RBE3FD_cjs.runFields(workflow).map((f) => f.name),
558
+ fields: chunkVYRKO3XU_cjs.runFields(workflow).map((f) => f.name),
341
559
  patch,
342
560
  l,
343
561
  testId
@@ -352,6 +570,15 @@ function StepInspector({
352
570
  "data-testid": `${testId}-instructions`
353
571
  }
354
572
  ) }),
573
+ /* @__PURE__ */ jsxRuntime.jsx(
574
+ SignalsEditor,
575
+ {
576
+ step,
577
+ onChange: (signals) => patch({ signals }),
578
+ labels: signalLabels,
579
+ testId: `${testId}-signals`
580
+ }
581
+ ),
355
582
  /* @__PURE__ */ jsxRuntime.jsxs(
356
583
  ui.Button,
357
584
  {
@@ -413,7 +640,7 @@ function FormFields({
413
640
  "select",
414
641
  {
415
642
  "aria-label": l.fieldType,
416
- className: ui.cn(selectClass, "h-8"),
643
+ className: ui.cn(selectClass2, "h-8"),
417
644
  value: f.type,
418
645
  onChange: (e) => set(i, { type: e.target.value }),
419
646
  children: FIELD_TYPES.map((t) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: t, children: t }, t))
@@ -480,7 +707,7 @@ function AgentSettings({
480
707
  /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.runs, children: /* @__PURE__ */ jsxRuntime.jsxs(
481
708
  "select",
482
709
  {
483
- className: selectClass,
710
+ className: selectClass2,
484
711
  value,
485
712
  onChange: (e) => {
486
713
  const id = e.target.value;
@@ -537,7 +764,7 @@ function AgentSettings({
537
764
  /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.thread, children: /* @__PURE__ */ jsxRuntime.jsxs(
538
765
  "select",
539
766
  {
540
- className: selectClass,
767
+ className: selectClass2,
541
768
  value: step.branch ? "branch" : "main",
542
769
  onChange: (e) => patch({ branch: e.target.value === "branch" || void 0 }),
543
770
  "data-testid": `${testId}-thread`,
@@ -550,7 +777,7 @@ function AgentSettings({
550
777
  /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.output, children: /* @__PURE__ */ jsxRuntime.jsxs(
551
778
  "select",
552
779
  {
553
- className: selectClass,
780
+ className: selectClass2,
554
781
  value: step.output ?? "answer",
555
782
  onChange: (e) => patch({ output: e.target.value === "artifact" ? "artifact" : void 0 }),
556
783
  children: [
@@ -561,6 +788,138 @@ function AgentSettings({
561
788
  ) })
562
789
  ] });
563
790
  }
791
+
792
+ // src/workflow-canvas/trigger.ts
793
+ var WORKFLOW_SIGNAL_EVENT = "workflow_signal";
794
+ var DEFAULT_WORKFLOW_TRIGGER = {
795
+ start: "manual",
796
+ runAt: "",
797
+ rrule: "",
798
+ timezone: typeof Intl !== "undefined" ? Intl.DateTimeFormat().resolvedOptions().timeZone : "UTC",
799
+ eventKind: "",
800
+ signal: "",
801
+ afterTaskId: "",
802
+ agentId: "",
803
+ access: "ask_each_run"
804
+ };
805
+ function triggerProblem(trigger) {
806
+ if (trigger.start === "once" && !trigger.runAt) return "runAt";
807
+ if (trigger.start === "repeat" && !trigger.rrule.trim()) return "rrule";
808
+ if (trigger.start === "event" && !trigger.eventKind.trim()) return "event";
809
+ if (isSignalTrigger(trigger) && !trigger.signal.trim()) return "signal";
810
+ if (trigger.start === "task" && !trigger.afterTaskId) return "task";
811
+ return null;
812
+ }
813
+ var isSignalTrigger = (trigger) => trigger.start === "event" && trigger.eventKind.trim() === WORKFLOW_SIGNAL_EVENT;
814
+ function eventFilter(trigger) {
815
+ if (trigger.start !== "event") return null;
816
+ if (isSignalTrigger(trigger)) return { signal: trigger.signal.trim() };
817
+ return trigger.eventFilter && Object.keys(trigger.eventFilter).length ? trigger.eventFilter : null;
818
+ }
819
+ function triggerFields(trigger, clearOthers) {
820
+ const none = clearOthers ? null : void 0;
821
+ const filter = eventFilter(trigger);
822
+ return {
823
+ timezone: trigger.timezone,
824
+ rrule: trigger.start === "repeat" ? trigger.rrule.trim() : none,
825
+ run_at: trigger.start === "once" ? chunk7FKARMA3_cjs.localInputToIso(trigger.runAt) : none,
826
+ event_kind: trigger.start === "event" ? trigger.eventKind.trim() : none,
827
+ // A step signal is `workflow_signal` narrowed to one signal name.
828
+ event_filter: filter ?? none,
829
+ after_conversation_ext_id: trigger.start === "task" ? trigger.afterTaskId : none,
830
+ on_demand: trigger.start === "manual"
831
+ };
832
+ }
833
+ var authMode = (trigger) => trigger.start === "manual" ? "run_now_temp" : trigger.access === "standing" ? "scheduled_permanent" : "scheduled_require_auth";
834
+ var withoutUndefined = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
835
+ function plan(value, options) {
836
+ return {
837
+ goal: value.workflow.description,
838
+ criteria: [],
839
+ max_passes: 3,
840
+ documents: [],
841
+ steps: chunkVYRKO3XU_cjs.toPlanSteps(value.workflow, options)
842
+ };
843
+ }
844
+ function builderToWorkflowRequest(value, workspaceId, options = {}) {
845
+ return withoutUndefined({
846
+ workspace_ext_id: workspaceId,
847
+ name: value.workflow.title,
848
+ description: value.workflow.description,
849
+ active: true,
850
+ shared: true,
851
+ ...triggerFields(value.trigger, false),
852
+ prompt: "",
853
+ skill_ref: null,
854
+ skill_inputs: null,
855
+ agent_ext_id: value.trigger.agentId || null,
856
+ auth_mode: authMode(value.trigger),
857
+ plan: plan(value, options)
858
+ });
859
+ }
860
+ function builderToWorkflowUpdate(value, options = {}) {
861
+ return withoutUndefined({
862
+ name: value.workflow.title,
863
+ description: value.workflow.description,
864
+ ...triggerFields(value.trigger, true),
865
+ // The steps are what runs (a classic automation's single prompt or skill becomes its one step).
866
+ prompt: "",
867
+ skill_ref: null,
868
+ skill_inputs: null,
869
+ agent_ext_id: value.trigger.agentId || null,
870
+ auth_mode: authMode(value.trigger),
871
+ plan: plan(value, options)
872
+ });
873
+ }
874
+ function workflowRecordToBuilder(record) {
875
+ const planned = record.plan?.steps ?? [];
876
+ const steps = planned.length ? chunkVYRKO3XU_cjs.fromPlanSteps(planned) : record.prompt || record.skill_ref ? [
877
+ {
878
+ id: "work",
879
+ kind: "agent",
880
+ title: record.name,
881
+ ...record.skill_ref ? { workflow: record.skill_ref } : { run: { kind: "prompt", promptTemplate: record.prompt } }
882
+ }
883
+ ] : [];
884
+ const when = chunk7FKARMA3_cjs.workflowWhen(record);
885
+ return {
886
+ workflow: {
887
+ id: record.external_id,
888
+ title: record.name,
889
+ description: record.description ?? "",
890
+ inputs: [],
891
+ landing: "chat",
892
+ schedulable: false,
893
+ run: { kind: "steps", steps, layout: chunkVYRKO3XU_cjs.layoutFromPlanSteps(planned ?? []) }
894
+ },
895
+ trigger: {
896
+ ...DEFAULT_WORKFLOW_TRIGGER,
897
+ start: when === "now" ? "manual" : when,
898
+ runAt: chunk7FKARMA3_cjs.isoToLocalInput(record.run_at),
899
+ rrule: record.rrule ?? "",
900
+ timezone: record.timezone || DEFAULT_WORKFLOW_TRIGGER.timezone,
901
+ eventKind: record.event_kind ?? "",
902
+ signal: record.event_kind === WORKFLOW_SIGNAL_EVENT && typeof record.event_filter?.signal === "string" ? record.event_filter.signal : "",
903
+ eventFilter: record.event_kind && record.event_kind !== WORKFLOW_SIGNAL_EVENT && record.event_filter ? record.event_filter : void 0,
904
+ afterTaskId: record.after_conversation_ext_id ?? "",
905
+ agentId: record.agent_ext_id ?? "",
906
+ access: record.auth_mode === "scheduled_permanent" ? "standing" : "ask_each_run"
907
+ }
908
+ };
909
+ }
910
+ function declaredSignals(records, current) {
911
+ const out = /* @__PURE__ */ new Map();
912
+ const add = (workflow, steps) => {
913
+ for (const step of steps)
914
+ for (const signal of step.signals ?? [])
915
+ if (signal.name && !out.has(signal.name))
916
+ out.set(signal.name, { value: signal.name, label: `${workflow} \u203A ${step.title}` });
917
+ };
918
+ for (const record of records)
919
+ add(record.name, record.plan?.steps ?? []);
920
+ if (current?.run.kind === "steps") add(current.title, current.run.steps);
921
+ return [...out.values()];
922
+ }
564
923
  var DEFAULT_TRIGGER_INSPECTOR_LABELS = {
565
924
  heading: "Start",
566
925
  start: "Starts",
@@ -574,6 +933,11 @@ var DEFAULT_TRIGGER_INSPECTOR_LABELS = {
574
933
  runAt: "When",
575
934
  event: "Event",
576
935
  eventPlaceholder: "Pick an event",
936
+ stepSignals: "When a step signals",
937
+ signal: "Signal",
938
+ signalPlaceholder: "e.g. risk-high",
939
+ signalHint: "Starts as its own thread, linked to the thread whose step raised it, with that run\u2019s inputs.",
940
+ signalSummary: "When a step signals \u201C{signal}\u201D",
577
941
  afterTask: "After this task",
578
942
  afterTaskPlaceholder: "Pick a task",
579
943
  agent: "Runs as",
@@ -587,8 +951,10 @@ function triggerSummary(trigger, options = {}) {
587
951
  case "once":
588
952
  return trigger.runAt ? new Date(trigger.runAt).toLocaleString() : l.starts.once;
589
953
  case "repeat":
590
- return trigger.rrule ? chunk5LP54CWR_cjs.describeRRule(trigger.rrule) : l.starts.repeat;
954
+ return trigger.rrule ? chunk7FKARMA3_cjs.describeRRule(trigger.rrule) : l.starts.repeat;
591
955
  case "event":
956
+ if (isSignalTrigger(trigger))
957
+ return trigger.signal ? l.signalSummary.replace("{signal}", trigger.signal) : l.stepSignals;
592
958
  return trigger.eventKind && options.eventLabel?.(trigger.eventKind) || trigger.eventKind || l.starts.event;
593
959
  case "task":
594
960
  return trigger.afterTaskId && options.taskLabel?.(trigger.afterTaskId) || l.starts.task;
@@ -596,7 +962,7 @@ function triggerSummary(trigger, options = {}) {
596
962
  return l.starts.manual;
597
963
  }
598
964
  }
599
- var selectClass2 = "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
965
+ var selectClass3 = "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
600
966
  var STARTS = ["manual", "once", "repeat", "event", "task"];
601
967
  function TriggerInspector({
602
968
  trigger,
@@ -604,11 +970,13 @@ function TriggerInspector({
604
970
  agents = [],
605
971
  eventKinds = [],
606
972
  tasks = [],
973
+ signals = [],
607
974
  labels,
608
975
  testId = "trigger-inspector"
609
976
  }) {
610
977
  const l = { ...DEFAULT_TRIGGER_INSPECTOR_LABELS, ...labels };
611
978
  const set = (patch) => onChange({ ...trigger, ...patch });
979
+ const events = eventKinds.some((k) => k.value === WORKFLOW_SIGNAL_EVENT) ? eventKinds : [...eventKinds, { value: WORKFLOW_SIGNAL_EVENT, label: l.stepSignals }];
612
980
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", "data-testid": testId, children: [
613
981
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold", children: l.heading }),
614
982
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
@@ -642,29 +1010,45 @@ function TriggerInspector({
642
1010
  }
643
1011
  )
644
1012
  ] }),
645
- trigger.start === "repeat" && /* @__PURE__ */ jsxRuntime.jsx(chunk5LP54CWR_cjs.RecurrenceBuilder, { rrule: trigger.rrule, onChange: (rrule) => set({ rrule }) }),
1013
+ trigger.start === "repeat" && /* @__PURE__ */ jsxRuntime.jsx(chunk7FKARMA3_cjs.RecurrenceBuilder, { rrule: trigger.rrule, onChange: (rrule) => set({ rrule }) }),
646
1014
  trigger.start === "event" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
647
1015
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.event }),
648
1016
  /* @__PURE__ */ jsxRuntime.jsxs(
649
1017
  "select",
650
1018
  {
651
- className: selectClass2,
1019
+ className: selectClass3,
652
1020
  value: trigger.eventKind,
653
- onChange: (e) => set({ eventKind: e.target.value }),
1021
+ onChange: (e) => set({ eventKind: e.target.value, eventFilter: void 0 }),
654
1022
  "data-testid": `${testId}-event`,
655
1023
  children: [
656
1024
  /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: l.eventPlaceholder }),
657
- eventKinds.map((k) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: k.value, children: k.label }, k.value))
1025
+ events.map((k) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: k.value, children: k.label }, k.value))
658
1026
  ]
659
1027
  }
660
1028
  )
661
1029
  ] }),
1030
+ isSignalTrigger(trigger) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
1031
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", htmlFor: `${testId}-signal`, children: l.signal }),
1032
+ /* @__PURE__ */ jsxRuntime.jsx(
1033
+ ui.Input,
1034
+ {
1035
+ id: `${testId}-signal`,
1036
+ list: `${testId}-signal-options`,
1037
+ value: trigger.signal,
1038
+ placeholder: l.signalPlaceholder,
1039
+ onChange: (e) => set({ signal: e.target.value.trim().toLowerCase() }),
1040
+ "data-testid": `${testId}-signal`
1041
+ }
1042
+ ),
1043
+ /* @__PURE__ */ jsxRuntime.jsx("datalist", { id: `${testId}-signal-options`, children: signals.map((s) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: s.value, children: s.label }, s.value)) }),
1044
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: l.signalHint })
1045
+ ] }),
662
1046
  trigger.start === "task" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
663
1047
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.afterTask }),
664
1048
  /* @__PURE__ */ jsxRuntime.jsxs(
665
1049
  "select",
666
1050
  {
667
- className: selectClass2,
1051
+ className: selectClass3,
668
1052
  value: trigger.afterTaskId,
669
1053
  onChange: (e) => set({ afterTaskId: e.target.value }),
670
1054
  "data-testid": `${testId}-after-task`,
@@ -678,7 +1062,7 @@ function TriggerInspector({
678
1062
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
679
1063
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.agent }),
680
1064
  /* @__PURE__ */ jsxRuntime.jsx(
681
- chunk5LP54CWR_cjs.AgentSelect,
1065
+ chunk7FKARMA3_cjs.AgentSelect,
682
1066
  {
683
1067
  agents,
684
1068
  value: trigger.agentId,
@@ -693,7 +1077,7 @@ function TriggerInspector({
693
1077
  /* @__PURE__ */ jsxRuntime.jsxs(
694
1078
  "select",
695
1079
  {
696
- className: selectClass2,
1080
+ className: selectClass3,
697
1081
  value: trigger.access,
698
1082
  onChange: (e) => set({ access: e.target.value === "standing" ? "standing" : "ask_each_run" }),
699
1083
  "data-testid": `${testId}-access`,
@@ -927,12 +1311,12 @@ function WorkflowCanvas({
927
1311
  testId = "workflow-canvas"
928
1312
  }) {
929
1313
  const l = react.useMemo(() => ({ ...DEFAULT_WORKFLOW_CANVAS_LABELS, ...labels }), [labels]);
930
- const steps = chunkP2RBE3FD_cjs.workflowSteps(workflow);
1314
+ const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
931
1315
  const editable = !!onChange;
932
1316
  const built = react.useMemo(() => {
933
1317
  const layout = layoutWithDefaults(workflow);
934
- const all = chunkP2RBE3FD_cjs.workflowSteps(workflow);
935
- const roots = all.filter((s) => chunkP2RBE3FD_cjs.stepDependencies(all, s.id).length === 0);
1318
+ const all = chunkVYRKO3XU_cjs.workflowSteps(workflow);
1319
+ const roots = all.filter((s) => chunkVYRKO3XU_cjs.stepDependencies(all, s.id).length === 0);
936
1320
  const triggerNode = trigger ? [
937
1321
  {
938
1322
  id: TRIGGER_NODE,
@@ -969,7 +1353,7 @@ function WorkflowCanvas({
969
1353
  react.useEffect(() => setNodes(built), [built]);
970
1354
  const edges = react.useMemo(
971
1355
  () => steps.flatMap((s) => {
972
- const deps = chunkP2RBE3FD_cjs.stepDependencies(steps, s.id);
1356
+ const deps = chunkVYRKO3XU_cjs.stepDependencies(steps, s.id);
973
1357
  const from = deps.length ? deps : trigger ? [TRIGGER_NODE] : [];
974
1358
  return from.map((d) => ({
975
1359
  id: `${d}->${s.id}`,
@@ -1189,6 +1573,7 @@ function WorkflowBuilder({
1189
1573
  agents = [],
1190
1574
  eventKinds = [],
1191
1575
  tasks = [],
1576
+ signals = [],
1192
1577
  compose,
1193
1578
  renderIcon,
1194
1579
  actions,
@@ -1209,8 +1594,8 @@ function WorkflowBuilder({
1209
1594
  const [mode, setMode] = react.useState("design");
1210
1595
  const [adding, setAdding] = react.useState(false);
1211
1596
  const { workflow, trigger } = value;
1212
- const steps = chunkP2RBE3FD_cjs.workflowSteps(workflow);
1213
- const problems = chunkP2RBE3FD_cjs.validateWorkflowGraph(steps);
1597
+ const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
1598
+ const problems = chunkVYRKO3XU_cjs.validateWorkflowGraph(steps);
1214
1599
  const titles = react.useMemo(() => new Map(workflows.map((w) => [w.id, w.title])), [workflows]);
1215
1600
  const setWorkflow = (next) => onChange({ ...value, workflow: next });
1216
1601
  const addAfter = (from, kind) => {
@@ -1371,6 +1756,12 @@ function WorkflowBuilder({
1371
1756
  agents,
1372
1757
  eventKinds,
1373
1758
  tasks,
1759
+ signals: [
1760
+ ...signals,
1761
+ ...declaredSignals([], workflow).filter(
1762
+ (d) => !signals.some((s) => s.value === d.value)
1763
+ )
1764
+ ],
1374
1765
  labels: triggerLabels,
1375
1766
  testId: `${testId}-trigger`
1376
1767
  }
@@ -1425,13 +1816,13 @@ function WorkflowPreview({
1425
1816
  renderIcon,
1426
1817
  testId
1427
1818
  }) {
1428
- const run = chunk5LP54CWR_cjs.useWorkflowPreview(workflow, {
1819
+ const run = chunk7FKARMA3_cjs.useWorkflowPreview(workflow, {
1429
1820
  resolveWorkflow: (id) => workflows.find((w) => w.id === id),
1430
1821
  compose,
1431
1822
  answer
1432
1823
  });
1433
1824
  return /* @__PURE__ */ jsxRuntime.jsx(
1434
- chunkP2RBE3FD_cjs.WorkflowRunner,
1825
+ chunkVYRKO3XU_cjs.WorkflowRunner,
1435
1826
  {
1436
1827
  workflow,
1437
1828
  run,
@@ -1448,111 +1839,6 @@ function WorkflowPreview({
1448
1839
  }
1449
1840
  );
1450
1841
  }
1451
-
1452
- // src/workflow-canvas/trigger.ts
1453
- var DEFAULT_WORKFLOW_TRIGGER = {
1454
- start: "manual",
1455
- runAt: "",
1456
- rrule: "",
1457
- timezone: typeof Intl !== "undefined" ? Intl.DateTimeFormat().resolvedOptions().timeZone : "UTC",
1458
- eventKind: "",
1459
- afterTaskId: "",
1460
- agentId: "",
1461
- access: "ask_each_run"
1462
- };
1463
- function triggerProblem(trigger) {
1464
- if (trigger.start === "once" && !trigger.runAt) return "runAt";
1465
- if (trigger.start === "repeat" && !trigger.rrule.trim()) return "rrule";
1466
- if (trigger.start === "event" && !trigger.eventKind.trim()) return "event";
1467
- if (trigger.start === "task" && !trigger.afterTaskId) return "task";
1468
- return null;
1469
- }
1470
- function triggerFields(trigger, clearOthers) {
1471
- const none = clearOthers ? null : void 0;
1472
- return {
1473
- timezone: trigger.timezone,
1474
- rrule: trigger.start === "repeat" ? trigger.rrule.trim() : none,
1475
- run_at: trigger.start === "once" ? chunk5LP54CWR_cjs.localInputToIso(trigger.runAt) : none,
1476
- event_kind: trigger.start === "event" ? trigger.eventKind.trim() : none,
1477
- after_conversation_ext_id: trigger.start === "task" ? trigger.afterTaskId : none,
1478
- on_demand: trigger.start === "manual"
1479
- };
1480
- }
1481
- var authMode = (trigger) => trigger.start === "manual" ? "run_now_temp" : trigger.access === "standing" ? "scheduled_permanent" : "scheduled_require_auth";
1482
- var withoutUndefined = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
1483
- function plan(value, options) {
1484
- return {
1485
- goal: value.workflow.description,
1486
- criteria: [],
1487
- max_passes: 3,
1488
- documents: [],
1489
- steps: chunkP2RBE3FD_cjs.toPlanSteps(value.workflow, options)
1490
- };
1491
- }
1492
- function builderToWorkflowRequest(value, workspaceId, options = {}) {
1493
- return withoutUndefined({
1494
- workspace_ext_id: workspaceId,
1495
- name: value.workflow.title,
1496
- description: value.workflow.description,
1497
- active: true,
1498
- shared: true,
1499
- ...triggerFields(value.trigger, false),
1500
- prompt: "",
1501
- skill_ref: null,
1502
- skill_inputs: null,
1503
- agent_ext_id: value.trigger.agentId || null,
1504
- auth_mode: authMode(value.trigger),
1505
- plan: plan(value, options)
1506
- });
1507
- }
1508
- function builderToWorkflowUpdate(value, options = {}) {
1509
- return withoutUndefined({
1510
- name: value.workflow.title,
1511
- description: value.workflow.description,
1512
- ...triggerFields(value.trigger, true),
1513
- // The steps are what runs (a classic automation's single prompt or skill becomes its one step).
1514
- prompt: "",
1515
- skill_ref: null,
1516
- skill_inputs: null,
1517
- agent_ext_id: value.trigger.agentId || null,
1518
- auth_mode: authMode(value.trigger),
1519
- plan: plan(value, options)
1520
- });
1521
- }
1522
- function workflowRecordToBuilder(record) {
1523
- const planned = record.plan?.steps ?? [];
1524
- const steps = planned.length ? chunkP2RBE3FD_cjs.fromPlanSteps(planned) : record.prompt || record.skill_ref ? [
1525
- {
1526
- id: "work",
1527
- kind: "agent",
1528
- title: record.name,
1529
- ...record.skill_ref ? { workflow: record.skill_ref } : { run: { kind: "prompt", promptTemplate: record.prompt } }
1530
- }
1531
- ] : [];
1532
- const when = chunk5LP54CWR_cjs.workflowWhen(record);
1533
- return {
1534
- workflow: {
1535
- id: record.external_id,
1536
- title: record.name,
1537
- description: record.description ?? "",
1538
- inputs: [],
1539
- landing: "chat",
1540
- schedulable: false,
1541
- run: { kind: "steps", steps, layout: chunkP2RBE3FD_cjs.layoutFromPlanSteps(planned ?? []) }
1542
- },
1543
- trigger: {
1544
- ...DEFAULT_WORKFLOW_TRIGGER,
1545
- start: when === "now" ? "manual" : when,
1546
- runAt: chunk5LP54CWR_cjs.isoToLocalInput(record.run_at),
1547
- rrule: record.rrule ?? "",
1548
- timezone: record.timezone || DEFAULT_WORKFLOW_TRIGGER.timezone,
1549
- eventKind: record.event_kind ?? "",
1550
- afterTaskId: record.after_conversation_ext_id ?? "",
1551
- agentId: record.agent_ext_id ?? "",
1552
- access: record.auth_mode === "scheduled_permanent" ? "standing" : "ask_each_run"
1553
- }
1554
- };
1555
- }
1556
1842
  var DEFAULT_CONNECTED_WORKFLOW_BUILDER_LABELS = {
1557
1843
  save: "Save",
1558
1844
  saving: "Saving\u2026",
@@ -1565,7 +1851,8 @@ var DEFAULT_WORKFLOW_EVENT_KINDS = [
1565
1851
  { value: "conversation_ready", label: "Work is ready for me" },
1566
1852
  { value: "mention", label: "Someone mentions me" },
1567
1853
  { value: "workflow_completed", label: "Another workflow finishes" },
1568
- { value: "workflow_failed", label: "Another workflow fails" }
1854
+ { value: "workflow_failed", label: "Another workflow fails" },
1855
+ { value: "workflow_signal", label: "When a step signals" }
1569
1856
  ];
1570
1857
  function ConnectedWorkflowBuilder({
1571
1858
  workflowId,
@@ -1604,7 +1891,7 @@ function ConnectedWorkflowBuilder({
1604
1891
  () => [
1605
1892
  ...hostWorkflows,
1606
1893
  ...(skills.data ?? []).map(
1607
- (s) => chunkP2RBE3FD_cjs.skillToWorkflow({
1894
+ (s) => chunkVYRKO3XU_cjs.skillToWorkflow({
1608
1895
  name: s.name,
1609
1896
  slug: s.slug,
1610
1897
  description: s.description,
@@ -1620,7 +1907,7 @@ function ConnectedWorkflowBuilder({
1620
1907
  }));
1621
1908
  const tasks = (conversations.data ?? []).filter((c) => c.status && c.status !== "done").map((c) => ({ value: c.external_id, label: c.title || c.external_id }));
1622
1909
  const options = { resolveWorkflow: (wid) => workflows.find((w) => w.id === wid), compose };
1623
- const problem = triggerProblem(value.trigger) ?? (chunkP2RBE3FD_cjs.validateWorkflowGraph(chunkP2RBE3FD_cjs.workflowSteps(value.workflow)).length ? "graph" : null);
1910
+ const problem = triggerProblem(value.trigger) ?? (chunkVYRKO3XU_cjs.validateWorkflowGraph(chunkVYRKO3XU_cjs.workflowSteps(value.workflow)).length ? "graph" : null);
1624
1911
  const busy = create.isPending || update.isPending || run.isPending;
1625
1912
  const save = async () => {
1626
1913
  if (!workspaceId) return void 0;
@@ -1642,6 +1929,7 @@ function ConnectedWorkflowBuilder({
1642
1929
  agents,
1643
1930
  eventKinds,
1644
1931
  tasks,
1932
+ signals: declaredSignals(saved.data ?? []),
1645
1933
  compose,
1646
1934
  testId,
1647
1935
  actions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -1688,15 +1976,18 @@ function ConnectedWorkflowBuilder({
1688
1976
 
1689
1977
  exports.ConnectedWorkflowBuilder = ConnectedWorkflowBuilder;
1690
1978
  exports.DEFAULT_CONNECTED_WORKFLOW_BUILDER_LABELS = DEFAULT_CONNECTED_WORKFLOW_BUILDER_LABELS;
1979
+ exports.DEFAULT_SIGNALS_EDITOR_LABELS = DEFAULT_SIGNALS_EDITOR_LABELS;
1691
1980
  exports.DEFAULT_STEP_INSPECTOR_LABELS = DEFAULT_STEP_INSPECTOR_LABELS;
1692
1981
  exports.DEFAULT_TRIGGER_INSPECTOR_LABELS = DEFAULT_TRIGGER_INSPECTOR_LABELS;
1693
1982
  exports.DEFAULT_WORKFLOW_BUILDER_LABELS = DEFAULT_WORKFLOW_BUILDER_LABELS;
1694
1983
  exports.DEFAULT_WORKFLOW_CANVAS_LABELS = DEFAULT_WORKFLOW_CANVAS_LABELS;
1695
1984
  exports.DEFAULT_WORKFLOW_EVENT_KINDS = DEFAULT_WORKFLOW_EVENT_KINDS;
1696
1985
  exports.DEFAULT_WORKFLOW_TRIGGER = DEFAULT_WORKFLOW_TRIGGER;
1986
+ exports.SignalsEditor = SignalsEditor;
1697
1987
  exports.StepInspector = StepInspector;
1698
1988
  exports.TRIGGER_NODE = TRIGGER_NODE;
1699
1989
  exports.TriggerInspector = TriggerInspector;
1990
+ exports.WORKFLOW_SIGNAL_EVENT = WORKFLOW_SIGNAL_EVENT;
1700
1991
  exports.WorkflowBuilder = WorkflowBuilder;
1701
1992
  exports.WorkflowCanvas = WorkflowCanvas;
1702
1993
  exports.addStep = addStep;
@@ -1704,11 +1995,15 @@ exports.autoLayout = autoLayout;
1704
1995
  exports.builderToWorkflowRequest = builderToWorkflowRequest;
1705
1996
  exports.builderToWorkflowUpdate = builderToWorkflowUpdate;
1706
1997
  exports.connectSteps = connectSteps;
1998
+ exports.declaredSignals = declaredSignals;
1707
1999
  exports.disconnectSteps = disconnectSteps;
2000
+ exports.isSignalTrigger = isSignalTrigger;
1708
2001
  exports.layoutWithDefaults = layoutWithDefaults;
1709
2002
  exports.moveStep = moveStep;
1710
2003
  exports.newSteppedWorkflow = newSteppedWorkflow;
1711
2004
  exports.removeStep = removeStep;
2005
+ exports.signalConditions = signalConditions;
2006
+ exports.signalSlug = signalSlug;
1712
2007
  exports.stepIdFor = stepIdFor;
1713
2008
  exports.triggerProblem = triggerProblem;
1714
2009
  exports.triggerSummary = triggerSummary;