@arbidocs/blocks 0.4.121 → 0.4.123

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/{StreamedArtifactEditor-IZWYNFMM.cjs → StreamedArtifactEditor-DNBDUNP2.cjs} +5 -5
  2. package/dist/{StreamedArtifactEditor-IZWYNFMM.cjs.map → StreamedArtifactEditor-DNBDUNP2.cjs.map} +1 -1
  3. package/dist/{StreamedArtifactEditor-HTNPG4NB.js → StreamedArtifactEditor-WDHPTWX7.js} +3 -3
  4. package/dist/{StreamedArtifactEditor-HTNPG4NB.js.map → StreamedArtifactEditor-WDHPTWX7.js.map} +1 -1
  5. package/dist/agents/index.cjs +392 -328
  6. package/dist/agents/index.js +11 -11
  7. package/dist/agents/tasks/ConversationListView.d.ts +2 -1
  8. package/dist/agents/tasks/ConversationTurnSpeaker.d.ts +3 -1
  9. package/dist/agents/tasks/TaskFlow.d.ts +17 -0
  10. package/dist/agents/tasks/ThreadLauncher.d.ts +51 -0
  11. package/dist/agents/tasks/ThreadStatusLine.d.ts +33 -0
  12. package/dist/agents/tasks/WorkflowRunStatus.d.ts +32 -0
  13. package/dist/agents/tasks/WorkflowThreadStrip.d.ts +29 -3
  14. package/dist/agents/tasks/compact-thread-activity.d.ts +5 -2
  15. package/dist/agents/tasks/index.d.ts +3 -0
  16. package/dist/agents/workflows/StepBarFrame.d.ts +18 -17
  17. package/dist/agents/workflows/StepChip.d.ts +37 -0
  18. package/dist/agents/workflows/StepDocuments.d.ts +64 -0
  19. package/dist/agents/workflows/WorkflowStepBar.d.ts +1 -2
  20. package/dist/agents/workflows/index.d.ts +2 -0
  21. package/dist/agents/workflows/stepKinds.d.ts +24 -0
  22. package/dist/artifacts/VersionTimeline.d.ts +7 -0
  23. package/dist/artifacts/index.cjs +21 -21
  24. package/dist/artifacts/index.js +1 -1
  25. package/dist/calls/index.cjs +1 -1
  26. package/dist/calls/index.js +1 -1
  27. package/dist/chat/ChatPage.d.ts +1 -1
  28. package/dist/chat/DraftingDocChip.d.ts +22 -0
  29. package/dist/chat/WorkflowStepChip.d.ts +23 -5
  30. package/dist/chat/chat-page-types.d.ts +18 -2
  31. package/dist/chat/flashMessage.d.ts +6 -0
  32. package/dist/chat/index.cjs +144 -131
  33. package/dist/chat/index.d.ts +2 -0
  34. package/dist/chat/index.js +4 -3
  35. package/dist/{chunk-UDK553WP.cjs → chunk-4VCKYR4D.cjs} +4 -4
  36. package/dist/{chunk-UDK553WP.cjs.map → chunk-4VCKYR4D.cjs.map} +1 -1
  37. package/dist/{chunk-5JVPLVDT.cjs → chunk-7FZWNDPU.cjs} +163 -837
  38. package/dist/chunk-7FZWNDPU.cjs.map +1 -0
  39. package/dist/chunk-7HAM7Y5U.js +907 -0
  40. package/dist/chunk-7HAM7Y5U.js.map +1 -0
  41. package/dist/{chunk-TCNYKDYE.js → chunk-CXLVI3SB.js} +73 -40
  42. package/dist/chunk-CXLVI3SB.js.map +1 -0
  43. package/dist/chunk-HM23LXUP.cjs +976 -0
  44. package/dist/chunk-HM23LXUP.cjs.map +1 -0
  45. package/dist/{chunk-WN64RF46.js → chunk-HQH35JWC.js} +3 -3
  46. package/dist/{chunk-WN64RF46.js.map → chunk-HQH35JWC.js.map} +1 -1
  47. package/dist/{chunk-DFHDWO6U.js → chunk-MD7RVFKA.js} +132 -752
  48. package/dist/chunk-MD7RVFKA.js.map +1 -0
  49. package/dist/{chunk-65HZ36MY.js → chunk-OTDGTBAS.js} +20 -3
  50. package/dist/chunk-OTDGTBAS.js.map +1 -0
  51. package/dist/{chunk-5Y7JRY7Y.js → chunk-P5ST47VY.js} +3 -3
  52. package/dist/{chunk-5Y7JRY7Y.js.map → chunk-P5ST47VY.js.map} +1 -1
  53. package/dist/{chunk-N5S6JG7S.js → chunk-RARHNGKM.js} +735 -187
  54. package/dist/chunk-RARHNGKM.js.map +1 -0
  55. package/dist/{chunk-4MRQKBD2.js → chunk-SOZNA52K.js} +3 -3
  56. package/dist/{chunk-4MRQKBD2.js.map → chunk-SOZNA52K.js.map} +1 -1
  57. package/dist/{chunk-GIEHWHVO.cjs → chunk-U2F4SSJR.cjs} +5 -5
  58. package/dist/{chunk-GIEHWHVO.cjs.map → chunk-U2F4SSJR.cjs.map} +1 -1
  59. package/dist/{chunk-SCLMCCMU.cjs → chunk-V4V2CVNE.cjs} +778 -224
  60. package/dist/chunk-V4V2CVNE.cjs.map +1 -0
  61. package/dist/{chunk-CK4C3IQR.cjs → chunk-VMZXFYHK.cjs} +47 -6
  62. package/dist/chunk-VMZXFYHK.cjs.map +1 -0
  63. package/dist/{chunk-SVJQWLOF.cjs → chunk-W4GXDARU.cjs} +20 -3
  64. package/dist/chunk-W4GXDARU.cjs.map +1 -0
  65. package/dist/{chunk-S2KVJYBD.cjs → chunk-WV4IDVDQ.cjs} +76 -43
  66. package/dist/chunk-WV4IDVDQ.cjs.map +1 -0
  67. package/dist/{chunk-2FUJXMGO.js → chunk-Y4X3RBFI.js} +44 -6
  68. package/dist/{chunk-CK4C3IQR.cjs.map → chunk-Y4X3RBFI.js.map} +1 -1
  69. package/dist/{chunk-NYHGG2IA.cjs → chunk-ZV3BKLFY.cjs} +3 -3
  70. package/dist/{chunk-NYHGG2IA.cjs.map → chunk-ZV3BKLFY.cjs.map} +1 -1
  71. package/dist/collaboration/index.cjs +10 -10
  72. package/dist/collaboration/index.js +2 -2
  73. package/dist/connect/index.cjs +66 -49
  74. package/dist/connect/index.cjs.map +1 -1
  75. package/dist/connect/index.js +36 -19
  76. package/dist/connect/index.js.map +1 -1
  77. package/dist/connection/WorkflowRunThread.d.ts +4 -4
  78. package/dist/connection/ai.d.ts +2 -0
  79. package/dist/document-tools/index.cjs +1 -1
  80. package/dist/document-tools/index.js +1 -1
  81. package/dist/facts/index.cjs +2 -2
  82. package/dist/facts/index.js +2 -2
  83. package/dist/files/index.cjs +3 -3
  84. package/dist/files/index.js +3 -3
  85. package/dist/home/index.cjs +17 -17
  86. package/dist/home/index.js +3 -3
  87. package/dist/index.cjs +790 -714
  88. package/dist/index.js +19 -19
  89. package/dist/settings/index.cjs +12 -12
  90. package/dist/settings/index.js +4 -4
  91. package/dist/shell/index.cjs +10 -10
  92. package/dist/shell/index.js +2 -2
  93. package/dist/site/index.cjs +5 -5
  94. package/dist/site/index.js +1 -1
  95. package/dist/studio/index.cjs +6 -5
  96. package/dist/studio/index.cjs.map +1 -1
  97. package/dist/studio/index.js +5 -4
  98. package/dist/studio/index.js.map +1 -1
  99. package/dist/workflow-canvas/WorkflowCanvas.d.ts +0 -9
  100. package/dist/workflow-canvas/edit.d.ts +2 -11
  101. package/dist/workflow-canvas/index.cjs +65 -89
  102. package/dist/workflow-canvas/index.cjs.map +1 -1
  103. package/dist/workflow-canvas/index.js +16 -40
  104. package/dist/workflow-canvas/index.js.map +1 -1
  105. package/dist/workspaces/index.cjs +1 -1
  106. package/dist/workspaces/index.js +1 -1
  107. package/node_modules/@arbidocs/coedit/package.json +1 -1
  108. package/package.json +4 -4
  109. package/src/blocks.css +168 -0
  110. package/src/workflow-canvas/canvas.css +2 -40
  111. package/dist/chunk-2FUJXMGO.js.map +0 -1
  112. package/dist/chunk-5JVPLVDT.cjs.map +0 -1
  113. package/dist/chunk-65HZ36MY.js.map +0 -1
  114. package/dist/chunk-B4SRYJLM.cjs +0 -107
  115. package/dist/chunk-B4SRYJLM.cjs.map +0 -1
  116. package/dist/chunk-DFHDWO6U.js.map +0 -1
  117. package/dist/chunk-HOXKR26S.js +0 -103
  118. package/dist/chunk-HOXKR26S.js.map +0 -1
  119. package/dist/chunk-N5S6JG7S.js.map +0 -1
  120. package/dist/chunk-S2KVJYBD.cjs.map +0 -1
  121. package/dist/chunk-SCLMCCMU.cjs.map +0 -1
  122. package/dist/chunk-SVJQWLOF.cjs.map +0 -1
  123. package/dist/chunk-TCNYKDYE.js.map +0 -1
@@ -1,278 +1,16 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
+ var chunk7D737FLE_cjs = require('./chunk-7D737FLE.cjs');
4
5
  var chunkDETZZBG2_cjs = require('./chunk-DETZZBG2.cjs');
6
+ var chunkHM23LXUP_cjs = require('./chunk-HM23LXUP.cjs');
5
7
  var chunk32HW2Q33_cjs = require('./chunk-32HW2Q33.cjs');
6
- var chunk7D737FLE_cjs = require('./chunk-7D737FLE.cjs');
7
- var chunkB4SRYJLM_cjs = require('./chunk-B4SRYJLM.cjs');
8
8
  var chunkMHVNT4J3_cjs = require('./chunk-MHVNT4J3.cjs');
9
9
  var react = require('react');
10
10
  var lucideReact = require('lucide-react');
11
11
  var ui = require('@arbidocs/react/ui');
12
12
  var jsxRuntime = require('react/jsx-runtime');
13
13
 
14
- // src/agents/workflows/types.ts
15
- var EMPTY_WORKFLOW_SCOPE = { folders: [], labels: [] };
16
-
17
- // src/agents/workflows/workflow.ts
18
- var isWorkflowScope = (value) => typeof value === "object" && value !== null && Array.isArray(value.folders) && Array.isArray(value.labels);
19
- var isEmptyWorkflowScope = (scope) => scope.folders.length === 0 && scope.labels.length === 0 && !scope.documents?.length;
20
- var isFileField = (field) => field.type === "scope" || field.type === "documents";
21
- function emptyValue(field) {
22
- switch (field.type) {
23
- case "boolean":
24
- return false;
25
- case "scope":
26
- return { folders: [], labels: [] };
27
- case "documents":
28
- return { folders: [], labels: [], documents: [] };
29
- default:
30
- return "";
31
- }
32
- }
33
- function defaultInputs(workflow) {
34
- const inputs = {};
35
- for (const field of workflow.inputs) {
36
- const d = field.default;
37
- inputs[field.name] = d === void 0 ? emptyValue(field) : isWorkflowScope(d) ? { ...d } : d;
38
- }
39
- return inputs;
40
- }
41
- function validateInputs(workflow, inputs) {
42
- const errors = {};
43
- for (const field of workflow.inputs) {
44
- const value = inputs[field.name];
45
- if (field.type === "number") {
46
- const blank = value === "" || value === void 0;
47
- if (blank) {
48
- if (field.required) errors[field.name] = "required";
49
- continue;
50
- }
51
- const n = Number(value);
52
- if (Number.isNaN(n)) errors[field.name] = "number";
53
- else if (field.min !== void 0 && n < field.min) errors[field.name] = "min";
54
- else if (field.max !== void 0 && n > field.max) errors[field.name] = "max";
55
- continue;
56
- }
57
- if (!field.required) continue;
58
- if (field.type === "documents") {
59
- if (!isWorkflowScope(value) || !value.documents?.length) errors[field.name] = "required";
60
- continue;
61
- }
62
- if (field.type === "boolean" || field.type === "scope") continue;
63
- if (typeof value !== "string" || value.trim() === "") errors[field.name] = "required";
64
- }
65
- return errors;
66
- }
67
- function promptFieldName(workflow) {
68
- return workflow.inputs.find((f) => !f.advanced && (f.type === "text" || f.type === "longtext"))?.name;
69
- }
70
- var quoteList = (names) => {
71
- const quoted = names.map((n) => `"${n}"`);
72
- return quoted.length <= 1 ? quoted[0] ?? "" : `${quoted.slice(0, -1).join(", ")} and ${quoted[quoted.length - 1]}`;
73
- };
74
- function fragment(field, value, ctx) {
75
- switch (field.type) {
76
- case "documents": {
77
- const ids = isWorkflowScope(value) ? value.documents ?? [] : [];
78
- const names = ids.flatMap((id) => {
79
- const title = ctx?.documentTitles?.[id];
80
- return title ? [title] : [];
81
- });
82
- return quoteList(names);
83
- }
84
- case "boolean":
85
- return value ? field.trueText ?? "yes" : field.falseText ?? "no";
86
- case "select": {
87
- const option = field.options?.find((o) => o.value === value);
88
- return option ? option.text ?? option.label : String(value ?? "");
89
- }
90
- case "scope":
91
- return "";
92
- default:
93
- return typeof value === "string" ? value.trim() : String(value ?? "");
94
- }
95
- }
96
- function composeWorkflowPrompt(workflow, inputs, ctx) {
97
- if (workflow.run.kind !== "prompt") return "";
98
- const byName = new Map(workflow.inputs.map((f) => [f.name, f]));
99
- const template = workflow.run.promptTemplate;
100
- let out = "";
101
- let last = 0;
102
- const append = (text, isValue) => {
103
- let t = text;
104
- if (!isValue) {
105
- t = t.replace(/[ \t]{2,}/g, " ");
106
- if (/[ \t]$/.test(out)) t = t.replace(/^[ \t]+/, "");
107
- }
108
- out += t;
109
- };
110
- for (const m of template.matchAll(/\{\{\s*([a-z][a-z0-9_]*)\s*\}\}/gi)) {
111
- append(template.slice(last, m.index), false);
112
- const field = byName.get(m[1]);
113
- append(field ? fragment(field, inputs[m[1]], ctx) : "", true);
114
- last = m.index + m[0].length;
115
- }
116
- append(template.slice(last), false);
117
- return out.trim();
118
- }
119
- function buildLaunch(workflow, inputs, agentId) {
120
- const scopeField = workflow.inputs.find(isFileField);
121
- const raw = scopeField ? inputs[scopeField.name] : void 0;
122
- const scope = isWorkflowScope(raw) ? raw : { ...EMPTY_WORKFLOW_SCOPE };
123
- return { workflow, inputs, scope, agentId: agentId || workflow.defaultAgentId || void 0 };
124
- }
125
- function workflowAccepts(workflow) {
126
- const kinds = /* @__PURE__ */ new Set();
127
- for (const field of workflow.inputs) if (field.context) kinds.add(field.context);
128
- return [...kinds];
129
- }
130
- function workflowsAccepting(workflows, supplied) {
131
- return workflows.filter((w) => workflowAccepts(w).some((k) => supplied.includes(k)));
132
- }
133
- function workflowsForHost(workflows, host) {
134
- return workflows.filter((w) => !w.host || w.host === host);
135
- }
136
- function inputsFromContext(workflow, context) {
137
- const inputs = {};
138
- for (const field of workflow.inputs) {
139
- if (!field.context) continue;
140
- if (field.context === "selection") {
141
- if (context.selection) inputs[field.name] = context.selection;
142
- continue;
143
- }
144
- const ids = field.context === "image" ? context.image ? [context.image] : [] : context.documents;
145
- if (ids?.length && isFileField(field)) {
146
- inputs[field.name] = { folders: [], labels: [], documents: ids.slice(0, field.max ?? 1) };
147
- }
148
- }
149
- return inputs;
150
- }
151
- var SKILL_PROMPT_LABEL = "What should it work on?";
152
- var SKILL_PROMPT_FALLBACK_PLACEHOLDER = "Describe what you want";
153
- var plainHint = (hint) => hint.replace(/^[<[]\s*|\s*[>\]]$/g, "").trim();
154
- function skillToWorkflow(skill) {
155
- const hint = plainHint((skill.arg_hint ?? "").trim());
156
- const inputs = [
157
- {
158
- name: "args",
159
- type: "longtext",
160
- label: SKILL_PROMPT_LABEL,
161
- placeholder: hint || SKILL_PROMPT_FALLBACK_PLACEHOLDER,
162
- required: true
163
- }
164
- ];
165
- return {
166
- id: skill.slug,
167
- skill: skill.slug,
168
- title: skill.name || skill.slug,
169
- description: skill.description ?? "",
170
- inputs,
171
- run: { kind: "prompt", promptTemplate: `/${skill.slug} {{args}}` },
172
- landing: "chat",
173
- schedulable: true
174
- };
175
- }
176
- var FIELD_TYPES = [
177
- "text",
178
- "longtext",
179
- "boolean",
180
- "select",
181
- "number",
182
- "date",
183
- "scope",
184
- "documents"
185
- ];
186
- var str = (v) => typeof v === "string" ? v : void 0;
187
- var num = (v) => typeof v === "number" ? v : void 0;
188
- var bool = (v) => typeof v === "boolean" ? v : void 0;
189
- function fieldFromFrontmatter(raw) {
190
- if (typeof raw !== "object" || raw === null) return null;
191
- const r = raw;
192
- const name = str(r.name);
193
- const type = FIELD_TYPES.find((t) => t === r.type);
194
- if (!name || !/^[a-z][a-z0-9_]*$/.test(name) || !type) return null;
195
- const options = Array.isArray(r.options) ? r.options.flatMap((o) => {
196
- const ro = o;
197
- const value = str(ro?.value);
198
- const label = str(ro?.label);
199
- return value && label ? [
200
- {
201
- value,
202
- label,
203
- description: str(ro.description),
204
- text: str(ro.text),
205
- icon: str(ro.icon),
206
- tone: chunk32HW2Q33_cjs.isTone(ro.tone) ? ro.tone : void 0
207
- }
208
- ] : [];
209
- }) : void 0;
210
- return {
211
- name,
212
- type,
213
- label: str(r.label) ?? name,
214
- description: str(r.description),
215
- placeholder: str(r.placeholder),
216
- required: bool(r.required),
217
- default: r.default,
218
- options,
219
- min: num(r.min),
220
- max: num(r.max),
221
- trueText: str(r.true_text),
222
- falseText: str(r.false_text),
223
- advanced: bool(r.advanced),
224
- accept: r.accept === "image" ? "image" : void 0,
225
- context: r.context === "documents" || r.context === "selection" || r.context === "image" ? r.context : void 0,
226
- by: Array.isArray(r.by) ? r.by.filter((b) => b === "folders" || b === "labels") : void 0
227
- };
228
- }
229
- function workflowFromFrontmatter(id, frontmatter, body) {
230
- const inputs = Array.isArray(frontmatter.inputs) ? frontmatter.inputs.flatMap((f) => {
231
- const field = fieldFromFrontmatter(f);
232
- return field ? [field] : [];
233
- }) : [];
234
- return {
235
- id,
236
- title: str(frontmatter.name) ?? id,
237
- description: str(frontmatter.description) ?? "",
238
- icon: str(frontmatter.icon),
239
- inputs,
240
- run: { kind: "prompt", promptTemplate: body.trim() },
241
- landing: frontmatter.landing === "files" ? "files" : "chat",
242
- requiresFiles: bool(frontmatter.requires_files),
243
- schedulable: bool(frontmatter.schedulable) ?? true
244
- };
245
- }
246
- function fieldToFrontmatter(field) {
247
- return compact({
248
- name: field.name,
249
- type: field.type,
250
- label: field.label,
251
- description: field.description,
252
- placeholder: field.placeholder,
253
- required: field.required,
254
- default: field.default,
255
- options: field.options?.map(
256
- (o) => compact({
257
- value: o.value,
258
- label: o.label,
259
- description: o.description,
260
- text: o.text,
261
- icon: o.icon,
262
- tone: o.tone
263
- })
264
- ),
265
- min: field.min,
266
- max: field.max,
267
- true_text: field.trueText,
268
- false_text: field.falseText,
269
- advanced: field.advanced,
270
- by: field.by,
271
- accept: field.accept,
272
- context: field.context
273
- });
274
- }
275
- var compact = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
276
14
  var DEFAULT_SCHEMA_FORM_LABELS = {
277
15
  optional: "(optional)",
278
16
  advanced: "More options",
@@ -378,7 +116,7 @@ function FieldControl({
378
116
  case "select": {
379
117
  const options = field.options ?? [];
380
118
  if (options.length > 0 && options.length <= TILE_MAX) {
381
- const compact3 = options.every((o) => !o.icon && !o.description);
119
+ const compact2 = options.every((o) => !o.icon && !o.description);
382
120
  return /* @__PURE__ */ jsxRuntime.jsx(
383
121
  "div",
384
122
  {
@@ -391,7 +129,7 @@ function FieldControl({
391
129
  {
392
130
  option,
393
131
  selected: value === option.value,
394
- compact: compact3,
132
+ compact: compact2,
395
133
  renderIcon,
396
134
  testId: chunkMHVNT4J3_cjs.prefixedTestId(testId, option.value, {
397
135
  testId: `workflow-field-${field.name}-${option.value}`
@@ -409,11 +147,11 @@ function FieldControl({
409
147
  ] });
410
148
  }
411
149
  case "scope": {
412
- const scope = isWorkflowScope(value) ? value : { folders: [], labels: [] };
150
+ const scope = chunkHM23LXUP_cjs.isWorkflowScope(value) ? value : { folders: [], labels: [] };
413
151
  return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": testId, children: renderScope?.(field, scope, onChange) });
414
152
  }
415
153
  case "documents": {
416
- const picked = isWorkflowScope(value) ? value : { folders: [], labels: [], documents: [] };
154
+ const picked = chunkHM23LXUP_cjs.isWorkflowScope(value) ? value : { folders: [], labels: [], documents: [] };
417
155
  return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": testId, children: renderDocuments?.(field, picked, onChange) });
418
156
  }
419
157
  case "person":
@@ -449,7 +187,7 @@ function FieldControl({
449
187
  function ChoiceTile({
450
188
  option,
451
189
  selected,
452
- compact: compact3,
190
+ compact: compact2,
453
191
  renderIcon,
454
192
  testId,
455
193
  onSelect
@@ -467,7 +205,7 @@ function ChoiceTile({
467
205
  className: ui.cn(
468
206
  // Sized to its label (flex-basis auto), growing to share the row, never wider than it.
469
207
  "flex max-w-full min-w-[min(4rem,100%)] flex-auto flex-col items-center justify-center gap-1.5 rounded-lg border text-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
470
- compact3 ? "min-h-9 px-3 py-1.5 pointer-coarse:min-h-11" : "min-h-24 p-3 pointer-coarse:min-h-28",
208
+ compact2 ? "min-h-9 px-3 py-1.5 pointer-coarse:min-h-11" : "min-h-24 p-3 pointer-coarse:min-h-28",
471
209
  tone ? selected ? ui.cn(chunk32HW2Q33_cjs.TONE_SURFACE[tone], chunk32HW2Q33_cjs.TONE_SOLID_BORDER[tone]) : ui.cn(chunk32HW2Q33_cjs.TONE_BORDER[tone], "bg-card [&:hover]:bg-muted") : selected ? "border-primary bg-primary/10" : "border-border bg-card [&:hover]:border-primary [&:hover]:bg-muted"
472
210
  ),
473
211
  children: [
@@ -583,313 +321,6 @@ function SchemaForm({
583
321
  ] });
584
322
  }
585
323
 
586
- // src/agents/workflows/run.ts
587
- function workflowSteps(workflow) {
588
- return workflow.run.kind === "steps" ? workflow.run.steps : [];
589
- }
590
- var isSteppedWorkflow = (workflow) => workflow.run.kind === "steps";
591
- function stepDependencies(steps, id) {
592
- const i = steps.findIndex((s) => s.id === id);
593
- if (i < 0) return [];
594
- return steps[i].after ?? (i > 0 ? [steps[i - 1].id] : []);
595
- }
596
- function dependsOn(steps, a, b) {
597
- const seen = /* @__PURE__ */ new Set();
598
- const stack = [...stepDependencies(steps, a)];
599
- while (stack.length) {
600
- const id = stack.pop();
601
- if (id === b) return true;
602
- if (seen.has(id)) continue;
603
- seen.add(id);
604
- stack.push(...stepDependencies(steps, id));
605
- }
606
- return false;
607
- }
608
- function orderSteps(steps) {
609
- const explicit = steps.map((s) => ({ ...s, after: stepDependencies(steps, s.id) }));
610
- const known = new Set(explicit.map((s) => s.id));
611
- const placed = /* @__PURE__ */ new Set();
612
- const out = [];
613
- let progress = true;
614
- while (out.length < explicit.length && progress) {
615
- progress = false;
616
- for (const s of explicit) {
617
- if (placed.has(s.id)) continue;
618
- if (s.after.every((d) => placed.has(d) || !known.has(d))) {
619
- out.push(s);
620
- placed.add(s.id);
621
- progress = true;
622
- break;
623
- }
624
- }
625
- }
626
- return [...out, ...explicit.filter((s) => !placed.has(s.id))];
627
- }
628
- function validateWorkflowGraph(steps) {
629
- const problems = [];
630
- const ids = /* @__PURE__ */ new Set();
631
- for (const s of steps) {
632
- if (ids.has(s.id)) problems.push({ code: "duplicate", step: s.id });
633
- ids.add(s.id);
634
- }
635
- steps.forEach((s, i) => {
636
- for (const d of stepDependencies(steps, s.id)) {
637
- if (!ids.has(d)) problems.push({ code: "unknown", step: s.id, dependency: d });
638
- else if (d === s.id || dependsOn(steps, d, s.id)) problems.push({ code: "cycle", step: s.id });
639
- else if (steps.findIndex((x) => x.id === d) > i)
640
- problems.push({ code: "order", step: s.id, dependency: d });
641
- }
642
- });
643
- return problems;
644
- }
645
- function stepLevels(steps) {
646
- const depth = /* @__PURE__ */ new Map();
647
- for (const s of steps) {
648
- const deps = stepDependencies(steps, s.id).filter((d) => depth.has(d));
649
- depth.set(s.id, deps.length ? Math.max(...deps.map((d) => depth.get(d))) + 1 : 0);
650
- }
651
- const levels = [];
652
- for (const s of steps) (levels[depth.get(s.id)] ??= []).push(s);
653
- return levels.filter(Boolean);
654
- }
655
- var STEP_EVENTS = {
656
- step_started: "running",
657
- step_waiting: "waiting",
658
- step_done: "done",
659
- step_skipped: "skipped",
660
- step_failed: "failed"
661
- };
662
- var str2 = (v) => typeof v === "string" && v ? v : void 0;
663
- var ACTION_TYPES = ["sign", "email_draft", "tabular_review"];
664
- var asAction = (v) => ACTION_TYPES.includes(v) ? v : void 0;
665
- var asRecord = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
666
- var asStrings = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : void 0;
667
- function waitingDocuments(state) {
668
- return state?.status === "waiting" ? asStrings(state.waiting?.documents) ?? [] : [];
669
- }
670
- function eventWaitingDocuments(detail) {
671
- return asStrings(asRecord(detail?.waiting)?.documents);
672
- }
673
- function waitingForDocumentsText(count) {
674
- return `Waiting for ${count} ${count === 1 ? "document" : "documents"} to finish processing`;
675
- }
676
- function reopenedBy(detail) {
677
- const to = str2(detail.to);
678
- return asStrings(detail.reopened) ?? (to ? [to] : []);
679
- }
680
- function stepStatesFromActivity(events) {
681
- const states = {};
682
- for (const e of events) {
683
- const detail = e.detail ?? {};
684
- const step = str2(detail.step);
685
- if (!step) continue;
686
- if (e.kind === "step_sent_back") {
687
- const to = str2(detail.to);
688
- for (const id of reopenedBy(detail))
689
- states[id] = id === to ? {
690
- status: "pending",
691
- sentBack: true,
692
- hasNote: typeof detail.note_encrypted === "string"
693
- } : { status: "pending" };
694
- continue;
695
- }
696
- if (e.kind === "step_ready") {
697
- states[step] = { ...states[step] ?? { status: "pending" }, announcedTo: str2(detail.to) };
698
- continue;
699
- }
700
- if (e.kind === "step_progress") {
701
- const before2 = states[step];
702
- const waiting2 = asRecord(detail.waiting);
703
- if (before2?.status === "waiting" && waiting2) states[step] = { ...before2, waiting: waiting2 };
704
- continue;
705
- }
706
- const status = STEP_EVENTS[e.kind];
707
- if (!status) continue;
708
- const before = states[step];
709
- const responseId = str2(detail.response_id) ?? before?.responseId ?? null;
710
- const startedAt = status === "running" ? e.created_at : before?.startedAt;
711
- const action = asAction(detail.action) ?? before?.action;
712
- const documents = asStrings(detail.documents) ?? before?.documents;
713
- const waiting = status === "waiting" ? asRecord(detail.waiting) : void 0;
714
- const output = status === "done" ? asRecord(detail.output) : void 0;
715
- const approved = Array.isArray(detail.approved) ? detail.approved.filter(asRecord) : void 0;
716
- const finished2 = status === "done" || status === "skipped" || status === "failed";
717
- const declinedBy = str2(detail.declined_by);
718
- const afterFailure = status === "skipped" && (before?.status === "failed" || !!before?.skippedAfterFailure);
719
- states[step] = {
720
- status,
721
- responseId,
722
- error: str2(detail.error) ?? (afterFailure ? before?.error ?? null : null),
723
- ...afterFailure ? { skippedAfterFailure: true } : {},
724
- ...startedAt ? { startedAt } : {},
725
- ...action ? { action } : {},
726
- ...documents?.length ? { documents } : {},
727
- ...waiting ? { waiting } : {},
728
- ...output ? { output } : {},
729
- ...approved ? { approved } : {},
730
- ...finished2 ? { by: e.actor_ext_id ?? null } : {},
731
- ...finished2 && e.created_at ? { at: e.created_at } : {},
732
- ...declinedBy ? { declinedBy } : {}
733
- };
734
- }
735
- return states;
736
- }
737
- function stepFields(step) {
738
- return step.kind === "form" ? step.inputs : step.kind === "review" ? step.fields ?? [] : [];
739
- }
740
- var runFieldsOf = (steps) => steps.flatMap(stepFields);
741
- function runFields(workflow) {
742
- return [...workflow.inputs, ...workflowSteps(workflow).flatMap(stepFields)];
743
- }
744
- function initialRunInputs(workflow, inputs = {}) {
745
- return { ...defaultInputs({ ...workflow, inputs: runFields(workflow) }), ...inputs };
746
- }
747
- var finished = (s) => s?.status === "done" || s?.status === "skipped";
748
- function stepPhase(steps, states, id) {
749
- const s = states[id];
750
- if (s && s.status !== "pending") return s.status;
751
- return stepDependencies(steps, id).every((d) => finished(states[d])) ? "ready" : "blocked";
752
- }
753
- var isRunFinished = (steps, states) => steps.length > 0 && steps.every((s) => finished(states[s.id]));
754
- var isPersonStep = (step) => step.kind !== "agent" && step.kind !== "action";
755
- var isPersonAction = (step) => step.kind === "action" && (step.action.type === "sign" || step.action.type === "email_draft");
756
- var canAssign = (step) => isPersonStep(step) || isPersonAction(step);
757
- function nextAction(steps, states, current, { needsStart = false, canRetry = false } = {}) {
758
- const i = steps.findIndex((s) => s.id === current);
759
- const step = steps[i];
760
- if (!step) return "wait";
761
- const phase = stepPhase(steps, states, step.id);
762
- if (phase === "blocked") return "wait";
763
- const following = steps[i + 1];
764
- const independentNext = !!following && !dependsOn(steps, following.id, step.id);
765
- if (phase === "done" || phase === "skipped") {
766
- if (following) return "move";
767
- return isRunFinished(steps, states) ? "finish" : "wait";
768
- }
769
- if (isPersonStep(step)) return "complete";
770
- if (phase === "waiting" && step.kind === "action" && step.action.type === "email_draft")
771
- return "complete";
772
- if (phase === "ready" && needsStart) return "start";
773
- if (phase !== "failed") return independentNext ? "move" : "wait";
774
- const waitedFor = steps.slice(i + 1).some((s) => dependsOn(steps, s.id, step.id));
775
- if (!waitedFor && following) return "move";
776
- return canRetry ? "retry" : "wait";
777
- }
778
- function failedUpstream(steps, states, id) {
779
- return upstreamSteps(steps, id).flatMap((s) => {
780
- const state = states[s.id];
781
- return state && (state.status === "failed" || state.skippedAfterFailure) ? [{ step: s, state }] : [];
782
- });
783
- }
784
- function validateStep(step, inputs) {
785
- const fields = stepFields(step);
786
- if (!fields.length) return {};
787
- return validateInputs(
788
- {
789
- id: step.id,
790
- title: step.title,
791
- inputs: fields},
792
- inputs
793
- );
794
- }
795
- function upstreamSteps(steps, id) {
796
- return steps.filter((s) => s.id !== id && dependsOn(steps, id, s.id));
797
- }
798
- function sendBackTargets(steps, states, id) {
799
- return upstreamSteps(steps, id).filter((s) => ["done", "skipped", "failed"].includes(states[s.id]?.status ?? "pending")).reverse();
800
- }
801
- var isBlankRef = (ref) => "step" in ref ? !ref.step : "input" in ref ? !ref.input : !ref.id.trim();
802
- function stepConfigProblems(steps) {
803
- const out = [];
804
- for (const s of steps) {
805
- if (s.kind === "action") {
806
- const a = s.action;
807
- if (a.type === "sign") {
808
- if (!a.document || isBlankRef(a.document)) out.push({ step: s.id, missing: "document" });
809
- if (!a.signers.length) out.push({ step: s.id, missing: "signers" });
810
- } else if (a.type === "email_draft") {
811
- if (!a.to.some((t) => t.trim())) out.push({ step: s.id, missing: "recipients" });
812
- } else {
813
- if (!a.tags.length) out.push({ step: s.id, missing: "tags" });
814
- if (Array.isArray(a.documents) && !a.documents.length)
815
- out.push({ step: s.id, missing: "documents" });
816
- }
817
- }
818
- if (s.kind === "agent" && s.editDocument && isBlankRef(s.editDocument))
819
- out.push({ step: s.id, missing: "document" });
820
- }
821
- return out;
822
- }
823
- function splitDocRef(ref) {
824
- const m = /^(doc-[A-Za-z0-9]+)(?:@v(\d+))?$/.exec(ref);
825
- return m ? { id: m[1], ...m[2] ? { version: Number(m[2]) } : {} } : { id: ref };
826
- }
827
- var DEFAULT_ASSIGNEE_WORDING = {
828
- runOwner: "whoever started the run",
829
- projectLead: "the project lead",
830
- input: "the person in \u201C{field}\u201D"
831
- };
832
- function assigneeName(assignee, options = {}) {
833
- const w = { ...DEFAULT_ASSIGNEE_WORDING, ...options.wording };
834
- const name = (id) => options.nameOf?.(id) ?? id;
835
- const told = options.announcedTo ? options.nameOf?.(options.announcedTo) : void 0;
836
- if (told) return told;
837
- if (!assignee) return void 0;
838
- if ("user" in assignee) return name(assignee.user);
839
- if ("input" in assignee) {
840
- const value = options.inputs?.[assignee.input];
841
- if (typeof value === "string" && value) return name(value);
842
- const label = options.fields?.find((f) => f.name === assignee.input)?.label ?? assignee.input;
843
- return w.input.replace("{field}", label);
844
- }
845
- if ("runOwner" in assignee) return w.runOwner;
846
- return w.projectLead;
847
- }
848
- var asText = (value) => typeof value === "string" ? value.trim() : typeof value === "number" ? String(value) : "";
849
- function fillStepInputs(templates, inputs) {
850
- const out = {};
851
- for (const [name, template] of Object.entries(templates ?? {})) {
852
- const bare = /^\{\{\s*([a-z][a-z0-9_]*)\s*\}\}$/i.exec(template);
853
- if (bare) {
854
- out[name] = inputs[bare[1]] ?? "";
855
- continue;
856
- }
857
- out[name] = fillRunText(template, inputs);
858
- }
859
- return out;
860
- }
861
- function fillRunText(template, inputs) {
862
- return template.replace(/\{\{([^}]*)\}\}/g, (_, expr) => {
863
- for (const ref of expr.split("||")) {
864
- const text = asText(inputs[ref.trim()]);
865
- if (text) return text;
866
- }
867
- return "";
868
- }).trim();
869
- }
870
- function runThreadTitle(workflow, inputs) {
871
- const template = workflow.run.kind === "steps" ? workflow.run.threadTitle : void 0;
872
- return template && fillRunText(template, inputs) || workflow.title;
873
- }
874
- function reviewInstructions(step, inputs) {
875
- return step.instructions && fillRunText(step.instructions, inputs) || step.title;
876
- }
877
- function composeStepPrompt(workflow, step, runInputs, { resolveWorkflow, compose } = {}) {
878
- if (step.workflow) {
879
- const target = resolveWorkflow?.(step.workflow);
880
- if (!target) return "";
881
- const inputs = { ...defaultInputs(target), ...fillStepInputs(step.with, runInputs) };
882
- return target.run.kind === "prompt" ? composeWorkflowPrompt(target, inputs) : compose?.(target.id, inputs, runInputs) ?? "";
883
- }
884
- if (step.run?.kind === "prompt") {
885
- return composeWorkflowPrompt(
886
- { ...workflow, inputs: runFields(workflow), run: step.run },
887
- runInputs
888
- );
889
- }
890
- return compose?.(step.id, runInputs, runInputs) ?? "";
891
- }
892
-
893
324
  // src/agents/workflows/planSteps.ts
894
325
  function toPlanAssignee(a) {
895
326
  if ("user" in a) return { user: a.user };
@@ -996,9 +427,9 @@ function toStepField(f) {
996
427
  ...f.max !== void 0 ? { max: f.max } : {}
997
428
  };
998
429
  }
999
- var compact2 = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0 && v !== ""));
430
+ var compact = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0 && v !== ""));
1000
431
  function placeholders(workflow) {
1001
- return Object.fromEntries(runFields(workflow).map((f) => [f.name, `{{${f.name}}}`]));
432
+ return Object.fromEntries(chunkHM23LXUP_cjs.runFields(workflow).map((f) => [f.name, `{{${f.name}}}`]));
1002
433
  }
1003
434
  function agentStep(workflow, step, options) {
1004
435
  const target = step.workflow ? options.resolveWorkflow?.(step.workflow) : void 0;
@@ -1007,12 +438,12 @@ function agentStep(workflow, step, options) {
1007
438
  ([, v]) => v !== void 0 && v !== null && v !== ""
1008
439
  );
1009
440
  const inputs = { ...placeholders(workflow), ...Object.fromEntries(given) };
1010
- return { skill: null, inputs: null, prompt: composeStepPrompt(workflow, step, inputs, options) };
441
+ return { skill: null, inputs: null, prompt: chunkHM23LXUP_cjs.composeStepPrompt(workflow, step, inputs, options) };
1011
442
  }
1012
443
  function toPlanSteps(workflow, options = {}) {
1013
444
  const layout = workflow.run.kind === "steps" ? workflow.run.layout : void 0;
1014
- return workflowSteps(workflow).map((step) => {
1015
- const ui = compact2({
445
+ return chunkHM23LXUP_cjs.workflowSteps(workflow).map((step) => {
446
+ const ui = compact({
1016
447
  description: step.description,
1017
448
  icon: step.icon,
1018
449
  commit: step.commit,
@@ -1038,8 +469,8 @@ function toPlanSteps(workflow, options = {}) {
1038
469
  ui,
1039
470
  // An unfinished signal (still being typed) is not saved: the server would refuse it.
1040
471
  ...step.signals?.some((s) => !isIncompleteSignal(s)) ? { signals: step.signals.filter((s) => !isIncompleteSignal(s)).map(toPlanSignal) } : {},
1041
- ...step.assignee && canAssign(step) ? { assignee: toPlanAssignee(step.assignee) } : {},
1042
- ...step.remindAfterHours && canAssign(step) ? { remind_after_hours: step.remindAfterHours } : {},
472
+ ...step.assignee && chunkHM23LXUP_cjs.canAssign(step) ? { assignee: toPlanAssignee(step.assignee) } : {},
473
+ ...step.remindAfterHours && chunkHM23LXUP_cjs.canAssign(step) ? { remind_after_hours: step.remindAfterHours } : {},
1043
474
  // A review's fields are what approving it is checked against (the server's `fields`).
1044
475
  ...step.kind === "review" && step.fields?.length ? { fields: step.fields.map(toStepField) } : {},
1045
476
  ...step.kind === "action" ? { action: toPlanAction(step.action) } : {},
@@ -1118,7 +549,7 @@ function layoutFromPlanSteps(steps) {
1118
549
  });
1119
550
  return entries.length ? Object.fromEntries(entries) : void 0;
1120
551
  }
1121
- var FIELD_TYPES2 = /* @__PURE__ */ new Set([
552
+ var FIELD_TYPES = /* @__PURE__ */ new Set([
1122
553
  "text",
1123
554
  "longtext",
1124
555
  "boolean",
@@ -1132,7 +563,7 @@ var FIELD_TYPES2 = /* @__PURE__ */ new Set([
1132
563
  function fromStepField(f) {
1133
564
  return {
1134
565
  name: f.name,
1135
- type: FIELD_TYPES2.has(f.type) ? f.type : "text",
566
+ type: FIELD_TYPES.has(f.type) ? f.type : "text",
1136
567
  label: f.label ?? f.name,
1137
568
  ...f.required ? { required: true } : {},
1138
569
  ...f.options?.length ? { options: f.options.map((o) => ({ value: o.value, label: o.label ?? o.value })) } : {},
@@ -1143,7 +574,7 @@ function fromStepField(f) {
1143
574
  var errorMessage = (e) => e instanceof Error ? e.message : typeof e === "string" ? e : "Something went wrong.";
1144
575
  function firstOpen(steps, states) {
1145
576
  const open = steps.find((s) => !["done", "skipped"].includes(states[s.id]?.status ?? "pending"));
1146
- return open?.id ?? (steps.length && isRunFinished(steps, states) ? null : steps[0]?.id ?? null);
577
+ return open?.id ?? (steps.length && chunkHM23LXUP_cjs.isRunFinished(steps, states) ? null : steps[0]?.id ?? null);
1147
578
  }
1148
579
  function useWorkflowView(options) {
1149
580
  const { steps, states, inputs, setInput, loaded = true } = options;
@@ -1183,11 +614,11 @@ function useWorkflowView(options) {
1183
614
  }),
1184
615
  []
1185
616
  );
1186
- const action = busy ? "wait" : nextAction(steps, states, current, actionOptions(options));
617
+ const action = busy ? "wait" : chunkHM23LXUP_cjs.nextAction(steps, states, current, actionOptions(options));
1187
618
  const next = react.useCallback(async () => {
1188
619
  const { steps: s, states: st, inputs: values } = optionsRef.current;
1189
620
  const at = s.find((x) => x.id === current);
1190
- const act2 = nextAction(s, st, current, actionOptions(optionsRef.current));
621
+ const act2 = chunkHM23LXUP_cjs.nextAction(s, st, current, actionOptions(optionsRef.current));
1191
622
  if (!at || act2 === "wait" || busy) return;
1192
623
  setActionError(null);
1193
624
  if (act2 === "finish") return setCurrent(null);
@@ -1198,7 +629,7 @@ function useWorkflowView(options) {
1198
629
  await (act2 === "start" ? optionsRef.current.start?.() : optionsRef.current.retry?.(at.id));
1199
630
  return;
1200
631
  }
1201
- if (Object.keys(validateStep(at, values)).length > 0) {
632
+ if (Object.keys(chunkHM23LXUP_cjs.validateStep(at, values)).length > 0) {
1202
633
  setShowErrors(true);
1203
634
  return;
1204
635
  }
@@ -1299,10 +730,10 @@ function useWorkflowView(options) {
1299
730
  inputs,
1300
731
  setInput,
1301
732
  stateOf: (id) => states[id],
1302
- phaseOf: (id) => stepPhase(steps, states, id),
1303
- failedUpstreamOf: (id) => failedUpstream(steps, states, id),
733
+ phaseOf: (id) => chunkHM23LXUP_cjs.stepPhase(steps, states, id),
734
+ failedUpstreamOf: (id) => chunkHM23LXUP_cjs.failedUpstream(steps, states, id),
1304
735
  isLocked,
1305
- errors: showErrors && step && !isLocked(step.id) ? validateStep(step, inputs) : {},
736
+ errors: showErrors && step && !isLocked(step.id) ? chunkHM23LXUP_cjs.validateStep(step, inputs) : {},
1306
737
  busy,
1307
738
  actionError,
1308
739
  isRunning: Object.values(states).some((s) => s.status === "running"),
@@ -1320,11 +751,11 @@ function useWorkflowView(options) {
1320
751
  nameOf: options.nameOf,
1321
752
  assigneeOf: (id) => {
1322
753
  const s = steps.find((x) => x.id === id);
1323
- if (!s || !canAssign(s)) return void 0;
1324
- return assigneeName(s.assignee, {
754
+ if (!s || !chunkHM23LXUP_cjs.canAssign(s)) return void 0;
755
+ return chunkHM23LXUP_cjs.assigneeName(s.assignee, {
1325
756
  nameOf: options.nameOf,
1326
757
  inputs,
1327
- fields: runFieldsOf(steps),
758
+ fields: chunkHM23LXUP_cjs.runFieldsOf(steps),
1328
759
  announcedTo: states[id]?.announcedTo
1329
760
  });
1330
761
  },
@@ -1339,7 +770,7 @@ function useWorkflowView(options) {
1339
770
  // src/agents/workflows/stepWindow.ts
1340
771
  var LABEL_MAX_PX = 320;
1341
772
  var CHAR_PX = 6.5;
1342
- var LEVEL_CHROME_PX = 56;
773
+ var LEVEL_CHROME_PX = 60;
1343
774
  var GROUP_CHIP_PX = 32;
1344
775
  function levelRoomPx(titles) {
1345
776
  const label = Math.max(0, ...titles.map((t) => Math.min(LABEL_MAX_PX, t.length * CHAR_PX)));
@@ -1407,20 +838,12 @@ function stepWindow({
1407
838
  total: all.length
1408
839
  };
1409
840
  }
1410
- function PhaseMark({ phase, icon }) {
1411
- if (phase === "done") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-3.5 shrink-0" });
1412
- if (phase === "running") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-3.5 shrink-0 animate-spin" });
1413
- if (phase === "waiting") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Hourglass, { className: "size-3.5 shrink-0" });
1414
- if (phase === "failed") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "size-3.5 shrink-0" });
1415
- if (phase === "skipped") return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MinusCircle, { className: "size-3.5 shrink-0" });
1416
- return icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5", children: icon }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mx-1 size-1.5 shrink-0 rounded-full bg-current opacity-60" });
1417
- }
1418
841
  var DEFAULT_STEP_BAR_LABELS = {
1419
842
  nav: "Workflow steps",
1420
843
  back: "Earlier steps",
1421
844
  forward: "Later steps",
1422
- hiddenBefore: "{count} earlier steps: show all steps",
1423
- hiddenAfter: "{count} later steps: show all steps",
845
+ hiddenBefore: "{count} earlier steps",
846
+ hiddenAfter: "{count} later steps",
1424
847
  position: "Step {position} of {total}",
1425
848
  parallel: "{count} more in parallel",
1426
849
  inParallel: "In parallel",
@@ -1438,53 +861,27 @@ var DEFAULT_STEP_BAR_LABELS = {
1438
861
  failed: "Failed"
1439
862
  }
1440
863
  };
1441
- function stepPillTone(phase, current) {
1442
- if (current) return "border-primary bg-primary/10 text-primary font-semibold shadow-sm";
1443
- switch (phase) {
1444
- case "done":
1445
- return "border-emerald-600/30 text-emerald-700 dark:border-emerald-400/30 dark:text-emerald-400";
1446
- case "running":
1447
- return "border-primary/40 bg-primary/5 text-primary";
1448
- case "waiting":
1449
- return "border-amber-500/40 text-amber-700 dark:text-amber-300";
1450
- case "failed":
1451
- return "border-destructive/40 text-destructive";
1452
- case "skipped":
1453
- return "border-border text-muted-foreground line-through decoration-1";
1454
- case "ready":
1455
- return "border-border text-foreground";
1456
- default:
1457
- return "border-dashed border-border text-muted-foreground";
1458
- }
1459
- }
1460
- var PHASE_TEXT = {
1461
- done: "text-emerald-700 dark:text-emerald-400",
1462
- running: "text-primary",
1463
- waiting: "text-amber-700 dark:text-amber-300",
1464
- failed: "text-destructive",
1465
- skipped: "text-muted-foreground",
1466
- ready: "text-foreground",
1467
- blocked: "text-muted-foreground"
1468
- };
1469
- var STEP_PILL = "flex min-w-0 items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 py-1 text-xs font-medium transition-colors";
1470
864
  var STEP_LABEL = "min-w-[2.5rem] truncate";
1471
865
  var STEP_LABEL_MAX = "max-w-[20rem]";
1472
- var STEP_LABEL_CURRENT = "min-w-[2.5rem] max-w-[26rem] whitespace-normal text-left text-balance line-clamp-2";
866
+ var STEP_LABEL_CURRENT = "block min-w-[2.5rem] max-w-[26rem] truncate";
1473
867
  var STEP_EXTRA = "min-w-[3rem] shrink-[1000000] truncate font-normal opacity-80";
1474
868
  var fill = (template, values) => Object.entries(values).reduce((s, [k, v]) => s.replace(`{${k}}`, String(v)), template);
1475
869
  var NARROW_PX = 560;
870
+ var ARROWS_PX = 56;
871
+ var HIDDEN_PX = 40;
1476
872
  function StepBarFrame({
1477
873
  levels,
1478
874
  phaseOf,
1479
875
  current,
1480
876
  onSelect,
1481
877
  renderStep,
1482
- noteOf,
1483
878
  renderAfter,
1484
879
  leading,
1485
880
  trailing,
881
+ reservePx = {},
1486
882
  isSelectable = () => true,
1487
883
  icon,
884
+ kindOf = () => "adhoc",
1488
885
  disabled,
1489
886
  labels,
1490
887
  tid,
@@ -1492,15 +889,33 @@ function StepBarFrame({
1492
889
  }) {
1493
890
  const l = { ...DEFAULT_STEP_BAR_LABELS, ...labels };
1494
891
  const box = react.useRef(null);
1495
- const { width } = chunkB4SRYJLM_cjs.useElementSize(box);
892
+ const { width } = chunkHM23LXUP_cjs.useElementSize(box);
1496
893
  const narrow = width > 0 && width < NARROW_PX;
1497
894
  const [start, setStart] = react.useState(null);
1498
895
  react.useEffect(() => setStart(null), [current]);
1499
- const wholeFits = width >= levels.reduce((sum, lv) => sum + levelRoomPx(lv.map((s) => s.title)), 0);
1500
- const span = narrow ? 2 : wholeFits ? levels.length : 3;
896
+ const roomOf = (lv) => levelRoomPx(lv.map((s) => s.title));
897
+ const fits = (k) => {
898
+ const w = stepWindow({ levels, phaseOf, current, start, span: k });
899
+ const reserve = (reservePx.always ?? 0) + (w.start === 0 ? reservePx.leading ?? 0 : 0) + (w.canForward ? 0 : reservePx.trailing ?? 0) + ARROWS_PX + (w.hiddenBefore ? HIDDEN_PX : 0) + (w.hiddenAfter ? HIDDEN_PX : 0);
900
+ return width - reserve >= w.visible.reduce((sum, lv) => sum + roomOf(lv.steps), 0);
901
+ };
902
+ let span = width > 0 ? 1 : 3;
903
+ if (!narrow && width > 0) {
904
+ for (let k = levels.length; k > 1; k--)
905
+ if (fits(k)) {
906
+ span = k;
907
+ break;
908
+ }
909
+ }
1501
910
  const win = stepWindow({ levels, phaseOf, current, start, span });
1502
911
  const [listOpen, setListOpen] = react.useState(null);
1503
912
  const move = (to) => setStart(Math.max(0, Math.min(win.levels.length - 1, to)));
913
+ const keyMoved = react.useRef(false);
914
+ react.useEffect(() => {
915
+ if (!keyMoved.current) return;
916
+ keyMoved.current = false;
917
+ box.current?.querySelector("[data-role] button")?.focus();
918
+ }, [win.start]);
1504
919
  const select = (id) => {
1505
920
  setListOpen(null);
1506
921
  setStart(null);
@@ -1511,6 +926,7 @@ function StepBarFrame({
1511
926
  const to = e.key === "ArrowLeft" ? win.start - 1 : e.key === "ArrowRight" ? win.start + 1 : e.key === "Home" ? 0 : e.key === "End" ? win.levels.length : null;
1512
927
  if (to === null) return;
1513
928
  e.preventDefault();
929
+ keyMoved.current = true;
1514
930
  move(to);
1515
931
  };
1516
932
  const row = (s, isCurrent) => {
@@ -1524,13 +940,25 @@ function StepBarFrame({
1524
940
  onClick: () => select(s.id),
1525
941
  "aria-current": isCurrent ? "step" : void 0,
1526
942
  className: ui.cn(
943
+ `wf-kind-${kindOf(s)}`,
1527
944
  "flex w-full min-w-0 items-center gap-2 rounded-md px-2 py-1 text-left text-xs hover:bg-accent disabled:cursor-default disabled:hover:bg-transparent",
1528
- isCurrent && "bg-primary/10 font-semibold text-primary"
945
+ isCurrent && "bg-accent font-semibold"
1529
946
  ),
1530
947
  "data-phase": phase,
1531
948
  "data-testid": tid(`list-step-${s.id}`),
1532
949
  children: [
1533
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.cn("flex shrink-0", !isCurrent && PHASE_TEXT[phase]), children: /* @__PURE__ */ jsxRuntime.jsx(PhaseMark, { phase, icon: icon?.(s) }) }),
950
+ /* @__PURE__ */ jsxRuntime.jsx(
951
+ "span",
952
+ {
953
+ className: ui.cn(
954
+ "wf-badge flex size-5 shrink-0 items-center justify-center rounded-md [&_svg]:size-3",
955
+ phase === "done" && "bg-[hsl(var(--wf-accent))] text-card",
956
+ phase === "blocked" && "opacity-60"
957
+ ),
958
+ "aria-hidden": true,
959
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkHM23LXUP_cjs.StepBadgeMark, { phase, icon: icon?.(s) })
960
+ }
961
+ ),
1534
962
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", title: s.title, children: s.title }),
1535
963
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] font-normal text-muted-foreground", children: l.phases[phase] })
1536
964
  ]
@@ -1549,12 +977,14 @@ function StepBarFrame({
1549
977
  el.focus();
1550
978
  el.scrollIntoView?.({ block: "nearest" });
1551
979
  };
1552
- const allSteps = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1553
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-2 py-1 text-[11px] font-medium text-muted-foreground", children: fill(l.position, { position: win.position, total: win.total }) }),
1554
- /* @__PURE__ */ jsxRuntime.jsx("ol", { children: win.levels.map((level) => /* @__PURE__ */ jsxRuntime.jsxs(
980
+ const stepList = (side) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
981
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-2 py-1 text-[11px] font-medium text-muted-foreground", children: side ? fill(side === "before" ? l.hiddenBefore : l.hiddenAfter, {
982
+ count: side === "before" ? win.hiddenBefore : win.hiddenAfter
983
+ }) : fill(l.position, { position: win.position, total: win.total }) }),
984
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { children: (side === "before" ? win.levels.slice(0, win.start) : side === "after" ? win.levels.slice(win.end) : win.levels).map((level) => /* @__PURE__ */ jsxRuntime.jsxs(
1555
985
  "li",
1556
986
  {
1557
- className: ui.cn(level.steps.length > 1 && "my-0.5 border-l-2 border-primary/30 pl-1"),
987
+ className: ui.cn(level.steps.length > 1 && "my-0.5 border-l-2 border-border pl-1"),
1558
988
  children: [
1559
989
  level.steps.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: l.inParallel }),
1560
990
  level.steps.map((s) => row(s, s.id === atId))
@@ -1586,7 +1016,7 @@ function StepBarFrame({
1586
1016
  className: "max-h-[min(24rem,70vh)] w-72 overflow-y-auto p-1",
1587
1017
  onOpenAutoFocus: focusCurrent,
1588
1018
  "data-testid": tid("all-steps"),
1589
- children: allSteps
1019
+ children: stepList()
1590
1020
  }
1591
1021
  )
1592
1022
  ] }) : null : count > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Popover, { open: listOpen === side, onOpenChange: (o) => setListOpen(o ? side : null), children: [
@@ -1611,7 +1041,7 @@ function StepBarFrame({
1611
1041
  className: "max-h-[min(24rem,70vh)] w-80 overflow-y-auto p-1",
1612
1042
  onOpenAutoFocus: focusCurrent,
1613
1043
  "data-testid": tid("all-steps"),
1614
- children: allSteps
1044
+ children: stepList(side)
1615
1045
  }
1616
1046
  )
1617
1047
  ] }) : null;
@@ -1633,33 +1063,17 @@ function StepBarFrame({
1633
1063
  );
1634
1064
  };
1635
1065
  const running = win.runningHidden;
1636
- const workingPill = (s) => /* @__PURE__ */ jsxRuntime.jsxs(
1637
- "button",
1066
+ const outOfViewChip = (s, kind) => /* @__PURE__ */ jsxRuntime.jsx(
1067
+ chunkHM23LXUP_cjs.StepChip,
1638
1068
  {
1639
- type: "button",
1069
+ kind: kindOf(s),
1070
+ phase: kind === "working" ? "running" : "failed",
1071
+ label: fill(l[kind], { title: s.title }),
1072
+ labelClassName: narrow ? "sr-only" : "truncate",
1640
1073
  onClick: () => select(s.id),
1641
- className: "flex min-w-0 max-w-[14rem] shrink items-center gap-1.5 rounded-full border border-primary/40 bg-primary/5 px-2 py-1 text-xs text-primary hover:bg-primary/10",
1642
- title: fill(l.working, { title: s.title }),
1643
- "data-testid": tid(`working-${s.id}`),
1644
- children: [
1645
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-3.5 shrink-0 animate-spin" }),
1646
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: fill(l.working, { title: s.title }) })
1647
- ]
1648
- },
1649
- s.id
1650
- );
1651
- const failedPill = (s) => /* @__PURE__ */ jsxRuntime.jsxs(
1652
- "button",
1653
- {
1654
- type: "button",
1655
- onClick: () => select(s.id),
1656
- className: "flex min-w-0 max-w-[14rem] shrink items-center gap-1.5 rounded-full border border-destructive/40 bg-destructive/5 px-2 py-1 text-xs text-destructive hover:bg-destructive/10",
1657
- title: fill(l.failedStep, { title: s.title }),
1658
- "data-testid": tid(`failed-${s.id}`),
1659
- children: [
1660
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "size-3.5 shrink-0" }),
1661
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: fill(l.failedStep, { title: s.title }) })
1662
- ]
1074
+ className: "max-w-[14rem] shrink",
1075
+ title: fill(l[kind], { title: s.title }),
1076
+ "data-testid": tid(`${kind === "working" ? "working" : "failed"}-${s.id}`)
1663
1077
  },
1664
1078
  s.id
1665
1079
  );
@@ -1669,7 +1083,7 @@ function StepBarFrame({
1669
1083
  ref: box,
1670
1084
  "aria-label": l.nav,
1671
1085
  onKeyDown,
1672
- className: ui.cn("flex min-w-0 items-center gap-1", narrow && "flex-wrap", className),
1086
+ className: ui.cn("flex min-w-0 items-center gap-1", className),
1673
1087
  "data-testid": tid("steps"),
1674
1088
  "data-narrow": narrow || void 0,
1675
1089
  children: [
@@ -1702,10 +1116,8 @@ function StepBarFrame({
1702
1116
  "span",
1703
1117
  {
1704
1118
  "aria-hidden": true,
1705
- className: ui.cn(
1706
- "h-px min-w-2 flex-1",
1707
- level.steps.every((s) => ["done", "skipped"].includes(phaseOf(s.id))) ? "bg-emerald-600/40" : "bg-border"
1708
- )
1119
+ className: ui.cn("wf-link", `wf-kind-${kindOf(level.primary)}`),
1120
+ "data-done": level.steps.every((s) => ["done", "skipped"].includes(phaseOf(s.id))) || void 0
1709
1121
  }
1710
1122
  )
1711
1123
  ]
@@ -1715,30 +1127,21 @@ function StepBarFrame({
1715
1127
  overflow("after", win.hiddenAfter),
1716
1128
  !win.canForward && trailing,
1717
1129
  arrow("forward"),
1718
- narrow && atId && noteOf?.(atId) && /* @__PURE__ */ jsxRuntime.jsx(
1719
- "p",
1720
- {
1721
- className: "min-w-0 basis-full truncate px-1 text-[11px] text-muted-foreground",
1722
- "data-testid": tid("note"),
1723
- children: noteOf(atId)
1724
- }
1725
- ),
1726
1130
  running.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
1727
1131
  "div",
1728
1132
  {
1729
- className: ui.cn(
1730
- "flex min-w-[6.5rem] shrink-[1000] items-center gap-1",
1731
- narrow && "basis-full"
1732
- ),
1133
+ className: ui.cn("flex shrink-[1000] items-center gap-1", !narrow && "min-w-[6.5rem]"),
1733
1134
  "data-testid": tid("working"),
1734
1135
  children: [
1735
- (running.length > 2 ? running.slice(0, 1) : running).map(workingPill),
1136
+ (running.length > 2 ? running.slice(0, 1) : running).map(
1137
+ (s) => outOfViewChip(s, "working")
1138
+ ),
1736
1139
  running.length > 2 && /* @__PURE__ */ jsxRuntime.jsxs(ui.Popover, { children: [
1737
1140
  /* @__PURE__ */ jsxRuntime.jsx(ui.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1738
1141
  "button",
1739
1142
  {
1740
1143
  type: "button",
1741
- className: "flex shrink-0 items-center gap-1 rounded-full border border-primary/40 bg-primary/5 px-2 py-1 text-xs text-primary hover:bg-primary/10",
1144
+ className: "flex shrink-0 items-center gap-1 rounded-lg border border-border bg-card px-2 py-1 text-xs text-muted-foreground hover:text-foreground",
1742
1145
  "data-testid": tid("working-more"),
1743
1146
  children: [
1744
1147
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-3.5 animate-spin" }),
@@ -1754,12 +1157,9 @@ function StepBarFrame({
1754
1157
  win.failedHidden.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1755
1158
  "div",
1756
1159
  {
1757
- className: ui.cn(
1758
- "flex min-w-[6.5rem] shrink-[1000] items-center gap-1",
1759
- narrow && "basis-full"
1760
- ),
1160
+ className: ui.cn("flex shrink-[1000] items-center gap-1", !narrow && "min-w-[6.5rem]"),
1761
1161
  "data-testid": tid("failed"),
1762
- children: win.failedHidden.map(failedPill)
1162
+ children: win.failedHidden.map((s) => outOfViewChip(s, "failedStep"))
1763
1163
  }
1764
1164
  )
1765
1165
  ]
@@ -1778,7 +1178,7 @@ function GroupChip({
1778
1178
  "button",
1779
1179
  {
1780
1180
  type: "button",
1781
- className: "shrink-0 rounded-full border border-border bg-muted px-1.5 py-0.5 text-[11px] font-medium tabular-nums text-muted-foreground hover:border-primary/40 hover:text-primary",
1181
+ className: "shrink-0 rounded-md border border-border bg-card px-1.5 py-0.5 text-[11px] font-medium tabular-nums text-muted-foreground shadow-sm hover:text-foreground",
1782
1182
  "aria-label": label,
1783
1183
  title: label,
1784
1184
  "data-testid": tid(`group-${level.steps[0].id}`),
@@ -1836,12 +1236,8 @@ var DEFAULT_WORKFLOW_STEP_PARTS_LABELS = {
1836
1236
  redlineHint: "The edits are tracked changes: accept or reject each one in Word.",
1837
1237
  someone: "someone"
1838
1238
  };
1839
- var formatDate = (iso) => {
1840
- const t = iso ? Date.parse(iso) : NaN;
1841
- return Number.isNaN(t) ? "" : new Date(t).toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
1842
- };
1843
1239
  var docName = (ref, nameOfDoc) => {
1844
- const { id, version } = splitDocRef(ref);
1240
+ const { id, version } = chunkHM23LXUP_cjs.splitDocRef(ref);
1845
1241
  const name = nameOfDoc?.(id) ?? id;
1846
1242
  return version ? `${name} \xB7 v${version}` : name;
1847
1243
  };
@@ -1923,7 +1319,7 @@ function SendBackControl({
1923
1319
  const states = Object.fromEntries(
1924
1320
  run.steps.map((s) => [s.id, run.stateOf(s.id) ?? { status: "pending" }])
1925
1321
  );
1926
- const targets = sendBackTargets(run.steps, states, step.id);
1322
+ const targets = chunkHM23LXUP_cjs.sendBackTargets(run.steps, states, step.id);
1927
1323
  const [open, setOpen] = react.useState(false);
1928
1324
  const [to, setTo] = react.useState(targets[0]?.id ?? "");
1929
1325
  const [note, setNote] = react.useState("");
@@ -1996,13 +1392,6 @@ function SendBackControl({
1996
1392
  }
1997
1393
  );
1998
1394
  }
1999
- var shownValue = (v, field, nameOf) => {
2000
- if (v === void 0 || v === null || v === "") return "\u2014";
2001
- if (typeof v === "boolean") return v ? "\u2713" : "\u2717";
2002
- if (field.type === "person" && typeof v === "string") return nameOf?.(v) ?? v;
2003
- if (field.type === "select") return field.options?.find((o) => o.value === v)?.label ?? String(v);
2004
- return typeof v === "object" ? JSON.stringify(v) : String(v);
2005
- };
2006
1395
  function ApprovalEvidence({
2007
1396
  run,
2008
1397
  step,
@@ -2020,7 +1409,7 @@ function ApprovalEvidence({
2020
1409
  /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "flex flex-wrap items-center gap-1.5 text-sm font-medium", children: [
2021
1410
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "size-4 text-primary" }),
2022
1411
  approver ? l.approvedBy.replace("{name}", approver) : null,
2023
- state.at && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-normal text-muted-foreground", children: l.approvedAt.replace("{date}", formatDate(state.at)) })
1412
+ state.at && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-normal text-muted-foreground", children: l.approvedAt.replace("{date}", chunkHM23LXUP_cjs.formatDate(state.at)) })
2024
1413
  ] }),
2025
1414
  evidence.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
2026
1415
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: l.approvedWhat }),
@@ -2053,7 +1442,7 @@ function ApprovalEvidence({
2053
1442
  ] }),
2054
1443
  (step.fields ?? []).length > 0 && /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 text-xs", children: (step.fields ?? []).map((f) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "contents", children: [
2055
1444
  /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: f.label }),
2056
- /* @__PURE__ */ jsxRuntime.jsx("dd", { "data-testid": `${testId}-evidence-field-${f.name}`, children: shownValue(run.inputs[f.name], f, run.nameOf) })
1445
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { "data-testid": `${testId}-evidence-field-${f.name}`, children: chunkHM23LXUP_cjs.shownValue(run.inputs[f.name], f, run.nameOf) })
2057
1446
  ] }, f.name)) })
2058
1447
  ] });
2059
1448
  }
@@ -2149,7 +1538,7 @@ function ActionStepBody({
2149
1538
  waiting?.expires_at && phase === "waiting" && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
2150
1539
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "size-3.5" }),
2151
1540
  " ",
2152
- l.expires.replace("{date}", formatDate(waiting.expires_at))
1541
+ l.expires.replace("{date}", chunkHM23LXUP_cjs.formatDate(waiting.expires_at))
2153
1542
  ] }),
2154
1543
  phase === "waiting" && mine && !declining && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
2155
1544
  actions?.sign && state && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2296,12 +1685,7 @@ function WorkflowStepBar({
2296
1685
  const done = { id: DONE, title: doneTitle };
2297
1686
  const phaseOf = (id) => id === DONE ? run.isComplete ? "done" : "blocked" : run.phaseOf(id);
2298
1687
  const current = run.isComplete ? DONE : run.current;
2299
- const waitingOf = (id) => {
2300
- if (id === DONE || !["ready", "waiting"].includes(phaseOf(id))) return void 0;
2301
- const assignee = run.assigneeOf(id);
2302
- return assignee ? l.waitingFor.replace("{name}", assignee) : void 0;
2303
- };
2304
- const pill = (s, narrow = false) => {
1688
+ const pill = (s) => {
2305
1689
  const phase = phaseOf(s.id);
2306
1690
  const isCurrent = s.id === current;
2307
1691
  const assignee = ["ready", "waiting"].includes(phase) ? run.assigneeOf(s.id) : void 0;
@@ -2311,55 +1695,51 @@ function WorkflowStepBar({
2311
1695
  const title = [s.title, waiting, failure].filter(Boolean).join(" \xB7 ");
2312
1696
  const name = `${title} (${l.phases[phase]})`;
2313
1697
  if (s.id === DONE)
2314
- return /* @__PURE__ */ jsxRuntime.jsxs(
2315
- "span",
1698
+ return /* @__PURE__ */ jsxRuntime.jsx(
1699
+ chunkHM23LXUP_cjs.StepChip,
2316
1700
  {
2317
- className: ui.cn(STEP_PILL, stepPillTone(phase, isCurrent)),
2318
- "aria-current": isCurrent ? "step" : void 0,
1701
+ inert: true,
1702
+ kind: "start",
1703
+ phase: run.isComplete ? "done" : "ready",
1704
+ icon: doneIcon,
1705
+ label: doneTitle,
1706
+ labelClassName: ui.cn(STEP_LABEL, STEP_LABEL_MAX),
1707
+ current: isCurrent,
2319
1708
  "aria-label": name,
2320
1709
  title: doneTitle,
2321
- "data-phase": phase,
2322
- "data-testid": tid("step-done"),
2323
- children: [
2324
- /* @__PURE__ */ jsxRuntime.jsx(PhaseMark, { phase: run.isComplete ? "done" : "ready", icon: doneIcon }),
2325
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.cn(STEP_LABEL, STEP_LABEL_MAX), children: doneTitle })
2326
- ]
1710
+ "data-testid": tid("step-done")
2327
1711
  }
2328
1712
  );
2329
- return /* @__PURE__ */ jsxRuntime.jsxs(
2330
- "button",
1713
+ const kind = chunkHM23LXUP_cjs.stepKindOf(s);
1714
+ const KindIcon = chunkHM23LXUP_cjs.STEP_KIND_ICONS[kind];
1715
+ return /* @__PURE__ */ jsxRuntime.jsx(
1716
+ chunkHM23LXUP_cjs.StepChip,
2331
1717
  {
2332
- type: "button",
1718
+ kind,
1719
+ phase,
1720
+ icon: icon(s.icon) ?? /* @__PURE__ */ jsxRuntime.jsx(KindIcon, {}),
1721
+ label: s.title,
1722
+ current: isCurrent,
1723
+ heading: chunkHM23LXUP_cjs.DEFAULT_STEP_KIND_LABELS[kind],
1724
+ labelClassName: isCurrent ? STEP_LABEL_CURRENT : ui.cn(STEP_LABEL, STEP_LABEL_MAX),
1725
+ labelTestId: tid(`step-${s.id}-label`),
2333
1726
  onClick: () => run.goTo(s.id),
2334
1727
  disabled: run.busy,
2335
- className: ui.cn(STEP_PILL, stepPillTone(phase, isCurrent), "disabled:cursor-default"),
2336
- "aria-current": isCurrent ? "step" : void 0,
1728
+ className: "disabled:cursor-default",
2337
1729
  "aria-label": name,
2338
1730
  title,
2339
- "data-phase": phase,
2340
1731
  "data-testid": tid(`step-${s.id}`),
2341
- children: [
2342
- /* @__PURE__ */ jsxRuntime.jsx(PhaseMark, { phase, icon: icon(s.icon) }),
2343
- /* @__PURE__ */ jsxRuntime.jsx(
2344
- "span",
2345
- {
2346
- className: isCurrent ? STEP_LABEL_CURRENT : ui.cn(STEP_LABEL, STEP_LABEL_MAX),
2347
- "data-testid": tid(`step-${s.id}-label`),
2348
- children: s.title
2349
- }
2350
- ),
2351
- assignee && isCurrent && !narrow && /* @__PURE__ */ jsxRuntime.jsxs(
2352
- "span",
2353
- {
2354
- className: ui.cn(STEP_EXTRA, "max-w-[12rem]"),
2355
- "data-testid": tid(`step-${s.id}-assignee`),
2356
- children: [
2357
- "\xB7 ",
2358
- waiting
2359
- ]
2360
- }
2361
- )
2362
- ]
1732
+ children: assignee && isCurrent && /* @__PURE__ */ jsxRuntime.jsxs(
1733
+ "span",
1734
+ {
1735
+ className: ui.cn(STEP_EXTRA, "max-w-[12rem]"),
1736
+ "data-testid": tid(`step-${s.id}-assignee`),
1737
+ children: [
1738
+ "\xB7 ",
1739
+ waiting
1740
+ ]
1741
+ }
1742
+ )
2363
1743
  }
2364
1744
  );
2365
1745
  };
@@ -2371,9 +1751,9 @@ function WorkflowStepBar({
2371
1751
  current,
2372
1752
  onSelect: (id) => id !== DONE && run.goTo(id),
2373
1753
  isSelectable: (id) => id !== DONE,
2374
- renderStep: (s, _level, _win, narrow) => pill(s, narrow),
2375
- noteOf: waitingOf,
1754
+ renderStep: (s) => pill(s),
2376
1755
  icon: (s) => s.id === DONE ? doneIcon : icon(s.icon),
1756
+ kindOf: (s) => s.id === DONE ? "start" : chunkHM23LXUP_cjs.stepKindOf(s),
2377
1757
  disabled: run.busy,
2378
1758
  labels,
2379
1759
  tid,
@@ -2444,7 +1824,7 @@ function WorkflowRunner({
2444
1824
  actions,
2445
1825
  nameOfDoc,
2446
1826
  hideStepBar,
2447
- compact: compact3,
1827
+ compact: compact2,
2448
1828
  labels,
2449
1829
  partsLabels,
2450
1830
  testIdPrefix = "workflow-run",
@@ -2452,11 +1832,11 @@ function WorkflowRunner({
2452
1832
  }) {
2453
1833
  const l = { ...DEFAULT_WORKFLOW_RUNNER_LABELS, ...labels };
2454
1834
  const pl = { ...DEFAULT_WORKFLOW_STEP_PARTS_LABELS, ...partsLabels };
2455
- const box = compact3 ? "p-4" : "max-w-2xl p-6";
1835
+ const box = compact2 ? "p-4" : "max-w-2xl p-6";
2456
1836
  const { steps, step, isComplete, action } = run;
2457
1837
  const completion = workflow.run.kind === "steps" ? workflow.run.completion : void 0;
2458
1838
  const tid = (suffix) => `${testIdPrefix}-${suffix}`;
2459
- const levels = stepLevels(steps);
1839
+ const levels = chunkHM23LXUP_cjs.stepLevels(steps);
2460
1840
  const icon = (key) => key && renderIcon ? renderIcon(key) : void 0;
2461
1841
  const added = step?.kind === "upload" ? (files ?? []).filter((f) => f.addedFor === step.id) : [];
2462
1842
  const unread = added.filter((f) => f.status === "processing").length;
@@ -2464,9 +1844,9 @@ function WorkflowRunner({
2464
1844
  const sending = added.filter((f) => f.status === "uploading").length;
2465
1845
  const unsent = added.filter((f) => f.status === "upload-failed").length;
2466
1846
  const uploadHold = step?.kind === "upload" && (sending > 0 || uploading || unsent > 0);
2467
- const docsWait = !!step && waitingDocuments(run.stateOf(step.id)).length > 0;
1847
+ const docsWait = !!step && chunkHM23LXUP_cjs.waitingDocuments(run.stateOf(step.id)).length > 0;
2468
1848
  const nextLabel = sending ? sending === 1 ? l.uploadingFile : l.uploadingFiles.replace("{count}", String(sending)) : uploadHold && uploading ? l.uploadingAny : uploadHold ? unsent === 1 ? l.uploadFailed : l.uploadsFailed.replace("{count}", String(unsent)) : reading ? l.readingFiles.replace("{current}", String(Math.min(added.length - unread + 1, added.length))).replace("{count}", String(added.length)) : action === "start" ? l.start : action === "retry" ? l.retry : action === "finish" ? l.finish : action === "complete" && step?.kind === "review" ? l.approve : action === "complete" && step?.kind === "action" ? l.markSent : action === "wait" && (run.isRunning || run.busy || docsWait) ? l.working : (step && !run.isLocked(step.id) ? step.nextLabel : void 0) ?? l.next;
2469
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn(compact3 ? "space-y-3" : "space-y-6", className), "data-testid": testIdPrefix, children: [
1849
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn(compact2 ? "space-y-3" : "space-y-6", className), "data-testid": testIdPrefix, children: [
2470
1850
  !hideStepBar && /* @__PURE__ */ jsxRuntime.jsx(
2471
1851
  WorkflowStepBar,
2472
1852
  {
@@ -2496,7 +1876,7 @@ function WorkflowRunner({
2496
1876
  /* @__PURE__ */ jsxRuntime.jsx(StepNotices, { run, step, l, tid }),
2497
1877
  run.phaseOf(step.id) === "blocked" ? /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { className: ui.cn(box, "p-6"), "data-testid": tid(step.id), children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", "data-testid": tid(`${step.id}-blocked`), children: l.blocked.replace(
2498
1878
  "{steps}",
2499
- stepDependencies(steps, step.id).map((d) => steps.find((s) => s.id === d)?.title ?? d).join(", ")
1879
+ chunkHM23LXUP_cjs.stepDependencies(steps, step.id).map((d) => steps.find((s) => s.id === d)?.title ?? d).join(", ")
2500
1880
  ) }) }) : step.kind === "form" ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { className: ui.cn(box, "space-y-4"), "data-testid": tid(step.id), children: [
2501
1881
  /* @__PURE__ */ jsxRuntime.jsx(StepHeading, { step, icon: icon(step.icon), testId: tid(`${step.id}-title`) }),
2502
1882
  /* @__PURE__ */ jsxRuntime.jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
@@ -2552,7 +1932,7 @@ function WorkflowRunner({
2552
1932
  ] }) : step.kind === "review" ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { className: ui.cn(box, "space-y-4"), "data-testid": tid(step.id), children: [
2553
1933
  /* @__PURE__ */ jsxRuntime.jsx(StepHeading, { step, icon: icon(step.icon) }),
2554
1934
  /* @__PURE__ */ jsxRuntime.jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
2555
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-line text-sm text-muted-foreground", children: reviewInstructions(step, run.inputs) }),
1935
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-line text-sm text-muted-foreground", children: chunkHM23LXUP_cjs.reviewInstructions(step, run.inputs) }),
2556
1936
  /* @__PURE__ */ jsxRuntime.jsx(AssigneeLine, { run, stepId: step.id, l: pl, testId: tid(step.id) }),
2557
1937
  !(run.phaseOf(step.id) === "done" && run.stateOf(step.id)?.by) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", "data-testid": tid(`${step.id}-status`), children: run.phaseOf(step.id) === "done" ? l.approved : run.phaseOf(step.id) === "skipped" ? l.skipped : l.awaitingReview }),
2558
1938
  (step.fields ?? []).length > 0 && run.phaseOf(step.id) === "ready" && /* @__PURE__ */ jsxRuntime.jsx(
@@ -2607,7 +1987,7 @@ function WorkflowRunner({
2607
1987
  renderAgentOutput,
2608
1988
  icon: icon(step.icon),
2609
1989
  renderStepNote,
2610
- compact: compact3,
1990
+ compact: compact2,
2611
1991
  nameOfDoc,
2612
1992
  extra: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2613
1993
  /* @__PURE__ */ jsxRuntime.jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
@@ -2632,7 +2012,7 @@ function WorkflowRunner({
2632
2012
  {
2633
2013
  className: ui.cn(
2634
2014
  "flex items-center justify-between border-t border-border pt-4",
2635
- compact3 && "flex-wrap gap-2 pt-3"
2015
+ compact2 && "flex-wrap gap-2 pt-3"
2636
2016
  ),
2637
2017
  children: [
2638
2018
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2652,7 +2032,7 @@ function WorkflowRunner({
2652
2032
  /* @__PURE__ */ jsxRuntime.jsxs(
2653
2033
  "div",
2654
2034
  {
2655
- className: ui.cn("flex items-center gap-2", compact3 && "ml-auto flex-wrap justify-end"),
2035
+ className: ui.cn("flex items-center gap-2", compact2 && "ml-auto flex-wrap justify-end"),
2656
2036
  children: [
2657
2037
  step && // A step that commits (creates the matter, starts the thread) is what the run stands on.
2658
2038
  !step.commit && ["ready", "blocked", "failed"].includes(run.phaseOf(step.id)) && /* @__PURE__ */ jsxRuntime.jsx(
@@ -2812,15 +2192,15 @@ function AgentStepBody({
2812
2192
  icon,
2813
2193
  renderStepNote,
2814
2194
  extra,
2815
- compact: compact3,
2195
+ compact: compact2,
2816
2196
  nameOfDoc,
2817
2197
  l,
2818
2198
  tid
2819
2199
  }) {
2820
2200
  const state = run.stateOf(step.id);
2821
2201
  const phase = run.phaseOf(step.id);
2822
- const pending = waitingDocuments(state);
2823
- const pendingNames = pending.flatMap((ref) => nameOfDoc?.(splitDocRef(ref).id) ?? []);
2202
+ const pending = chunkHM23LXUP_cjs.waitingDocuments(state);
2203
+ const pendingNames = pending.flatMap((ref) => nameOfDoc?.(chunkHM23LXUP_cjs.splitDocRef(ref).id) ?? []);
2824
2204
  const header = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
2825
2205
  /* @__PURE__ */ jsxRuntime.jsx(StepHeading, { step, icon }),
2826
2206
  phase === "failed" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center gap-2", children: run.retry && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2875,7 +2255,7 @@ function AgentStepBody({
2875
2255
  phase === "skipped" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", "data-testid": tid(`${step.id}-skipped`), children: state?.skippedAfterFailure ? l.skippedAfterFailure.replace("{error}", state.error ? `: ${state.error}` : "") : l.skipped }),
2876
2256
  extra
2877
2257
  ] });
2878
- if (step.output === "artifact" && !compact3) {
2258
+ if (step.output === "artifact" && !compact2) {
2879
2259
  return /* @__PURE__ */ jsxRuntime.jsxs(
2880
2260
  "div",
2881
2261
  {
@@ -2892,7 +2272,7 @@ function AgentStepBody({
2892
2272
  }
2893
2273
  );
2894
2274
  }
2895
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { className: ui.cn("space-y-3", compact3 ? "p-4" : "p-6"), "data-testid": tid(step.id), children: [
2275
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { className: ui.cn("space-y-3", compact2 ? "p-4" : "p-6"), "data-testid": tid(step.id), children: [
2896
2276
  header,
2897
2277
  status,
2898
2278
  renderAgentOutput(step, state),
@@ -2905,7 +2285,7 @@ function StepNotices({
2905
2285
  l,
2906
2286
  tid
2907
2287
  }) {
2908
- const notStarted = !isPersonStep(step) && run.needsStart && run.phaseOf(step.id) === "ready";
2288
+ const notStarted = !chunkHM23LXUP_cjs.isPersonStep(step) && run.needsStart && run.phaseOf(step.id) === "ready";
2909
2289
  const failed = run.failedUpstreamOf(step.id);
2910
2290
  if (!notStarted && failed.length === 0) return null;
2911
2291
  const why = (error) => error ? `: ${error}` : "";
@@ -3027,12 +2407,12 @@ function taskActivityHeadline(e, labels = DEFAULT_TASK_ACTIVITY_LABELS, agentNam
3027
2407
  case "step_skipped":
3028
2408
  return "Step skipped";
3029
2409
  case "step_waiting": {
3030
- const documents = eventWaitingDocuments(detail);
3031
- return documents ? waitingForDocumentsText(documents.length) : "Waiting on people";
2410
+ const documents = chunkHM23LXUP_cjs.eventWaitingDocuments(detail);
2411
+ return documents ? chunkHM23LXUP_cjs.waitingForDocumentsText(documents.length) : "Waiting on people";
3032
2412
  }
3033
2413
  case "step_progress": {
3034
- const documents = eventWaitingDocuments(detail);
3035
- return documents ? waitingForDocumentsText(documents.length) : detail.signed ? "Signed" : "Step moved on";
2414
+ const documents = chunkHM23LXUP_cjs.eventWaitingDocuments(detail);
2415
+ return documents ? chunkHM23LXUP_cjs.waitingForDocumentsText(documents.length) : detail.signed ? "Signed" : "Step moved on";
3036
2416
  }
3037
2417
  case "step_sent_back":
3038
2418
  return "Sent the work back";
@@ -3136,21 +2516,14 @@ function TaskActivityTimeline({
3136
2516
  exports.ActionStepBody = ActionStepBody;
3137
2517
  exports.ApprovalEvidence = ApprovalEvidence;
3138
2518
  exports.AssigneeLine = AssigneeLine;
3139
- exports.DEFAULT_ASSIGNEE_WORDING = DEFAULT_ASSIGNEE_WORDING;
3140
2519
  exports.DEFAULT_SCHEMA_FORM_LABELS = DEFAULT_SCHEMA_FORM_LABELS;
3141
2520
  exports.DEFAULT_STEP_BAR_LABELS = DEFAULT_STEP_BAR_LABELS;
3142
2521
  exports.DEFAULT_TASK_ACTIVITY_LABELS = DEFAULT_TASK_ACTIVITY_LABELS;
3143
2522
  exports.DEFAULT_WORKFLOW_RUNNER_LABELS = DEFAULT_WORKFLOW_RUNNER_LABELS;
3144
2523
  exports.DEFAULT_WORKFLOW_STEP_PARTS_LABELS = DEFAULT_WORKFLOW_STEP_PARTS_LABELS;
3145
- exports.EMPTY_WORKFLOW_SCOPE = EMPTY_WORKFLOW_SCOPE;
3146
- exports.PhaseMark = PhaseMark;
3147
- exports.SKILL_PROMPT_FALLBACK_PLACEHOLDER = SKILL_PROMPT_FALLBACK_PLACEHOLDER;
3148
- exports.SKILL_PROMPT_LABEL = SKILL_PROMPT_LABEL;
3149
- exports.STEP_EXTRA = STEP_EXTRA;
3150
2524
  exports.STEP_LABEL = STEP_LABEL;
3151
2525
  exports.STEP_LABEL_CURRENT = STEP_LABEL_CURRENT;
3152
2526
  exports.STEP_LABEL_MAX = STEP_LABEL_MAX;
3153
- exports.STEP_PILL = STEP_PILL;
3154
2527
  exports.SchemaForm = SchemaForm;
3155
2528
  exports.SendBackControl = SendBackControl;
3156
2529
  exports.StepBarFrame = StepBarFrame;
@@ -3158,63 +2531,16 @@ exports.TaskActivityTimeline = TaskActivityTimeline;
3158
2531
  exports.WorkflowRunner = WorkflowRunner;
3159
2532
  exports.WorkflowStepBar = WorkflowStepBar;
3160
2533
  exports.activeStepId = activeStepId;
3161
- exports.assigneeName = assigneeName;
3162
- exports.buildLaunch = buildLaunch;
3163
- exports.canAssign = canAssign;
3164
- exports.composeStepPrompt = composeStepPrompt;
3165
- exports.composeWorkflowPrompt = composeWorkflowPrompt;
3166
- exports.defaultInputs = defaultInputs;
3167
- exports.dependsOn = dependsOn;
3168
- exports.eventWaitingDocuments = eventWaitingDocuments;
3169
- exports.fieldToFrontmatter = fieldToFrontmatter;
3170
- exports.fillRunText = fillRunText;
3171
- exports.fillStepInputs = fillStepInputs;
3172
2534
  exports.fromPlanAssignee = fromPlanAssignee;
3173
2535
  exports.fromPlanDocumentRef = fromPlanDocumentRef;
3174
2536
  exports.fromPlanSteps = fromPlanSteps;
3175
- exports.initialRunInputs = initialRunInputs;
3176
- exports.inputsFromContext = inputsFromContext;
3177
- exports.isEmptyWorkflowScope = isEmptyWorkflowScope;
3178
2537
  exports.isIncompleteSignal = isIncompleteSignal;
3179
- exports.isPersonAction = isPersonAction;
3180
- exports.isPersonStep = isPersonStep;
3181
- exports.isRunFinished = isRunFinished;
3182
- exports.isSteppedWorkflow = isSteppedWorkflow;
3183
- exports.isWorkflowScope = isWorkflowScope;
3184
2538
  exports.layoutFromPlanSteps = layoutFromPlanSteps;
3185
- exports.nextAction = nextAction;
3186
- exports.orderSteps = orderSteps;
3187
- exports.promptFieldName = promptFieldName;
3188
- exports.reviewInstructions = reviewInstructions;
3189
- exports.runFields = runFields;
3190
- exports.runFieldsOf = runFieldsOf;
3191
- exports.runThreadTitle = runThreadTitle;
3192
- exports.sendBackTargets = sendBackTargets;
3193
- exports.skillToWorkflow = skillToWorkflow;
3194
- exports.splitDocRef = splitDocRef;
3195
- exports.stepConfigProblems = stepConfigProblems;
3196
- exports.stepDependencies = stepDependencies;
3197
- exports.stepFields = stepFields;
3198
- exports.stepLevels = stepLevels;
3199
- exports.stepPhase = stepPhase;
3200
- exports.stepPillTone = stepPillTone;
3201
- exports.stepStatesFromActivity = stepStatesFromActivity;
3202
2539
  exports.stepWindow = stepWindow;
3203
2540
  exports.taskActivityHeadline = taskActivityHeadline;
3204
2541
  exports.toPlanAssignee = toPlanAssignee;
3205
2542
  exports.toPlanDocumentRef = toPlanDocumentRef;
3206
2543
  exports.toPlanSteps = toPlanSteps;
3207
- exports.upstreamSteps = upstreamSteps;
3208
2544
  exports.useWorkflowView = useWorkflowView;
3209
- exports.validateInputs = validateInputs;
3210
- exports.validateStep = validateStep;
3211
- exports.validateWorkflowGraph = validateWorkflowGraph;
3212
- exports.waitingDocuments = waitingDocuments;
3213
- exports.waitingForDocumentsText = waitingForDocumentsText;
3214
- exports.workflowAccepts = workflowAccepts;
3215
- exports.workflowFromFrontmatter = workflowFromFrontmatter;
3216
- exports.workflowSteps = workflowSteps;
3217
- exports.workflowsAccepting = workflowsAccepting;
3218
- exports.workflowsForHost = workflowsForHost;
3219
- //# sourceMappingURL=chunk-5JVPLVDT.cjs.map
3220
- //# sourceMappingURL=chunk-5JVPLVDT.cjs.map
2545
+ //# sourceMappingURL=chunk-7FZWNDPU.cjs.map
2546
+ //# sourceMappingURL=chunk-7FZWNDPU.cjs.map