@arbidocs/blocks 0.4.76 → 0.4.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 (123) hide show
  1. package/dist/agents/index.cjs +346 -258
  2. package/dist/agents/index.js +5 -5
  3. package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
  4. package/dist/agents/tasks/WorkflowThreadStrip.d.ts +15 -4
  5. package/dist/agents/workflows/SchemaForm.d.ts +6 -1
  6. package/dist/agents/workflows/StepBarFrame.d.ts +75 -0
  7. package/dist/agents/workflows/StepParts.d.ts +109 -0
  8. package/dist/agents/workflows/WorkflowRunner.d.ts +15 -2
  9. package/dist/agents/workflows/WorkflowStepBar.d.ts +9 -11
  10. package/dist/agents/workflows/index.d.ts +5 -2
  11. package/dist/agents/workflows/planSteps.d.ts +8 -1
  12. package/dist/agents/workflows/run.d.ts +61 -8
  13. package/dist/agents/workflows/stepWindow.d.ts +59 -0
  14. package/dist/agents/workflows/types.d.ts +133 -4
  15. package/dist/agents/workflows/useWorkflowPreview.d.ts +2 -1
  16. package/dist/agents/workflows/useWorkflowView.d.ts +19 -0
  17. package/dist/chat/ChatPage.d.ts +1 -1
  18. package/dist/chat/WorkflowStepChip.d.ts +24 -0
  19. package/dist/chat/chat-page-types.d.ts +9 -0
  20. package/dist/chat/index.cjs +130 -122
  21. package/dist/chat/index.d.ts +1 -0
  22. package/dist/chat/index.js +2 -2
  23. package/dist/{chunk-TKB7TVMW.js → chunk-5OC5CGYX.js} +168 -100
  24. package/dist/chunk-5OC5CGYX.js.map +1 -0
  25. package/dist/{chunk-ZWA7UUZL.cjs → chunk-7YUFMNFW.cjs} +2 -54
  26. package/dist/chunk-7YUFMNFW.cjs.map +1 -0
  27. package/dist/chunk-A24C6BNA.js +92 -0
  28. package/dist/chunk-A24C6BNA.js.map +1 -0
  29. package/dist/chunk-AINNADMT.cjs +62 -0
  30. package/dist/chunk-AINNADMT.cjs.map +1 -0
  31. package/dist/chunk-CWAZNXC5.js +441 -0
  32. package/dist/chunk-CWAZNXC5.js.map +1 -0
  33. package/dist/{chunk-UIWLDSTF.js → chunk-EWSEQEPL.js} +71 -7
  34. package/dist/chunk-EWSEQEPL.js.map +1 -0
  35. package/dist/chunk-FE4ULGOR.js +151 -0
  36. package/dist/chunk-FE4ULGOR.js.map +1 -0
  37. package/dist/chunk-FT5FFXSJ.js +60 -0
  38. package/dist/chunk-FT5FFXSJ.js.map +1 -0
  39. package/dist/{chunk-WJEKRSPH.js → chunk-ICBAFX5B.js} +3 -3
  40. package/dist/{chunk-WJEKRSPH.js.map → chunk-ICBAFX5B.js.map} +1 -1
  41. package/dist/{chunk-7CVF3DK2.cjs → chunk-IF6VAYIA.cjs} +5 -5
  42. package/dist/{chunk-7CVF3DK2.cjs.map → chunk-IF6VAYIA.cjs.map} +1 -1
  43. package/dist/chunk-MLAHDAN5.cjs +450 -0
  44. package/dist/chunk-MLAHDAN5.cjs.map +1 -0
  45. package/dist/{chunk-IPGKTUF7.cjs → chunk-MP6FK43E.cjs} +71 -5
  46. package/dist/chunk-MP6FK43E.cjs.map +1 -0
  47. package/dist/{chunk-5EBGRG3X.js → chunk-OPA2Y6YZ.js} +3 -54
  48. package/dist/chunk-OPA2Y6YZ.js.map +1 -0
  49. package/dist/{chunk-7FKARMA3.cjs → chunk-SSDISIDW.cjs} +190 -122
  50. package/dist/chunk-SSDISIDW.cjs.map +1 -0
  51. package/dist/chunk-TZR36PPP.cjs +95 -0
  52. package/dist/chunk-TZR36PPP.cjs.map +1 -0
  53. package/dist/chunk-VFIZYSZB.cjs +2783 -0
  54. package/dist/chunk-VFIZYSZB.cjs.map +1 -0
  55. package/dist/chunk-WXRCMIAE.js +2707 -0
  56. package/dist/chunk-WXRCMIAE.js.map +1 -0
  57. package/dist/{chunk-HITAN7JF.cjs → chunk-XMBYDLZQ.cjs} +4 -4
  58. package/dist/{chunk-HITAN7JF.cjs.map → chunk-XMBYDLZQ.cjs.map} +1 -1
  59. package/dist/{chunk-MK6NJQGF.js → chunk-XQDM6T6C.js} +3 -3
  60. package/dist/{chunk-MK6NJQGF.js.map → chunk-XQDM6T6C.js.map} +1 -1
  61. package/dist/chunk-ZVBPRMHJ.cjs +153 -0
  62. package/dist/chunk-ZVBPRMHJ.cjs.map +1 -0
  63. package/dist/connect/docx.cjs +10 -88
  64. package/dist/connect/docx.cjs.map +1 -1
  65. package/dist/connect/docx.js +6 -86
  66. package/dist/connect/docx.js.map +1 -1
  67. package/dist/connect/index.cjs +468 -49
  68. package/dist/connect/index.cjs.map +1 -1
  69. package/dist/connect/index.d.ts +2 -0
  70. package/dist/connect/index.js +454 -37
  71. package/dist/connect/index.js.map +1 -1
  72. package/dist/connection/ConnectedTagMatrix.d.ts +20 -0
  73. package/dist/connection/ConnectedWorkflowRunner.d.ts +28 -2
  74. package/dist/connection/WorkflowRunThread.d.ts +21 -0
  75. package/dist/connection/WorkflowRunnerDialogs.d.ts +37 -0
  76. package/dist/connection/useWorkflowThread.d.ts +12 -0
  77. package/dist/document-tools/index.cjs +7 -143
  78. package/dist/document-tools/index.cjs.map +1 -1
  79. package/dist/document-tools/index.js +5 -144
  80. package/dist/document-tools/index.js.map +1 -1
  81. package/dist/docx/index.cjs +18 -17
  82. package/dist/docx/index.cjs.map +1 -1
  83. package/dist/docx/index.js +3 -2
  84. package/dist/docx/index.js.map +1 -1
  85. package/dist/facts/index.cjs +1 -1
  86. package/dist/facts/index.js +1 -1
  87. package/dist/files/index.cjs +1 -1
  88. package/dist/files/index.js +1 -1
  89. package/dist/home/index.cjs +1 -1
  90. package/dist/home/index.js +1 -1
  91. package/dist/index.cjs +560 -431
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +10 -9
  95. package/dist/index.js.map +1 -1
  96. package/dist/shell/index.cjs +1 -1
  97. package/dist/shell/index.js +1 -1
  98. package/dist/studio/index.cjs +4 -4
  99. package/dist/studio/index.js +3 -3
  100. package/dist/tags/TagMatrix.d.ts +64 -0
  101. package/dist/tags/index.d.ts +3 -0
  102. package/dist/tags/tagMatrixModel.d.ts +39 -0
  103. package/dist/workflow-canvas/StepActionSettings.d.ts +132 -0
  104. package/dist/workflow-canvas/StepInspector.d.ts +25 -2
  105. package/dist/workflow-canvas/WorkflowBuilder.d.ts +11 -3
  106. package/dist/workflow-canvas/WorkflowCanvas.d.ts +27 -2
  107. package/dist/workflow-canvas/edit.d.ts +9 -1
  108. package/dist/workflow-canvas/index.cjs +882 -102
  109. package/dist/workflow-canvas/index.cjs.map +1 -1
  110. package/dist/workflow-canvas/index.js +849 -69
  111. package/dist/workflow-canvas/index.js.map +1 -1
  112. package/package.json +4 -4
  113. package/src/workflow-canvas/canvas.css +9 -0
  114. package/dist/chunk-22P5KNIM.js +0 -1422
  115. package/dist/chunk-22P5KNIM.js.map +0 -1
  116. package/dist/chunk-5EBGRG3X.js.map +0 -1
  117. package/dist/chunk-7FKARMA3.cjs.map +0 -1
  118. package/dist/chunk-IPGKTUF7.cjs.map +0 -1
  119. package/dist/chunk-TKB7TVMW.js.map +0 -1
  120. package/dist/chunk-UIWLDSTF.js.map +0 -1
  121. package/dist/chunk-VYRKO3XU.cjs +0 -1469
  122. package/dist/chunk-VYRKO3XU.cjs.map +0 -1
  123. package/dist/chunk-ZWA7UUZL.cjs.map +0 -1
@@ -2,25 +2,25 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkMUMH3Z6K_cjs = require('../chunk-MUMH3Z6K.cjs');
5
- var chunk7FKARMA3_cjs = require('../chunk-7FKARMA3.cjs');
5
+ var chunkSSDISIDW_cjs = require('../chunk-SSDISIDW.cjs');
6
6
  require('../chunk-YJQVLVBJ.cjs');
7
7
  require('../chunk-ZW6FPIFC.cjs');
8
- var chunkVYRKO3XU_cjs = require('../chunk-VYRKO3XU.cjs');
8
+ var chunkVFIZYSZB_cjs = require('../chunk-VFIZYSZB.cjs');
9
9
  require('../chunk-7RGLTF76.cjs');
10
+ require('../chunk-Z5VUZ6YD.cjs');
11
+ require('../chunk-7D737FLE.cjs');
10
12
  require('../chunk-3AFWGEDJ.cjs');
11
13
  require('../chunk-VFUWWH52.cjs');
12
14
  require('../chunk-DETZZBG2.cjs');
13
15
  require('../chunk-V4ISCZJ7.cjs');
14
16
  require('../chunk-2EI7NCUA.cjs');
15
17
  require('../chunk-IXALYQT7.cjs');
16
- require('../chunk-Z5VUZ6YD.cjs');
17
- require('../chunk-7D737FLE.cjs');
18
18
  require('../chunk-OB5F4577.cjs');
19
- require('../chunk-C54XEN5T.cjs');
20
19
  require('../chunk-B4SRYJLM.cjs');
21
20
  require('../chunk-7UTB4PHM.cjs');
22
21
  require('../chunk-FX3K6LNZ.cjs');
23
22
  require('../chunk-PPCATBOY.cjs');
23
+ require('../chunk-C54XEN5T.cjs');
24
24
  require('../chunk-KDG6FER6.cjs');
25
25
  require('../chunk-ULWRNGGE.cjs');
26
26
  require('../chunk-MHVNT4J3.cjs');
@@ -33,6 +33,16 @@ var jsxRuntime = require('react/jsx-runtime');
33
33
  var react$1 = require('@xyflow/react');
34
34
 
35
35
  // src/workflow-canvas/edit.ts
36
+ var WORKFLOW_STEP_KINDS = [
37
+ "form",
38
+ "upload",
39
+ "agent",
40
+ "review",
41
+ "sign",
42
+ "email_draft",
43
+ "tabular_review"
44
+ ];
45
+ var stepKindOf = (step) => step.kind === "action" ? step.action.type : step.kind;
36
46
  function newSteppedWorkflow(id, title) {
37
47
  return {
38
48
  id,
@@ -48,11 +58,11 @@ function withSteps(workflow, steps, layout) {
48
58
  const run = workflow.run.kind === "steps" ? workflow.run : { kind: "steps", steps: [] };
49
59
  return {
50
60
  ...workflow,
51
- run: { ...run, steps: chunkVYRKO3XU_cjs.orderSteps(steps), layout: layout ?? run.layout }
61
+ run: { ...run, steps: chunkVFIZYSZB_cjs.orderSteps(steps), layout: layout ?? run.layout }
52
62
  };
53
63
  }
54
64
  var layoutOf = (workflow) => workflow.run.kind === "steps" && workflow.run.layout || {};
55
- var explicit = (steps) => steps.map((s) => ({ ...s, after: chunkVYRKO3XU_cjs.stepDependencies(steps, s.id) }));
65
+ var explicit = (steps) => steps.map((s) => ({ ...s, after: chunkVFIZYSZB_cjs.stepDependencies(steps, s.id) }));
56
66
  function stepIdFor(steps, title) {
57
67
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/^[^a-z]+/, "") || "step";
58
68
  const taken = new Set(steps.map((s) => s.id));
@@ -65,7 +75,10 @@ var DEFAULT_TITLES = {
65
75
  form: "Details",
66
76
  upload: "Upload files",
67
77
  agent: "Agent step",
68
- review: "Review"
78
+ review: "Review",
79
+ sign: "Sign",
80
+ email_draft: "Email draft",
81
+ tabular_review: "Tabular review"
69
82
  };
70
83
  function blankStep(kind, id, title) {
71
84
  switch (kind) {
@@ -77,10 +90,26 @@ function blankStep(kind, id, title) {
77
90
  return { id, kind, title };
78
91
  case "review":
79
92
  return { id, kind, title, instructions: "" };
93
+ case "sign":
94
+ return { id, kind: "action", title, action: { type: "sign", signers: [] } };
95
+ case "email_draft":
96
+ return {
97
+ id,
98
+ kind: "action",
99
+ title,
100
+ action: { type: "email_draft", to: [], subject: "", body: "" }
101
+ };
102
+ case "tabular_review":
103
+ return {
104
+ id,
105
+ kind: "action",
106
+ title,
107
+ action: { type: "tabular_review", tags: [], documents: "run_uploads" }
108
+ };
80
109
  }
81
110
  }
82
111
  function addStep(workflow, kind, options = {}) {
83
- const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
112
+ const steps = explicit(chunkVFIZYSZB_cjs.workflowSteps(workflow));
84
113
  const title = options.title ?? DEFAULT_TITLES[kind];
85
114
  const id = stepIdFor(steps, title);
86
115
  const step = { ...blankStep(kind, id, title), after: options.after ? [options.after] : [] };
@@ -89,7 +118,7 @@ function addStep(workflow, kind, options = {}) {
89
118
  return { workflow: withSteps(workflow, [...steps, step], layout), id };
90
119
  }
91
120
  function removeStep(workflow, id) {
92
- const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
121
+ const steps = explicit(chunkVFIZYSZB_cjs.workflowSteps(workflow));
93
122
  const removed = steps.find((s) => s.id === id);
94
123
  if (!removed) return workflow;
95
124
  const bridged = steps.filter((s) => s.id !== id).map(
@@ -102,8 +131,8 @@ function removeStep(workflow, id) {
102
131
  return withSteps(workflow, bridged, layout);
103
132
  }
104
133
  function connectSteps(workflow, 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)) {
134
+ const steps = explicit(chunkVFIZYSZB_cjs.workflowSteps(workflow));
135
+ if (from === to || !steps.some((s) => s.id === from) || chunkVFIZYSZB_cjs.dependsOn(steps, from, to)) {
107
136
  return workflow;
108
137
  }
109
138
  return withSteps(
@@ -113,16 +142,16 @@ function connectSteps(workflow, from, to) {
113
142
  )
114
143
  );
115
144
  }
116
- var wouldCycle = (workflow, from, to) => from === to || chunkVYRKO3XU_cjs.dependsOn(chunkVYRKO3XU_cjs.workflowSteps(workflow), from, to);
145
+ var wouldCycle = (workflow, from, to) => from === to || chunkVFIZYSZB_cjs.dependsOn(chunkVFIZYSZB_cjs.workflowSteps(workflow), from, to);
117
146
  function disconnectSteps(workflow, from, to) {
118
- const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
147
+ const steps = explicit(chunkVFIZYSZB_cjs.workflowSteps(workflow));
119
148
  return withSteps(
120
149
  workflow,
121
150
  steps.map((s) => s.id === to ? { ...s, after: (s.after ?? []).filter((d) => d !== from) } : s)
122
151
  );
123
152
  }
124
153
  function updateStep(workflow, id, patch) {
125
- const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
154
+ const steps = explicit(chunkVFIZYSZB_cjs.workflowSteps(workflow));
126
155
  return withSteps(
127
156
  workflow,
128
157
  steps.map(
@@ -136,27 +165,62 @@ var renameIn = (text, from, to) => text.replace(
136
165
  );
137
166
  function renameInput(workflow, from, to) {
138
167
  if (from === to) return workflow;
139
- const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow).map((s) => {
168
+ const steps = chunkVFIZYSZB_cjs.workflowSteps(workflow).map((s) => {
140
169
  if (s.kind === "agent")
141
170
  return {
142
171
  ...s,
143
172
  with: s.with ? Object.fromEntries(Object.entries(s.with).map(([k, v]) => [k, renameIn(v, from, to)])) : s.with,
144
- run: s.run?.kind === "prompt" ? { ...s.run, promptTemplate: renameIn(s.run.promptTemplate, from, to) } : s.run
173
+ run: s.run?.kind === "prompt" ? { ...s.run, promptTemplate: renameIn(s.run.promptTemplate, from, to) } : s.run,
174
+ ...s.editDocument ? { editDocument: renameRef(s.editDocument, from, to) } : {}
145
175
  };
146
- if (s.kind === "review" && s.instructions)
147
- return { ...s, instructions: renameIn(s.instructions, from, to) };
148
- return s;
176
+ const assignee = s.assignee && renamePerson(s.assignee, from, to);
177
+ const base = assignee ? { ...s, assignee } : s;
178
+ if (base.kind === "review" && base.instructions)
179
+ return { ...base, instructions: renameIn(base.instructions, from, to) };
180
+ if (base.kind === "action") {
181
+ const a = base.action;
182
+ if (a.type === "sign")
183
+ return {
184
+ ...base,
185
+ action: {
186
+ ...a,
187
+ document: a.document && renameRef(a.document, from, to),
188
+ signers: a.signers.map((x) => renamePerson(x, from, to)),
189
+ ...a.message ? { message: renameIn(a.message, from, to) } : {}
190
+ }
191
+ };
192
+ if (a.type === "email_draft")
193
+ return {
194
+ ...base,
195
+ action: {
196
+ ...a,
197
+ to: a.to.map((t) => renameIn(t, from, to)),
198
+ ...a.cc ? { cc: a.cc.map((t) => renameIn(t, from, to)) } : {},
199
+ subject: renameIn(a.subject, from, to),
200
+ body: renameIn(a.body, from, to),
201
+ ...a.attachments ? { attachments: a.attachments.map((r) => renameRef(r, from, to)) } : {}
202
+ }
203
+ };
204
+ if (Array.isArray(a.documents))
205
+ return {
206
+ ...base,
207
+ action: { ...a, documents: a.documents.map((r) => renameRef(r, from, to)) }
208
+ };
209
+ }
210
+ return base;
149
211
  });
150
212
  return withSteps(workflow, steps);
151
213
  }
214
+ var renamePerson = (a, from, to) => "input" in a && a.input === from ? { input: to } : a;
215
+ var renameRef = (r, from, to) => "input" in r && r.input === from ? { input: to } : r;
152
216
  function moveStep(workflow, id, position) {
153
- return withSteps(workflow, chunkVYRKO3XU_cjs.workflowSteps(workflow), { ...layoutOf(workflow), [id]: position });
217
+ return withSteps(workflow, chunkVFIZYSZB_cjs.workflowSteps(workflow), { ...layoutOf(workflow), [id]: position });
154
218
  }
155
219
  var COLUMN = 300;
156
220
  var ROW = 140;
157
221
  function autoLayout(steps) {
158
222
  const layout = {};
159
- chunkVYRKO3XU_cjs.stepLevels(steps).forEach(
223
+ chunkVFIZYSZB_cjs.stepLevels(steps).forEach(
160
224
  (level, x) => level.forEach((s, y) => {
161
225
  layout[s.id] = { x: x * COLUMN, y: (y - (level.length - 1) / 2) * ROW };
162
226
  })
@@ -164,7 +228,7 @@ function autoLayout(steps) {
164
228
  return layout;
165
229
  }
166
230
  function layoutWithDefaults(workflow) {
167
- const auto = autoLayout(chunkVYRKO3XU_cjs.workflowSteps(workflow));
231
+ const auto = autoLayout(chunkVFIZYSZB_cjs.workflowSteps(workflow));
168
232
  return { ...auto, ...layoutOf(workflow) };
169
233
  }
170
234
  var DEFAULT_SIGNALS_EDITOR_LABELS = {
@@ -261,9 +325,9 @@ function SignalsEditor({
261
325
  {
262
326
  className: ui.cn(
263
327
  "space-y-1.5 rounded-md border p-2",
264
- chunkVYRKO3XU_cjs.isIncompleteSignal(signal) ? "border-destructive/50" : "border-border"
328
+ chunkVFIZYSZB_cjs.isIncompleteSignal(signal) ? "border-destructive/50" : "border-border"
265
329
  ),
266
- "data-incomplete": chunkVYRKO3XU_cjs.isIncompleteSignal(signal) || void 0,
330
+ "data-incomplete": chunkVFIZYSZB_cjs.isIncompleteSignal(signal) || void 0,
267
331
  "data-testid": `${testId}-${i}`,
268
332
  children: [
269
333
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -383,6 +447,537 @@ function SignalsEditor({
383
447
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: l.hint })
384
448
  ] });
385
449
  }
450
+ var DEFAULT_STEP_ACTION_SETTINGS_LABELS = {
451
+ assignee: "Who does it",
452
+ assigneeAnyone: "Anyone on the run",
453
+ assigneeRunOwner: "Whoever started the run",
454
+ assigneeProjectLead: "The project lead",
455
+ assigneeFields: "The person in a form field",
456
+ assigneePeople: "A person",
457
+ remind: "Remind after (hours)",
458
+ remindHint: "Left that long, they are told again. Blank: no reminder.",
459
+ documentFrom: "Document",
460
+ docFromStep: "From an earlier step",
461
+ docFromInput: "From a run input",
462
+ docById: "A document",
463
+ chooseStep: "Choose a step\u2026",
464
+ chooseInput: "Choose an input\u2026",
465
+ chooseDocument: "Choose a document\u2026",
466
+ documentIdPlaceholder: "doc-\u2026",
467
+ signDocument: "Document to sign",
468
+ signers: "Signers",
469
+ addSigner: "Add signer",
470
+ signMessage: "Message to the signers",
471
+ expires: "Expires after (hours)",
472
+ expiresHint: "Unsigned by then, the step fails. Blank: no expiry.",
473
+ emailTo: "To",
474
+ emailCc: "Cc",
475
+ emailSubject: "Subject",
476
+ emailBody: "Body",
477
+ addressesHint: "Separate several with commas.",
478
+ variablesHint: "Variables (click to add to the body):",
479
+ attachments: "Attachments",
480
+ addAttachment: "Add attachment",
481
+ reviewColumns: "Columns (labels)",
482
+ noTags: "No labels in this workspace yet.",
483
+ reviewDocuments: "Documents",
484
+ reviewRunUploads: "The files this run collects",
485
+ reviewWorkspace: "Every document in the workspace",
486
+ reviewChosen: "Chosen documents",
487
+ addDocument: "Add document",
488
+ overwrite: "Fill cells that already have a value again",
489
+ editDocument: "Edit this document (tracked changes)",
490
+ editDocumentHint: "The instruction says what to change; the edited copy is saved as its next version, to accept or reject change by change."
491
+ };
492
+ 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";
493
+ function Field({
494
+ label,
495
+ children,
496
+ hint
497
+ }) {
498
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
499
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: label }),
500
+ children,
501
+ hint && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: hint })
502
+ ] });
503
+ }
504
+ var assigneeValue = (a) => !a ? "" : "user" in a ? `user:${a.user}` : "input" in a ? `input:${a.input}` : "runOwner" in a ? "owner" : "lead";
505
+ var parseAssignee = (v) => v === "owner" ? { runOwner: true } : v === "lead" ? { projectLead: true } : v.startsWith("user:") ? { user: v.slice(5) } : v.startsWith("input:") ? { input: v.slice(6) } : void 0;
506
+ function AssigneeSelect({
507
+ value,
508
+ onChange,
509
+ ctx,
510
+ l,
511
+ anyone,
512
+ testId,
513
+ ariaLabel
514
+ }) {
515
+ const personFields = ctx.fields.filter((f) => f.type === "person");
516
+ const v = assigneeValue(value);
517
+ const known = !v.startsWith("user:") || ctx.people.some((p) => `user:${p.value}` === v) ? null : v.slice(5);
518
+ return /* @__PURE__ */ jsxRuntime.jsxs(
519
+ "select",
520
+ {
521
+ className: selectClass2,
522
+ value: v,
523
+ "aria-label": ariaLabel,
524
+ onChange: (e) => onChange(parseAssignee(e.target.value)),
525
+ "data-testid": testId,
526
+ children: [
527
+ anyone !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: anyone }) : /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true }),
528
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "owner", children: l.assigneeRunOwner }),
529
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "lead", children: l.assigneeProjectLead }),
530
+ personFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("optgroup", { label: l.assigneeFields, children: personFields.map((f) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: `input:${f.name}`, children: f.label }, f.name)) }),
531
+ (ctx.people.length > 0 || known) && /* @__PURE__ */ jsxRuntime.jsxs("optgroup", { label: l.assigneePeople, children: [
532
+ ctx.people.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: `user:${p.value}`, children: p.label }, p.value)),
533
+ known && /* @__PURE__ */ jsxRuntime.jsx("option", { value: v, children: known })
534
+ ] })
535
+ ]
536
+ }
537
+ );
538
+ }
539
+ function AssigneeSettings({
540
+ step,
541
+ patch,
542
+ ctx,
543
+ l,
544
+ testId
545
+ }) {
546
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
547
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.assignee, children: /* @__PURE__ */ jsxRuntime.jsx(
548
+ AssigneeSelect,
549
+ {
550
+ value: step.assignee,
551
+ onChange: (assignee) => patch({ assignee }),
552
+ ctx,
553
+ l,
554
+ anyone: l.assigneeAnyone,
555
+ testId: `${testId}-assignee`
556
+ }
557
+ ) }),
558
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.remind, hint: l.remindHint, children: /* @__PURE__ */ jsxRuntime.jsx(
559
+ ui.Input,
560
+ {
561
+ type: "number",
562
+ min: 1,
563
+ value: step.remindAfterHours ?? "",
564
+ onChange: (e) => {
565
+ const n = Number(e.target.value);
566
+ patch({ remindAfterHours: e.target.value && n > 0 ? n : void 0 });
567
+ },
568
+ className: "w-28",
569
+ "data-testid": `${testId}-remind`
570
+ }
571
+ ) })
572
+ ] });
573
+ }
574
+ var modeOf = (ref) => !ref ? "step" : "step" in ref ? "step" : "input" in ref ? "input" : "id";
575
+ function DocumentRefPicker({
576
+ value,
577
+ onChange,
578
+ ctx,
579
+ l,
580
+ testId
581
+ }) {
582
+ const mode = modeOf(value);
583
+ const inputs = ctx.fields.filter((f) => f.type === "documents" || f.type === "text");
584
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", "data-testid": testId, children: [
585
+ /* @__PURE__ */ jsxRuntime.jsxs(
586
+ "select",
587
+ {
588
+ className: ui.cn(selectClass2, "h-8"),
589
+ value: mode,
590
+ "aria-label": l.documentFrom,
591
+ onChange: (e) => {
592
+ const m = e.target.value;
593
+ onChange(m === "step" ? { step: "" } : m === "input" ? { input: "" } : { id: "" });
594
+ },
595
+ "data-testid": `${testId}-mode`,
596
+ children: [
597
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "step", children: l.docFromStep }),
598
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "input", children: l.docFromInput }),
599
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "id", children: l.docById })
600
+ ]
601
+ }
602
+ ),
603
+ mode === "step" && /* @__PURE__ */ jsxRuntime.jsxs(
604
+ "select",
605
+ {
606
+ className: ui.cn(selectClass2, "h-8"),
607
+ value: value && "step" in value ? value.step : "",
608
+ onChange: (e) => onChange({ step: e.target.value }),
609
+ "data-testid": `${testId}-step`,
610
+ children: [
611
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: l.chooseStep }),
612
+ ctx.earlier.map((s) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: s.id, children: s.title }, s.id))
613
+ ]
614
+ }
615
+ ),
616
+ mode === "input" && /* @__PURE__ */ jsxRuntime.jsxs(
617
+ "select",
618
+ {
619
+ className: ui.cn(selectClass2, "h-8"),
620
+ value: value && "input" in value ? value.input : "",
621
+ onChange: (e) => onChange({ input: e.target.value }),
622
+ "data-testid": `${testId}-input`,
623
+ children: [
624
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: l.chooseInput }),
625
+ inputs.map((f) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: f.name, children: f.label }, f.name))
626
+ ]
627
+ }
628
+ ),
629
+ mode === "id" && (ctx.documents.length ? /* @__PURE__ */ jsxRuntime.jsxs(
630
+ "select",
631
+ {
632
+ className: ui.cn(selectClass2, "h-8"),
633
+ value: value && "id" in value ? value.id : "",
634
+ onChange: (e) => onChange({ id: e.target.value }),
635
+ "data-testid": `${testId}-id`,
636
+ children: [
637
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: l.chooseDocument }),
638
+ ctx.documents.map((d) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: d.value, children: d.label }, d.value))
639
+ ]
640
+ }
641
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
642
+ ui.Input,
643
+ {
644
+ className: "h-8",
645
+ value: value && "id" in value ? value.id : "",
646
+ placeholder: l.documentIdPlaceholder,
647
+ onChange: (e) => onChange({ id: e.target.value }),
648
+ "data-testid": `${testId}-id`
649
+ }
650
+ ))
651
+ ] });
652
+ }
653
+ function DocumentRefList({
654
+ value,
655
+ onChange,
656
+ ctx,
657
+ l,
658
+ addLabel,
659
+ testId
660
+ }) {
661
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
662
+ value.map((ref, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1.5", children: [
663
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
664
+ DocumentRefPicker,
665
+ {
666
+ value: ref,
667
+ onChange: (next) => onChange(value.map((r, j) => j === i ? next : r)),
668
+ ctx,
669
+ l,
670
+ testId: `${testId}-${i}`
671
+ }
672
+ ) }),
673
+ /* @__PURE__ */ jsxRuntime.jsx(
674
+ "button",
675
+ {
676
+ type: "button",
677
+ className: "mt-2",
678
+ "aria-label": `${addLabel} \xD7`,
679
+ onClick: () => onChange(value.filter((_, j) => j !== i)),
680
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4 text-muted-foreground" })
681
+ }
682
+ )
683
+ ] }, i)),
684
+ /* @__PURE__ */ jsxRuntime.jsxs(
685
+ ui.Button,
686
+ {
687
+ variant: "outline",
688
+ size: "sm",
689
+ onClick: () => onChange([...value, { step: "" }]),
690
+ "data-testid": `${testId}-add`,
691
+ children: [
692
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "size-4" }),
693
+ " ",
694
+ addLabel
695
+ ]
696
+ }
697
+ )
698
+ ] });
699
+ }
700
+ var optionalNumber = (raw) => {
701
+ const n = Number(raw);
702
+ return raw && n > 0 ? n : void 0;
703
+ };
704
+ function SignSettings({
705
+ action,
706
+ onChange,
707
+ ctx,
708
+ l,
709
+ testId
710
+ }) {
711
+ const set = (p) => onChange({ ...action, ...p });
712
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
713
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.signDocument, children: /* @__PURE__ */ jsxRuntime.jsx(
714
+ DocumentRefPicker,
715
+ {
716
+ value: action.document,
717
+ onChange: (document) => set({ document }),
718
+ ctx,
719
+ l,
720
+ testId: `${testId}-document`
721
+ }
722
+ ) }),
723
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.signers, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", "data-testid": `${testId}-signers`, children: [
724
+ action.signers.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
725
+ /* @__PURE__ */ jsxRuntime.jsx(
726
+ AssigneeSelect,
727
+ {
728
+ value: s,
729
+ onChange: (next) => set({
730
+ signers: next ? action.signers.map((x, j) => j === i ? next : x) : action.signers.filter((_, j) => j !== i)
731
+ }),
732
+ ctx,
733
+ l,
734
+ ariaLabel: `${l.signers} ${i + 1}`,
735
+ testId: `${testId}-signer-${i}`
736
+ }
737
+ ),
738
+ /* @__PURE__ */ jsxRuntime.jsx(
739
+ "button",
740
+ {
741
+ type: "button",
742
+ "aria-label": `${l.signers} ${i + 1} \xD7`,
743
+ onClick: () => set({ signers: action.signers.filter((_, j) => j !== i) }),
744
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4 text-muted-foreground" })
745
+ }
746
+ )
747
+ ] }, i)),
748
+ /* @__PURE__ */ jsxRuntime.jsxs(
749
+ ui.Button,
750
+ {
751
+ variant: "outline",
752
+ size: "sm",
753
+ onClick: () => set({ signers: [...action.signers, { runOwner: true }] }),
754
+ "data-testid": `${testId}-add-signer`,
755
+ children: [
756
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "size-4" }),
757
+ " ",
758
+ l.addSigner
759
+ ]
760
+ }
761
+ )
762
+ ] }) }),
763
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.signMessage, children: /* @__PURE__ */ jsxRuntime.jsx(
764
+ ui.Textarea,
765
+ {
766
+ rows: 3,
767
+ value: action.message ?? "",
768
+ onChange: (e) => set({ message: e.target.value || void 0 }),
769
+ "data-testid": `${testId}-message`
770
+ }
771
+ ) }),
772
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.expires, hint: l.expiresHint, children: /* @__PURE__ */ jsxRuntime.jsx(
773
+ ui.Input,
774
+ {
775
+ type: "number",
776
+ min: 1,
777
+ className: "w-28",
778
+ value: action.expiresAfterHours ?? "",
779
+ onChange: (e) => set({ expiresAfterHours: optionalNumber(e.target.value) }),
780
+ "data-testid": `${testId}-expires`
781
+ }
782
+ ) })
783
+ ] });
784
+ }
785
+ var addresses = (list) => (list ?? []).join(", ");
786
+ var parseAddresses = (text) => text.split(",").map((t) => t.trim());
787
+ function templateVariables(ctx) {
788
+ return [
789
+ ...ctx.fields.map((f) => `{{${f.name}}}`),
790
+ ...ctx.earlier.filter((s) => s.kind === "agent").map((s) => `{{${s.id}.answer}}`)
791
+ ];
792
+ }
793
+ function EmailDraftSettings({
794
+ action,
795
+ onChange,
796
+ ctx,
797
+ l,
798
+ testId
799
+ }) {
800
+ const set = (p) => onChange({ ...action, ...p });
801
+ const vars = templateVariables(ctx);
802
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
803
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.emailTo, hint: l.addressesHint, children: /* @__PURE__ */ jsxRuntime.jsx(
804
+ ui.Input,
805
+ {
806
+ value: addresses(action.to),
807
+ onChange: (e) => set({ to: parseAddresses(e.target.value) }),
808
+ placeholder: "{{client_email}}",
809
+ "data-testid": `${testId}-to`
810
+ }
811
+ ) }),
812
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.emailCc, children: /* @__PURE__ */ jsxRuntime.jsx(
813
+ ui.Input,
814
+ {
815
+ value: addresses(action.cc),
816
+ onChange: (e) => {
817
+ const cc = parseAddresses(e.target.value);
818
+ set({ cc: cc.some(Boolean) ? cc : void 0 });
819
+ },
820
+ "data-testid": `${testId}-cc`
821
+ }
822
+ ) }),
823
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.emailSubject, children: /* @__PURE__ */ jsxRuntime.jsx(
824
+ ui.Input,
825
+ {
826
+ value: action.subject,
827
+ onChange: (e) => set({ subject: e.target.value }),
828
+ "data-testid": `${testId}-subject`
829
+ }
830
+ ) }),
831
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.emailBody, children: /* @__PURE__ */ jsxRuntime.jsx(
832
+ ui.Textarea,
833
+ {
834
+ rows: 6,
835
+ value: action.body,
836
+ onChange: (e) => set({ body: e.target.value }),
837
+ "data-testid": `${testId}-body`
838
+ }
839
+ ) }),
840
+ vars.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", "data-testid": `${testId}-variables`, children: [
841
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-full text-xs text-muted-foreground", children: l.variablesHint }),
842
+ vars.map((v) => /* @__PURE__ */ jsxRuntime.jsx(
843
+ "button",
844
+ {
845
+ type: "button",
846
+ onClick: () => set({ body: `${action.body}${action.body ? " " : ""}${v}` }),
847
+ className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] text-muted-foreground hover:text-foreground",
848
+ title: v,
849
+ children: v
850
+ },
851
+ v
852
+ ))
853
+ ] }),
854
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.attachments, children: /* @__PURE__ */ jsxRuntime.jsx(
855
+ DocumentRefList,
856
+ {
857
+ value: action.attachments ?? [],
858
+ onChange: (attachments) => set({ attachments: attachments.length ? attachments : void 0 }),
859
+ ctx,
860
+ l,
861
+ addLabel: l.addAttachment,
862
+ testId: `${testId}-attachments`
863
+ }
864
+ ) })
865
+ ] });
866
+ }
867
+ function TabularReviewSettings({
868
+ action,
869
+ onChange,
870
+ ctx,
871
+ l,
872
+ testId
873
+ }) {
874
+ const set = (p) => onChange({ ...action, ...p });
875
+ const mode = Array.isArray(action.documents) ? "chosen" : action.documents;
876
+ const toggle = (id) => set({
877
+ tags: action.tags.includes(id) ? action.tags.filter((t) => t !== id) : [...action.tags, id]
878
+ });
879
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
880
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.reviewColumns, children: /* @__PURE__ */ jsxRuntime.jsxs(
881
+ "div",
882
+ {
883
+ className: "max-h-44 space-y-1 overflow-y-auto rounded-md border border-border p-2",
884
+ "data-testid": `${testId}-tags`,
885
+ children: [
886
+ ctx.tags.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: l.noTags }),
887
+ ctx.tags.map((t) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
888
+ /* @__PURE__ */ jsxRuntime.jsx(
889
+ ui.Checkbox,
890
+ {
891
+ checked: action.tags.includes(t.value),
892
+ onCheckedChange: () => toggle(t.value),
893
+ "data-testid": `${testId}-tag-${t.value}`
894
+ }
895
+ ),
896
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: t.label })
897
+ ] }, t.value)),
898
+ action.tags.filter((t) => !ctx.tags.some((x) => x.value === t)).map((t) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
899
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { checked: true, onCheckedChange: () => toggle(t) }),
900
+ /* @__PURE__ */ jsxRuntime.jsx("code", { className: "text-xs", children: t })
901
+ ] }, t))
902
+ ]
903
+ }
904
+ ) }),
905
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.reviewDocuments, children: /* @__PURE__ */ jsxRuntime.jsxs(
906
+ "select",
907
+ {
908
+ className: selectClass2,
909
+ value: mode,
910
+ onChange: (e) => {
911
+ const v = e.target.value;
912
+ set({ documents: v === "chosen" ? [] : v });
913
+ },
914
+ "data-testid": `${testId}-documents`,
915
+ children: [
916
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "run_uploads", children: l.reviewRunUploads }),
917
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "workspace", children: l.reviewWorkspace }),
918
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "chosen", children: l.reviewChosen })
919
+ ]
920
+ }
921
+ ) }),
922
+ Array.isArray(action.documents) && /* @__PURE__ */ jsxRuntime.jsx(
923
+ DocumentRefList,
924
+ {
925
+ value: action.documents,
926
+ onChange: (documents) => set({ documents }),
927
+ ctx,
928
+ l,
929
+ addLabel: l.addDocument,
930
+ testId: `${testId}-chosen`
931
+ }
932
+ ),
933
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
934
+ /* @__PURE__ */ jsxRuntime.jsx(
935
+ ui.Checkbox,
936
+ {
937
+ checked: !!action.overwrite,
938
+ onCheckedChange: (v) => set({ overwrite: v === true || void 0 })
939
+ }
940
+ ),
941
+ l.overwrite
942
+ ] })
943
+ ] });
944
+ }
945
+ function EditDocumentSettings({
946
+ step,
947
+ patch,
948
+ ctx,
949
+ l,
950
+ testId
951
+ }) {
952
+ const on = !!step.editDocument;
953
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
954
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-start gap-2 text-sm", children: [
955
+ /* @__PURE__ */ jsxRuntime.jsx(
956
+ ui.Checkbox,
957
+ {
958
+ checked: on,
959
+ disabled: !!step.branch,
960
+ onCheckedChange: (v) => patch({ editDocument: v === true ? { step: "" } : void 0 }),
961
+ "data-testid": `${testId}-edit-document`
962
+ }
963
+ ),
964
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
965
+ l.editDocument,
966
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: l.editDocumentHint })
967
+ ] })
968
+ ] }),
969
+ on && /* @__PURE__ */ jsxRuntime.jsx(
970
+ DocumentRefPicker,
971
+ {
972
+ value: step.editDocument,
973
+ onChange: (editDocument) => patch({ editDocument }),
974
+ ctx,
975
+ l,
976
+ testId: `${testId}-edit-document-ref`
977
+ }
978
+ )
979
+ ] });
980
+ }
386
981
  var DEFAULT_STEP_INSPECTOR_LABELS = {
387
982
  workflow: "Workflow",
388
983
  title: "Title",
@@ -412,17 +1007,19 @@ var DEFAULT_STEP_INSPECTOR_LABELS = {
412
1007
  hint: "Hint",
413
1008
  instructions: "What to review",
414
1009
  instructionsHint: "Shown on the review task; {{field}} and {{steps.<id>}} work here.",
1010
+ reviewFields: "Filled in when approving",
1011
+ reviewFieldsHint: "E.g. a rating or a comment; the answers join the run\u2019s inputs.",
415
1012
  deleteStep: "Delete step"
416
1013
  };
417
- var FIELD_TYPES = ["text", "longtext", "boolean", "number", "date", "scope"];
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";
419
- function Field({ label, children, hint }) {
420
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
421
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: label }),
422
- children,
423
- hint && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: hint })
424
- ] });
425
- }
1014
+ var FIELD_TYPES = [
1015
+ "text",
1016
+ "longtext",
1017
+ "boolean",
1018
+ "number",
1019
+ "date",
1020
+ "scope",
1021
+ "person"
1022
+ ];
426
1023
  var fieldName = (label, taken) => {
427
1024
  const base = label.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").replace(/^[^a-z]+/, "") || "field";
428
1025
  let name = base;
@@ -436,12 +1033,16 @@ function StepInspector({
436
1033
  onChange,
437
1034
  onSelect,
438
1035
  workflows = [],
1036
+ people = [],
1037
+ tags = [],
1038
+ documents = [],
439
1039
  labels,
1040
+ actionLabels,
440
1041
  signalLabels,
441
1042
  testId = "step-inspector"
442
1043
  }) {
443
1044
  const l = { ...DEFAULT_STEP_INSPECTOR_LABELS, ...labels };
444
- const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
1045
+ const steps = chunkVFIZYSZB_cjs.workflowSteps(workflow);
445
1046
  const step = steps.find((s) => s.id === stepId);
446
1047
  const run = workflow.run.kind === "steps" ? workflow.run : void 0;
447
1048
  if (!step || !run) {
@@ -466,7 +1067,31 @@ function StepInspector({
466
1067
  ] });
467
1068
  }
468
1069
  const patch = (p) => onChange(updateStep(workflow, step.id, p));
469
- const deps = chunkVYRKO3XU_cjs.stepDependencies(steps, step.id);
1070
+ const al = { ...DEFAULT_STEP_ACTION_SETTINGS_LABELS, ...actionLabels };
1071
+ const ctx = {
1072
+ earlier: chunkVFIZYSZB_cjs.upstreamSteps(steps, step.id),
1073
+ fields: chunkVFIZYSZB_cjs.runFields(workflow),
1074
+ people,
1075
+ tags,
1076
+ documents
1077
+ };
1078
+ const takenBy = (id) => steps.flatMap(
1079
+ (s) => s.id === id ? [] : s.kind === "form" ? s.inputs : s.kind === "review" ? s.fields ?? [] : []
1080
+ ).map((f) => f.name);
1081
+ const setFields = (before, after, key) => {
1082
+ const renamed = before.flatMap(
1083
+ (f, i) => after[i] && after[i].name !== f.name ? [[f.name, after[i].name]] : []
1084
+ );
1085
+ onChange(
1086
+ renamed.reduce(
1087
+ (w, [from, to]) => renameInput(w, from, to),
1088
+ updateStep(workflow, step.id, {
1089
+ [key]: key === "fields" && !after.length ? void 0 : after
1090
+ })
1091
+ )
1092
+ );
1093
+ };
1094
+ const deps = chunkVFIZYSZB_cjs.stepDependencies(steps, step.id);
470
1095
  const titleOf = (id) => steps.find((s) => s.id === id)?.title ?? id;
471
1096
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", "data-testid": `${testId}-step`, children: [
472
1097
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
@@ -515,18 +1140,8 @@ function StepInspector({
515
1140
  FormFields,
516
1141
  {
517
1142
  fields: step.inputs,
518
- taken: steps.flatMap((s) => s.kind === "form" && s.id !== step.id ? s.inputs : []).map((f) => f.name),
519
- onChange: (inputs) => {
520
- const renamed = step.inputs.flatMap(
521
- (f, i) => inputs[i] && inputs[i].name !== f.name ? [[f.name, inputs[i].name]] : []
522
- );
523
- onChange(
524
- renamed.reduce(
525
- (w, [from, to]) => renameInput(w, from, to),
526
- updateStep(workflow, step.id, { inputs })
527
- )
528
- );
529
- },
1143
+ taken: takenBy(step.id),
1144
+ onChange: (inputs) => setFields(step.inputs, inputs, "inputs"),
530
1145
  l,
531
1146
  testId
532
1147
  }
@@ -550,26 +1165,73 @@ function StepInspector({
550
1165
  }
551
1166
  ) })
552
1167
  ] }),
553
- step.kind === "agent" && /* @__PURE__ */ jsxRuntime.jsx(
554
- AgentSettings,
1168
+ step.kind === "agent" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1169
+ /* @__PURE__ */ jsxRuntime.jsx(
1170
+ AgentSettings,
1171
+ {
1172
+ step,
1173
+ workflows,
1174
+ fields: chunkVFIZYSZB_cjs.runFields(workflow).map((f) => f.name),
1175
+ patch,
1176
+ l,
1177
+ testId
1178
+ }
1179
+ ),
1180
+ /* @__PURE__ */ jsxRuntime.jsx(EditDocumentSettings, { step, patch, ctx, l: al, testId })
1181
+ ] }),
1182
+ step.kind === "review" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1183
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.instructions, hint: l.instructionsHint, children: /* @__PURE__ */ jsxRuntime.jsx(
1184
+ ui.Textarea,
1185
+ {
1186
+ value: step.instructions ?? "",
1187
+ rows: 4,
1188
+ onChange: (e) => patch({ instructions: e.target.value || void 0 }),
1189
+ "data-testid": `${testId}-instructions`
1190
+ }
1191
+ ) }),
1192
+ /* @__PURE__ */ jsxRuntime.jsx(
1193
+ FormFields,
1194
+ {
1195
+ fields: step.fields ?? [],
1196
+ taken: takenBy(step.id),
1197
+ onChange: (fields) => setFields(step.fields ?? [], fields, "fields"),
1198
+ l: { ...l, fields: l.reviewFields },
1199
+ hint: l.reviewFieldsHint,
1200
+ testId: `${testId}-review`
1201
+ }
1202
+ )
1203
+ ] }),
1204
+ step.kind === "action" && step.action.type === "sign" && /* @__PURE__ */ jsxRuntime.jsx(
1205
+ SignSettings,
555
1206
  {
556
- step,
557
- workflows,
558
- fields: chunkVYRKO3XU_cjs.runFields(workflow).map((f) => f.name),
559
- patch,
560
- l,
561
- testId
1207
+ action: step.action,
1208
+ onChange: (action) => patch({ action }),
1209
+ ctx,
1210
+ l: al,
1211
+ testId: `${testId}-sign`
562
1212
  }
563
1213
  ),
564
- step.kind === "review" && /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.instructions, hint: l.instructionsHint, children: /* @__PURE__ */ jsxRuntime.jsx(
565
- ui.Textarea,
1214
+ step.kind === "action" && step.action.type === "email_draft" && /* @__PURE__ */ jsxRuntime.jsx(
1215
+ EmailDraftSettings,
566
1216
  {
567
- value: step.instructions ?? "",
568
- rows: 4,
569
- onChange: (e) => patch({ instructions: e.target.value || void 0 }),
570
- "data-testid": `${testId}-instructions`
1217
+ action: step.action,
1218
+ onChange: (action) => patch({ action }),
1219
+ ctx,
1220
+ l: al,
1221
+ testId: `${testId}-email`
571
1222
  }
572
- ) }),
1223
+ ),
1224
+ step.kind === "action" && step.action.type === "tabular_review" && /* @__PURE__ */ jsxRuntime.jsx(
1225
+ TabularReviewSettings,
1226
+ {
1227
+ action: step.action,
1228
+ onChange: (action) => patch({ action }),
1229
+ ctx,
1230
+ l: al,
1231
+ testId: `${testId}-review-grid`
1232
+ }
1233
+ ),
1234
+ chunkVFIZYSZB_cjs.canAssign(step) && /* @__PURE__ */ jsxRuntime.jsx(AssigneeSettings, { step, patch, ctx, l: al, testId }),
573
1235
  /* @__PURE__ */ jsxRuntime.jsx(
574
1236
  SignalsEditor,
575
1237
  {
@@ -604,10 +1266,11 @@ function FormFields({
604
1266
  taken,
605
1267
  onChange,
606
1268
  l,
1269
+ hint,
607
1270
  testId
608
1271
  }) {
609
1272
  const set = (i, p) => onChange(fields.map((f, j) => j === i ? { ...f, ...p } : f));
610
- return /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.fields, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", "data-testid": `${testId}-fields`, children: [
1273
+ return /* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.fields, hint, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", "data-testid": `${testId}-fields`, children: [
611
1274
  fields.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5 rounded-md border border-border p-2", children: [
612
1275
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
613
1276
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -643,7 +1306,9 @@ function FormFields({
643
1306
  className: ui.cn(selectClass2, "h-8"),
644
1307
  value: f.type,
645
1308
  onChange: (e) => set(i, { type: e.target.value }),
646
- children: FIELD_TYPES.map((t) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: t, children: t }, t))
1309
+ children: (FIELD_TYPES.includes(f.type) ? FIELD_TYPES : [...FIELD_TYPES, f.type]).map(
1310
+ (t) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: t, children: t }, t)
1311
+ )
647
1312
  }
648
1313
  ),
649
1314
  /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex shrink-0 items-center gap-1.5 text-xs", children: [
@@ -822,7 +1487,7 @@ function triggerFields(trigger, clearOthers) {
822
1487
  return {
823
1488
  timezone: trigger.timezone,
824
1489
  rrule: trigger.start === "repeat" ? trigger.rrule.trim() : none,
825
- run_at: trigger.start === "once" ? chunk7FKARMA3_cjs.localInputToIso(trigger.runAt) : none,
1490
+ run_at: trigger.start === "once" ? chunkSSDISIDW_cjs.localInputToIso(trigger.runAt) : none,
826
1491
  event_kind: trigger.start === "event" ? trigger.eventKind.trim() : none,
827
1492
  // A step signal is `workflow_signal` narrowed to one signal name.
828
1493
  event_filter: filter ?? none,
@@ -838,7 +1503,7 @@ function plan(value, options) {
838
1503
  criteria: [],
839
1504
  max_passes: 3,
840
1505
  documents: [],
841
- steps: chunkVYRKO3XU_cjs.toPlanSteps(value.workflow, options)
1506
+ steps: chunkVFIZYSZB_cjs.toPlanSteps(value.workflow, options)
842
1507
  };
843
1508
  }
844
1509
  function builderToWorkflowRequest(value, workspaceId, options = {}) {
@@ -873,7 +1538,7 @@ function builderToWorkflowUpdate(value, options = {}) {
873
1538
  }
874
1539
  function workflowRecordToBuilder(record) {
875
1540
  const planned = record.plan?.steps ?? [];
876
- const steps = planned.length ? chunkVYRKO3XU_cjs.fromPlanSteps(planned) : record.prompt || record.skill_ref ? [
1541
+ const steps = planned.length ? chunkVFIZYSZB_cjs.fromPlanSteps(planned) : record.prompt || record.skill_ref ? [
877
1542
  {
878
1543
  id: "work",
879
1544
  kind: "agent",
@@ -881,7 +1546,7 @@ function workflowRecordToBuilder(record) {
881
1546
  ...record.skill_ref ? { workflow: record.skill_ref } : { run: { kind: "prompt", promptTemplate: record.prompt } }
882
1547
  }
883
1548
  ] : [];
884
- const when = chunk7FKARMA3_cjs.workflowWhen(record);
1549
+ const when = chunkSSDISIDW_cjs.workflowWhen(record);
885
1550
  return {
886
1551
  workflow: {
887
1552
  id: record.external_id,
@@ -890,12 +1555,12 @@ function workflowRecordToBuilder(record) {
890
1555
  inputs: [],
891
1556
  landing: "chat",
892
1557
  schedulable: false,
893
- run: { kind: "steps", steps, layout: chunkVYRKO3XU_cjs.layoutFromPlanSteps(planned ?? []) }
1558
+ run: { kind: "steps", steps, layout: chunkVFIZYSZB_cjs.layoutFromPlanSteps(planned ?? []) }
894
1559
  },
895
1560
  trigger: {
896
1561
  ...DEFAULT_WORKFLOW_TRIGGER,
897
1562
  start: when === "now" ? "manual" : when,
898
- runAt: chunk7FKARMA3_cjs.isoToLocalInput(record.run_at),
1563
+ runAt: chunkSSDISIDW_cjs.isoToLocalInput(record.run_at),
899
1564
  rrule: record.rrule ?? "",
900
1565
  timezone: record.timezone || DEFAULT_WORKFLOW_TRIGGER.timezone,
901
1566
  eventKind: record.event_kind ?? "",
@@ -951,7 +1616,7 @@ function triggerSummary(trigger, options = {}) {
951
1616
  case "once":
952
1617
  return trigger.runAt ? new Date(trigger.runAt).toLocaleString() : l.starts.once;
953
1618
  case "repeat":
954
- return trigger.rrule ? chunk7FKARMA3_cjs.describeRRule(trigger.rrule) : l.starts.repeat;
1619
+ return trigger.rrule ? chunkSSDISIDW_cjs.describeRRule(trigger.rrule) : l.starts.repeat;
955
1620
  case "event":
956
1621
  if (isSignalTrigger(trigger))
957
1622
  return trigger.signal ? l.signalSummary.replace("{signal}", trigger.signal) : l.stepSignals;
@@ -1010,7 +1675,7 @@ function TriggerInspector({
1010
1675
  }
1011
1676
  )
1012
1677
  ] }),
1013
- trigger.start === "repeat" && /* @__PURE__ */ jsxRuntime.jsx(chunk7FKARMA3_cjs.RecurrenceBuilder, { rrule: trigger.rrule, onChange: (rrule) => set({ rrule }) }),
1678
+ trigger.start === "repeat" && /* @__PURE__ */ jsxRuntime.jsx(chunkSSDISIDW_cjs.RecurrenceBuilder, { rrule: trigger.rrule, onChange: (rrule) => set({ rrule }) }),
1014
1679
  trigger.start === "event" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
1015
1680
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.event }),
1016
1681
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1062,7 +1727,7 @@ function TriggerInspector({
1062
1727
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
1063
1728
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.agent }),
1064
1729
  /* @__PURE__ */ jsxRuntime.jsx(
1065
- chunk7FKARMA3_cjs.AgentSelect,
1730
+ chunkSSDISIDW_cjs.AgentSelect,
1066
1731
  {
1067
1732
  agents,
1068
1733
  value: trigger.agentId,
@@ -1134,12 +1799,19 @@ var DEFAULT_WORKFLOW_CANVAS_LABELS = {
1134
1799
  upload: "Upload",
1135
1800
  agent: "AI step",
1136
1801
  review: "Approval",
1802
+ sign: "Sign",
1803
+ email_draft: "Email draft",
1804
+ tabular_review: "Tabular review",
1805
+ redline: "Tracked changes",
1137
1806
  branch: "Branch",
1138
1807
  kindHints: {
1139
1808
  form: "Ask for details",
1140
1809
  upload: "Collect files",
1141
1810
  agent: "Run a skill or an instruction",
1142
- review: "A person approves"
1811
+ review: "A person approves",
1812
+ sign: "People e-sign a document",
1813
+ email_draft: "Prepare an email to send",
1814
+ tabular_review: "Review documents in a grid"
1143
1815
  },
1144
1816
  addNext: "Add the next step",
1145
1817
  runs: "Runs \u201C{name}\u201D",
@@ -1147,6 +1819,14 @@ var DEFAULT_WORKFLOW_CANVAS_LABELS = {
1147
1819
  fields: "{count} fields",
1148
1820
  noFields: "No fields yet",
1149
1821
  approvedBy: "A person approves",
1822
+ signers: "{count} signers",
1823
+ chooseDocument: "Choose the document to sign",
1824
+ emailTo: "To {to}",
1825
+ noRecipients: "Add a recipient",
1826
+ reviewColumns: "{count} columns",
1827
+ noColumns: "Choose the columns",
1828
+ assignee: "{name}",
1829
+ remind: "Reminds after {hours}h",
1150
1830
  emptyTitle: "Start your workflow",
1151
1831
  emptyHint: "Add the first step: what should happen when it starts?",
1152
1832
  fitView: "Fit view"
@@ -1156,9 +1836,12 @@ var STEP_KIND_ICONS = {
1156
1836
  form: lucideReact.FileInput,
1157
1837
  upload: lucideReact.Upload,
1158
1838
  agent: lucideReact.Bot,
1159
- review: lucideReact.ClipboardCheck
1839
+ review: lucideReact.ClipboardCheck,
1840
+ sign: lucideReact.PenLine,
1841
+ email_draft: lucideReact.Mail,
1842
+ tabular_review: lucideReact.Table2
1160
1843
  };
1161
- var KINDS = ["form", "upload", "agent", "review"];
1844
+ var KINDS = WORKFLOW_STEP_KINDS;
1162
1845
  function AddNext({
1163
1846
  from,
1164
1847
  onAdd,
@@ -1211,20 +1894,23 @@ function AddNext({
1211
1894
  }
1212
1895
  function PhaseMark({ phase }) {
1213
1896
  if (phase === "running") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "wf-kind-text size-4 animate-spin" });
1897
+ if (phase === "waiting") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Hourglass, { className: "wf-kind-text size-4" });
1214
1898
  if (phase === "done") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "wf-kind-text size-4" });
1215
1899
  if (phase === "failed") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "size-4 text-destructive" });
1216
1900
  if (phase === "skipped") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MinusCircle, { className: "size-4 text-muted-foreground" });
1217
1901
  return null;
1218
1902
  }
1219
1903
  function StepNode({ data }) {
1220
- const { step, phase, summary, icon, l, onAdd, testId } = data;
1221
- const KindIcon = STEP_KIND_ICONS[step.kind];
1904
+ const { step, phase, summary, assignee, icon, l, onAdd, testId } = data;
1905
+ const kind = stepKindOf(step);
1906
+ const KindIcon = STEP_KIND_ICONS[kind];
1907
+ const redline = step.kind === "agent" && !!step.editDocument;
1222
1908
  return /* @__PURE__ */ jsxRuntime.jsxs(
1223
1909
  "div",
1224
1910
  {
1225
1911
  className: ui.cn(
1226
1912
  "wf-node w-64 py-3 pl-4 pr-3 text-left",
1227
- `wf-kind-${step.kind}`,
1913
+ `wf-kind-${kind}`,
1228
1914
  phase && `wf-phase-${phase}`
1229
1915
  ),
1230
1916
  "data-testid": `${testId}-node-${step.id}`,
@@ -1235,15 +1921,44 @@ function StepNode({ data }) {
1235
1921
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "wf-badge flex size-8 shrink-0 items-center justify-center rounded-lg [&_svg]:size-4", children: icon ?? /* @__PURE__ */ jsxRuntime.jsx(KindIcon, {}) }),
1236
1922
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
1237
1923
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1238
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "wf-kind-text text-[10px] font-semibold uppercase tracking-wider", children: l[step.kind] }),
1924
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "wf-kind-text text-[10px] font-semibold uppercase tracking-wider", children: l[kind] }),
1239
1925
  /* @__PURE__ */ jsxRuntime.jsx(PhaseMark, { phase })
1240
1926
  ] }),
1241
1927
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-sm font-semibold leading-snug", children: step.title }),
1242
1928
  summary && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 line-clamp-2 text-xs leading-snug text-muted-foreground", children: summary }),
1243
- step.kind === "agent" && step.branch && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mt-1.5 inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: [
1244
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitBranch, { className: "size-3" }),
1245
- " ",
1246
- l.branch
1929
+ (redline || step.kind === "agent" && step.branch || assignee) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [
1930
+ step.kind === "agent" && step.branch && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: [
1931
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitBranch, { className: "size-3" }),
1932
+ " ",
1933
+ l.branch
1934
+ ] }),
1935
+ redline && /* @__PURE__ */ jsxRuntime.jsxs(
1936
+ "span",
1937
+ {
1938
+ className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground",
1939
+ "data-testid": `${testId}-node-${step.id}-redline`,
1940
+ children: [
1941
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FilePenLine, { className: "size-3" }),
1942
+ " ",
1943
+ l.redline
1944
+ ]
1945
+ }
1946
+ ),
1947
+ assignee && /* @__PURE__ */ jsxRuntime.jsxs(
1948
+ "span",
1949
+ {
1950
+ className: "inline-flex max-w-full items-center gap-1 truncate rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground",
1951
+ title: assignee,
1952
+ "data-testid": `${testId}-node-${step.id}-assignee`,
1953
+ children: [
1954
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserRound, { className: "size-3 shrink-0" }),
1955
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: l.assignee.replace(
1956
+ "{name}",
1957
+ assignee.charAt(0).toUpperCase() + assignee.slice(1)
1958
+ ) })
1959
+ ]
1960
+ }
1961
+ )
1247
1962
  ] })
1248
1963
  ] })
1249
1964
  ] }),
@@ -1292,6 +2007,16 @@ function summaryOf(step, l, workflowTitle) {
1292
2007
  return step.hint;
1293
2008
  case "review":
1294
2009
  return step.instructions ? firstWords(step.instructions) : l.approvedBy;
2010
+ case "action": {
2011
+ const a = step.action;
2012
+ if (a.type === "sign")
2013
+ return !a.document ? l.chooseDocument : a.signers.length ? l.signers.replace("{count}", String(a.signers.length)) : void 0;
2014
+ if (a.type === "email_draft") {
2015
+ const to = a.to.find((t) => t.trim());
2016
+ return to ? l.emailTo.replace("{to}", to) : l.noRecipients;
2017
+ }
2018
+ return a.tags.length ? l.reviewColumns.replace("{count}", String(a.tags.length)) : l.noColumns;
2019
+ }
1295
2020
  }
1296
2021
  }
1297
2022
  function WorkflowCanvas({
@@ -1303,6 +2028,7 @@ function WorkflowCanvas({
1303
2028
  onAddAfter,
1304
2029
  phases,
1305
2030
  workflowTitle,
2031
+ assigneeOf,
1306
2032
  trigger,
1307
2033
  renderIcon,
1308
2034
  labels,
@@ -1311,12 +2037,12 @@ function WorkflowCanvas({
1311
2037
  testId = "workflow-canvas"
1312
2038
  }) {
1313
2039
  const l = react.useMemo(() => ({ ...DEFAULT_WORKFLOW_CANVAS_LABELS, ...labels }), [labels]);
1314
- const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
2040
+ const steps = chunkVFIZYSZB_cjs.workflowSteps(workflow);
1315
2041
  const editable = !!onChange;
1316
2042
  const built = react.useMemo(() => {
1317
2043
  const layout = layoutWithDefaults(workflow);
1318
- const all = chunkVYRKO3XU_cjs.workflowSteps(workflow);
1319
- const roots = all.filter((s) => chunkVYRKO3XU_cjs.stepDependencies(all, s.id).length === 0);
2044
+ const all = chunkVFIZYSZB_cjs.workflowSteps(workflow);
2045
+ const roots = all.filter((s) => chunkVFIZYSZB_cjs.stepDependencies(all, s.id).length === 0);
1320
2046
  const triggerNode = trigger ? [
1321
2047
  {
1322
2048
  id: TRIGGER_NODE,
@@ -1341,6 +2067,7 @@ function WorkflowCanvas({
1341
2067
  step,
1342
2068
  phase: phases?.[step.id],
1343
2069
  summary: summaryOf(step, l, workflowTitle),
2070
+ assignee: assigneeOf?.(step),
1344
2071
  icon: step.icon && renderIcon ? renderIcon(step.icon) : void 0,
1345
2072
  l,
1346
2073
  onAdd: onAddAfter,
@@ -1348,12 +2075,23 @@ function WorkflowCanvas({
1348
2075
  }
1349
2076
  }))
1350
2077
  ];
1351
- }, [workflow, selected, phases, workflowTitle, trigger, renderIcon, l, onAddAfter, testId]);
2078
+ }, [
2079
+ workflow,
2080
+ selected,
2081
+ phases,
2082
+ workflowTitle,
2083
+ assigneeOf,
2084
+ trigger,
2085
+ renderIcon,
2086
+ l,
2087
+ onAddAfter,
2088
+ testId
2089
+ ]);
1352
2090
  const [nodes, setNodes] = react.useState(built);
1353
2091
  react.useEffect(() => setNodes(built), [built]);
1354
2092
  const edges = react.useMemo(
1355
2093
  () => steps.flatMap((s) => {
1356
- const deps = chunkVYRKO3XU_cjs.stepDependencies(steps, s.id);
2094
+ const deps = chunkVFIZYSZB_cjs.stepDependencies(steps, s.id);
1357
2095
  const from = deps.length ? deps : trigger ? [TRIGGER_NODE] : [];
1358
2096
  return from.map((d) => ({
1359
2097
  id: `${d}->${s.id}`,
@@ -1562,10 +2300,17 @@ var DEFAULT_WORKFLOW_BUILDER_LABELS = {
1562
2300
  unknown: "\u201C{step}\u201D waits for a step that does not exist.",
1563
2301
  cycle: "\u201C{step}\u201D waits for itself (a loop).",
1564
2302
  order: "\u201C{step}\u201D is listed before a step it waits for."
2303
+ },
2304
+ missing: {
2305
+ document: "\u201C{step}\u201D needs a document.",
2306
+ signers: "\u201C{step}\u201D needs at least one signer.",
2307
+ recipients: "\u201C{step}\u201D needs a recipient.",
2308
+ tags: "\u201C{step}\u201D needs at least one column.",
2309
+ documents: "\u201C{step}\u201D needs documents to review."
1565
2310
  }
1566
2311
  };
1567
2312
  var PANEL_WIDTH = 344;
1568
- var KINDS2 = ["form", "upload", "agent", "review"];
2313
+ var KINDS2 = WORKFLOW_STEP_KINDS;
1569
2314
  function WorkflowBuilder({
1570
2315
  value,
1571
2316
  onChange,
@@ -1574,6 +2319,9 @@ function WorkflowBuilder({
1574
2319
  eventKinds = [],
1575
2320
  tasks = [],
1576
2321
  signals = [],
2322
+ people = [],
2323
+ tags = [],
2324
+ documents = [],
1577
2325
  compose,
1578
2326
  renderIcon,
1579
2327
  actions,
@@ -1594,8 +2342,12 @@ function WorkflowBuilder({
1594
2342
  const [mode, setMode] = react.useState("design");
1595
2343
  const [adding, setAdding] = react.useState(false);
1596
2344
  const { workflow, trigger } = value;
1597
- const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
1598
- const problems = chunkVYRKO3XU_cjs.validateWorkflowGraph(steps);
2345
+ const steps = chunkVFIZYSZB_cjs.workflowSteps(workflow);
2346
+ const problems = chunkVFIZYSZB_cjs.validateWorkflowGraph(steps);
2347
+ const missing = chunkVFIZYSZB_cjs.stepConfigProblems(steps);
2348
+ const nameOf = (id) => people.find((p) => p.value === id)?.label;
2349
+ const fields = chunkVFIZYSZB_cjs.runFields(workflow);
2350
+ const assigneeOf = (step) => chunkVFIZYSZB_cjs.canAssign(step) ? chunkVFIZYSZB_cjs.assigneeName(step.assignee, { nameOf, fields }) : void 0;
1599
2351
  const titles = react.useMemo(() => new Map(workflows.map((w) => [w.id, w.title])), [workflows]);
1600
2352
  const setWorkflow = (next) => onChange({ ...value, workflow: next });
1601
2353
  const addAfter = (from, kind) => {
@@ -1708,10 +2460,16 @@ function WorkflowBuilder({
1708
2460
  ] }),
1709
2461
  actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: actions })
1710
2462
  ] }),
1711
- problems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1 text-sm text-destructive", "data-testid": `${testId}-problems`, children: problems.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: l.problems[p.code].replace(
1712
- "{step}",
1713
- steps.find((s) => s.id === p.step)?.title ?? p.step
1714
- ) }, i)) }),
2463
+ problems.length + missing.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "space-y-1 text-sm text-destructive", "data-testid": `${testId}-problems`, children: [
2464
+ problems.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: l.problems[p.code].replace(
2465
+ "{step}",
2466
+ steps.find((s) => s.id === p.step)?.title ?? p.step
2467
+ ) }, i)),
2468
+ missing.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { "data-testid": `${testId}-missing-${p.step}-${p.missing}`, children: l.missing[p.missing].replace(
2469
+ "{step}",
2470
+ steps.find((s) => s.id === p.step)?.title ?? p.step
2471
+ ) }, `m${i}`))
2472
+ ] }),
1715
2473
  mode === "design" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1716
2474
  /* @__PURE__ */ jsxRuntime.jsx(
1717
2475
  WorkflowCanvas,
@@ -1724,6 +2482,7 @@ function WorkflowBuilder({
1724
2482
  onAddAfter: addAfter,
1725
2483
  trigger: { title: l.start, summary },
1726
2484
  workflowTitle: (id) => titles.get(id),
2485
+ assigneeOf,
1727
2486
  renderIcon,
1728
2487
  labels: canvasLabels,
1729
2488
  reserveRight: panelOpen ? PANEL_WIDTH : 0,
@@ -1773,6 +2532,9 @@ function WorkflowBuilder({
1773
2532
  onChange: setWorkflow,
1774
2533
  onSelect: setSelected,
1775
2534
  workflows,
2535
+ people,
2536
+ tags,
2537
+ documents,
1776
2538
  labels: inspectorLabels,
1777
2539
  testId: `${testId}-inspector`
1778
2540
  }
@@ -1816,13 +2578,13 @@ function WorkflowPreview({
1816
2578
  renderIcon,
1817
2579
  testId
1818
2580
  }) {
1819
- const run = chunk7FKARMA3_cjs.useWorkflowPreview(workflow, {
2581
+ const run = chunkSSDISIDW_cjs.useWorkflowPreview(workflow, {
1820
2582
  resolveWorkflow: (id) => workflows.find((w) => w.id === id),
1821
2583
  compose,
1822
2584
  answer
1823
2585
  });
1824
2586
  return /* @__PURE__ */ jsxRuntime.jsx(
1825
- chunkVYRKO3XU_cjs.WorkflowRunner,
2587
+ chunkVFIZYSZB_cjs.WorkflowRunner,
1826
2588
  {
1827
2589
  workflow,
1828
2590
  run,
@@ -1868,7 +2630,22 @@ function ConnectedWorkflowBuilder({
1868
2630
  ...builderProps
1869
2631
  }) {
1870
2632
  const l = { ...DEFAULT_CONNECTED_WORKFLOW_BUILDER_LABELS, ...connectedLabels };
1871
- const { workspaceId } = chunkMUMH3Z6K_cjs.useConnection();
2633
+ const { workspaceId, status, ensureWorkspaceOpen } = chunkMUMH3Z6K_cjs.useConnection();
2634
+ const members = react$2.useWorkspaceUsers(workspaceId ?? void 0, {
2635
+ enabled: status === "authenticated" && !!workspaceId,
2636
+ beforeFetch: ensureWorkspaceOpen
2637
+ });
2638
+ const tagsQuery = react$2.useTags(workspaceId ?? void 0);
2639
+ const docsQuery = react$2.useDocuments(workspaceId ?? void 0);
2640
+ const people = (members.data ?? []).map((m) => ({
2641
+ value: m.user.external_id,
2642
+ label: [m.user.given_name, m.user.family_name].filter(Boolean).join(" ") || m.user.email
2643
+ }));
2644
+ const tagOptions = (tagsQuery.data ?? []).map((t) => ({ value: t.external_id, label: t.name }));
2645
+ const documentOptions = (docsQuery.data ?? []).map((d) => ({
2646
+ value: d.external_id,
2647
+ label: d.file_name ?? d.external_id
2648
+ }));
1872
2649
  const saved = react$2.useWorkflows();
1873
2650
  const skills = react$2.useSkills();
1874
2651
  const agentsQuery = react$2.useAgents();
@@ -1891,7 +2668,7 @@ function ConnectedWorkflowBuilder({
1891
2668
  () => [
1892
2669
  ...hostWorkflows,
1893
2670
  ...(skills.data ?? []).map(
1894
- (s) => chunkVYRKO3XU_cjs.skillToWorkflow({
2671
+ (s) => chunkVFIZYSZB_cjs.skillToWorkflow({
1895
2672
  name: s.name,
1896
2673
  slug: s.slug,
1897
2674
  description: s.description,
@@ -1907,7 +2684,7 @@ function ConnectedWorkflowBuilder({
1907
2684
  }));
1908
2685
  const tasks = (conversations.data ?? []).filter((c) => c.status && c.status !== "done").map((c) => ({ value: c.external_id, label: c.title || c.external_id }));
1909
2686
  const options = { resolveWorkflow: (wid) => workflows.find((w) => w.id === wid), compose };
1910
- const problem = triggerProblem(value.trigger) ?? (chunkVYRKO3XU_cjs.validateWorkflowGraph(chunkVYRKO3XU_cjs.workflowSteps(value.workflow)).length ? "graph" : null);
2687
+ const problem = triggerProblem(value.trigger) ?? (chunkVFIZYSZB_cjs.validateWorkflowGraph(chunkVFIZYSZB_cjs.workflowSteps(value.workflow)).length || chunkVFIZYSZB_cjs.stepConfigProblems(chunkVFIZYSZB_cjs.workflowSteps(value.workflow)).length ? "graph" : null);
1911
2688
  const busy = create.isPending || update.isPending || run.isPending;
1912
2689
  const save = async () => {
1913
2690
  if (!workspaceId) return void 0;
@@ -1929,6 +2706,9 @@ function ConnectedWorkflowBuilder({
1929
2706
  agents,
1930
2707
  eventKinds,
1931
2708
  tasks,
2709
+ people,
2710
+ tags: tagOptions,
2711
+ documents: documentOptions,
1932
2712
  signals: declaredSignals(saved.data ?? []),
1933
2713
  compose,
1934
2714
  testId,