@arbidocs/blocks 0.4.76 → 0.4.77

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 (97) hide show
  1. package/dist/agents/index.cjs +331 -255
  2. package/dist/agents/index.js +2 -2
  3. package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
  4. package/dist/agents/tasks/WorkflowThreadStrip.d.ts +7 -1
  5. package/dist/agents/workflows/SchemaForm.d.ts +6 -1
  6. package/dist/agents/workflows/StepParts.d.ts +109 -0
  7. package/dist/agents/workflows/WorkflowRunner.d.ts +11 -2
  8. package/dist/agents/workflows/index.d.ts +3 -2
  9. package/dist/agents/workflows/planSteps.d.ts +8 -1
  10. package/dist/agents/workflows/run.d.ts +61 -8
  11. package/dist/agents/workflows/types.d.ts +133 -4
  12. package/dist/agents/workflows/useWorkflowPreview.d.ts +2 -1
  13. package/dist/agents/workflows/useWorkflowView.d.ts +19 -0
  14. package/dist/chat/ChatPage.d.ts +1 -1
  15. package/dist/chat/WorkflowStepChip.d.ts +24 -0
  16. package/dist/chat/chat-page-types.d.ts +4 -0
  17. package/dist/chat/index.cjs +130 -122
  18. package/dist/chat/index.d.ts +1 -0
  19. package/dist/chat/index.js +2 -2
  20. package/dist/{chunk-22P5KNIM.js → chunk-34UW6XUQ.js} +928 -38
  21. package/dist/chunk-34UW6XUQ.js.map +1 -0
  22. package/dist/{chunk-VYRKO3XU.cjs → chunk-3XR3IEGU.cjs} +944 -35
  23. package/dist/chunk-3XR3IEGU.cjs.map +1 -0
  24. package/dist/{chunk-ZWA7UUZL.cjs → chunk-7YUFMNFW.cjs} +2 -54
  25. package/dist/chunk-7YUFMNFW.cjs.map +1 -0
  26. package/dist/chunk-A24C6BNA.js +92 -0
  27. package/dist/chunk-A24C6BNA.js.map +1 -0
  28. package/dist/chunk-AINNADMT.cjs +62 -0
  29. package/dist/chunk-AINNADMT.cjs.map +1 -0
  30. package/dist/{chunk-7CVF3DK2.cjs → chunk-EKIUMNCN.cjs} +5 -5
  31. package/dist/{chunk-7CVF3DK2.cjs.map → chunk-EKIUMNCN.cjs.map} +1 -1
  32. package/dist/chunk-FE4ULGOR.js +151 -0
  33. package/dist/chunk-FE4ULGOR.js.map +1 -0
  34. package/dist/chunk-FT5FFXSJ.js +60 -0
  35. package/dist/chunk-FT5FFXSJ.js.map +1 -0
  36. package/dist/{chunk-HITAN7JF.cjs → chunk-GTXOV7IJ.cjs} +4 -4
  37. package/dist/{chunk-HITAN7JF.cjs.map → chunk-GTXOV7IJ.cjs.map} +1 -1
  38. package/dist/{chunk-TKB7TVMW.js → chunk-HEVVT6IT.js} +78 -14
  39. package/dist/chunk-HEVVT6IT.js.map +1 -0
  40. package/dist/{chunk-IPGKTUF7.cjs → chunk-HOD6OM7L.cjs} +68 -3
  41. package/dist/chunk-HOD6OM7L.cjs.map +1 -0
  42. package/dist/{chunk-7FKARMA3.cjs → chunk-JFUN4D7D.cjs} +101 -37
  43. package/dist/chunk-JFUN4D7D.cjs.map +1 -0
  44. package/dist/{chunk-UIWLDSTF.js → chunk-NIP5BOP7.js} +68 -5
  45. package/dist/chunk-NIP5BOP7.js.map +1 -0
  46. package/dist/{chunk-MK6NJQGF.js → chunk-OEM5ARVM.js} +3 -3
  47. package/dist/{chunk-MK6NJQGF.js.map → chunk-OEM5ARVM.js.map} +1 -1
  48. package/dist/{chunk-5EBGRG3X.js → chunk-OPA2Y6YZ.js} +3 -54
  49. package/dist/chunk-OPA2Y6YZ.js.map +1 -0
  50. package/dist/chunk-TZR36PPP.cjs +95 -0
  51. package/dist/chunk-TZR36PPP.cjs.map +1 -0
  52. package/dist/{chunk-WJEKRSPH.js → chunk-UEU23PTW.js} +3 -3
  53. package/dist/{chunk-WJEKRSPH.js.map → chunk-UEU23PTW.js.map} +1 -1
  54. package/dist/chunk-ZVBPRMHJ.cjs +153 -0
  55. package/dist/chunk-ZVBPRMHJ.cjs.map +1 -0
  56. package/dist/connect/docx.cjs +10 -88
  57. package/dist/connect/docx.cjs.map +1 -1
  58. package/dist/connect/docx.js +6 -86
  59. package/dist/connect/docx.js.map +1 -1
  60. package/dist/connect/index.cjs +293 -30
  61. package/dist/connect/index.cjs.map +1 -1
  62. package/dist/connect/index.js +278 -15
  63. package/dist/connect/index.js.map +1 -1
  64. package/dist/connection/ConnectedWorkflowRunner.d.ts +16 -2
  65. package/dist/connection/WorkflowRunnerDialogs.d.ts +37 -0
  66. package/dist/connection/useWorkflowThread.d.ts +12 -0
  67. package/dist/document-tools/index.cjs +7 -143
  68. package/dist/document-tools/index.cjs.map +1 -1
  69. package/dist/document-tools/index.js +5 -144
  70. package/dist/document-tools/index.js.map +1 -1
  71. package/dist/docx/index.cjs +18 -17
  72. package/dist/docx/index.cjs.map +1 -1
  73. package/dist/docx/index.js +3 -2
  74. package/dist/docx/index.js.map +1 -1
  75. package/dist/index.cjs +467 -383
  76. package/dist/index.js +5 -5
  77. package/dist/studio/index.cjs +3 -3
  78. package/dist/studio/index.js +2 -2
  79. package/dist/workflow-canvas/StepActionSettings.d.ts +132 -0
  80. package/dist/workflow-canvas/StepInspector.d.ts +25 -2
  81. package/dist/workflow-canvas/WorkflowBuilder.d.ts +11 -3
  82. package/dist/workflow-canvas/WorkflowCanvas.d.ts +27 -2
  83. package/dist/workflow-canvas/edit.d.ts +9 -1
  84. package/dist/workflow-canvas/index.cjs +879 -99
  85. package/dist/workflow-canvas/index.cjs.map +1 -1
  86. package/dist/workflow-canvas/index.js +846 -66
  87. package/dist/workflow-canvas/index.js.map +1 -1
  88. package/package.json +4 -4
  89. package/src/workflow-canvas/canvas.css +9 -0
  90. package/dist/chunk-22P5KNIM.js.map +0 -1
  91. package/dist/chunk-5EBGRG3X.js.map +0 -1
  92. package/dist/chunk-7FKARMA3.cjs.map +0 -1
  93. package/dist/chunk-IPGKTUF7.cjs.map +0 -1
  94. package/dist/chunk-TKB7TVMW.js.map +0 -1
  95. package/dist/chunk-UIWLDSTF.js.map +0 -1
  96. package/dist/chunk-VYRKO3XU.cjs.map +0 -1
  97. package/dist/chunk-ZWA7UUZL.cjs.map +0 -1
@@ -4,9 +4,9 @@ import { FoldSection } from './chunk-XD2M6LIG.js';
4
4
  import { useElementSize } from './chunk-HOXKR26S.js';
5
5
  import { testIdOr, prefixedTestId } from './chunk-7F6CBP3Z.js';
6
6
  import { useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect } from 'react';
7
- import { cn, Card, Button, Label, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Switch, Input, Textarea } from '@arbidocs/react/ui';
7
+ import { cn, Button, Textarea, Card, Label, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Switch } from '@arbidocs/react/ui';
8
8
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
- import { CheckCircle2, ArrowLeft, Loader2, ArrowRight, RotateCw, GitBranch, FileText, Check, AlertTriangle, MinusCircle } from 'lucide-react';
9
+ import { UserRound, CornerUpLeft, ShieldCheck, MessageSquare, Check, Hourglass, Clock, PenLine, X, ExternalLink, Mail, Table2, CheckCircle2, ArrowLeft, Loader2, ArrowRight, RotateCw, GitBranch, FileText, AlertTriangle, MinusCircle } from 'lucide-react';
10
10
 
11
11
  // src/agents/workflows/types.ts
12
12
  var EMPTY_WORKFLOW_SCOPE = { folders: [], labels: [] };
@@ -289,7 +289,8 @@ function FieldControl({
289
289
  renderScope,
290
290
  renderDocuments,
291
291
  renderIcon,
292
- onEnterSubmit
292
+ onEnterSubmit,
293
+ people
293
294
  }) {
294
295
  const id = `${idFor()}-control`;
295
296
  const testId = idFor();
@@ -422,6 +423,34 @@ function FieldControl({
422
423
  const picked = isWorkflowScope(value) ? value : { folders: [], labels: [], documents: [] };
423
424
  return /* @__PURE__ */ jsx("div", { "data-testid": testId, children: renderDocuments?.(field, picked, onChange) });
424
425
  }
426
+ case "person":
427
+ return people?.length ? /* @__PURE__ */ jsxs(
428
+ "select",
429
+ {
430
+ id,
431
+ "data-testid": testId,
432
+ value: String(value ?? ""),
433
+ "aria-required": field.required || void 0,
434
+ "aria-invalid": error ? true : void 0,
435
+ onChange: (e) => onChange(e.target.value),
436
+ className: "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm",
437
+ children: [
438
+ /* @__PURE__ */ jsx("option", { value: "", children: field.placeholder ?? "" }),
439
+ people.map((p) => /* @__PURE__ */ jsx("option", { value: p.value, children: p.label }, p.value))
440
+ ]
441
+ }
442
+ ) : /* @__PURE__ */ jsx(
443
+ Input,
444
+ {
445
+ id,
446
+ "data-testid": testId,
447
+ value: String(value ?? ""),
448
+ placeholder: field.placeholder ?? "usr-\u2026",
449
+ "aria-required": field.required || void 0,
450
+ "aria-invalid": error ? true : void 0,
451
+ onChange: (e) => onChange(e.target.value)
452
+ }
453
+ );
425
454
  }
426
455
  }
427
456
  function FormField(props) {
@@ -472,6 +501,7 @@ function SchemaForm({
472
501
  renderDocuments,
473
502
  renderIcon,
474
503
  onEnterSubmit,
504
+ people,
475
505
  testIdPrefix,
476
506
  labels,
477
507
  className
@@ -496,7 +526,8 @@ function SchemaForm({
496
526
  renderScope,
497
527
  renderDocuments,
498
528
  renderIcon,
499
- onEnterSubmit
529
+ onEnterSubmit,
530
+ people
500
531
  },
501
532
  field.name
502
533
  );
@@ -586,33 +617,81 @@ function stepLevels(steps) {
586
617
  }
587
618
  var STEP_EVENTS = {
588
619
  step_started: "running",
620
+ step_waiting: "waiting",
589
621
  step_done: "done",
590
622
  step_skipped: "skipped",
591
623
  step_failed: "failed"
592
624
  };
625
+ var str2 = (v) => typeof v === "string" && v ? v : void 0;
626
+ var ACTION_TYPES = ["sign", "email_draft", "tabular_review"];
627
+ var asAction = (v) => ACTION_TYPES.includes(v) ? v : void 0;
628
+ var asRecord = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
629
+ var asStrings = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : void 0;
630
+ function reopenedBy(detail) {
631
+ const to = str2(detail.to);
632
+ return asStrings(detail.reopened) ?? (to ? [to] : []);
633
+ }
593
634
  function stepStatesFromActivity(events) {
594
635
  const states = {};
595
636
  for (const e of events) {
637
+ const detail = e.detail ?? {};
638
+ const step = str2(detail.step);
639
+ if (!step) continue;
640
+ if (e.kind === "step_sent_back") {
641
+ const to = str2(detail.to);
642
+ for (const id of reopenedBy(detail))
643
+ states[id] = id === to ? {
644
+ status: "pending",
645
+ sentBack: true,
646
+ hasNote: typeof detail.note_encrypted === "string"
647
+ } : { status: "pending" };
648
+ continue;
649
+ }
650
+ if (e.kind === "step_ready") {
651
+ states[step] = { ...states[step] ?? { status: "pending" }, announcedTo: str2(detail.to) };
652
+ continue;
653
+ }
654
+ if (e.kind === "step_progress") {
655
+ const before2 = states[step];
656
+ const waiting2 = asRecord(detail.waiting);
657
+ if (before2?.status === "waiting" && waiting2) states[step] = { ...before2, waiting: waiting2 };
658
+ continue;
659
+ }
596
660
  const status = STEP_EVENTS[e.kind];
597
- const step = e.detail?.step;
598
- if (!status || typeof step !== "string") continue;
599
- const responseId = typeof e.detail?.response_id === "string" ? e.detail.response_id : void 0;
600
- const error = typeof e.detail?.error === "string" ? e.detail.error : null;
601
- const startedAt = status === "running" ? e.created_at : states[step]?.startedAt;
661
+ if (!status) continue;
662
+ const before = states[step];
663
+ const responseId = str2(detail.response_id) ?? before?.responseId ?? null;
664
+ const startedAt = status === "running" ? e.created_at : before?.startedAt;
665
+ const action = asAction(detail.action) ?? before?.action;
666
+ const documents = asStrings(detail.documents) ?? before?.documents;
667
+ const waiting = status === "waiting" ? asRecord(detail.waiting) : void 0;
668
+ const output = status === "done" ? asRecord(detail.output) : void 0;
669
+ const approved = Array.isArray(detail.approved) ? detail.approved.filter(asRecord) : void 0;
670
+ const finished2 = status === "done" || status === "skipped" || status === "failed";
671
+ const declinedBy = str2(detail.declined_by);
602
672
  states[step] = {
603
673
  status,
604
- responseId: responseId ?? states[step]?.responseId ?? null,
605
- error,
606
- ...startedAt ? { startedAt } : {}
674
+ responseId,
675
+ error: str2(detail.error) ?? null,
676
+ ...startedAt ? { startedAt } : {},
677
+ ...action ? { action } : {},
678
+ ...documents?.length ? { documents } : {},
679
+ ...waiting ? { waiting } : {},
680
+ ...output ? { output } : {},
681
+ ...approved ? { approved } : {},
682
+ ...finished2 ? { by: e.actor_ext_id ?? null } : {},
683
+ ...finished2 && e.created_at ? { at: e.created_at } : {},
684
+ ...declinedBy ? { declinedBy } : {}
607
685
  };
608
686
  }
609
687
  return states;
610
688
  }
689
+ function stepFields(step) {
690
+ return step.kind === "form" ? step.inputs : step.kind === "review" ? step.fields ?? [] : [];
691
+ }
692
+ var runFieldsOf = (steps) => steps.flatMap(stepFields);
611
693
  function runFields(workflow) {
612
- return [
613
- ...workflow.inputs,
614
- ...workflowSteps(workflow).flatMap((s) => s.kind === "form" ? s.inputs : [])
615
- ];
694
+ return [...workflow.inputs, ...workflowSteps(workflow).flatMap(stepFields)];
616
695
  }
617
696
  function initialRunInputs(workflow, inputs = {}) {
618
697
  return { ...defaultInputs({ ...workflow, inputs: runFields(workflow) }), ...inputs };
@@ -624,7 +703,9 @@ function stepPhase(steps, states, id) {
624
703
  return stepDependencies(steps, id).every((d) => finished(states[d])) ? "ready" : "blocked";
625
704
  }
626
705
  var isRunFinished = (steps, states) => steps.length > 0 && steps.every((s) => finished(states[s.id]));
627
- var isPersonStep = (step) => step.kind !== "agent";
706
+ var isPersonStep = (step) => step.kind !== "agent" && step.kind !== "action";
707
+ var isPersonAction = (step) => step.kind === "action" && (step.action.type === "sign" || step.action.type === "email_draft");
708
+ var canAssign = (step) => isPersonStep(step) || isPersonAction(step);
628
709
  function nextAction(steps, states, current) {
629
710
  const i = steps.findIndex((s) => s.id === current);
630
711
  const step = steps[i];
@@ -638,20 +719,76 @@ function nextAction(steps, states, current) {
638
719
  return isRunFinished(steps, states) ? "finish" : "wait";
639
720
  }
640
721
  if (isPersonStep(step)) return "complete";
722
+ if (phase === "waiting" && step.kind === "action" && step.action.type === "email_draft")
723
+ return "complete";
641
724
  if (phase !== "failed") return independentNext ? "move" : "wait";
642
725
  const waitedFor = steps.slice(i + 1).some((s) => dependsOn(steps, s.id, step.id));
643
726
  return waitedFor || !following ? "skip" : "move";
644
727
  }
645
728
  function validateStep(step, inputs) {
646
- if (step.kind !== "form") return {};
729
+ const fields = stepFields(step);
730
+ if (!fields.length) return {};
647
731
  return validateInputs(
648
732
  {
649
733
  id: step.id,
650
734
  title: step.title,
651
- inputs: step.inputs},
735
+ inputs: fields},
652
736
  inputs
653
737
  );
654
738
  }
739
+ function upstreamSteps(steps, id) {
740
+ return steps.filter((s) => s.id !== id && dependsOn(steps, id, s.id));
741
+ }
742
+ function sendBackTargets(steps, states, id) {
743
+ return upstreamSteps(steps, id).filter((s) => ["done", "skipped", "failed"].includes(states[s.id]?.status ?? "pending")).reverse();
744
+ }
745
+ var isBlankRef = (ref) => "step" in ref ? !ref.step : "input" in ref ? !ref.input : !ref.id.trim();
746
+ function stepConfigProblems(steps) {
747
+ const out = [];
748
+ for (const s of steps) {
749
+ if (s.kind === "action") {
750
+ const a = s.action;
751
+ if (a.type === "sign") {
752
+ if (!a.document || isBlankRef(a.document)) out.push({ step: s.id, missing: "document" });
753
+ if (!a.signers.length) out.push({ step: s.id, missing: "signers" });
754
+ } else if (a.type === "email_draft") {
755
+ if (!a.to.some((t) => t.trim())) out.push({ step: s.id, missing: "recipients" });
756
+ } else {
757
+ if (!a.tags.length) out.push({ step: s.id, missing: "tags" });
758
+ if (Array.isArray(a.documents) && !a.documents.length)
759
+ out.push({ step: s.id, missing: "documents" });
760
+ }
761
+ }
762
+ if (s.kind === "agent" && s.editDocument && isBlankRef(s.editDocument))
763
+ out.push({ step: s.id, missing: "document" });
764
+ }
765
+ return out;
766
+ }
767
+ function splitDocRef(ref) {
768
+ const m = /^(doc-[A-Za-z0-9]+)(?:@v(\d+))?$/.exec(ref);
769
+ return m ? { id: m[1], ...m[2] ? { version: Number(m[2]) } : {} } : { id: ref };
770
+ }
771
+ var DEFAULT_ASSIGNEE_WORDING = {
772
+ runOwner: "whoever started the run",
773
+ projectLead: "the project lead",
774
+ input: "the person in \u201C{field}\u201D"
775
+ };
776
+ function assigneeName(assignee, options = {}) {
777
+ const w = { ...DEFAULT_ASSIGNEE_WORDING, ...options.wording };
778
+ const name = (id) => options.nameOf?.(id) ?? id;
779
+ const told = options.announcedTo ? options.nameOf?.(options.announcedTo) : void 0;
780
+ if (told) return told;
781
+ if (!assignee) return void 0;
782
+ if ("user" in assignee) return name(assignee.user);
783
+ if ("input" in assignee) {
784
+ const value = options.inputs?.[assignee.input];
785
+ if (typeof value === "string" && value) return name(value);
786
+ const label = options.fields?.find((f) => f.name === assignee.input)?.label ?? assignee.input;
787
+ return w.input.replace("{field}", label);
788
+ }
789
+ if ("runOwner" in assignee) return w.runOwner;
790
+ return w.projectLead;
791
+ }
655
792
  var asText = (value) => typeof value === "string" ? value.trim() : typeof value === "number" ? String(value) : "";
656
793
  function fillStepInputs(templates, inputs) {
657
794
  const out = {};
@@ -698,6 +835,111 @@ function composeStepPrompt(workflow, step, runInputs, { resolveWorkflow, compose
698
835
  }
699
836
 
700
837
  // src/agents/workflows/planSteps.ts
838
+ function toPlanAssignee(a) {
839
+ if ("user" in a) return { user: a.user };
840
+ if ("input" in a) return { input: a.input };
841
+ if ("runOwner" in a) return { run_owner: true };
842
+ return { project_lead: true };
843
+ }
844
+ function fromPlanAssignee(a) {
845
+ if (!a) return void 0;
846
+ if (a.user) return { user: a.user };
847
+ if (a.input) return { input: a.input };
848
+ if (a.run_owner) return { runOwner: true };
849
+ if (a.project_lead) return { projectLead: true };
850
+ return void 0;
851
+ }
852
+ function toPlanDocumentRef(ref) {
853
+ if ("step" in ref) return { step: ref.step };
854
+ if ("input" in ref) return { input: ref.input };
855
+ return ref.id.trim();
856
+ }
857
+ function fromPlanDocumentRef(ref) {
858
+ if (!ref) return void 0;
859
+ if (typeof ref === "string") return { id: ref };
860
+ if (ref.step) return { step: ref.step };
861
+ if (ref.input) return { input: ref.input };
862
+ return void 0;
863
+ }
864
+ var docRefs = (refs) => (refs ?? []).map(toPlanDocumentRef);
865
+ var fromDocRefs = (refs) => (refs ?? []).flatMap((r) => {
866
+ const ref = fromPlanDocumentRef(r);
867
+ return ref ? [ref] : [];
868
+ });
869
+ function toPlanAction(a) {
870
+ switch (a.type) {
871
+ case "sign":
872
+ return {
873
+ type: "sign",
874
+ // The builder may hold a signature step whose document is not chosen yet: the server
875
+ // refuses it, and the builder says so before saving (`stepConfigProblems`).
876
+ document: a.document ? toPlanDocumentRef(a.document) : "",
877
+ signers: a.signers.map(toPlanAssignee),
878
+ ...a.message?.trim() ? { message: a.message.trim() } : {},
879
+ ...a.expiresAfterHours ? { expires_after_hours: a.expiresAfterHours } : {}
880
+ };
881
+ case "email_draft":
882
+ return {
883
+ type: "email_draft",
884
+ to: a.to.map((t) => t.trim()).filter(Boolean),
885
+ cc: (a.cc ?? []).map((t) => t.trim()).filter(Boolean),
886
+ subject: a.subject,
887
+ body_template: a.body,
888
+ attachments: docRefs(a.attachments)
889
+ };
890
+ case "tabular_review":
891
+ return {
892
+ type: "tabular_review",
893
+ tags: a.tags,
894
+ documents: Array.isArray(a.documents) ? docRefs(a.documents) : a.documents,
895
+ overwrite: !!a.overwrite
896
+ };
897
+ }
898
+ }
899
+ function fromPlanAction(a) {
900
+ switch (a?.type) {
901
+ case "sign":
902
+ return {
903
+ type: "sign",
904
+ document: fromPlanDocumentRef(a.document),
905
+ signers: (a.signers ?? []).flatMap((s) => {
906
+ const one = fromPlanAssignee(s);
907
+ return one ? [one] : [];
908
+ }),
909
+ ...a.message ? { message: a.message } : {},
910
+ ...a.expires_after_hours ? { expiresAfterHours: a.expires_after_hours } : {}
911
+ };
912
+ case "email_draft":
913
+ return {
914
+ type: "email_draft",
915
+ to: a.to ?? [],
916
+ ...a.cc?.length ? { cc: a.cc } : {},
917
+ subject: a.subject ?? "",
918
+ body: a.body_template ?? "",
919
+ ...a.attachments?.length ? { attachments: fromDocRefs(a.attachments) } : {}
920
+ };
921
+ case "tabular_review":
922
+ return {
923
+ type: "tabular_review",
924
+ tags: a.tags ?? [],
925
+ documents: Array.isArray(a.documents) ? fromDocRefs(a.documents) : a.documents ?? "run_uploads",
926
+ ...a.overwrite ? { overwrite: true } : {}
927
+ };
928
+ default:
929
+ return { type: "tabular_review", tags: [], documents: "run_uploads" };
930
+ }
931
+ }
932
+ function toStepField(f) {
933
+ return {
934
+ name: f.name,
935
+ type: f.type,
936
+ label: f.label,
937
+ required: !!f.required,
938
+ ...f.options ? { options: f.options.map((o) => ({ value: o.value, label: o.label })) } : {},
939
+ ...f.min !== void 0 ? { min: f.min } : {},
940
+ ...f.max !== void 0 ? { max: f.max } : {}
941
+ };
942
+ }
701
943
  var compact2 = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0 && v !== ""));
702
944
  function placeholders(workflow) {
703
945
  return Object.fromEntries(runFields(workflow).map((f) => [f.name, `{{${f.name}}}`]));
@@ -722,7 +964,7 @@ function toPlanSteps(workflow, options = {}) {
722
964
  position: layout?.[step.id],
723
965
  ...step.kind === "form" ? { fields: step.inputs } : {},
724
966
  ...step.kind === "upload" ? { required: step.required, accept: step.accept, hint: step.hint } : {},
725
- ...step.kind === "review" ? { instructions: step.instructions } : {},
967
+ ...step.kind === "review" ? { instructions: step.instructions, fields: step.fields?.length ? step.fields : void 0 } : {},
726
968
  ...step.kind === "agent" ? {
727
969
  output: step.output,
728
970
  workflow: step.workflow,
@@ -740,6 +982,12 @@ function toPlanSteps(workflow, options = {}) {
740
982
  ui,
741
983
  // An unfinished signal (still being typed) is not saved: the server would refuse it.
742
984
  ...step.signals?.some((s) => !isIncompleteSignal(s)) ? { signals: step.signals.filter((s) => !isIncompleteSignal(s)).map(toPlanSignal) } : {},
985
+ ...step.assignee && canAssign(step) ? { assignee: toPlanAssignee(step.assignee) } : {},
986
+ ...step.remindAfterHours && canAssign(step) ? { remind_after_hours: step.remindAfterHours } : {},
987
+ // A review's fields are what approving it is checked against (the server's `fields`).
988
+ ...step.kind === "review" && step.fields?.length ? { fields: step.fields.map(toStepField) } : {},
989
+ ...step.kind === "action" ? { action: toPlanAction(step.action) } : {},
990
+ ...step.kind === "agent" && step.editDocument && !step.branch ? { edit_document: toPlanDocumentRef(step.editDocument) } : {},
743
991
  ...step.kind === "agent" ? agentStep(workflow, step, options) : { skill: null, inputs: null, prompt: null }
744
992
  };
745
993
  });
@@ -772,7 +1020,9 @@ function fromPlanSteps(steps) {
772
1020
  commit: ui.commit,
773
1021
  nextLabel: ui.next_label,
774
1022
  ...p.after != null ? { after: p.after } : {},
775
- ...p.signals?.length ? { signals: p.signals.map(fromPlanSignal) } : {}
1023
+ ...p.signals?.length ? { signals: p.signals.map(fromPlanSignal) } : {},
1024
+ ...fromPlanAssignee(p.assignee) ? { assignee: fromPlanAssignee(p.assignee) } : {},
1025
+ ...p.remind_after_hours ? { remindAfterHours: p.remind_after_hours } : {}
776
1026
  };
777
1027
  switch (p.kind) {
778
1028
  case "form":
@@ -780,7 +1030,15 @@ function fromPlanSteps(steps) {
780
1030
  case "upload":
781
1031
  return { ...base, kind: "upload", required: ui.required, accept: ui.accept, hint: ui.hint };
782
1032
  case "review":
783
- return { ...base, kind: "review", instructions: ui.instructions };
1033
+ return {
1034
+ ...base,
1035
+ kind: "review",
1036
+ instructions: ui.instructions,
1037
+ // The client's copy of the fields (labels, options) when it kept one, else the plan's.
1038
+ ...ui.fields?.length ? { fields: ui.fields } : p.fields?.length ? { fields: p.fields.map(fromStepField) } : {}
1039
+ };
1040
+ case "action":
1041
+ return { ...base, kind: "action", action: fromPlanAction(p.action) };
784
1042
  default: {
785
1043
  const promptTemplate = ui.prompt_template ?? p.prompt ?? void 0;
786
1044
  return {
@@ -790,7 +1048,8 @@ function fromPlanSteps(steps) {
790
1048
  with: ui.with ?? p.inputs ?? void 0,
791
1049
  run: !ui.workflow && !p.skill && promptTemplate ? { kind: "prompt", promptTemplate } : void 0,
792
1050
  output: ui.output,
793
- branch: p.branch || void 0
1051
+ branch: p.branch || void 0,
1052
+ ...fromPlanDocumentRef(p.edit_document) ? { editDocument: fromPlanDocumentRef(p.edit_document) } : {}
794
1053
  };
795
1054
  }
796
1055
  }
@@ -803,25 +1062,47 @@ function layoutFromPlanSteps(steps) {
803
1062
  });
804
1063
  return entries.length ? Object.fromEntries(entries) : void 0;
805
1064
  }
1065
+ var FIELD_TYPES2 = /* @__PURE__ */ new Set([
1066
+ "text",
1067
+ "longtext",
1068
+ "boolean",
1069
+ "select",
1070
+ "number",
1071
+ "date",
1072
+ "scope",
1073
+ "documents",
1074
+ "person"
1075
+ ]);
1076
+ function fromStepField(f) {
1077
+ return {
1078
+ name: f.name,
1079
+ type: FIELD_TYPES2.has(f.type) ? f.type : "text",
1080
+ label: f.label ?? f.name,
1081
+ ...f.required ? { required: true } : {},
1082
+ ...f.options?.length ? { options: f.options.map((o) => ({ value: o.value, label: o.label ?? o.value })) } : {},
1083
+ ...f.min != null ? { min: f.min } : {},
1084
+ ...f.max != null ? { max: f.max } : {}
1085
+ };
1086
+ }
806
1087
  var errorMessage = (e) => e instanceof Error ? e.message : typeof e === "string" ? e : "Something went wrong.";
807
1088
  function firstOpen(steps, states) {
808
1089
  const open = steps.find((s) => !["done", "skipped"].includes(states[s.id]?.status ?? "pending"));
809
1090
  return open?.id ?? (steps.length && isRunFinished(steps, states) ? null : steps[0]?.id ?? null);
810
1091
  }
811
1092
  function useWorkflowView(options) {
812
- const { steps, states, inputs, setInput } = options;
1093
+ const { steps, states, inputs, setInput, loaded = true } = options;
813
1094
  const [current, setCurrent] = useState(() => firstOpen(steps, states));
814
1095
  const [showErrors, setShowErrors] = useState(false);
815
1096
  const [busy, setBusy] = useState(false);
816
1097
  const [actionError, setActionError] = useState(null);
817
1098
  const optionsRef = useRef(options);
818
1099
  optionsRef.current = options;
819
- const placed = useRef(steps.length > 0);
1100
+ const placed = useRef(steps.length > 0 && loaded);
820
1101
  useEffect(() => {
821
- if (placed.current || steps.length === 0) return;
1102
+ if (placed.current || steps.length === 0 || !loaded) return;
822
1103
  placed.current = true;
823
1104
  setCurrent(firstOpen(steps, states));
824
- }, [steps, states]);
1105
+ }, [steps, states, loaded]);
825
1106
  const step = steps.find((s) => s.id === current);
826
1107
  const following = useCallback(
827
1108
  (id) => {
@@ -909,6 +1190,40 @@ function useWorkflowView(options) {
909
1190
  // eslint-disable-next-line react-hooks/exhaustive-deps
910
1191
  [act, !!options.retry]
911
1192
  );
1193
+ const sendBack = useMemo(
1194
+ () => options.sendBack ? async (stepId, to, note) => {
1195
+ setBusy(true);
1196
+ setActionError(null);
1197
+ try {
1198
+ await optionsRef.current.sendBack?.(stepId, to, note);
1199
+ setShowErrors(false);
1200
+ setCurrent(to);
1201
+ } catch (e) {
1202
+ setActionError(errorMessage(e));
1203
+ } finally {
1204
+ setBusy(false);
1205
+ }
1206
+ } : void 0,
1207
+ // Only whether the host offers it matters here.
1208
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1209
+ [!!options.sendBack]
1210
+ );
1211
+ const declineWithNote = useMemo(
1212
+ () => options.decline ? async (stepId, note) => {
1213
+ setBusy(true);
1214
+ setActionError(null);
1215
+ try {
1216
+ await optionsRef.current.decline?.(stepId, note);
1217
+ } catch (e) {
1218
+ setActionError(errorMessage(e));
1219
+ } finally {
1220
+ setBusy(false);
1221
+ }
1222
+ } : void 0,
1223
+ // Only whether the host offers it matters here.
1224
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1225
+ [!!options.decline]
1226
+ );
912
1227
  const isLocked = useCallback(
913
1228
  (stepId) => optionsRef.current.isLocked?.(stepId) ?? false,
914
1229
  []
@@ -934,6 +1249,19 @@ function useWorkflowView(options) {
934
1249
  goTo,
935
1250
  skip,
936
1251
  retry,
1252
+ sendBack,
1253
+ decline: declineWithNote,
1254
+ nameOf: options.nameOf,
1255
+ assigneeOf: (id) => {
1256
+ const s = steps.find((x) => x.id === id);
1257
+ if (!s || !canAssign(s)) return void 0;
1258
+ return assigneeName(s.assignee, {
1259
+ nameOf: options.nameOf,
1260
+ inputs,
1261
+ fields: runFieldsOf(steps),
1262
+ announcedTo: states[id]?.announcedTo
1263
+ });
1264
+ },
937
1265
  restart: () => {
938
1266
  setShowErrors(false);
939
1267
  setActionError(null);
@@ -941,9 +1269,489 @@ function useWorkflowView(options) {
941
1269
  }
942
1270
  };
943
1271
  }
1272
+ var DEFAULT_WORKFLOW_STEP_PARTS_LABELS = {
1273
+ waitingFor: "Waiting for {name}",
1274
+ sendBack: "Send back",
1275
+ sendBackTo: "Send back to",
1276
+ sendBackNote: "What needs to change? (optional)",
1277
+ cancel: "Cancel",
1278
+ sentBackHere: "This step was sent back to be done again.",
1279
+ approvedBy: "Approved by {name}",
1280
+ approvedAt: "{date}",
1281
+ approvedWhat: "What was approved",
1282
+ viewAnswer: "View the answer",
1283
+ fieldsHeading: "Recorded with the approval",
1284
+ signers: "Signers",
1285
+ signed: "Signed",
1286
+ notSigned: "Not signed yet",
1287
+ openAndSign: "Open and sign",
1288
+ decline: "Decline",
1289
+ declineNote: "Why are you declining? (optional)",
1290
+ declineConfirm: "Decline to sign",
1291
+ declined: "Declined by {name}.",
1292
+ signedVersion: "Open the signed version",
1293
+ preparingSign: "Preparing the signature request\u2026",
1294
+ expires: "Expires {date}",
1295
+ preparingDraft: "Preparing the draft\u2026",
1296
+ draftReady: "The draft is ready in native mail. Check it, send it, then mark it as sent.",
1297
+ openDraft: "Open draft",
1298
+ emailSent: "Sent.",
1299
+ reviewRunning: "Reviewing the documents\u2026",
1300
+ reviewDone: "Reviewed {docs} documents in {cols} columns.",
1301
+ openReview: "Open the review",
1302
+ openInWord: "Open in Word",
1303
+ redlineHint: "The edits are tracked changes: accept or reject each one in Word.",
1304
+ someone: "someone"
1305
+ };
1306
+ var formatDate = (iso) => {
1307
+ const t = iso ? Date.parse(iso) : NaN;
1308
+ return Number.isNaN(t) ? "" : new Date(t).toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
1309
+ };
1310
+ var docName = (ref, nameOfDoc) => {
1311
+ const { id, version } = splitDocRef(ref);
1312
+ const name = nameOfDoc?.(id) ?? id;
1313
+ return version ? `${name} \xB7 v${version}` : name;
1314
+ };
1315
+ function DocChip({
1316
+ docRef,
1317
+ actions,
1318
+ nameOfDoc,
1319
+ testId
1320
+ }) {
1321
+ const label = docName(docRef, nameOfDoc);
1322
+ const cls = "inline-flex max-w-full items-center gap-1 rounded-md border border-border px-1.5 py-0.5 text-xs";
1323
+ return actions?.openDocument ? /* @__PURE__ */ jsxs(
1324
+ "button",
1325
+ {
1326
+ type: "button",
1327
+ onClick: () => actions.openDocument?.(docRef),
1328
+ className: cn(cls, "hover:border-primary/40 hover:text-primary"),
1329
+ title: docRef,
1330
+ "data-testid": testId,
1331
+ children: [
1332
+ /* @__PURE__ */ jsx(FileText, { className: "size-3 shrink-0" }),
1333
+ " ",
1334
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: label })
1335
+ ]
1336
+ }
1337
+ ) : /* @__PURE__ */ jsxs("span", { className: cls, title: docRef, "data-testid": testId, children: [
1338
+ /* @__PURE__ */ jsx(FileText, { className: "size-3 shrink-0" }),
1339
+ " ",
1340
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: label })
1341
+ ] });
1342
+ }
1343
+ function AssigneeLine({
1344
+ run,
1345
+ stepId,
1346
+ l,
1347
+ testId
1348
+ }) {
1349
+ const name = run.assigneeOf(stepId);
1350
+ const phase = run.phaseOf(stepId);
1351
+ if (!name || !["ready", "waiting", "blocked"].includes(phase)) return null;
1352
+ return /* @__PURE__ */ jsxs(
1353
+ "p",
1354
+ {
1355
+ className: "flex items-center gap-1.5 text-xs text-muted-foreground",
1356
+ "data-testid": `${testId}-assignee`,
1357
+ children: [
1358
+ /* @__PURE__ */ jsx(UserRound, { className: "size-3.5" }),
1359
+ " ",
1360
+ l.waitingFor.replace("{name}", name)
1361
+ ]
1362
+ }
1363
+ );
1364
+ }
1365
+ function SentBackNote({
1366
+ state,
1367
+ l,
1368
+ testId
1369
+ }) {
1370
+ if (!state?.sentBack) return null;
1371
+ return /* @__PURE__ */ jsxs(
1372
+ "p",
1373
+ {
1374
+ className: "flex items-center gap-1.5 rounded-md bg-amber-500/10 px-2 py-1 text-xs text-amber-700 dark:text-amber-300",
1375
+ "data-testid": `${testId}-sent-back`,
1376
+ children: [
1377
+ /* @__PURE__ */ jsx(CornerUpLeft, { className: "size-3.5" }),
1378
+ " ",
1379
+ l.sentBackHere
1380
+ ]
1381
+ }
1382
+ );
1383
+ }
1384
+ function SendBackControl({
1385
+ run,
1386
+ step,
1387
+ l,
1388
+ testId
1389
+ }) {
1390
+ const states = Object.fromEntries(
1391
+ run.steps.map((s) => [s.id, run.stateOf(s.id) ?? { status: "pending" }])
1392
+ );
1393
+ const targets = sendBackTargets(run.steps, states, step.id);
1394
+ const [open, setOpen] = useState(false);
1395
+ const [to, setTo] = useState(targets[0]?.id ?? "");
1396
+ const [note, setNote] = useState("");
1397
+ if (!run.sendBack || run.phaseOf(step.id) !== "ready" || targets.length === 0) return null;
1398
+ if (!open)
1399
+ return /* @__PURE__ */ jsxs(
1400
+ Button,
1401
+ {
1402
+ variant: "outline",
1403
+ size: "sm",
1404
+ onClick: () => setOpen(true),
1405
+ disabled: run.busy,
1406
+ "data-testid": `${testId}-send-back`,
1407
+ children: [
1408
+ /* @__PURE__ */ jsx(CornerUpLeft, { className: "size-4" }),
1409
+ " ",
1410
+ l.sendBack
1411
+ ]
1412
+ }
1413
+ );
1414
+ const target = targets.some((t) => t.id === to) ? to : targets[0].id;
1415
+ return /* @__PURE__ */ jsxs(
1416
+ "div",
1417
+ {
1418
+ className: "space-y-2 rounded-md border border-border p-3",
1419
+ "data-testid": `${testId}-send-back-form`,
1420
+ children: [
1421
+ /* @__PURE__ */ jsxs("label", { className: "block space-y-1 text-xs font-medium", children: [
1422
+ l.sendBackTo,
1423
+ /* @__PURE__ */ jsx(
1424
+ "select",
1425
+ {
1426
+ className: "flex h-8 w-full rounded-md border border-input bg-background px-2 text-sm",
1427
+ value: target,
1428
+ onChange: (e) => setTo(e.target.value),
1429
+ "data-testid": `${testId}-send-back-to`,
1430
+ children: targets.map((t) => /* @__PURE__ */ jsx("option", { value: t.id, children: t.title }, t.id))
1431
+ }
1432
+ )
1433
+ ] }),
1434
+ /* @__PURE__ */ jsx(
1435
+ Textarea,
1436
+ {
1437
+ rows: 3,
1438
+ value: note,
1439
+ placeholder: l.sendBackNote,
1440
+ "aria-label": l.sendBackNote,
1441
+ onChange: (e) => setNote(e.target.value),
1442
+ "data-testid": `${testId}-send-back-note`
1443
+ }
1444
+ ),
1445
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
1446
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => setOpen(false), children: l.cancel }),
1447
+ /* @__PURE__ */ jsxs(
1448
+ Button,
1449
+ {
1450
+ size: "sm",
1451
+ disabled: run.busy,
1452
+ onClick: () => void run.sendBack?.(step.id, target, note.trim() || void 0),
1453
+ "data-testid": `${testId}-send-back-confirm`,
1454
+ children: [
1455
+ /* @__PURE__ */ jsx(CornerUpLeft, { className: "size-4" }),
1456
+ " ",
1457
+ l.sendBack
1458
+ ]
1459
+ }
1460
+ )
1461
+ ] })
1462
+ ]
1463
+ }
1464
+ );
1465
+ }
1466
+ var shownValue = (v, field, nameOf) => {
1467
+ if (v === void 0 || v === null || v === "") return "\u2014";
1468
+ if (typeof v === "boolean") return v ? "\u2713" : "\u2717";
1469
+ if (field.type === "person" && typeof v === "string") return nameOf?.(v) ?? v;
1470
+ if (field.type === "select") return field.options?.find((o) => o.value === v)?.label ?? String(v);
1471
+ return typeof v === "object" ? JSON.stringify(v) : String(v);
1472
+ };
1473
+ function ApprovalEvidence({
1474
+ run,
1475
+ step,
1476
+ actions,
1477
+ nameOfDoc,
1478
+ l,
1479
+ testId
1480
+ }) {
1481
+ const state = run.stateOf(step.id);
1482
+ if (state?.status !== "done") return null;
1483
+ const approver = state.by ? run.nameOf?.(state.by) ?? l.someone : void 0;
1484
+ const evidence = state.approved ?? [];
1485
+ const titleOf = (id) => run.steps.find((s) => s.id === id)?.title ?? id;
1486
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2 rounded-md bg-muted/40 p-3", "data-testid": `${testId}-evidence`, children: [
1487
+ /* @__PURE__ */ jsxs("p", { className: "flex flex-wrap items-center gap-1.5 text-sm font-medium", children: [
1488
+ /* @__PURE__ */ jsx(ShieldCheck, { className: "size-4 text-primary" }),
1489
+ approver ? l.approvedBy.replace("{name}", approver) : null,
1490
+ state.at && /* @__PURE__ */ jsx("span", { className: "text-xs font-normal text-muted-foreground", children: l.approvedAt.replace("{date}", formatDate(state.at)) })
1491
+ ] }),
1492
+ evidence.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
1493
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: l.approvedWhat }),
1494
+ evidence.map((e) => /* @__PURE__ */ jsxs(
1495
+ "div",
1496
+ {
1497
+ className: "flex flex-wrap items-center gap-1.5 text-xs",
1498
+ "data-testid": `${testId}-evidence-${e.step}`,
1499
+ children: [
1500
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: titleOf(e.step) }),
1501
+ e.response_id && (actions?.openMessage ? /* @__PURE__ */ jsxs(
1502
+ "button",
1503
+ {
1504
+ type: "button",
1505
+ onClick: () => actions.openMessage?.(e.response_id),
1506
+ className: "inline-flex items-center gap-1 text-primary hover:underline",
1507
+ "data-testid": `${testId}-evidence-${e.step}-answer`,
1508
+ children: [
1509
+ /* @__PURE__ */ jsx(MessageSquare, { className: "size-3" }),
1510
+ " ",
1511
+ l.viewAnswer
1512
+ ]
1513
+ }
1514
+ ) : null),
1515
+ (e.documents ?? []).map((d) => /* @__PURE__ */ jsx(DocChip, { docRef: d, actions, nameOfDoc }, d))
1516
+ ]
1517
+ },
1518
+ e.step
1519
+ ))
1520
+ ] }),
1521
+ (step.fields ?? []).length > 0 && /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 text-xs", children: (step.fields ?? []).map((f) => /* @__PURE__ */ jsxs("div", { className: "contents", children: [
1522
+ /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: f.label }),
1523
+ /* @__PURE__ */ jsx("dd", { "data-testid": `${testId}-evidence-field-${f.name}`, children: shownValue(run.inputs[f.name], f, run.nameOf) })
1524
+ ] }, f.name)) })
1525
+ ] });
1526
+ }
1527
+ function RedlineOpen({
1528
+ step,
1529
+ state,
1530
+ actions,
1531
+ l,
1532
+ testId
1533
+ }) {
1534
+ const version = state?.status === "done" ? state.documents?.[0] : void 0;
1535
+ if (!step.editDocument || !version || !actions?.openRedline) return null;
1536
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", "data-testid": `${testId}-redline`, children: [
1537
+ /* @__PURE__ */ jsxs(
1538
+ Button,
1539
+ {
1540
+ size: "sm",
1541
+ onClick: () => actions.openRedline?.(version),
1542
+ "data-testid": `${testId}-open-word`,
1543
+ children: [
1544
+ /* @__PURE__ */ jsx(FileText, { className: "size-4" }),
1545
+ " ",
1546
+ l.openInWord
1547
+ ]
1548
+ }
1549
+ ),
1550
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: l.redlineHint })
1551
+ ] });
1552
+ }
1553
+ function ActionStepBody({
1554
+ step,
1555
+ run,
1556
+ actions,
1557
+ nameOfDoc,
1558
+ heading,
1559
+ l,
1560
+ testId
1561
+ }) {
1562
+ const state = run.stateOf(step.id);
1563
+ const phase = run.phaseOf(step.id);
1564
+ const name = (id) => run.nameOf?.(id) ?? id;
1565
+ const [declining, setDeclining] = useState(false);
1566
+ const [note, setNote] = useState("");
1567
+ const a = step.action;
1568
+ const working = (text) => /* @__PURE__ */ jsxs(
1569
+ "p",
1570
+ {
1571
+ className: "flex items-center gap-2 text-sm text-muted-foreground",
1572
+ "data-testid": `${testId}-working`,
1573
+ children: [
1574
+ /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
1575
+ " ",
1576
+ text
1577
+ ]
1578
+ }
1579
+ );
1580
+ let body = null;
1581
+ if (a.type === "sign") {
1582
+ const waiting = state?.waiting;
1583
+ const signers = waiting?.signers ?? [];
1584
+ const signed = new Set(waiting?.signed ?? []);
1585
+ const mine = !actions?.me || signers.includes(actions.me) && !signed.has(actions.me);
1586
+ const signedRef = state?.status === "done" ? state.documents?.[0] : void 0;
1587
+ body = /* @__PURE__ */ jsxs(Fragment, { children: [
1588
+ (phase === "ready" || phase === "running") && working(l.preparingSign),
1589
+ phase === "waiting" && waiting?.doc_ext_id && /* @__PURE__ */ jsx(
1590
+ DocChip,
1591
+ {
1592
+ docRef: `${waiting.doc_ext_id}${waiting.version ? `@v${waiting.version}` : ""}`,
1593
+ actions,
1594
+ nameOfDoc,
1595
+ testId: `${testId}-document`
1596
+ }
1597
+ ),
1598
+ signers.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-1", "data-testid": `${testId}-signers`, children: [
1599
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: l.signers }),
1600
+ signers.map((id) => /* @__PURE__ */ jsxs(
1601
+ "p",
1602
+ {
1603
+ className: "flex items-center gap-2 text-sm",
1604
+ "data-signed": signed.has(id) || void 0,
1605
+ "data-testid": `${testId}-signer-${id}`,
1606
+ children: [
1607
+ signed.has(id) ? /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-primary" }) : /* @__PURE__ */ jsx(Hourglass, { className: "size-3.5 text-muted-foreground" }),
1608
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: name(id) }),
1609
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: signed.has(id) ? l.signed : l.notSigned })
1610
+ ]
1611
+ },
1612
+ id
1613
+ ))
1614
+ ] }),
1615
+ waiting?.expires_at && phase === "waiting" && /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
1616
+ /* @__PURE__ */ jsx(Clock, { className: "size-3.5" }),
1617
+ " ",
1618
+ l.expires.replace("{date}", formatDate(waiting.expires_at))
1619
+ ] }),
1620
+ phase === "waiting" && mine && !declining && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
1621
+ actions?.sign && state && /* @__PURE__ */ jsxs(
1622
+ Button,
1623
+ {
1624
+ size: "sm",
1625
+ onClick: () => actions.sign?.(step, state),
1626
+ "data-testid": `${testId}-open-sign`,
1627
+ children: [
1628
+ /* @__PURE__ */ jsx(PenLine, { className: "size-4" }),
1629
+ " ",
1630
+ l.openAndSign
1631
+ ]
1632
+ }
1633
+ ),
1634
+ run.decline && /* @__PURE__ */ jsxs(
1635
+ Button,
1636
+ {
1637
+ size: "sm",
1638
+ variant: "ghost",
1639
+ onClick: () => setDeclining(true),
1640
+ "data-testid": `${testId}-decline`,
1641
+ children: [
1642
+ /* @__PURE__ */ jsx(X, { className: "size-4" }),
1643
+ " ",
1644
+ l.decline
1645
+ ]
1646
+ }
1647
+ )
1648
+ ] }),
1649
+ declining && /* @__PURE__ */ jsxs("div", { className: "space-y-2", "data-testid": `${testId}-decline-form`, children: [
1650
+ /* @__PURE__ */ jsx(
1651
+ Textarea,
1652
+ {
1653
+ rows: 2,
1654
+ value: note,
1655
+ placeholder: l.declineNote,
1656
+ "aria-label": l.declineNote,
1657
+ onChange: (e) => setNote(e.target.value),
1658
+ "data-testid": `${testId}-decline-note`
1659
+ }
1660
+ ),
1661
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
1662
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => setDeclining(false), children: l.cancel }),
1663
+ /* @__PURE__ */ jsx(
1664
+ Button,
1665
+ {
1666
+ size: "sm",
1667
+ variant: "destructive",
1668
+ disabled: run.busy,
1669
+ onClick: async () => {
1670
+ await run.decline?.(step.id, note.trim() || void 0);
1671
+ setDeclining(false);
1672
+ },
1673
+ "data-testid": `${testId}-decline-confirm`,
1674
+ children: l.declineConfirm
1675
+ }
1676
+ )
1677
+ ] })
1678
+ ] }),
1679
+ phase === "failed" && state?.declinedBy && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", "data-testid": `${testId}-declined`, children: l.declined.replace("{name}", name(state.declinedBy)) }),
1680
+ signedRef && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", children: actions?.openDocument ? /* @__PURE__ */ jsxs(
1681
+ Button,
1682
+ {
1683
+ size: "sm",
1684
+ variant: "outline",
1685
+ onClick: () => actions.openDocument?.(signedRef),
1686
+ "data-testid": `${testId}-signed-version`,
1687
+ children: [
1688
+ /* @__PURE__ */ jsx(ExternalLink, { className: "size-4" }),
1689
+ " ",
1690
+ l.signedVersion
1691
+ ]
1692
+ }
1693
+ ) : /* @__PURE__ */ jsx(DocChip, { docRef: signedRef, nameOfDoc }) })
1694
+ ] });
1695
+ } else if (a.type === "email_draft") {
1696
+ const draftId = state?.waiting?.draft_id ?? (typeof state?.output?.draft_id === "string" ? state.output.draft_id : void 0);
1697
+ body = /* @__PURE__ */ jsxs(Fragment, { children: [
1698
+ (phase === "ready" || phase === "running") && working(l.preparingDraft),
1699
+ phase === "waiting" && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.draftReady }),
1700
+ phase === "done" && /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 text-sm", "data-testid": `${testId}-sent`, children: [
1701
+ /* @__PURE__ */ jsx(Check, { className: "size-4 text-primary" }),
1702
+ " ",
1703
+ l.emailSent
1704
+ ] }),
1705
+ draftId && actions?.openDraft && phase !== "done" && /* @__PURE__ */ jsxs(
1706
+ Button,
1707
+ {
1708
+ size: "sm",
1709
+ variant: "outline",
1710
+ onClick: () => actions.openDraft?.(draftId, state?.waiting?.mailbox),
1711
+ "data-testid": `${testId}-open-draft`,
1712
+ children: [
1713
+ /* @__PURE__ */ jsx(Mail, { className: "size-4" }),
1714
+ " ",
1715
+ l.openDraft
1716
+ ]
1717
+ }
1718
+ )
1719
+ ] });
1720
+ } else {
1721
+ const tags = state?.output?.tag_ext_ids ?? a.tags;
1722
+ const docs = state?.output?.doc_ext_ids ?? [];
1723
+ body = /* @__PURE__ */ jsxs(Fragment, { children: [
1724
+ (phase === "ready" || phase === "running") && working(l.reviewRunning),
1725
+ phase === "done" && /* @__PURE__ */ jsxs(Fragment, { children: [
1726
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", "data-testid": `${testId}-reviewed`, children: l.reviewDone.replace("{docs}", String(docs.length)).replace("{cols}", String(tags.length)) }),
1727
+ actions?.openReview && /* @__PURE__ */ jsxs(
1728
+ Button,
1729
+ {
1730
+ size: "sm",
1731
+ onClick: () => actions.openReview?.(tags, docs),
1732
+ "data-testid": `${testId}-open-review`,
1733
+ children: [
1734
+ /* @__PURE__ */ jsx(Table2, { className: "size-4" }),
1735
+ " ",
1736
+ l.openReview
1737
+ ]
1738
+ }
1739
+ )
1740
+ ] })
1741
+ ] });
1742
+ }
1743
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
1744
+ heading,
1745
+ /* @__PURE__ */ jsx(SentBackNote, { state, l, testId }),
1746
+ /* @__PURE__ */ jsx(AssigneeLine, { run, stepId: step.id, l, testId }),
1747
+ body,
1748
+ phase === "failed" && !state?.declinedBy && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", "data-testid": `${testId}-failed`, children: state?.error || "" })
1749
+ ] });
1750
+ }
944
1751
  function PhaseMark({ phase, icon }) {
945
1752
  if (phase === "done") return /* @__PURE__ */ jsx(Check, { className: "size-3.5 shrink-0" });
946
1753
  if (phase === "running") return /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 shrink-0 animate-spin" });
1754
+ if (phase === "waiting") return /* @__PURE__ */ jsx(Hourglass, { className: "size-3.5 shrink-0" });
947
1755
  if (phase === "failed") return /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3.5 shrink-0" });
948
1756
  if (phase === "skipped") return /* @__PURE__ */ jsx(MinusCircle, { className: "size-3.5 shrink-0" });
949
1757
  return icon ? /* @__PURE__ */ jsx("span", { className: "flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5", children: icon }) : null;
@@ -976,6 +1784,8 @@ function WorkflowStepBar({
976
1784
  const pill = (s) => {
977
1785
  const phase = run.phaseOf(s.id);
978
1786
  const current = s.id === run.current;
1787
+ const assignee = ["ready", "waiting"].includes(phase) ? run.assigneeOf(s.id) : void 0;
1788
+ const title = assignee ? `${s.title} \xB7 ${assignee}` : s.title;
979
1789
  return /* @__PURE__ */ jsxs(
980
1790
  "button",
981
1791
  {
@@ -985,16 +1795,27 @@ function WorkflowStepBar({
985
1795
  className: cn(
986
1796
  PILL,
987
1797
  "transition-colors disabled:cursor-default",
988
- current ? "border-primary bg-primary/10 text-primary" : phase === "failed" ? "border-destructive/40 text-destructive" : phase === "done" || phase === "skipped" || phase === "running" ? "border-primary/30 bg-primary/5 text-primary" : "border-border text-muted-foreground"
1798
+ current ? "border-primary bg-primary/10 text-primary" : phase === "failed" ? "border-destructive/40 text-destructive" : phase === "done" || phase === "skipped" || phase === "running" || phase === "waiting" ? "border-primary/30 bg-primary/5 text-primary" : "border-border text-muted-foreground"
989
1799
  ),
990
1800
  "aria-current": current ? "step" : void 0,
991
- "aria-label": s.title,
992
- title: s.title,
1801
+ "aria-label": title,
1802
+ title,
993
1803
  "data-phase": phase,
994
1804
  "data-testid": tid(`step-${s.id}`),
995
1805
  children: [
996
1806
  /* @__PURE__ */ jsx(PhaseMark, { phase, icon: icon(s.icon) }),
997
- (current || !compact3) && /* @__PURE__ */ jsx("span", { className: LABEL, "data-testid": tid(`step-${s.id}-label`), children: s.title })
1807
+ (current || !compact3) && /* @__PURE__ */ jsx("span", { className: LABEL, "data-testid": tid(`step-${s.id}-label`), children: s.title }),
1808
+ assignee && !compact3 && /* @__PURE__ */ jsxs(
1809
+ "span",
1810
+ {
1811
+ className: "min-w-0 max-w-[8rem] truncate font-normal opacity-75",
1812
+ "data-testid": tid(`step-${s.id}-assignee`),
1813
+ children: [
1814
+ "\xB7 ",
1815
+ assignee
1816
+ ]
1817
+ }
1818
+ )
998
1819
  ]
999
1820
  },
1000
1821
  s.id
@@ -1099,7 +1920,8 @@ var DEFAULT_WORKFLOW_RUNNER_LABELS = {
1099
1920
  fileReading: "Reading\u2026",
1100
1921
  fileReady: "Ready",
1101
1922
  fileFailed: "Could not be read",
1102
- readingFiles: "Reading {current} of {count} files\u2026"
1923
+ readingFiles: "Reading {current} of {count} files\u2026",
1924
+ markSent: "Mark as sent"
1103
1925
  };
1104
1926
  function WorkflowRunner({
1105
1927
  workflow,
@@ -1115,11 +1937,16 @@ function WorkflowRunner({
1115
1937
  renderScope,
1116
1938
  renderDocuments,
1117
1939
  renderIcon,
1940
+ people,
1941
+ actions,
1942
+ nameOfDoc,
1118
1943
  labels,
1944
+ partsLabels,
1119
1945
  testIdPrefix = "workflow-run",
1120
1946
  className
1121
1947
  }) {
1122
1948
  const l = { ...DEFAULT_WORKFLOW_RUNNER_LABELS, ...labels };
1949
+ const pl = { ...DEFAULT_WORKFLOW_STEP_PARTS_LABELS, ...partsLabels };
1123
1950
  const { steps, step, isComplete, action } = run;
1124
1951
  const completion = workflow.run.kind === "steps" ? workflow.run.completion : void 0;
1125
1952
  const tid = (suffix) => `${testIdPrefix}-${suffix}`;
@@ -1128,7 +1955,7 @@ function WorkflowRunner({
1128
1955
  const added = step?.kind === "upload" ? (files ?? []).filter((f) => f.addedFor === step.id) : [];
1129
1956
  const unread = added.filter((f) => f.status === "processing").length;
1130
1957
  const reading = action === "complete" && unread > 0;
1131
- const nextLabel = reading ? l.readingFiles.replace("{current}", String(Math.min(added.length - unread + 1, added.length))).replace("{count}", String(added.length)) : action === "skip" ? l.skip : action === "finish" ? l.finish : action === "complete" && step?.kind === "review" ? l.approve : action === "wait" && (run.isRunning || run.busy) ? l.working : (step && !run.isLocked(step.id) ? step.nextLabel : void 0) ?? l.next;
1958
+ const nextLabel = reading ? l.readingFiles.replace("{current}", String(Math.min(added.length - unread + 1, added.length))).replace("{count}", String(added.length)) : action === "skip" ? l.skip : action === "finish" ? l.finish : action === "complete" && step?.kind === "review" ? l.approve : action === "complete" && step?.kind === "action" ? l.markSent : action === "wait" && (run.isRunning || run.busy) ? l.working : (step && !run.isLocked(step.id) ? step.nextLabel : void 0) ?? l.next;
1132
1959
  return /* @__PURE__ */ jsxs("div", { className: cn("space-y-6", className), "data-testid": testIdPrefix, children: [
1133
1960
  /* @__PURE__ */ jsx(
1134
1961
  WorkflowStepBar,
@@ -1160,6 +1987,8 @@ function WorkflowRunner({
1160
1987
  stepDependencies(steps, step.id).map((d) => steps.find((s) => s.id === d)?.title ?? d).join(", ")
1161
1988
  ) }) }) : step.kind === "form" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
1162
1989
  /* @__PURE__ */ jsx(StepHeading, { step, icon: icon(step.icon), testId: tid(`${step.id}-title`) }),
1990
+ /* @__PURE__ */ jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
1991
+ /* @__PURE__ */ jsx(AssigneeLine, { run, stepId: step.id, l: pl, testId: tid(step.id) }),
1163
1992
  /* @__PURE__ */ jsx("fieldset", { disabled: run.isLocked(step.id), className: "contents", children: /* @__PURE__ */ jsx(
1164
1993
  SchemaForm,
1165
1994
  {
@@ -1170,6 +1999,7 @@ function WorkflowRunner({
1170
1999
  renderScope,
1171
2000
  renderDocuments,
1172
2001
  renderIcon,
2002
+ people,
1173
2003
  onEnterSubmit: () => void run.next(),
1174
2004
  testIdPrefix: tid("field")
1175
2005
  }
@@ -1177,6 +2007,8 @@ function WorkflowRunner({
1177
2007
  run.actionError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", "data-testid": tid("action-error"), children: run.actionError }),
1178
2008
  renderStepNote?.(step, run)
1179
2009
  ] }) : step.kind === "upload" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
2010
+ /* @__PURE__ */ jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
2011
+ /* @__PURE__ */ jsx(AssigneeLine, { run, stepId: step.id, l: pl, testId: tid(step.id) }),
1180
2012
  renderUpload?.(step) ?? /* @__PURE__ */ jsxs(Fragment, { children: [
1181
2013
  /* @__PURE__ */ jsx(
1182
2014
  UploadDropzone,
@@ -1205,9 +2037,52 @@ function WorkflowRunner({
1205
2037
  renderStepNote?.(step, run)
1206
2038
  ] }) : step.kind === "review" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
1207
2039
  /* @__PURE__ */ jsx(StepHeading, { step, icon: icon(step.icon) }),
2040
+ /* @__PURE__ */ jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
1208
2041
  /* @__PURE__ */ jsx("p", { className: "whitespace-pre-line text-sm text-muted-foreground", children: reviewInstructions(step, run.inputs) }),
1209
- /* @__PURE__ */ 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 }),
2042
+ /* @__PURE__ */ jsx(AssigneeLine, { run, stepId: step.id, l: pl, testId: tid(step.id) }),
2043
+ !(run.phaseOf(step.id) === "done" && run.stateOf(step.id)?.by) && /* @__PURE__ */ 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 }),
2044
+ (step.fields ?? []).length > 0 && run.phaseOf(step.id) === "ready" && /* @__PURE__ */ jsx(
2045
+ SchemaForm,
2046
+ {
2047
+ fields: step.fields ?? [],
2048
+ values: run.inputs,
2049
+ onChange: run.setInput,
2050
+ errors: run.errors,
2051
+ renderScope,
2052
+ renderDocuments,
2053
+ renderIcon,
2054
+ people,
2055
+ testIdPrefix: tid("field")
2056
+ }
2057
+ ),
2058
+ /* @__PURE__ */ jsx(
2059
+ ApprovalEvidence,
2060
+ {
2061
+ run,
2062
+ step,
2063
+ actions,
2064
+ nameOfDoc,
2065
+ l: pl,
2066
+ testId: tid(step.id)
2067
+ }
2068
+ ),
1210
2069
  run.phaseOf(step.id) === "ready" && renderReview?.(step),
2070
+ /* @__PURE__ */ jsx(SendBackControl, { run, step, l: pl, testId: tid(step.id) }),
2071
+ run.actionError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: run.actionError }),
2072
+ renderStepNote?.(step, run)
2073
+ ] }) : step.kind === "action" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
2074
+ /* @__PURE__ */ jsx(
2075
+ ActionStepBody,
2076
+ {
2077
+ step,
2078
+ run,
2079
+ actions,
2080
+ nameOfDoc,
2081
+ heading: /* @__PURE__ */ jsx(StepHeading, { step, icon: icon(step.icon) }),
2082
+ l: pl,
2083
+ testId: tid(step.id)
2084
+ }
2085
+ ),
1211
2086
  run.actionError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: run.actionError }),
1212
2087
  renderStepNote?.(step, run)
1213
2088
  ] }) : /* @__PURE__ */ jsx(
@@ -1218,6 +2093,19 @@ function WorkflowRunner({
1218
2093
  renderAgentOutput,
1219
2094
  icon: icon(step.icon),
1220
2095
  renderStepNote,
2096
+ extra: /* @__PURE__ */ jsxs(Fragment, { children: [
2097
+ /* @__PURE__ */ jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
2098
+ /* @__PURE__ */ jsx(
2099
+ RedlineOpen,
2100
+ {
2101
+ step,
2102
+ state: run.stateOf(step.id),
2103
+ actions,
2104
+ l: pl,
2105
+ testId: tid(step.id)
2106
+ }
2107
+ )
2108
+ ] }),
1221
2109
  l,
1222
2110
  tid
1223
2111
  }
@@ -1348,6 +2236,7 @@ function AgentStepBody({
1348
2236
  renderAgentOutput,
1349
2237
  icon,
1350
2238
  renderStepNote,
2239
+ extra,
1351
2240
  l,
1352
2241
  tid
1353
2242
  }) {
@@ -1390,7 +2279,8 @@ function AgentStepBody({
1390
2279
  }
1391
2280
  ),
1392
2281
  phase === "failed" && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", "data-testid": tid(`${step.id}-failed`), children: state?.error || l.failed }),
1393
- phase === "skipped" && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.skipped })
2282
+ phase === "skipped" && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.skipped }),
2283
+ extra
1394
2284
  ] });
1395
2285
  if (step.output === "artifact") {
1396
2286
  return /* @__PURE__ */ jsxs(
@@ -1417,6 +2307,6 @@ function AgentStepBody({
1417
2307
  ] });
1418
2308
  }
1419
2309
 
1420
- export { DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_WORKFLOW_RUNNER_LABELS, EMPTY_WORKFLOW_SCOPE, SKILL_PROMPT_FALLBACK_PLACEHOLDER, SKILL_PROMPT_LABEL, SchemaForm, WorkflowRunner, buildLaunch, composeStepPrompt, composeWorkflowPrompt, defaultInputs, dependsOn, fieldToFrontmatter, fillRunText, fillStepInputs, fromPlanSteps, initialRunInputs, inputsFromContext, isEmptyWorkflowScope, isIncompleteSignal, isPersonStep, isRunFinished, isSteppedWorkflow, isWorkflowScope, layoutFromPlanSteps, nextAction, orderSteps, promptFieldName, reviewInstructions, runFields, runThreadTitle, skillToWorkflow, stepDependencies, stepLevels, stepPhase, stepStatesFromActivity, toPlanSteps, useWorkflowView, validateInputs, validateStep, validateWorkflowGraph, workflowAccepts, workflowFromFrontmatter, workflowSteps, workflowsAccepting, workflowsForHost };
1421
- //# sourceMappingURL=chunk-22P5KNIM.js.map
1422
- //# sourceMappingURL=chunk-22P5KNIM.js.map
2310
+ export { ActionStepBody, ApprovalEvidence, AssigneeLine, DEFAULT_ASSIGNEE_WORDING, DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_WORKFLOW_RUNNER_LABELS, DEFAULT_WORKFLOW_STEP_PARTS_LABELS, EMPTY_WORKFLOW_SCOPE, SKILL_PROMPT_FALLBACK_PLACEHOLDER, SKILL_PROMPT_LABEL, SchemaForm, SendBackControl, WorkflowRunner, assigneeName, buildLaunch, canAssign, composeStepPrompt, composeWorkflowPrompt, defaultInputs, dependsOn, fieldToFrontmatter, fillRunText, fillStepInputs, fromPlanAssignee, fromPlanDocumentRef, fromPlanSteps, initialRunInputs, inputsFromContext, isEmptyWorkflowScope, isIncompleteSignal, isPersonAction, isPersonStep, isRunFinished, isSteppedWorkflow, isWorkflowScope, layoutFromPlanSteps, nextAction, orderSteps, promptFieldName, reviewInstructions, runFields, runFieldsOf, runThreadTitle, sendBackTargets, skillToWorkflow, splitDocRef, stepConfigProblems, stepDependencies, stepFields, stepLevels, stepPhase, stepStatesFromActivity, toPlanAssignee, toPlanDocumentRef, toPlanSteps, upstreamSteps, useWorkflowView, validateInputs, validateStep, validateWorkflowGraph, workflowAccepts, workflowFromFrontmatter, workflowSteps, workflowsAccepting, workflowsForHost };
2311
+ //# sourceMappingURL=chunk-34UW6XUQ.js.map
2312
+ //# sourceMappingURL=chunk-34UW6XUQ.js.map