@arbidocs/blocks 0.4.32 → 0.4.33

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 (179) hide show
  1. package/dist/agents/index.cjs +257 -215
  2. package/dist/agents/index.js +8 -6
  3. package/dist/agents/tasks/ConversationListView.d.ts +58 -0
  4. package/dist/agents/tasks/ConversationTurnSpeaker.d.ts +16 -0
  5. package/dist/agents/tasks/NewThreadDialog.d.ts +1 -1
  6. package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
  7. package/dist/agents/tasks/TaskFlow.d.ts +22 -0
  8. package/dist/agents/tasks/TaskInbox.d.ts +26 -0
  9. package/dist/agents/tasks/TaskReviewDialog.d.ts +22 -0
  10. package/dist/agents/tasks/TaskRowMenu.d.ts +10 -2
  11. package/dist/agents/tasks/TaskRunsDialog.d.ts +8 -3
  12. package/dist/agents/tasks/TaskStartDialog.d.ts +24 -0
  13. package/dist/agents/tasks/TaskTable.d.ts +1 -1
  14. package/dist/agents/tasks/ThreadNotifyDialog.d.ts +11 -0
  15. package/dist/agents/tasks/WorkflowComposer.d.ts +1 -1
  16. package/dist/agents/tasks/WorkflowsTable.d.ts +7 -0
  17. package/dist/agents/tasks/compact-thread-activity.d.ts +8 -0
  18. package/dist/agents/tasks/index.d.ts +10 -0
  19. package/dist/agents/tasks/taskComposerTypes.d.ts +16 -1
  20. package/dist/agents/tasks/taskRequest.d.ts +1 -0
  21. package/dist/agents/tasks/testGrid.d.ts +24 -0
  22. package/dist/agents/tasks/workflowColumns.d.ts +2 -1
  23. package/dist/agents/tasks/workflowRows.d.ts +6 -0
  24. package/dist/agents/workflows/types.d.ts +2 -0
  25. package/dist/auth/index.cjs +27 -27
  26. package/dist/auth/index.js +1 -1
  27. package/dist/chat/Message.d.ts +8 -2
  28. package/dist/chat/index.cjs +132 -120
  29. package/dist/chat/index.d.ts +2 -0
  30. package/dist/chat/index.js +2 -2
  31. package/dist/chat/participant-tints.d.ts +1 -0
  32. package/dist/chat/useRecipientDraft.d.ts +14 -0
  33. package/dist/{chunk-KF4EC5XU.js → chunk-24KQJYSB.js} +3 -3
  34. package/dist/{chunk-KF4EC5XU.js.map → chunk-24KQJYSB.js.map} +1 -1
  35. package/dist/{chunk-GVQOBJKR.cjs → chunk-2EAE5JP6.cjs} +7 -4
  36. package/dist/chunk-2EAE5JP6.cjs.map +1 -0
  37. package/dist/{chunk-S5HZBXZA.cjs → chunk-2QTT2RZE.cjs} +242 -2
  38. package/dist/chunk-2QTT2RZE.cjs.map +1 -0
  39. package/dist/chunk-3AFWGEDJ.cjs +53 -0
  40. package/dist/chunk-3AFWGEDJ.cjs.map +1 -0
  41. package/dist/{chunk-4XJZ6AAY.js → chunk-4AWS54US.js} +244 -6
  42. package/dist/chunk-4AWS54US.js.map +1 -0
  43. package/dist/{chunk-56BUD74K.cjs → chunk-65THHQVB.cjs} +27 -27
  44. package/dist/{chunk-56BUD74K.cjs.map → chunk-65THHQVB.cjs.map} +1 -1
  45. package/dist/{chunk-5B4PXAKI.cjs → chunk-6DNYPLCD.cjs} +21 -7
  46. package/dist/chunk-6DNYPLCD.cjs.map +1 -0
  47. package/dist/{chunk-TZ4QF7EP.js → chunk-6RXUMBTK.js} +1948 -594
  48. package/dist/chunk-6RXUMBTK.js.map +1 -0
  49. package/dist/{chunk-UTYQPVIW.cjs → chunk-7QDX2CO4.cjs} +6 -6
  50. package/dist/{chunk-UTYQPVIW.cjs.map → chunk-7QDX2CO4.cjs.map} +1 -1
  51. package/dist/{chunk-FRRDPYBR.cjs → chunk-AZ75JUIH.cjs} +74 -5
  52. package/dist/chunk-AZ75JUIH.cjs.map +1 -0
  53. package/dist/{chunk-NUPVHEJW.js → chunk-BUHKUKKB.js} +7 -4
  54. package/dist/chunk-BUHKUKKB.js.map +1 -0
  55. package/dist/chunk-C7FGONCM.js +124 -0
  56. package/dist/chunk-C7FGONCM.js.map +1 -0
  57. package/dist/{chunk-KXMDOTGW.js → chunk-DLBUFHLY.js} +10 -2
  58. package/dist/chunk-DLBUFHLY.js.map +1 -0
  59. package/dist/{chunk-ZHLMDJCO.cjs → chunk-DLVX6R6B.cjs} +62 -26
  60. package/dist/chunk-DLVX6R6B.cjs.map +1 -0
  61. package/dist/{chunk-JGZTRLKL.cjs → chunk-IA7RTPT3.cjs} +7 -4
  62. package/dist/chunk-IA7RTPT3.cjs.map +1 -0
  63. package/dist/{chunk-NJL4LIXX.js → chunk-LFGJAZ5H.js} +11 -8
  64. package/dist/chunk-LFGJAZ5H.js.map +1 -0
  65. package/dist/{chunk-IAKUTBPX.js → chunk-LYUO3E6V.js} +3 -3
  66. package/dist/{chunk-IAKUTBPX.js.map → chunk-LYUO3E6V.js.map} +1 -1
  67. package/dist/{chunk-EYPPB5CY.cjs → chunk-M2YGPC5N.cjs} +4 -4
  68. package/dist/{chunk-EYPPB5CY.cjs.map → chunk-M2YGPC5N.cjs.map} +1 -1
  69. package/dist/{chunk-5ZBP7TCD.cjs → chunk-MJCCBMM5.cjs} +10 -2
  70. package/dist/chunk-MJCCBMM5.cjs.map +1 -0
  71. package/dist/chunk-MZL67U2E.cjs +128 -0
  72. package/dist/chunk-MZL67U2E.cjs.map +1 -0
  73. package/dist/{chunk-OJSWQM4G.js → chunk-OZJ5PXA6.js} +29 -4
  74. package/dist/chunk-OZJ5PXA6.js.map +1 -0
  75. package/dist/{chunk-UBNVIIBT.js → chunk-PXFJDX2C.js} +21 -7
  76. package/dist/chunk-PXFJDX2C.js.map +1 -0
  77. package/dist/{chunk-RGHQFJOL.cjs → chunk-QFUF4A4J.cjs} +28 -2
  78. package/dist/chunk-QFUF4A4J.cjs.map +1 -0
  79. package/dist/chunk-RFXJYIDV.js +50 -0
  80. package/dist/chunk-RFXJYIDV.js.map +1 -0
  81. package/dist/{chunk-PLGVMLBD.cjs → chunk-SEQWI6E4.cjs} +1975 -610
  82. package/dist/chunk-SEQWI6E4.cjs.map +1 -0
  83. package/dist/{chunk-QN42OA5J.js → chunk-SFXVNFES.js} +4 -4
  84. package/dist/chunk-SFXVNFES.js.map +1 -0
  85. package/dist/{chunk-3NZR6PAG.js → chunk-V6U5KVAR.js} +70 -4
  86. package/dist/chunk-V6U5KVAR.js.map +1 -0
  87. package/dist/{chunk-YVIOCITQ.cjs → chunk-VUEZARW5.cjs} +3 -3
  88. package/dist/chunk-VUEZARW5.cjs.map +1 -0
  89. package/dist/{chunk-JLOYWXRB.js → chunk-VZGBCBYB.js} +3 -3
  90. package/dist/chunk-VZGBCBYB.js.map +1 -0
  91. package/dist/{chunk-ZVPTFTGV.cjs → chunk-WBDK4PIA.cjs} +11 -8
  92. package/dist/chunk-WBDK4PIA.cjs.map +1 -0
  93. package/dist/{chunk-ZORQ5M3W.cjs → chunk-WQFGG2BV.cjs} +4 -4
  94. package/dist/chunk-WQFGG2BV.cjs.map +1 -0
  95. package/dist/{chunk-C75S6USL.js → chunk-WYVCXY7R.js} +7 -4
  96. package/dist/chunk-WYVCXY7R.js.map +1 -0
  97. package/dist/{chunk-WSJVHSGN.js → chunk-XWEJ5LV2.js} +63 -27
  98. package/dist/chunk-XWEJ5LV2.js.map +1 -0
  99. package/dist/{chunk-YMHGF6R5.js → chunk-ZCF2JJFA.js} +3 -3
  100. package/dist/{chunk-YMHGF6R5.js.map → chunk-ZCF2JJFA.js.map} +1 -1
  101. package/dist/collaboration/index.cjs +45 -41
  102. package/dist/collaboration/index.js +1 -1
  103. package/dist/collaboration/mail/MailMessagePreview.d.ts +11 -0
  104. package/dist/collaboration/mail/index.d.ts +1 -0
  105. package/dist/connect/index.cjs +33 -33
  106. package/dist/connect/index.js +4 -4
  107. package/dist/facts/FactsFilterInput.d.ts +2 -46
  108. package/dist/facts/FactsToolbar.d.ts +5 -5
  109. package/dist/facts/index.cjs +27 -124
  110. package/dist/facts/index.cjs.map +1 -1
  111. package/dist/facts/index.js +13 -118
  112. package/dist/facts/index.js.map +1 -1
  113. package/dist/files/FilesPage.d.ts +1 -1
  114. package/dist/files/FilesToolbar.d.ts +1 -1
  115. package/dist/files/FolderPicker.d.ts +2 -1
  116. package/dist/files/ViewerChrome.d.ts +1 -1
  117. package/dist/files/bulk/FolderFilterButton.d.ts +3 -2
  118. package/dist/files/cells/BulkLabelSelect.d.ts +11 -0
  119. package/dist/files/cells/LabelMultiSelect.d.ts +2 -1
  120. package/dist/files/cells/index.d.ts +1 -0
  121. package/dist/files/index.cjs +109 -166
  122. package/dist/files/index.cjs.map +1 -1
  123. package/dist/files/index.js +95 -158
  124. package/dist/files/index.js.map +1 -1
  125. package/dist/home/index.cjs +19 -19
  126. package/dist/home/index.cjs.map +1 -1
  127. package/dist/home/index.js +4 -4
  128. package/dist/home/index.js.map +1 -1
  129. package/dist/index.cjs +787 -764
  130. package/dist/index.cjs.map +1 -1
  131. package/dist/index.d.ts +1 -0
  132. package/dist/index.js +21 -69
  133. package/dist/index.js.map +1 -1
  134. package/dist/settings/SettingsPanel.d.ts +1 -1
  135. package/dist/settings/index.cjs +55 -280
  136. package/dist/settings/index.cjs.map +1 -1
  137. package/dist/settings/index.js +17 -248
  138. package/dist/settings/index.js.map +1 -1
  139. package/dist/shell/FilterInput.d.ts +46 -0
  140. package/dist/shell/TabHeader.d.ts +5 -1
  141. package/dist/shell/index.cjs +61 -48
  142. package/dist/shell/index.d.ts +1 -0
  143. package/dist/shell/index.js +3 -2
  144. package/dist/site/index.cjs +62 -62
  145. package/dist/site/index.js +2 -2
  146. package/dist/studio/index.cjs +74 -74
  147. package/dist/studio/index.js +5 -5
  148. package/dist/workspaces/WorkspaceCard.d.ts +2 -2
  149. package/dist/workspaces/index.cjs +9 -2
  150. package/dist/workspaces/index.cjs.map +1 -1
  151. package/dist/workspaces/index.js +9 -2
  152. package/dist/workspaces/index.js.map +1 -1
  153. package/package.json +3 -3
  154. package/src/blocks.css +4 -0
  155. package/src/components/grid.css +10 -0
  156. package/dist/chunk-3NZR6PAG.js.map +0 -1
  157. package/dist/chunk-4XJZ6AAY.js.map +0 -1
  158. package/dist/chunk-5B4PXAKI.cjs.map +0 -1
  159. package/dist/chunk-5ZBP7TCD.cjs.map +0 -1
  160. package/dist/chunk-C75S6USL.js.map +0 -1
  161. package/dist/chunk-FRRDPYBR.cjs.map +0 -1
  162. package/dist/chunk-GVQOBJKR.cjs.map +0 -1
  163. package/dist/chunk-JGZTRLKL.cjs.map +0 -1
  164. package/dist/chunk-JLOYWXRB.js.map +0 -1
  165. package/dist/chunk-KXMDOTGW.js.map +0 -1
  166. package/dist/chunk-NJL4LIXX.js.map +0 -1
  167. package/dist/chunk-NUPVHEJW.js.map +0 -1
  168. package/dist/chunk-OJSWQM4G.js.map +0 -1
  169. package/dist/chunk-PLGVMLBD.cjs.map +0 -1
  170. package/dist/chunk-QN42OA5J.js.map +0 -1
  171. package/dist/chunk-RGHQFJOL.cjs.map +0 -1
  172. package/dist/chunk-S5HZBXZA.cjs.map +0 -1
  173. package/dist/chunk-TZ4QF7EP.js.map +0 -1
  174. package/dist/chunk-UBNVIIBT.js.map +0 -1
  175. package/dist/chunk-WSJVHSGN.js.map +0 -1
  176. package/dist/chunk-YVIOCITQ.cjs.map +0 -1
  177. package/dist/chunk-ZHLMDJCO.cjs.map +0 -1
  178. package/dist/chunk-ZORQ5M3W.cjs.map +0 -1
  179. package/dist/chunk-ZVPTFTGV.cjs.map +0 -1
@@ -2,12 +2,14 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkZW6FPIFC_cjs = require('./chunk-ZW6FPIFC.cjs');
5
- var chunkJGZTRLKL_cjs = require('./chunk-JGZTRLKL.cjs');
6
- var chunkZVPTFTGV_cjs = require('./chunk-ZVPTFTGV.cjs');
7
- var chunkS5HZBXZA_cjs = require('./chunk-S5HZBXZA.cjs');
8
- var chunkVFUWWH52_cjs = require('./chunk-VFUWWH52.cjs');
5
+ var chunkWBDK4PIA_cjs = require('./chunk-WBDK4PIA.cjs');
6
+ var chunk3AFWGEDJ_cjs = require('./chunk-3AFWGEDJ.cjs');
7
+ var chunkIA7RTPT3_cjs = require('./chunk-IA7RTPT3.cjs');
8
+ var chunkMZL67U2E_cjs = require('./chunk-MZL67U2E.cjs');
9
9
  var chunkOB5F4577_cjs = require('./chunk-OB5F4577.cjs');
10
- var chunk5B4PXAKI_cjs = require('./chunk-5B4PXAKI.cjs');
10
+ var chunk2QTT2RZE_cjs = require('./chunk-2QTT2RZE.cjs');
11
+ var chunk6DNYPLCD_cjs = require('./chunk-6DNYPLCD.cjs');
12
+ var chunkVFUWWH52_cjs = require('./chunk-VFUWWH52.cjs');
11
13
  var chunkC54XEN5T_cjs = require('./chunk-C54XEN5T.cjs');
12
14
  var chunkKDG6FER6_cjs = require('./chunk-KDG6FER6.cjs');
13
15
  var chunk2ZTONLT5_cjs = require('./chunk-2ZTONLT5.cjs');
@@ -483,7 +485,7 @@ function SchemaForm({
483
485
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("flex flex-col gap-4", className), "data-slot": "schema-form", children: [
484
486
  common.map(render),
485
487
  advanced.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
486
- chunkZVPTFTGV_cjs.FoldSection,
488
+ chunkWBDK4PIA_cjs.FoldSection,
487
489
  {
488
490
  label: l.advanced,
489
491
  open: advancedOpen,
@@ -658,7 +660,7 @@ function WorkflowConfigDialog({
658
660
  const firstField = workflow.inputs.find((f) => !f.advanced);
659
661
  const focusPromptFirst = firstField?.type === "text" || firstField?.type === "longtext";
660
662
  const defaultScopeRender = scopeSource ? (_field, value, onChange) => /* @__PURE__ */ jsxRuntime.jsx(
661
- chunkZVPTFTGV_cjs.ScopePicker,
663
+ chunkWBDK4PIA_cjs.ScopePicker,
662
664
  {
663
665
  folders: scopeSource.folders,
664
666
  unfiledCount: scopeSource.unfiledCount,
@@ -691,7 +693,7 @@ function WorkflowConfigDialog({
691
693
  },
692
694
  children: [
693
695
  /* @__PURE__ */ jsxRuntime.jsx(
694
- chunkZVPTFTGV_cjs.QuickActionDialogHeader,
696
+ chunkWBDK4PIA_cjs.QuickActionDialogHeader,
695
697
  {
696
698
  icon: workflow.icon && renderIcon ? renderIcon(workflow.icon) : null,
697
699
  title: workflow.title,
@@ -709,7 +711,7 @@ function WorkflowConfigDialog({
709
711
  submit();
710
712
  },
711
713
  children: noFiles ? /* @__PURE__ */ jsxRuntime.jsx(
712
- chunkZVPTFTGV_cjs.AddFilesFirst,
714
+ chunkWBDK4PIA_cjs.AddFilesFirst,
713
715
  {
714
716
  reason: l.addFilesReason,
715
717
  action: addFilesAction,
@@ -776,7 +778,7 @@ function defaultScopeRenderer(scopeSource) {
776
778
  if (!scopeSource) return void 0;
777
779
  return function renderScope(_field, value, onChange) {
778
780
  return /* @__PURE__ */ jsxRuntime.jsx(
779
- chunkZVPTFTGV_cjs.ScopePicker,
781
+ chunkWBDK4PIA_cjs.ScopePicker,
780
782
  {
781
783
  folders: scopeSource.folders,
782
784
  unfiledCount: scopeSource.unfiledCount,
@@ -861,7 +863,7 @@ function WorkflowLauncher({
861
863
  });
862
864
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-slot": "workflow-launcher", children: [
863
865
  showTiles && /* @__PURE__ */ jsxRuntime.jsx(
864
- chunkZVPTFTGV_cjs.StartTiles,
866
+ chunkWBDK4PIA_cjs.StartTiles,
865
867
  {
866
868
  items: [...tiles, ...extraTiles],
867
869
  caption,
@@ -943,7 +945,7 @@ function WorkflowDocumentsField({
943
945
  const set = (documents2) => onChange({ ...value, documents: documents2 });
944
946
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": `workflow-documents-${field.name}`, className: "space-y-2", children: [
945
947
  /* @__PURE__ */ jsxRuntime.jsx(
946
- chunkS5HZBXZA_cjs.DocumentPicker,
948
+ chunk2QTT2RZE_cjs.DocumentPicker,
947
949
  {
948
950
  groups: [{ id: "workspace", docs: documents }],
949
951
  value: ids[0] ?? "",
@@ -1577,7 +1579,7 @@ function AgentCreator({
1577
1579
  ] })
1578
1580
  ] }),
1579
1581
  /* @__PURE__ */ jsxRuntime.jsx(
1580
- chunkZVPTFTGV_cjs.FoldSection,
1582
+ chunkWBDK4PIA_cjs.FoldSection,
1581
1583
  {
1582
1584
  label: l.advanced,
1583
1585
  open: advancedOpen,
@@ -3413,144 +3415,6 @@ function TaskReviewActions({
3413
3415
  ] })
3414
3416
  ] });
3415
3417
  }
3416
-
3417
- // src/agents/tasks/taskRows.ts
3418
- var MAX_TASK_DEPTH = 5;
3419
- var ownerExtId = (task) => task.signoff_ext_id || task.owner_ext_id || task.created_by_ext_id || null;
3420
- var isPlainTodo = (task) => !task.agent_ext_id && !task.has_agent_action && !task.skill_ref;
3421
- function indexTasks(tasks) {
3422
- const byId = new Map(tasks.map((t) => [t.external_id, t]));
3423
- const kids = /* @__PURE__ */ new Map();
3424
- const parentOf = /* @__PURE__ */ new Map();
3425
- for (const task of tasks) {
3426
- const parent = task.parent_conversation_ext_id;
3427
- if (parent && parent !== task.external_id && byId.has(parent)) {
3428
- parentOf.set(task.external_id, parent);
3429
- const list = kids.get(parent);
3430
- if (list) list.push(task);
3431
- else kids.set(parent, [task]);
3432
- }
3433
- }
3434
- return { byId, kids, parentOf };
3435
- }
3436
- function descendantIds(tree, id) {
3437
- const out = [];
3438
- const seen = /* @__PURE__ */ new Set([id]);
3439
- const stack = [id];
3440
- while (stack.length) {
3441
- for (const child of tree.kids.get(stack.pop()) ?? []) {
3442
- if (seen.has(child.external_id)) continue;
3443
- seen.add(child.external_id);
3444
- out.push(child.external_id);
3445
- stack.push(child.external_id);
3446
- }
3447
- }
3448
- return out;
3449
- }
3450
- function subtreeLevels(tree, id, seen = /* @__PURE__ */ new Set()) {
3451
- if (seen.has(id)) return 0;
3452
- const next = new Set(seen).add(id);
3453
- let deepest = 0;
3454
- for (const child of tree.kids.get(id) ?? []) {
3455
- deepest = Math.max(deepest, subtreeLevels(tree, child.external_id, next));
3456
- }
3457
- return 1 + deepest;
3458
- }
3459
- function levelOf(tree, id) {
3460
- let level = 1;
3461
- const seen = /* @__PURE__ */ new Set([id]);
3462
- for (let at = tree.parentOf.get(id); at && !seen.has(at); at = tree.parentOf.get(at)) {
3463
- seen.add(at);
3464
- level += 1;
3465
- }
3466
- return level;
3467
- }
3468
- function moveTargets(tasks, task) {
3469
- const tree = indexTasks(tasks);
3470
- const banned = /* @__PURE__ */ new Set([task.external_id, ...descendantIds(tree, task.external_id)]);
3471
- const height = subtreeLevels(tree, task.external_id);
3472
- return tasks.filter(
3473
- (t) => !banned.has(t.external_id) && levelOf(tree, t.external_id) + height <= MAX_TASK_DEPTH
3474
- );
3475
- }
3476
- var sameStats = (a, b) => a === b || a !== void 0 && b !== void 0 && a.done === b.done && a.total === b.total;
3477
- function buildTaskRows(tasks, filter, collapsed, compare, options = {}) {
3478
- const tree = indexTasks(tasks);
3479
- const { kids, parentOf } = tree;
3480
- const sorted = (list) => compare ? [...list].sort(compare) : list;
3481
- const query = options.query?.trim().toLowerCase() ?? "";
3482
- const titleOf = options.titleOf ?? ((t) => t.title ?? "");
3483
- let included = null;
3484
- let matched = null;
3485
- if (filter !== "all" || query) {
3486
- matched = /* @__PURE__ */ new Set();
3487
- included = /* @__PURE__ */ new Set();
3488
- for (const task of tasks) {
3489
- const statusOk = filter === "all" || asTaskStatus(task.status) === filter;
3490
- const textOk = !query || `${titleOf(task)} ${task.description ?? ""}`.toLowerCase().includes(query);
3491
- if (!statusOk || !textOk) continue;
3492
- matched.add(task.external_id);
3493
- for (let at = task.external_id; at && !included.has(at); at = parentOf.get(at)) {
3494
- included.add(at);
3495
- }
3496
- }
3497
- }
3498
- const shown = (list) => included ? list.filter((t) => included.has(t.external_id)) : list;
3499
- const build = (task, depth, seen) => {
3500
- const nextSeen = new Set(seen).add(task.external_id);
3501
- return {
3502
- task,
3503
- depth,
3504
- context: matched ? !matched.has(task.external_id) : false,
3505
- children: sorted(shown(kids.get(task.external_id) ?? [])).filter((child) => !nextSeen.has(child.external_id)).map((child) => build(child, depth + 1, nextSeen))
3506
- };
3507
- };
3508
- const sections = new Map([
3509
- ...STATUS_ORDER.map((s) => [s, []]),
3510
- ["sorted", []]
3511
- ]);
3512
- const sectionOf = (task) => compare ? "sorted" : asTaskStatus(task.status);
3513
- const roots = tasks.filter((t) => !parentOf.has(t.external_id));
3514
- for (const task of sorted(shown(roots))) {
3515
- sections.get(sectionOf(task))?.push(build(task, 0, /* @__PURE__ */ new Set()));
3516
- }
3517
- const cache = options.cache;
3518
- const used = /* @__PURE__ */ new Set();
3519
- const rows = [];
3520
- const walk = (node, parentId, setSize, posInSet) => {
3521
- const id = node.task.external_id;
3522
- const expanded = !collapsed.has(id);
3523
- const all = kids.get(id);
3524
- const childStats = all ? { done: all.filter((c) => asTaskStatus(c.status) === "done").length, total: all.length } : void 0;
3525
- let row = {
3526
- external_id: id,
3527
- task: node.task,
3528
- depth: node.depth,
3529
- childStats,
3530
- expanded,
3531
- parentId,
3532
- setSize,
3533
- posInSet,
3534
- context: node.context
3535
- };
3536
- const prev = cache?.get(id);
3537
- if (prev && prev.task === row.task && prev.depth === row.depth && prev.expanded === row.expanded && prev.parentId === row.parentId && prev.setSize === row.setSize && prev.posInSet === row.posInSet && prev.context === row.context && sameStats(prev.childStats, row.childStats)) {
3538
- row = prev;
3539
- }
3540
- used.add(id);
3541
- cache?.set(id, row);
3542
- rows.push(row);
3543
- if (expanded) {
3544
- node.children.forEach((child, i) => walk(child, id, node.children.length, i + 1));
3545
- }
3546
- };
3547
- const ordered = [...STATUS_ORDER, "sorted"].flatMap((s) => sections.get(s) ?? []);
3548
- ordered.forEach((node, i) => walk(node, null, ordered.length, i + 1));
3549
- if (cache) {
3550
- for (const id of [...cache.keys()]) if (!used.has(id)) cache.delete(id);
3551
- }
3552
- return rows;
3553
- }
3554
3418
  function TaskRowMenu({
3555
3419
  task,
3556
3420
  status,
@@ -3559,6 +3423,10 @@ function TaskRowMenu({
3559
3423
  canAdmin,
3560
3424
  canEdit,
3561
3425
  labels,
3426
+ canMarkDone = canEdit,
3427
+ canReopen = canEdit,
3428
+ selected = false,
3429
+ onToggleSelected,
3562
3430
  onMarkDone,
3563
3431
  onReopen,
3564
3432
  onAddSubtask,
@@ -3567,6 +3435,7 @@ function TaskRowMenu({
3567
3435
  onMoveTo,
3568
3436
  onChangeOwner,
3569
3437
  onOpenActivity,
3438
+ onToggleShared,
3570
3439
  onGrantAccess,
3571
3440
  reviewActions
3572
3441
  }) {
@@ -3587,6 +3456,7 @@ function TaskRowMenu({
3587
3456
  }
3588
3457
  ) }),
3589
3458
  /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuContent, { align: "end", children: [
3459
+ onToggleSelected && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: onToggleSelected, "data-testid": `task-select-${id}`, children: selected ? "Deselect task" : "Select task" }),
3590
3460
  reviewActions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5", children: typeof reviewActions === "function" ? reviewActions(() => setOpen(false)) : reviewActions }),
3591
3461
  isOwner && onGrantAccess && task.pending_auth_request_id && /* @__PURE__ */ jsxRuntime.jsxs(
3592
3462
  ui.DropdownMenuItem,
@@ -3600,10 +3470,18 @@ function TaskRowMenu({
3600
3470
  ]
3601
3471
  }
3602
3472
  ),
3603
- isChat || !canEdit ? null : done ? /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuItem, { disabled: busy, onSelect: onReopen, "data-testid": `task-reopen-${id}`, children: [
3604
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "mr-2 size-4", "aria-hidden": true }),
3605
- labels.reopen
3606
- ] }) : isPlainTodo(task) && /* @__PURE__ */ jsxRuntime.jsxs(
3473
+ isChat || !canEdit ? null : done ? canReopen && /* @__PURE__ */ jsxRuntime.jsxs(
3474
+ ui.DropdownMenuItem,
3475
+ {
3476
+ disabled: busy,
3477
+ onSelect: onReopen,
3478
+ "data-testid": `task-reopen-${id}`,
3479
+ children: [
3480
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "mr-2 size-4", "aria-hidden": true }),
3481
+ labels.reopen
3482
+ ]
3483
+ }
3484
+ ) : canMarkDone && /* @__PURE__ */ jsxRuntime.jsxs(
3607
3485
  ui.DropdownMenuItem,
3608
3486
  {
3609
3487
  disabled: busy,
@@ -3619,6 +3497,7 @@ function TaskRowMenu({
3619
3497
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "mr-2 size-4", "aria-hidden": true }),
3620
3498
  labels.activity
3621
3499
  ] }),
3500
+ isOwner && onToggleShared && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { disabled: busy, onSelect: onToggleShared, children: task.is_shared ? "Make private" : "Share with workspace" }),
3622
3501
  canEdit && onAddSubtask && /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuItem, { onSelect: onAddSubtask, "data-testid": `task-add-subtask-${id}`, children: [
3623
3502
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListPlus, { className: "mr-2 size-4", "aria-hidden": true }),
3624
3503
  labels.addSubtask
@@ -3635,7 +3514,7 @@ function TaskRowMenu({
3635
3514
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "mr-2 size-4", "aria-hidden": true }),
3636
3515
  isChat ? labels.rename : labels.edit
3637
3516
  ] }),
3638
- canEdit && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3517
+ canEdit && onDelete && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3639
3518
  /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuSeparator, {}),
3640
3519
  /* @__PURE__ */ jsxRuntime.jsxs(
3641
3520
  ui.DropdownMenuItem,
@@ -3858,99 +3737,237 @@ function applyColumnWidthRules(api, gridWidth, rules) {
3858
3737
  }
3859
3738
  }
3860
3739
 
3861
- // src/agents/tasks/taskTableLabels.ts
3862
- var DEFAULT_TASK_LIST_LABELS = {
3863
- filterAll: "All",
3864
- emptyTitle: "No tasks yet",
3865
- emptyMessage: "Use New to add one: just type what you need, or fill in an owner and a due date. Automations that create tasks live on the Workflows page. You always decide when a task is done.",
3866
- noMatches: "No tasks match.",
3867
- due: (when) => when,
3868
- overdue: (when) => `${when} \xB7 overdue`,
3869
- agent: "Agent",
3870
- colTask: "Task",
3871
- colOwner: "Owner",
3872
- ownerHint: "Who has the next step. They are notified when the previous step finishes.",
3873
- colOutputs: "Outputs",
3874
- changeOwner: "Change owner\u2026",
3875
- changeOwnerTitle: (name) => `Who has the next step on \u201C${name}\u201D?`,
3876
- changeOwnerMe: "Me",
3877
- preparedBy: (agent) => `Prepared by ${agent}`,
3878
- colDue: "Due",
3879
- colStatus: "Status",
3880
- me: "Me",
3881
- someone: "Someone",
3882
- noDue: "\u2014",
3883
- colShared: "Shared",
3884
- shared: "Shared with the workspace",
3885
- sharedOwnerOnly: "Only the creator can change who can see this",
3886
- deleteOwnerOnly: "Only the creator or workspace owner can delete this",
3887
- goalMet: (met, total) => `${met}/${total} met`,
3888
- subtasksDone: (done, total) => `${done}/${total} sub-tasks done`,
3889
- expandSubtasks: "Show sub-tasks",
3890
- collapseSubtasks: "Hide sub-tasks",
3891
- selectAll: "Select all tasks",
3892
- selectTask: (name) => `Select ${name}`,
3893
- markDone: "Mark done",
3894
- reopen: "Reopen",
3895
- markDoneMany: "Mark done",
3896
- markDoneManyHint: "Marks your own to-dos done. Agent work is finished by reviewing it.",
3897
- deleteMany: "Delete",
3898
- approve: "Approve",
3899
- moveTo: "Move to\u2026",
3900
- untitled: "Untitled task",
3901
- fromWorkflow: (name) => `From \u201C${name}\u201D`,
3902
- searchLabel: "Search tasks",
3903
- searchPlaceholder: "Search tasks\u2026",
3904
- expandAll: "Expand all",
3905
- collapseAll: "Collapse all",
3906
- moveToTitle: (name) => `Move \u201C${name}\u201D to\u2026`,
3907
- moveToNone: "No parent (top level)",
3908
- moveToSearch: "Search tasks\u2026",
3909
- moveToEmpty: "No task to move it under.",
3910
- moveToCancel: "Cancel",
3911
- subtasksSelected: (count) => `${count} ${count === 1 ? "sub-task" : "sub-tasks"} included`,
3912
- addSubtask: "Add sub-task",
3913
- edit: "Edit",
3914
- rename: "Rename",
3915
- delete: "Delete",
3916
- grantAccess: "Allow access and continue",
3917
- allowAccess: "Allow access",
3918
- moreActions: "More actions",
3919
- activity: "Activity",
3920
- statusHint: (status, ago, forWho) => [status, ago, forWho && `for ${forWho}`].filter(Boolean).join(" \xB7 "),
3921
- status: {}
3922
- };
3923
- var ROW_HEIGHT = 56;
3924
- var NARROW_ROW_HEIGHT = 76;
3925
- var MAX_INDENT_DEPTH = 4;
3926
- var ANIMATE_ROWS_UP_TO = 500;
3927
- var NARROW_GRID = 640;
3928
- var WIDTH_RULES = [
3929
- { colId: "shared", minWidth: 1050 },
3930
- { colId: "due", minWidth: 850 },
3931
- { colId: "outputs", minWidth: 930 },
3932
- { colId: "owner", minWidth: 730 },
3933
- { colId: "status", minWidth: NARROW_GRID }
3934
- ];
3935
- function statusHint(task, ctx) {
3936
- const { props: p, l, owner } = ctx;
3937
- if (!p.formatRelative || !task.updated_at) return void 0;
3938
- const key = asTaskStatus(task.status);
3939
- const pill = { ...DEFAULT_TASK_STATUS_PILL_LABELS, ...p.statusPillLabels };
3940
- const label = task.pending_auth_request_id ? pill.waitingForAccess : STATUS_LABELS[key];
3941
- return l.statusHint(
3942
- label,
3943
- p.formatRelative(task.updated_at),
3944
- key === "ready_for_review" ? owner(task).label : void 0
3945
- );
3740
+ // src/agents/tasks/taskRows.ts
3741
+ var MAX_TASK_DEPTH = 5;
3742
+ var ownerExtId = (task) => task.signoff_ext_id || task.owner_ext_id || task.created_by_ext_id || null;
3743
+ var isPlainTodo = (task) => !task.agent_ext_id && !task.has_agent_action && !task.skill_ref;
3744
+ function indexTasks(tasks) {
3745
+ const byId = new Map(tasks.map((t) => [t.external_id, t]));
3746
+ const kids = /* @__PURE__ */ new Map();
3747
+ const parentOf = /* @__PURE__ */ new Map();
3748
+ for (const task of tasks) {
3749
+ const parent = task.parent_conversation_ext_id;
3750
+ if (parent && parent !== task.external_id && byId.has(parent)) {
3751
+ parentOf.set(task.external_id, parent);
3752
+ const list = kids.get(parent);
3753
+ if (list) list.push(task);
3754
+ else kids.set(parent, [task]);
3755
+ }
3756
+ }
3757
+ return { byId, kids, parentOf };
3946
3758
  }
3947
- function TaskTable(props) {
3948
- const { tasks: allTasks, isLoading, busyId, header, testId } = props;
3949
- const l = {
3950
- ...DEFAULT_TASK_LIST_LABELS,
3951
- ...props.labels,
3952
- status: { ...STATUS_LABELS, ...props.labels?.status }
3953
- };
3759
+ function descendantIds(tree, id) {
3760
+ const out = [];
3761
+ const seen = /* @__PURE__ */ new Set([id]);
3762
+ const stack = [id];
3763
+ while (stack.length) {
3764
+ for (const child of tree.kids.get(stack.pop()) ?? []) {
3765
+ if (seen.has(child.external_id)) continue;
3766
+ seen.add(child.external_id);
3767
+ out.push(child.external_id);
3768
+ stack.push(child.external_id);
3769
+ }
3770
+ }
3771
+ return out;
3772
+ }
3773
+ function subtreeLevels(tree, id, seen = /* @__PURE__ */ new Set()) {
3774
+ if (seen.has(id)) return 0;
3775
+ const next = new Set(seen).add(id);
3776
+ let deepest = 0;
3777
+ for (const child of tree.kids.get(id) ?? []) {
3778
+ deepest = Math.max(deepest, subtreeLevels(tree, child.external_id, next));
3779
+ }
3780
+ return 1 + deepest;
3781
+ }
3782
+ function levelOf(tree, id) {
3783
+ let level = 1;
3784
+ const seen = /* @__PURE__ */ new Set([id]);
3785
+ for (let at = tree.parentOf.get(id); at && !seen.has(at); at = tree.parentOf.get(at)) {
3786
+ seen.add(at);
3787
+ level += 1;
3788
+ }
3789
+ return level;
3790
+ }
3791
+ function moveTargets(tasks, task) {
3792
+ const tree = indexTasks(tasks);
3793
+ const banned = /* @__PURE__ */ new Set([task.external_id, ...descendantIds(tree, task.external_id)]);
3794
+ const height = subtreeLevels(tree, task.external_id);
3795
+ return tasks.filter(
3796
+ (t) => !banned.has(t.external_id) && levelOf(tree, t.external_id) + height <= MAX_TASK_DEPTH
3797
+ );
3798
+ }
3799
+ var sameStats = (a, b) => a === b || a !== void 0 && b !== void 0 && a.done === b.done && a.total === b.total;
3800
+ function buildTaskRows(tasks, filter, collapsed, compare, options = {}) {
3801
+ const tree = indexTasks(tasks);
3802
+ const { kids, parentOf } = tree;
3803
+ const sorted = (list) => compare ? [...list].sort(compare) : list;
3804
+ const query = options.query?.trim().toLowerCase() ?? "";
3805
+ const titleOf = options.titleOf ?? ((t) => t.title ?? "");
3806
+ let included = null;
3807
+ let matched = null;
3808
+ if (filter !== "all" || query) {
3809
+ matched = /* @__PURE__ */ new Set();
3810
+ included = /* @__PURE__ */ new Set();
3811
+ for (const task of tasks) {
3812
+ const statusOk = filter === "all" || asTaskStatus(task.status) === filter;
3813
+ const textOk = !query || `${titleOf(task)} ${task.description ?? ""}`.toLowerCase().includes(query);
3814
+ if (!statusOk || !textOk) continue;
3815
+ matched.add(task.external_id);
3816
+ for (let at = task.external_id; at && !included.has(at); at = parentOf.get(at)) {
3817
+ included.add(at);
3818
+ }
3819
+ }
3820
+ }
3821
+ const shown = (list) => included ? list.filter((t) => included.has(t.external_id)) : list;
3822
+ const build = (task, depth, seen) => {
3823
+ const nextSeen = new Set(seen).add(task.external_id);
3824
+ return {
3825
+ task,
3826
+ depth,
3827
+ context: matched ? !matched.has(task.external_id) : false,
3828
+ children: sorted(shown(kids.get(task.external_id) ?? [])).filter((child) => !nextSeen.has(child.external_id)).map((child) => build(child, depth + 1, nextSeen))
3829
+ };
3830
+ };
3831
+ const sections = new Map([
3832
+ ...STATUS_ORDER.map((s) => [s, []]),
3833
+ ["sorted", []]
3834
+ ]);
3835
+ const sectionOf = (task) => compare ? "sorted" : asTaskStatus(task.status);
3836
+ const roots = tasks.filter((t) => !parentOf.has(t.external_id));
3837
+ for (const task of sorted(shown(roots))) {
3838
+ sections.get(sectionOf(task))?.push(build(task, 0, /* @__PURE__ */ new Set()));
3839
+ }
3840
+ const cache = options.cache;
3841
+ const used = /* @__PURE__ */ new Set();
3842
+ const rows = [];
3843
+ const walk = (node, parentId, setSize, posInSet) => {
3844
+ const id = node.task.external_id;
3845
+ const expanded = !collapsed.has(id);
3846
+ const all = kids.get(id);
3847
+ const childStats = all ? { done: all.filter((c) => asTaskStatus(c.status) === "done").length, total: all.length } : void 0;
3848
+ let row = {
3849
+ external_id: id,
3850
+ task: node.task,
3851
+ depth: node.depth,
3852
+ childStats,
3853
+ expanded,
3854
+ parentId,
3855
+ setSize,
3856
+ posInSet,
3857
+ context: node.context
3858
+ };
3859
+ const prev = cache?.get(id);
3860
+ if (prev && prev.task === row.task && prev.depth === row.depth && prev.expanded === row.expanded && prev.parentId === row.parentId && prev.setSize === row.setSize && prev.posInSet === row.posInSet && prev.context === row.context && sameStats(prev.childStats, row.childStats)) {
3861
+ row = prev;
3862
+ }
3863
+ used.add(id);
3864
+ cache?.set(id, row);
3865
+ rows.push(row);
3866
+ if (expanded) {
3867
+ node.children.forEach((child, i) => walk(child, id, node.children.length, i + 1));
3868
+ }
3869
+ };
3870
+ const ordered = [...STATUS_ORDER, "sorted"].flatMap((s) => sections.get(s) ?? []);
3871
+ ordered.forEach((node, i) => walk(node, null, ordered.length, i + 1));
3872
+ if (cache) {
3873
+ for (const id of [...cache.keys()]) if (!used.has(id)) cache.delete(id);
3874
+ }
3875
+ return rows;
3876
+ }
3877
+
3878
+ // src/agents/tasks/taskTableLabels.ts
3879
+ var DEFAULT_TASK_LIST_LABELS = {
3880
+ filterAll: "All",
3881
+ emptyTitle: "No tasks yet",
3882
+ emptyMessage: "Use New to add one: just type what you need, or fill in an owner and a due date. Automations that create tasks live on the Workflows page. You always decide when a task is done.",
3883
+ noMatches: "No tasks match.",
3884
+ due: (when) => when,
3885
+ overdue: (when) => `${when} \xB7 overdue`,
3886
+ agent: "Agent",
3887
+ colTask: "Task",
3888
+ colOwner: "Owner",
3889
+ ownerHint: "Who has the next step. They are notified when the previous step finishes.",
3890
+ colOutputs: "Outputs",
3891
+ changeOwner: "Change owner\u2026",
3892
+ changeOwnerTitle: (name) => `Who has the next step on \u201C${name}\u201D?`,
3893
+ changeOwnerMe: "Me",
3894
+ preparedBy: (agent) => `Prepared by ${agent}`,
3895
+ colDue: "Due",
3896
+ colStatus: "Status",
3897
+ me: "Me",
3898
+ someone: "Someone",
3899
+ noDue: "\u2014",
3900
+ colShared: "Shared",
3901
+ shared: "Shared with the workspace",
3902
+ sharedOwnerOnly: "Only the creator can change who can see this",
3903
+ deleteOwnerOnly: "Only the creator or workspace owner can delete this",
3904
+ goalMet: (met, total) => `${met}/${total} met`,
3905
+ subtasksDone: (done, total) => `${done}/${total} sub-tasks done`,
3906
+ expandSubtasks: "Show sub-tasks",
3907
+ collapseSubtasks: "Hide sub-tasks",
3908
+ selectAll: "Select all tasks",
3909
+ selectTask: (name) => `Select ${name}`,
3910
+ markDone: "Mark done",
3911
+ reopen: "Reopen",
3912
+ markDoneMany: "Mark done",
3913
+ markDoneManyHint: "Marks your own to-dos done. Agent work is finished by reviewing it.",
3914
+ deleteMany: "Delete",
3915
+ approve: "Approve",
3916
+ moveTo: "Move to\u2026",
3917
+ untitled: "Untitled task",
3918
+ fromWorkflow: (name) => `From \u201C${name}\u201D`,
3919
+ searchLabel: "Search tasks",
3920
+ searchPlaceholder: "Search tasks\u2026",
3921
+ expandAll: "Expand all",
3922
+ collapseAll: "Collapse all",
3923
+ moveToTitle: (name) => `Move \u201C${name}\u201D to\u2026`,
3924
+ moveToNone: "No parent (top level)",
3925
+ moveToSearch: "Search tasks\u2026",
3926
+ moveToEmpty: "No task to move it under.",
3927
+ moveToCancel: "Cancel",
3928
+ subtasksSelected: (count) => `${count} ${count === 1 ? "sub-task" : "sub-tasks"} included`,
3929
+ addSubtask: "Add sub-task",
3930
+ edit: "Edit",
3931
+ rename: "Rename",
3932
+ delete: "Delete",
3933
+ grantAccess: "Allow access and continue",
3934
+ allowAccess: "Allow access",
3935
+ moreActions: "More actions",
3936
+ activity: "Activity",
3937
+ statusHint: (status, ago, forWho) => [status, ago, forWho && `for ${forWho}`].filter(Boolean).join(" \xB7 "),
3938
+ status: {}
3939
+ };
3940
+ var ROW_HEIGHT = 56;
3941
+ var NARROW_ROW_HEIGHT = 76;
3942
+ var MAX_INDENT_DEPTH = 4;
3943
+ var ANIMATE_ROWS_UP_TO = 500;
3944
+ var NARROW_GRID = 640;
3945
+ var WIDTH_RULES = [
3946
+ { colId: "shared", minWidth: 1050 },
3947
+ { colId: "due", minWidth: 850 },
3948
+ { colId: "outputs", minWidth: 930 },
3949
+ { colId: "owner", minWidth: 730 },
3950
+ { colId: "status", minWidth: NARROW_GRID }
3951
+ ];
3952
+ function statusHint(task, ctx) {
3953
+ const { props: p, l, owner } = ctx;
3954
+ if (!p.formatRelative || !task.updated_at) return void 0;
3955
+ const key = asTaskStatus(task.status);
3956
+ const pill = { ...DEFAULT_TASK_STATUS_PILL_LABELS, ...p.statusPillLabels };
3957
+ const label = task.pending_auth_request_id ? pill.waitingForAccess : STATUS_LABELS[key];
3958
+ return l.statusHint(
3959
+ label,
3960
+ p.formatRelative(task.updated_at),
3961
+ key === "ready_for_review" ? owner(task).label : void 0
3962
+ );
3963
+ }
3964
+ function TaskTable(props) {
3965
+ const { tasks: allTasks, isLoading, busyId, header, testId } = props;
3966
+ const l = {
3967
+ ...DEFAULT_TASK_LIST_LABELS,
3968
+ ...props.labels,
3969
+ status: { ...STATUS_LABELS, ...props.labels?.status }
3970
+ };
3954
3971
  const [filter, setFilter] = react.useState("all");
3955
3972
  const [query, setQuery] = react.useState("");
3956
3973
  const [collapsed, setCollapsed] = react.useState(/* @__PURE__ */ new Set());
@@ -4505,7 +4522,7 @@ function TaskTable(props) {
4505
4522
  testId: "task-list-empty"
4506
4523
  }
4507
4524
  ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
4508
- chunkJGZTRLKL_cjs.GridView,
4525
+ chunkIA7RTPT3_cjs.GridView,
4509
4526
  {
4510
4527
  testId: "task-grid",
4511
4528
  gridId: props.gridId ?? "tasks-grid-v4",
@@ -4531,7 +4548,7 @@ function TaskTable(props) {
4531
4548
  }
4532
4549
  ) }),
4533
4550
  /* @__PURE__ */ jsxRuntime.jsx(
4534
- chunkJGZTRLKL_cjs.SelectionBar,
4551
+ chunkIA7RTPT3_cjs.SelectionBar,
4535
4552
  {
4536
4553
  count: selectedTasks.length,
4537
4554
  onClear: clearSelection,
@@ -4539,7 +4556,7 @@ function TaskTable(props) {
4539
4556
  children: (isCompact) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4540
4557
  props.selectionActions?.(selectedTasks, isCompact, clearSelection),
4541
4558
  props.onMarkDoneMany && /* @__PURE__ */ jsxRuntime.jsx(
4542
- chunkJGZTRLKL_cjs.SelectionBarAction,
4559
+ chunkIA7RTPT3_cjs.SelectionBarAction,
4543
4560
  {
4544
4561
  icon: lucideReact.CheckCheck,
4545
4562
  label: l.markDoneMany,
@@ -4554,7 +4571,7 @@ function TaskTable(props) {
4554
4571
  }
4555
4572
  ),
4556
4573
  props.onDeleteMany && /* @__PURE__ */ jsxRuntime.jsx(
4557
- chunkJGZTRLKL_cjs.SelectionBarAction,
4574
+ chunkIA7RTPT3_cjs.SelectionBarAction,
4558
4575
  {
4559
4576
  icon: lucideReact.Trash2,
4560
4577
  label: l.deleteMany,
@@ -4586,29 +4603,819 @@ function TaskTable(props) {
4586
4603
  empty: l.moveToEmpty,
4587
4604
  cancel: l.moveToCancel
4588
4605
  },
4589
- testId: "task-owner"
4606
+ testId: "task-owner"
4607
+ }
4608
+ ),
4609
+ moving && props.onMove && /* @__PURE__ */ jsxRuntime.jsx(
4610
+ TaskMoveDialog,
4611
+ {
4612
+ open: true,
4613
+ onOpenChange: (open) => !open && setMoving(null),
4614
+ options: moveTargets(tasks, moving).map((t) => ({ id: t.external_id, label: nameOf(t) })),
4615
+ currentParentId: moving.parent_conversation_ext_id,
4616
+ onPick: (parentId) => props.onMove?.(moving, parentId),
4617
+ labels: {
4618
+ title: l.moveToTitle(nameOf(moving)),
4619
+ none: l.moveToNone,
4620
+ search: l.moveToSearch,
4621
+ empty: l.moveToEmpty,
4622
+ cancel: l.moveToCancel
4623
+ }
4624
+ }
4625
+ )
4626
+ ]
4627
+ }
4628
+ );
4629
+ }
4630
+ function TaskInbox(p) {
4631
+ const [filterOpen, setFilterOpen] = react.useState(false);
4632
+ const [statusFilters, setStatusFilters] = react.useState(
4633
+ () => /* @__PURE__ */ new Map([["done", "exclude"]])
4634
+ );
4635
+ const [localQuery, setLocalQuery] = react.useState("");
4636
+ const [searchFields, setSearchFields] = react.useState(["text", "labels"]);
4637
+ const [selected, setSelected] = react.useState(/* @__PURE__ */ new Set());
4638
+ const [collapsed, setCollapsed] = react.useState(/* @__PURE__ */ new Set());
4639
+ const [moving, setMoving] = react.useState(null);
4640
+ const [handingOff, setHandingOff] = react.useState(null);
4641
+ const l = { ...DEFAULT_TASK_LIST_LABELS, ...p.labels };
4642
+ const nameOf = (t) => t.title?.trim() || t.workflow_ext_id && p.workflowNames?.[t.workflow_ext_id] || l.untitled;
4643
+ const all = p.tasks.filter((t) => t.status != null);
4644
+ const filterText = p.filterText ?? localQuery;
4645
+ const q = filterText.trim().toLowerCase();
4646
+ const included = [...statusFilters].filter(([, state]) => state === "include").map(([id]) => id);
4647
+ const statusMatches = (t) => statusFilters.get(asTaskStatus(t.status)) !== "exclude" && (!included.length || included.includes(asTaskStatus(t.status)));
4648
+ const rows = all.filter(
4649
+ (t) => statusMatches(t) && (!q || [
4650
+ searchFields.includes("text") ? `${nameOf(t)} ${t.description ?? ""}` : "",
4651
+ searchFields.includes("labels") && t.workflow_ext_id ? p.workflowNames?.[t.workflow_ext_id] ?? "" : ""
4652
+ ].join(" ").toLowerCase().includes(q))
4653
+ );
4654
+ const hasActiveFilters = !!q || [...statusFilters.values()].some((state) => state != null);
4655
+ const selectedTasks = all.filter((t) => selected.has(t.external_id));
4656
+ const canEdit = (t) => t.is_owner !== false || Boolean(p.canEditShared);
4657
+ const markable = (t) => t.status !== "done" && t.status !== "generating" && canEdit(t) && !t.in_progress;
4658
+ const markableTasks = selectedTasks.filter(markable);
4659
+ const deletableTasks = selectedTasks.filter((t) => t.is_owner !== false || p.isWorkspaceOwner);
4660
+ const clearSelection = () => setSelected(/* @__PURE__ */ new Set());
4661
+ const toggle = (set, id) => set((old) => {
4662
+ const next = new Set(old);
4663
+ if (next.has(id)) next.delete(id);
4664
+ else next.add(id);
4665
+ return next;
4666
+ });
4667
+ p.renderPerson ?? ((value) => /* @__PURE__ */ jsxRuntime.jsx(PersonPill, { person: value }));
4668
+ const taskById = new Map(all.map((t) => [t.external_id, t]));
4669
+ const visible = new Set(rows.map((t) => t.external_id));
4670
+ for (const task of rows) {
4671
+ let id = task.parent_conversation_ext_id;
4672
+ const seen = /* @__PURE__ */ new Set();
4673
+ while (id && taskById.has(id) && !seen.has(id)) {
4674
+ seen.add(id);
4675
+ visible.add(id);
4676
+ id = taskById.get(id)?.parent_conversation_ext_id;
4677
+ }
4678
+ }
4679
+ const listed = all.filter((t) => visible.has(t.external_id));
4680
+ const roots = listed.filter(
4681
+ (t) => !t.parent_conversation_ext_id || !visible.has(t.parent_conversation_ext_id)
4682
+ );
4683
+ const workflows = (p.workflows ?? []).filter((w) => {
4684
+ const runs = roots.filter((t) => t.workflow_ext_id === w.external_id);
4685
+ return runs.length > 0 || !included.length && (!q || w.name.toLowerCase().includes(q));
4686
+ });
4687
+ const workflowIds = new Set(workflows.map((w) => w.external_id));
4688
+ const order = (a, b) => {
4689
+ const weight = (t) => t.pending_auth_request_id || t.last_error ? 0 : t.status === "ready_for_review" ? 1 : t.status === "todo" ? 2 : t.status === "generating" ? 3 : 4;
4690
+ return weight(a) - weight(b) || (b.updated_at ?? "").localeCompare(a.updated_at ?? "");
4691
+ };
4692
+ const renderTask = (task, depth = 0) => {
4693
+ const id = task.external_id;
4694
+ const status = asTaskStatus(task.status);
4695
+ const busy = p.busyId === id;
4696
+ const children = listed.filter((t) => t.parent_conversation_ext_id === id).sort(order);
4697
+ const outputs = p.outputsByTask?.[id] ?? [];
4698
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { "data-testid": `task-inbox-row-${id}`, children: [
4699
+ /* @__PURE__ */ jsxRuntime.jsxs(
4700
+ "div",
4701
+ {
4702
+ className: ui.cn(
4703
+ "relative flex cursor-pointer items-start gap-2 border-b py-3 hover:bg-muted/40",
4704
+ selected.has(id) && "bg-muted/60"
4705
+ ),
4706
+ onClick: (event) => {
4707
+ if (!event.target.closest(
4708
+ 'button, a, input, select, textarea, [role="menuitem"], [role="checkbox"], [role="combobox"]'
4709
+ )) {
4710
+ p.onOpenThread(id, task);
4711
+ }
4712
+ },
4713
+ style: { paddingLeft: `${Math.min(depth, 5) * 20}px` },
4714
+ children: [
4715
+ children.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
4716
+ ui.Button,
4717
+ {
4718
+ variant: "ghost",
4719
+ size: "icon",
4720
+ className: "size-7 shrink-0",
4721
+ "aria-label": `${collapsed.has(id) ? "Expand" : "Collapse"} ${nameOf(task)}`,
4722
+ onClick: () => toggle(setCollapsed, id),
4723
+ children: collapsed.has(id) ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4" })
4724
+ }
4725
+ ),
4726
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
4727
+ /* @__PURE__ */ jsxRuntime.jsx(
4728
+ "button",
4729
+ {
4730
+ className: ui.cn(
4731
+ "block w-full text-left text-sm font-medium hover:underline",
4732
+ status === "done" && "text-muted-foreground"
4733
+ ),
4734
+ "data-testid": `task-open-${id}`,
4735
+ onClick: () => p.onOpenThread(id, task),
4736
+ children: nameOf(task)
4737
+ }
4738
+ ),
4739
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
4740
+ status !== "todo" && status !== "ready_for_review" && /* @__PURE__ */ jsxRuntime.jsx(
4741
+ TaskStatusPill,
4742
+ {
4743
+ id,
4744
+ status: task.status,
4745
+ runStartedAt: task.run_started_at,
4746
+ lastError: task.last_error,
4747
+ awaitingAccess: Boolean(task.pending_auth_request_id)
4748
+ }
4749
+ ),
4750
+ task.due_at && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4751
+ "Due ",
4752
+ p.formatDate(task.due_at)
4753
+ ] }),
4754
+ children.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
4755
+ all.filter((t) => t.parent_conversation_ext_id === id && t.status === "done").length,
4756
+ "/",
4757
+ all.filter((t) => t.parent_conversation_ext_id === id).length,
4758
+ " steps complete"
4759
+ ] })
4760
+ ] }),
4761
+ outputs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 flex flex-wrap gap-2", "aria-label": "Outputs", children: outputs.map((output) => /* @__PURE__ */ jsxRuntime.jsxs(
4762
+ ui.Button,
4763
+ {
4764
+ variant: "link",
4765
+ size: "sm",
4766
+ className: "h-auto max-w-full gap-1 px-0 py-1 text-xs",
4767
+ disabled: !p.onOpenOutput,
4768
+ onClick: () => p.onOpenOutput?.(output.id, task),
4769
+ "data-testid": `task-output-${id}-${output.id}`,
4770
+ children: [
4771
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-3.5 shrink-0" }),
4772
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: output.name })
4773
+ ]
4774
+ },
4775
+ output.id
4776
+ )) })
4777
+ ] }),
4778
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
4779
+ task.pending_auth_request_id && task.is_owner !== false && p.onGrantAccess && /* @__PURE__ */ jsxRuntime.jsx(
4780
+ ui.Button,
4781
+ {
4782
+ size: "sm",
4783
+ variant: "outline",
4784
+ disabled: busy,
4785
+ onClick: () => p.onGrantAccess?.(task),
4786
+ children: "Allow access"
4787
+ }
4788
+ ),
4789
+ /* @__PURE__ */ jsxRuntime.jsx(
4790
+ TaskRowMenu,
4791
+ {
4792
+ task,
4793
+ status,
4794
+ busy,
4795
+ isOwner: task.is_owner !== false,
4796
+ canAdmin: task.is_owner !== false || Boolean(p.isWorkspaceOwner),
4797
+ canEdit: canEdit(task),
4798
+ canMarkDone: markable(task),
4799
+ canReopen: canEdit(task),
4800
+ selected: selected.has(id),
4801
+ onToggleSelected: p.selectionActions || p.onMarkDoneMany || p.onDeleteMany ? () => toggle(setSelected, id) : void 0,
4802
+ labels: l,
4803
+ onMarkDone: () => p.onMarkDone(task),
4804
+ onNotify: p.onNotify ? () => p.onNotify?.(task) : void 0,
4805
+ onReopen: () => p.onReopen(task),
4806
+ onEdit: () => p.onEdit(task),
4807
+ onAddSubtask: p.onAddSubtask ? () => p.onAddSubtask?.(task) : void 0,
4808
+ onMoveTo: p.onMove ? () => setMoving(task) : void 0,
4809
+ onChangeOwner: status !== "ready_for_review" && p.onChangeOwner && p.people?.length ? () => setHandingOff(task) : void 0,
4810
+ onOpenActivity: p.onOpenActivity ? () => p.onOpenActivity?.(task) : void 0,
4811
+ onToggleShared: p.onToggleShared ? () => p.onToggleShared?.(task, !task.is_shared) : void 0
4812
+ }
4813
+ )
4814
+ ] })
4815
+ ]
4816
+ }
4817
+ ),
4818
+ children.length > 0 && !collapsed.has(id) && /* @__PURE__ */ jsxRuntime.jsx("ul", { children: children.map((child) => renderTask(child, depth + 1)) })
4819
+ ] }, id);
4820
+ };
4821
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col", "data-testid": p.testId ?? "task-inbox", children: [
4822
+ /* @__PURE__ */ jsxRuntime.jsx(
4823
+ chunk6DNYPLCD_cjs.TabHeader,
4824
+ {
4825
+ testId: "tasks-tab-header",
4826
+ tabs: [
4827
+ {
4828
+ id: "tasks",
4829
+ label: "",
4830
+ count: rows.length,
4831
+ countPlacement: "leading",
4832
+ countIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListTodo, { className: "size-3.5" }),
4833
+ hasActiveFilters,
4834
+ testId: "tasks-tab",
4835
+ presentation: "count"
4836
+ }
4837
+ ],
4838
+ activeTabId: "tasks",
4839
+ onTabChange: () => {
4840
+ },
4841
+ firstTabContent: /* @__PURE__ */ jsxRuntime.jsx(
4842
+ chunkMZL67U2E_cjs.FilterInput,
4843
+ {
4844
+ value: filterText,
4845
+ onChange: p.onFilterTextChange ?? setLocalQuery,
4846
+ fields: searchFields,
4847
+ onFieldsChange: setSearchFields,
4848
+ labels: { fieldNames: { text: "Task", labels: "Workflow" } },
4849
+ className: "w-44 max-w-[40vw]",
4850
+ testIds: {
4851
+ root: "tasks-filter",
4852
+ input: "tasks-filter-input",
4853
+ fieldsButton: "tasks-filter-fields"
4854
+ },
4855
+ filter: /* @__PURE__ */ jsxRuntime.jsx(
4856
+ chunk2QTT2RZE_cjs.TriStateFilterMenu,
4857
+ {
4858
+ testId: "tasks-status-filter",
4859
+ open: filterOpen,
4860
+ onOpenChange: setFilterOpen,
4861
+ filterStates: statusFilters,
4862
+ onFiltersChange: setStatusFilters,
4863
+ options: [
4864
+ {
4865
+ id: "todo",
4866
+ label: "To do",
4867
+ count: all.filter((t) => t.status === "todo").length
4868
+ },
4869
+ {
4870
+ id: "generating",
4871
+ label: "Generating",
4872
+ count: all.filter((t) => t.status === "generating").length
4873
+ },
4874
+ {
4875
+ id: "ready_for_review",
4876
+ label: "Ready for review",
4877
+ count: all.filter((t) => t.status === "ready_for_review").length
4878
+ },
4879
+ {
4880
+ id: "done",
4881
+ label: "Completed",
4882
+ count: all.filter((t) => t.status === "done").length
4883
+ }
4884
+ ],
4885
+ groups: [
4886
+ { label: "Status", options: ["todo", "generating", "ready_for_review", "done"] }
4887
+ ],
4888
+ triggerClassName: "flex h-5 items-center gap-0.5 rounded px-1 text-muted-foreground hover:text-foreground pointer-coarse:h-11! pointer-coarse:min-w-11 pointer-coarse:justify-center",
4889
+ renderChevron: true,
4890
+ disableHoverOpen: true
4891
+ }
4892
+ )
4893
+ }
4894
+ ),
4895
+ rightContent: p.onCreate ? /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
4896
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { "data-testid": "new-task-button", children: [
4897
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "mr-1 size-4" }),
4898
+ "New",
4899
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "ml-1 size-3" })
4900
+ ] }) }),
4901
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuContent, { align: "end", children: [
4902
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: p.onCreate, children: "Task" }),
4903
+ p.onCreateWorkflow && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: p.onCreateWorkflow, children: "Saved workflow" })
4904
+ ] })
4905
+ ] }) : p.header
4906
+ }
4907
+ ),
4908
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", "aria-busy": p.isLoading, children: p.isLoading ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "py-12 text-center text-sm text-muted-foreground", children: "Loading work\u2026" }) : !listed.length && !workflows.length ? /* @__PURE__ */ jsxRuntime.jsx(
4909
+ chunkZW6FPIFC_cjs.EmptyState,
4910
+ {
4911
+ title: q ? "No matches" : all.length ? "You\u2019re all caught up" : "No work here yet",
4912
+ description: "Create a task from a prompt or a saved workflow. Keep its drafts, reviews and handoffs together."
4913
+ }
4914
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("ul", { children: [
4915
+ workflows.map((w) => {
4916
+ const runs = roots.filter((t) => t.workflow_ext_id === w.external_id).sort(order);
4917
+ const editable = w.is_owner !== false || p.canEditShared;
4918
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { "data-testid": `task-workflow-${w.external_id}`, children: [
4919
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 border-b py-3", children: [
4920
+ runs.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
4921
+ ui.Button,
4922
+ {
4923
+ variant: "ghost",
4924
+ size: "icon",
4925
+ className: "size-7",
4926
+ "aria-label": `${collapsed.has(w.external_id) ? "Expand" : "Collapse"} ${w.name}`,
4927
+ onClick: () => toggle(setCollapsed, w.external_id),
4928
+ children: collapsed.has(w.external_id) ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4" })
4929
+ }
4930
+ ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "mx-1 mt-1 size-4 shrink-0 text-muted-foreground" }),
4931
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
4932
+ /* @__PURE__ */ jsxRuntime.jsx(
4933
+ "button",
4934
+ {
4935
+ className: "block text-left text-sm font-medium hover:underline",
4936
+ disabled: !editable,
4937
+ onClick: () => p.onEditWorkflow?.(w.external_id),
4938
+ children: w.name
4939
+ }
4940
+ ),
4941
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [
4942
+ "Saved workflow \xB7 ",
4943
+ w.summary ?? "Run when needed",
4944
+ !w.active ? " \xB7 Paused" : "",
4945
+ runs.length ? ` \xB7 ${runs.length} ${runs.length === 1 ? "task" : "tasks"}` : ""
4946
+ ] }),
4947
+ w.last_error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-destructive", children: w.last_error })
4948
+ ] }),
4949
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
4950
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4951
+ ui.Button,
4952
+ {
4953
+ variant: "ghost",
4954
+ size: "icon",
4955
+ className: "size-8",
4956
+ "aria-label": `Actions for ${w.name}`,
4957
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { className: "size-4" })
4958
+ }
4959
+ ) }),
4960
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuContent, { align: "end", children: [
4961
+ p.onWorkflowHistory && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: () => p.onWorkflowHistory?.(w.external_id), children: "Run history" }),
4962
+ editable && p.onToggleWorkflow && /* @__PURE__ */ jsxRuntime.jsx(
4963
+ ui.DropdownMenuItem,
4964
+ {
4965
+ onSelect: () => p.onToggleWorkflow?.(w.external_id, !w.active),
4966
+ children: w.active ? "Pause" : "Resume"
4967
+ }
4968
+ ),
4969
+ (w.is_owner !== false || p.isWorkspaceOwner) && p.onDeleteWorkflow && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: () => p.onDeleteWorkflow?.(w.external_id), children: "Delete workflow" })
4970
+ ] })
4971
+ ] })
4972
+ ] }),
4973
+ !collapsed.has(w.external_id) && runs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { children: runs.map((t) => renderTask(t, 1)) })
4974
+ ] }, w.external_id);
4975
+ }),
4976
+ roots.filter((t) => !t.workflow_ext_id || !workflowIds.has(t.workflow_ext_id)).sort(order).map((t) => renderTask(t))
4977
+ ] }) }),
4978
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIA7RTPT3_cjs.SelectionBar, { count: selectedTasks.length, onClear: clearSelection, children: (isCompact) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4979
+ p.selectionActions?.(selectedTasks, isCompact, clearSelection),
4980
+ p.onMarkDoneMany && /* @__PURE__ */ jsxRuntime.jsx(
4981
+ chunkIA7RTPT3_cjs.SelectionBarAction,
4982
+ {
4983
+ icon: lucideReact.CheckCheck,
4984
+ label: l.markDoneMany,
4985
+ isCompact,
4986
+ disabled: !markableTasks.length,
4987
+ onClick: () => {
4988
+ p.onMarkDoneMany?.(markableTasks);
4989
+ clearSelection();
4990
+ },
4991
+ testId: "task-bulk-done"
4992
+ }
4993
+ ),
4994
+ p.onDeleteMany && /* @__PURE__ */ jsxRuntime.jsx(
4995
+ chunkIA7RTPT3_cjs.SelectionBarAction,
4996
+ {
4997
+ icon: lucideReact.Trash2,
4998
+ label: l.deleteMany,
4999
+ isCompact,
5000
+ disabled: !deletableTasks.length,
5001
+ onClick: () => {
5002
+ p.onDeleteMany?.(deletableTasks);
5003
+ clearSelection();
5004
+ },
5005
+ className: "text-red-text hover:bg-red-bg hover:text-red-text",
5006
+ testId: "task-bulk-delete"
5007
+ }
5008
+ )
5009
+ ] }) }),
5010
+ moving && p.onMove && /* @__PURE__ */ jsxRuntime.jsx(
5011
+ TaskMoveDialog,
5012
+ {
5013
+ open: true,
5014
+ onOpenChange: (open) => !open && setMoving(null),
5015
+ options: moveTargets(all, moving).map((t) => ({ id: t.external_id, label: nameOf(t) })),
5016
+ currentParentId: moving.parent_conversation_ext_id,
5017
+ onPick: (id) => p.onMove?.(moving, id),
5018
+ labels: {
5019
+ title: l.moveToTitle(nameOf(moving)),
5020
+ none: l.moveToNone,
5021
+ search: l.moveToSearch,
5022
+ empty: l.moveToEmpty,
5023
+ cancel: l.moveToCancel
5024
+ }
5025
+ }
5026
+ ),
5027
+ handingOff && p.onChangeOwner && /* @__PURE__ */ jsxRuntime.jsx(
5028
+ TaskMoveDialog,
5029
+ {
5030
+ open: true,
5031
+ onOpenChange: (open) => !open && setHandingOff(null),
5032
+ options: p.people ?? [],
5033
+ currentParentId: handingOff.signoff_ext_id,
5034
+ onPick: (id) => p.onChangeOwner?.(handingOff, id),
5035
+ labels: {
5036
+ title: l.changeOwnerTitle(nameOf(handingOff)),
5037
+ none: l.changeOwnerMe,
5038
+ search: l.moveToSearch,
5039
+ empty: l.moveToEmpty,
5040
+ cancel: l.moveToCancel
5041
+ },
5042
+ testId: "task-owner"
5043
+ }
5044
+ )
5045
+ ] });
5046
+ }
5047
+ function EntityChip({
5048
+ variant = "pill",
5049
+ icon,
5050
+ label,
5051
+ detail,
5052
+ pillTooltip,
5053
+ showTooltip = true,
5054
+ href,
5055
+ onClick,
5056
+ size = "sm",
5057
+ labelMaxWidth,
5058
+ className,
5059
+ testId
5060
+ }) {
5061
+ if (variant === "icon") {
5062
+ const glyph = /* @__PURE__ */ jsxRuntime.jsx(
5063
+ "span",
5064
+ {
5065
+ "data-slot": "entity-chip",
5066
+ className: ui.cn("inline-flex items-center", (onClick || href) && "cursor-pointer", className),
5067
+ onClick,
5068
+ "data-testid": testId,
5069
+ children: href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children: icon }) : icon
5070
+ }
5071
+ );
5072
+ if (!showTooltip) return glyph;
5073
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Tooltip, { children: [
5074
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { className: "inline-flex", children: glyph }),
5075
+ /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipContent, { side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
5076
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: label }),
5077
+ detail && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: detail })
5078
+ ] }) })
5079
+ ] });
5080
+ }
5081
+ return /* @__PURE__ */ jsxRuntime.jsx(
5082
+ ui.EntityPill,
5083
+ {
5084
+ icon,
5085
+ label,
5086
+ size,
5087
+ shape: "rounded",
5088
+ href,
5089
+ onClick,
5090
+ tooltipContent: pillTooltip,
5091
+ labelMaxWidth,
5092
+ className,
5093
+ "data-testid": testId
5094
+ }
5095
+ );
5096
+ }
5097
+ function filterConversationRows(conversations, query, labelText, doneFilter = "exclude", visibilityFilters) {
5098
+ const q = query.trim().toLowerCase();
5099
+ return [...conversations].sort(
5100
+ (a, b) => (Date.parse(b.last_message_updated_at || b.updated_at || b.created_at || "") || 0) - (Date.parse(a.last_message_updated_at || a.updated_at || a.created_at || "") || 0)
5101
+ ).filter(
5102
+ (row) => doneFilter === "exclude" ? row.status !== "done" : doneFilter === "include" ? row.status === "done" : true
5103
+ ).filter((row) => {
5104
+ const state = row.is_shared ? visibilityFilters?.workspace : visibilityFilters?.me;
5105
+ const hasIncluded = visibilityFilters?.me === "include" || visibilityFilters?.workspace === "include";
5106
+ return state !== "exclude" && (!hasIncluded || state === "include");
5107
+ }).filter((row) => !q || `${row.title ?? ""} ${labelText?.(row) ?? ""}`.toLowerCase().includes(q));
5108
+ }
5109
+ function ConversationListView(p) {
5110
+ const liveProps = react.useRef(p);
5111
+ liveProps.current = p;
5112
+ const [query, setQuery] = react.useState("");
5113
+ const [selected, setSelected] = react.useState(/* @__PURE__ */ new Set());
5114
+ const q = `${query} ${p.filterText ?? ""}`.trim().toLowerCase();
5115
+ const rows = react.useMemo(
5116
+ () => filterConversationRows(p.conversations, q, p.labelText, p.doneFilter, p.visibilityFilters),
5117
+ [p.conversations, q, p.labelText, p.doneFilter, p.visibilityFilters]
5118
+ );
5119
+ const selectedRows = p.conversations.filter((c) => selected.has(c.external_id));
5120
+ const columns = react.useMemo(
5121
+ () => [
5122
+ {
5123
+ colId: "name",
5124
+ headerName: "Thread",
5125
+ flex: 1,
5126
+ minWidth: 180,
5127
+ valueGetter: ({ data }) => data?.title?.trim() || "Untitled thread",
5128
+ cellRenderer: ({ data }) => data && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group flex h-full min-w-0 items-center gap-2", children: [
5129
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: liveProps.current.renderThread ? liveProps.current.renderThread(data) : /* @__PURE__ */ jsxRuntime.jsx(
5130
+ EntityChip,
5131
+ {
5132
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ui.ThreadVisibilityIcon, { shared: data.is_shared ?? false, className: "size-4" }),
5133
+ label: data.title?.trim() || "Untitled thread",
5134
+ pillTooltip: "Open conversation",
5135
+ labelMaxWidth: "max-w-full",
5136
+ onClick: () => liveProps.current.onOpen(data),
5137
+ testId: `thread-open-${data.external_id}`
5138
+ }
5139
+ ) }),
5140
+ (data.is_owner !== false || liveProps.current.canEditShared) && /* @__PURE__ */ jsxRuntime.jsx(
5141
+ "button",
5142
+ {
5143
+ type: "button",
5144
+ "aria-label": `Rename ${data.title?.trim() || "Untitled thread"}`,
5145
+ onClick: () => liveProps.current.onRename(data),
5146
+ "data-testid": `thread-rename-${data.external_id}`,
5147
+ className: "shrink-0 pointer-coarse:flex pointer-coarse:size-11 pointer-coarse:items-center pointer-coarse:justify-center",
5148
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunk3AFWGEDJ_cjs.CellHoverIcon, {})
5149
+ }
5150
+ )
5151
+ ] })
5152
+ },
5153
+ ...liveProps.current.renderLabels ? [
5154
+ {
5155
+ colId: "labels",
5156
+ headerName: "Labels",
5157
+ flex: 0.5,
5158
+ minWidth: 160,
5159
+ valueGetter: ({ data }) => data ? liveProps.current.labelText?.(data) ?? "" : "",
5160
+ cellRenderer: ({ data }) => data && liveProps.current.renderLabels?.(data)
5161
+ }
5162
+ ] : [],
5163
+ ...liveProps.current.renderBy || liveProps.current.renderOwner ? [
5164
+ {
5165
+ colId: liveProps.current.renderBy ? "by" : "owner",
5166
+ headerName: liveProps.current.renderBy ? "By" : "Owner",
5167
+ width: 160,
5168
+ cellRenderer: ({ data }) => data && (liveProps.current.renderBy || liveProps.current.renderOwner)?.(data)
5169
+ }
5170
+ ] : [],
5171
+ {
5172
+ colId: "status",
5173
+ headerName: "Status",
5174
+ width: 150,
5175
+ valueGetter: ({ data }) => data?.status,
5176
+ cellRenderer: ({ data }) => data && (liveProps.current.renderStatus ? liveProps.current.renderStatus(data) : /* @__PURE__ */ jsxRuntime.jsx(TaskStatusPill, { id: data.external_id, status: data.status }))
5177
+ },
5178
+ {
5179
+ valueGetter: ({ data }) => data?.message_count,
5180
+ colId: "messages",
5181
+ headerName: "Messages",
5182
+ width: 110,
5183
+ valueFormatter: ({ value }) => value == null ? "\u2014" : String(value),
5184
+ cellClass: "text-muted-foreground"
5185
+ },
5186
+ ...liveProps.current.onToggleShared ? [
5187
+ {
5188
+ colId: "visibility",
5189
+ headerName: "Visibility",
5190
+ width: 100,
5191
+ cellClass: "cell-hcenter",
5192
+ sortable: false,
5193
+ resizable: false,
5194
+ cellRenderer: ({ data }) => data && /* @__PURE__ */ jsxRuntime.jsx(
5195
+ ui.VisibilityToggle,
5196
+ {
5197
+ items: [data],
5198
+ showLabel: false,
5199
+ disabled: data.is_owner === false,
5200
+ onToggle: () => liveProps.current.onToggleShared?.(data, !data.is_shared)
5201
+ }
5202
+ )
5203
+ }
5204
+ ] : [],
5205
+ {
5206
+ colId: "activity",
5207
+ initialSort: "desc",
5208
+ headerName: "Activity",
5209
+ width: 160,
5210
+ valueGetter: ({ data }) => data?.last_message_updated_at || data?.updated_at || data?.created_at || "",
5211
+ valueFormatter: ({ value }) => value ? liveProps.current.formatDate(value) : "\u2014",
5212
+ cellClass: "text-muted-foreground"
5213
+ }
5214
+ ],
5215
+ [
5216
+ Boolean(p.renderThread),
5217
+ Boolean(p.renderLabels),
5218
+ Boolean(p.renderOwner),
5219
+ Boolean(p.renderBy),
5220
+ Boolean(p.renderStatus),
5221
+ Boolean(p.onToggleShared)
5222
+ ]
5223
+ );
5224
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col", "data-testid": "conversation-list-view", children: [
5225
+ p.showHeader !== false && /* @__PURE__ */ jsxRuntime.jsx(
5226
+ chunk6DNYPLCD_cjs.TabHeader,
5227
+ {
5228
+ testId: "threads-tab-header",
5229
+ tabs: [
5230
+ {
5231
+ id: "threads",
5232
+ label: "",
5233
+ count: rows.length,
5234
+ countIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "size-3.5" }),
5235
+ countPlacement: "leading",
5236
+ presentation: "count",
5237
+ hasActiveFilters: !!q
5238
+ }
5239
+ ],
5240
+ activeTabId: "threads",
5241
+ onTabChange: () => {
5242
+ },
5243
+ firstTabContent: /* @__PURE__ */ jsxRuntime.jsx(
5244
+ chunkMZL67U2E_cjs.FilterInput,
5245
+ {
5246
+ value: query,
5247
+ hideFieldPicker: true,
5248
+ ariaLabel: "Search threads",
5249
+ onChange: setQuery,
5250
+ fields: ["text"],
5251
+ onFieldsChange: () => {
5252
+ },
5253
+ labels: {
5254
+ placeholder: "Find a thread\u2026",
5255
+ fieldNames: { text: "Thread" }
5256
+ },
5257
+ className: "w-44 max-w-[40vw]"
5258
+ }
5259
+ ),
5260
+ rightContent: p.header
5261
+ }
5262
+ ),
5263
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
5264
+ chunkIA7RTPT3_cjs.GridView,
5265
+ {
5266
+ testId: "threads-grid",
5267
+ items: rows,
5268
+ columnDefs: columns,
5269
+ getItemId: (row) => row.external_id,
5270
+ getRowTestId: (row) => `thread-row-${row.external_id}`,
5271
+ onRowClick: p.onOpen,
5272
+ height: "100%",
5273
+ isLoading: p.isLoading,
5274
+ loadingMessage: "Loading threads\u2026",
5275
+ emptyState: {
5276
+ title: q ? "No threads match" : "No conversations yet",
5277
+ message: "Start a conversation with people, ARBI, or both."
5278
+ },
5279
+ selection: p.selectionActions ? {
5280
+ mode: "multiple",
5281
+ controlled: true,
5282
+ selected: selectedRows,
5283
+ onSelectionChange: (items) => setSelected(new Set(items.map((item) => item.external_id)))
5284
+ } : void 0,
5285
+ gridOptions: {
5286
+ suppressClickEdit: true,
5287
+ onCellKeyDown: (event) => {
5288
+ if (event.event?.key === "Enter" && "column" in event && event.column.getColId() === "name" && event.data)
5289
+ p.onOpen(event.data);
5290
+ }
5291
+ }
5292
+ }
5293
+ ) }),
5294
+ p.selectionActions && /* @__PURE__ */ jsxRuntime.jsx(chunkIA7RTPT3_cjs.SelectionBar, { count: selectedRows.length, onClear: () => setSelected(/* @__PURE__ */ new Set()), children: (compact) => p.selectionActions?.(selectedRows, compact, () => setSelected(/* @__PURE__ */ new Set())) })
5295
+ ] });
5296
+ }
5297
+ function TaskStartDialog({
5298
+ open,
5299
+ onOpenChange,
5300
+ workflows,
5301
+ isPending,
5302
+ error,
5303
+ onStart,
5304
+ onLater
5305
+ }) {
5306
+ const [prompt, setPrompt] = react.useState("");
5307
+ const [choice, setChoice] = react.useState("prompt");
5308
+ const [shared, setShared] = react.useState(false);
5309
+ const todo = choice === "todo";
5310
+ const workflowId = choice === "prompt" || todo ? null : choice;
5311
+ const valid = workflowId ? workflows.some((w) => w.external_id === workflowId) : Boolean(prompt.trim());
5312
+ const values = {
5313
+ prompt: prompt.trim(),
5314
+ workflowId,
5315
+ todo,
5316
+ shared
5317
+ };
5318
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { modal: false, open, onOpenChange: (next) => !isPending && onOpenChange(next), children: /* @__PURE__ */ jsxRuntime.jsxs(
5319
+ ui.DialogContent,
5320
+ {
5321
+ presentation: "right",
5322
+ hideCloseButton: true,
5323
+ onInteractOutside: (event) => event.preventDefault(),
5324
+ className: "flex flex-col gap-0 overflow-hidden p-0 shadow-lg",
5325
+ "data-testid": "task-start-dialog",
5326
+ children: [
5327
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { className: "sr-only", children: "New task" }),
5328
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { className: "sr-only", children: "Describe the task, then start it now or schedule it." }),
5329
+ /* @__PURE__ */ jsxRuntime.jsx(
5330
+ chunk6DNYPLCD_cjs.TabHeader,
5331
+ {
5332
+ tabs: [{ id: "new-task", label: "New task", presentation: "count" }],
5333
+ activeTabId: "new-task",
5334
+ onTabChange: () => {
5335
+ },
5336
+ rightContent: /* @__PURE__ */ jsxRuntime.jsx(ui.DialogClose, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "ghost", size: "icon", "aria-label": "Close", disabled: isPending, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4" }) }) })
4590
5337
  }
4591
5338
  ),
4592
- moving && props.onMove && /* @__PURE__ */ jsxRuntime.jsx(
4593
- TaskMoveDialog,
4594
- {
4595
- open: true,
4596
- onOpenChange: (open) => !open && setMoving(null),
4597
- options: moveTargets(tasks, moving).map((t) => ({ id: t.external_id, label: nameOf(t) })),
4598
- currentParentId: moving.parent_conversation_ext_id,
4599
- onPick: (parentId) => props.onMove?.(moving, parentId),
4600
- labels: {
4601
- title: l.moveToTitle(nameOf(moving)),
4602
- none: l.moveToNone,
4603
- search: l.moveToSearch,
4604
- empty: l.moveToEmpty,
4605
- cancel: l.moveToCancel
5339
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 py-3", children: [
5340
+ !workflowId ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5341
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "sr-only", htmlFor: "task-start-prompt", children: todo ? "What needs doing?" : "What should ARBI do?" }),
5342
+ /* @__PURE__ */ jsxRuntime.jsx(
5343
+ ui.Textarea,
5344
+ {
5345
+ id: "task-start-prompt",
5346
+ autoFocus: true,
5347
+ value: prompt,
5348
+ onChange: (event) => setPrompt(event.target.value),
5349
+ disabled: isPending,
5350
+ placeholder: "What needs doing?",
5351
+ className: "min-h-44 resize-y shadow-none"
5352
+ }
5353
+ )
5354
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: workflows.find((workflow) => workflow.external_id === workflowId)?.name }),
5355
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: choice, onValueChange: setChoice, disabled: isPending, children: [
5356
+ /* @__PURE__ */ jsxRuntime.jsx(
5357
+ ui.SelectTrigger,
5358
+ {
5359
+ id: "task-start-source",
5360
+ "aria-label": "Who does the work",
5361
+ className: "mt-3 h-7 w-auto max-w-full border-0 bg-transparent px-1 text-xs font-normal text-muted-foreground shadow-none hover:bg-muted",
5362
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.SelectValue, {})
5363
+ }
5364
+ ),
5365
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.SelectContent, { children: [
5366
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "prompt", children: "With ARBI" }),
5367
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "todo", children: "People only" }),
5368
+ workflows.map((workflow) => /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: workflow.external_id, children: workflow.name }, workflow.external_id))
5369
+ ] })
5370
+ ] }),
5371
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "mt-3 text-sm text-destructive", children: error })
5372
+ ] }),
5373
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 border-t px-3 py-2", children: [
5374
+ /* @__PURE__ */ jsxRuntime.jsx(
5375
+ ui.Button,
5376
+ {
5377
+ variant: "ghost",
5378
+ disabled: !valid || isPending,
5379
+ onClick: () => onLater(values),
5380
+ "data-testid": "task-start-later",
5381
+ className: "h-8 px-2 text-sm font-medium",
5382
+ children: "Schedule"
4606
5383
  }
4607
- }
4608
- )
5384
+ ),
5385
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-3", children: [
5386
+ /* @__PURE__ */ jsxRuntime.jsx(
5387
+ ui.VisibilityToggle,
5388
+ {
5389
+ items: { shared },
5390
+ onToggle: setShared,
5391
+ label: shared ? "Workspace" : "Only Me",
5392
+ disabled: isPending,
5393
+ "data-testid": "task-start-visibility"
5394
+ }
5395
+ ),
5396
+ /* @__PURE__ */ jsxRuntime.jsx(
5397
+ ui.Button,
5398
+ {
5399
+ disabled: !valid || isPending,
5400
+ "data-testid": "task-start-now",
5401
+ className: "h-8 px-3 text-sm font-medium",
5402
+ onClick: async () => {
5403
+ try {
5404
+ await onStart(values);
5405
+ setPrompt("");
5406
+ setChoice("prompt");
5407
+ setShared(false);
5408
+ } catch {
5409
+ }
5410
+ },
5411
+ children: isPending ? "Starting\u2026" : "Start now"
5412
+ }
5413
+ )
5414
+ ] })
5415
+ ] })
4609
5416
  ]
4610
5417
  }
4611
- );
5418
+ ) });
4612
5419
  }
4613
5420
  var DEFAULT_DUE_DATE_MENU_LABELS = {
4614
5421
  today: "Today",
@@ -4782,6 +5589,25 @@ var hasDocumentInputs = (inputs) => Object.values(inputs).some(
4782
5589
  (v) => v !== null && typeof v === "object" && Array.isArray(v.documents) && (v.documents.length ?? 0) > 0
4783
5590
  );
4784
5591
  function workflowTaskFields(workflow, inputs, name, context) {
5592
+ if (workflow.documentAction) {
5593
+ const scope = inputs.scope && typeof inputs.scope === "object" ? inputs.scope : { labels: []};
5594
+ return {
5595
+ name: name?.trim() || workflow.title,
5596
+ prompt: "",
5597
+ skill_ref: null,
5598
+ skill_inputs: inputs,
5599
+ action: {
5600
+ type: workflow.documentAction,
5601
+ documents: {
5602
+ doc_ext_ids: scope.documents ?? [],
5603
+ label_ext_ids: scope.labels ?? [],
5604
+ latest: inputs.latest === true
5605
+ },
5606
+ tag_ext_ids: typeof inputs.output === "string" && inputs.output ? [inputs.output] : [],
5607
+ overwrite: inputs.overwrite === true
5608
+ }
5609
+ };
5610
+ }
4785
5611
  for (const value of Object.values(inputs)) {
4786
5612
  if (!value || typeof value !== "object") continue;
4787
5613
  const scope = value;
@@ -4894,6 +5720,7 @@ function composerToWorkflowRequest({ workflow, values, plan, documentTitles }, w
4894
5720
  shared: values.shared,
4895
5721
  timezone: values.timezone,
4896
5722
  ...workflowTrigger(values, false),
5723
+ ...fields.action ? { action: fields.action } : {},
4897
5724
  prompt: fields.prompt,
4898
5725
  skill_ref: fields.skill_ref,
4899
5726
  skill_inputs: fields.skill_inputs,
@@ -4906,7 +5733,7 @@ function composerToWorkflowRequest({ workflow, values, plan, documentTitles }, w
4906
5733
  });
4907
5734
  }
4908
5735
  function taskComposerToCreateRequest(ctx, workspaceId, forceWorkflow = false) {
4909
- if (forceWorkflow || !createsWork(ctx.values)) {
5736
+ if (forceWorkflow || ctx.workflow.documentAction || !createsWork(ctx.values)) {
4910
5737
  return { kind: "workflow", body: composerToWorkflowRequest(ctx, workspaceId) };
4911
5738
  }
4912
5739
  return ctx.values.assignee === "me" || !isAgenticWorkflow(ctx.workflow) ? { kind: "work", body: composerToWorkRequest(ctx, workspaceId) } : { kind: "query", query: composerToTaskQuery(ctx, workspaceId) };
@@ -4938,6 +5765,7 @@ function composerToWorkflowUpdate({
4938
5765
  shared: values.shared,
4939
5766
  timezone: values.timezone,
4940
5767
  ...workflowTrigger(values, true),
5768
+ action: fields.action ?? null,
4941
5769
  prompt: fields.prompt,
4942
5770
  skill_ref: fields.skill_ref,
4943
5771
  skill_inputs: fields.skill_inputs,
@@ -4966,10 +5794,11 @@ function taskToComposerValues(task, workflows) {
4966
5794
  };
4967
5795
  }
4968
5796
  function workflowWhen(workflow) {
5797
+ if (workflow.on_demand) return "now";
4969
5798
  if (workflow.after_conversation_ext_id) return "task";
4970
5799
  if (workflow.event_kind) return "event";
4971
5800
  if (workflow.rrule) return "repeat";
4972
- return "once";
5801
+ return workflow.run_at ? "once" : "now";
4973
5802
  }
4974
5803
  function workflowToComposerValues(workflow, workflows) {
4975
5804
  const reminder = !workflow.prompt && !workflow.skill_ref;
@@ -4990,6 +5819,25 @@ function workflowToComposerValues(workflow, workflows) {
4990
5819
  name: workflow.name,
4991
5820
  access: workflow.auth_mode === "scheduled_permanent" ? "standing" : "ask_each_run"
4992
5821
  };
5822
+ if (workflow.action) {
5823
+ const definition = workflows.definitions?.find(
5824
+ (d) => d.documentAction === workflow.action?.type
5825
+ );
5826
+ return {
5827
+ ...base,
5828
+ workflowId: definition?.id ?? workflows.customWorkflowId,
5829
+ inputs: {
5830
+ scope: {
5831
+ folders: [],
5832
+ labels: workflow.action.documents?.label_ext_ids ?? [],
5833
+ documents: workflow.action.documents?.doc_ext_ids ?? []
5834
+ },
5835
+ output: workflow.action.tag_ext_ids?.[0] ?? "",
5836
+ overwrite: workflow.action.overwrite ?? false,
5837
+ latest: workflow.action.documents?.latest ?? false
5838
+ }
5839
+ };
5840
+ }
4993
5841
  if (skill) {
4994
5842
  return {
4995
5843
  ...base,
@@ -5013,7 +5861,7 @@ function workflowToComposerValues(workflow, workflows) {
5013
5861
  var EMPTY_NEW_THREAD = {
5014
5862
  prompt: "",
5015
5863
  title: "",
5016
- shared: true,
5864
+ shared: false,
5017
5865
  ownerId: "",
5018
5866
  dueAt: "",
5019
5867
  parentId: "",
@@ -5106,12 +5954,7 @@ function NewThreadDialog({
5106
5954
  );
5107
5955
  const [values, setValues] = react.useState(seed);
5108
5956
  const [detailsOpen, setDetailsOpen] = react.useState(hasTaskFields(seed));
5109
- react.useEffect(() => {
5110
- if (open) {
5111
- setValues(seed);
5112
- setDetailsOpen(hasTaskFields(seed));
5113
- }
5114
- }, [open, seed]);
5957
+ const [submitError, setSubmitError] = react.useState(null);
5115
5958
  const id = chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "new-thread" });
5116
5959
  const set = (key, value) => setValues((v) => ({ ...v, [key]: value }));
5117
5960
  const canSubmit = values.prompt.trim() !== "" && !isPending;
@@ -5127,11 +5970,12 @@ function NewThreadDialog({
5127
5970
  label: t.name,
5128
5971
  icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownRight, { className: GLYPH, "aria-hidden": true })
5129
5972
  }));
5130
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
5973
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { modal: false, open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
5131
5974
  ui.DialogContent,
5132
5975
  {
5133
- presentation: "sheet",
5134
- className: "flex max-h-[calc(100dvh-2rem)] flex-col overflow-hidden p-0 sm:max-w-xl",
5976
+ presentation: "right",
5977
+ onInteractOutside: (event) => event.preventDefault(),
5978
+ className: "flex flex-col overflow-hidden p-0",
5135
5979
  "data-testid": id,
5136
5980
  children: [
5137
5981
  /* @__PURE__ */ jsxRuntime.jsxs(chunk2ZTONLT5_cjs.ModalHeader, { children: [
@@ -5142,9 +5986,17 @@ function NewThreadDialog({
5142
5986
  "form",
5143
5987
  {
5144
5988
  className: "flex min-h-0 flex-1 flex-col",
5145
- onSubmit: (event) => {
5989
+ onSubmit: async (event) => {
5146
5990
  event.preventDefault();
5147
- if (canSubmit) onSubmit(values);
5991
+ if (!canSubmit) return;
5992
+ setSubmitError(null);
5993
+ try {
5994
+ await onSubmit(values);
5995
+ setValues(EMPTY_NEW_THREAD);
5996
+ setDetailsOpen(false);
5997
+ } catch (error) {
5998
+ setSubmitError(error instanceof Error ? error.message : "Could not create the thread");
5999
+ }
5148
6000
  },
5149
6001
  children: [
5150
6002
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-6 pb-4", children: [
@@ -5186,6 +6038,7 @@ function NewThreadDialog({
5186
6038
  items: { shared: values.shared },
5187
6039
  onToggle: (share) => set("shared", share),
5188
6040
  label: l.visibility,
6041
+ presentation: "select",
5189
6042
  "data-testid": `${id}-visibility`
5190
6043
  }
5191
6044
  ) }),
@@ -5281,6 +6134,7 @@ function NewThreadDialog({
5281
6134
  ] })
5282
6135
  ] })
5283
6136
  ] }),
6137
+ submitError && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "px-6 pb-2 text-sm text-destructive", children: submitError }),
5284
6138
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col-reverse gap-2 border-t border-border px-6 py-3 sm:flex-row sm:justify-end", children: [
5285
6139
  /* @__PURE__ */ jsxRuntime.jsx(
5286
6140
  ui.Button,
@@ -5317,18 +6171,18 @@ function NewThreadDialog({
5317
6171
  var DEFAULT_TASK_TRIGGER_CHIP_LABELS = {
5318
6172
  after: (name) => `After \u201C${name}\u201D is done`,
5319
6173
  afterUnknown: "After another task is done",
5320
- onDemand: "On demand"
6174
+ onDemand: "Manual"
5321
6175
  };
5322
6176
  function TriggerIcon({ type, chained }) {
5323
- const cls = "size-3.5 shrink-0";
6177
+ const cls = "size-3.5 shrink-0 text-muted-foreground";
5324
6178
  if (chained) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: cls, "aria-hidden": true });
5325
6179
  switch (type) {
5326
6180
  case "on_demand":
5327
6181
  return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MousePointerClick, { className: cls, "aria-hidden": true });
5328
6182
  case "recurring":
5329
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Repeat, { className: cls, "aria-hidden": true });
6183
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: cls, "aria-hidden": true });
5330
6184
  case "event":
5331
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Zap, { className: cls, "aria-hidden": true });
6185
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bell, { className: cls, "aria-hidden": true });
5332
6186
  default:
5333
6187
  return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: cls, "aria-hidden": true });
5334
6188
  }
@@ -5348,7 +6202,7 @@ function TaskTriggerChip({
5348
6202
  return /* @__PURE__ */ jsxRuntime.jsxs(
5349
6203
  "span",
5350
6204
  {
5351
- className: "inline-flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground",
6205
+ className: "inline-flex min-w-0 max-w-full items-center gap-1.5 text-sm font-normal text-foreground",
5352
6206
  "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: `task-trigger-${id}` }),
5353
6207
  "data-trigger": chained ? "task" : triggerType,
5354
6208
  children: [
@@ -5374,12 +6228,24 @@ function workflowTriggerType(workflow) {
5374
6228
  if (workflow.run_at) return "one_time";
5375
6229
  return "on_demand";
5376
6230
  }
6231
+ function workflowRunStatusLabel(status) {
6232
+ if (!status) return "None";
6233
+ const labels = {
6234
+ completed: "Success",
6235
+ success: "Success",
6236
+ failed: "Failed",
6237
+ running: "In progress",
6238
+ awaiting_authorization: "Awaiting access"
6239
+ };
6240
+ return labels[status] ?? status.replaceAll("_", " ");
6241
+ }
5377
6242
 
5378
6243
  // src/agents/tasks/workflowColumns.tsx
5379
6244
  var WORKFLOW_COLUMN_ORDER = [
5380
6245
  "name",
5381
6246
  "trigger",
5382
6247
  "last_run",
6248
+ "result",
5383
6249
  "status",
5384
6250
  "shared",
5385
6251
  "actions"
@@ -5392,7 +6258,6 @@ function createWorkflowColumns(o) {
5392
6258
  const l = o.labels;
5393
6259
  const base = {
5394
6260
  sortable: false,
5395
- suppressMovable: true,
5396
6261
  cellStyle: { display: "flex", alignItems: "center" }
5397
6262
  };
5398
6263
  return [
@@ -5402,7 +6267,7 @@ function createWorkflowColumns(o) {
5402
6267
  sortable: true,
5403
6268
  headerName: l.colName,
5404
6269
  flex: 3,
5405
- minWidth: 250,
6270
+ minWidth: 210,
5406
6271
  valueGetter: (p) => p.data?.name.toLowerCase() ?? "",
5407
6272
  cellRenderer: cell2(o.renderName)
5408
6273
  },
@@ -5411,7 +6276,7 @@ function createWorkflowColumns(o) {
5411
6276
  colId: "trigger",
5412
6277
  headerName: l.colTrigger,
5413
6278
  flex: 2.4,
5414
- minWidth: 220,
6279
+ minWidth: 185,
5415
6280
  valueGetter: (p) => p.data ? o.getTriggerText(p.data) : "",
5416
6281
  cellRenderer: cell2(o.renderTrigger)
5417
6282
  },
@@ -5421,16 +6286,26 @@ function createWorkflowColumns(o) {
5421
6286
  sortable: true,
5422
6287
  headerName: l.colLastRun,
5423
6288
  flex: 1.4,
5424
- minWidth: 190,
6289
+ minWidth: 140,
6290
+ cellStyle: { display: "flex", alignItems: "center", padding: 0 },
5425
6291
  valueGetter: (p) => time(p.data?.last_fired_at),
5426
6292
  cellRenderer: cell2(o.renderLastRun)
5427
6293
  },
6294
+ {
6295
+ ...base,
6296
+ colId: "result",
6297
+ headerName: "Result",
6298
+ width: 130,
6299
+ valueGetter: (p) => p.data?.last_run_status ?? "",
6300
+ cellStyle: { display: "flex", alignItems: "center", padding: 0 },
6301
+ cellRenderer: cell2(o.renderResult)
6302
+ },
5428
6303
  {
5429
6304
  ...base,
5430
6305
  colId: "status",
5431
6306
  sortable: true,
5432
6307
  headerName: l.colStatus,
5433
- width: 140,
6308
+ width: 120,
5434
6309
  valueGetter: (p) => p.data ? workflowStatus(p.data) : "",
5435
6310
  cellRenderer: cell2(o.renderStatus)
5436
6311
  },
@@ -5448,10 +6323,8 @@ function createWorkflowColumns(o) {
5448
6323
  ...base,
5449
6324
  colId: "actions",
5450
6325
  headerName: "",
5451
- // Always in view, even if the rest has to scroll.
5452
- pinned: "right",
5453
- lockPinned: true,
5454
- width: 140,
6326
+ width: 180,
6327
+ minWidth: 180,
5455
6328
  cellStyle: { display: "flex", alignItems: "center", justifyContent: "flex-end" },
5456
6329
  cellRenderer: cell2(o.renderActions)
5457
6330
  }
@@ -5465,7 +6338,7 @@ var DEFAULT_WORKFLOW_LIST_LABELS = {
5465
6338
  colTrigger: "When",
5466
6339
  colAction: "What it does",
5467
6340
  colAgent: "Agent",
5468
- colStatus: "Status",
6341
+ colStatus: "Active",
5469
6342
  colShared: "Shared",
5470
6343
  colLastRun: "Last run",
5471
6344
  colNextRun: "Next run",
@@ -5475,7 +6348,7 @@ var DEFAULT_WORKFLOW_LIST_LABELS = {
5475
6348
  typeSkill: "Skill",
5476
6349
  typeWorkflow: "Workflow",
5477
6350
  statusActive: "Active",
5478
- statusPaused: "Paused",
6351
+ statusPaused: "Inactive",
5479
6352
  statusOnDemand: "On demand",
5480
6353
  activeSwitch: (name) => `Active: \u201C${name}\u201D`,
5481
6354
  agent: "Agent",
@@ -5505,17 +6378,18 @@ var DEFAULT_WORKFLOW_LIST_LABELS = {
5505
6378
  filterSkills: "Skills",
5506
6379
  filterWorkflows: "Workflows",
5507
6380
  filterActive: "Active",
5508
- filterPaused: "Paused",
6381
+ filterPaused: "Inactive",
5509
6382
  makeActive: "Make active",
5510
- makePaused: "Pause",
6383
+ makePaused: "Deactivate",
5511
6384
  selectAll: "Select all",
5512
6385
  selectWorkflow: (name) => `Select ${name}`
5513
6386
  };
5514
- var ROW_HEIGHT2 = 56;
6387
+ var ROW_HEIGHT2 = 40;
5515
6388
  function WorkflowsTable(props) {
5516
6389
  const { workflows, isLoading, busyId, header, testId } = props;
5517
6390
  const l = { ...DEFAULT_WORKFLOW_LIST_LABELS, ...props.labels };
5518
- const [filter, setFilter] = react.useState("all");
6391
+ const [filterStates, setFilterStates] = react.useState(/* @__PURE__ */ new Map());
6392
+ const [filterOpen, setFilterOpen] = react.useState(false);
5519
6393
  const [query, setQuery] = react.useState("");
5520
6394
  const [selected, setSelected] = react.useState([]);
5521
6395
  const apiRef = react.useRef(null);
@@ -5531,12 +6405,24 @@ function WorkflowsTable(props) {
5531
6405
  return out;
5532
6406
  }, [workflows, q]);
5533
6407
  const shown = react.useMemo(
5534
- () => workflows.filter((w) => matches(w) && inFilter(w, filter)),
5535
- // eslint-disable-next-line react-hooks/exhaustive-deps
5536
- [workflows, filter, q]
6408
+ () => workflows.filter((w) => {
6409
+ if (!matches(w)) return false;
6410
+ for (const group of [
6411
+ ["skills", "workflows"],
6412
+ ["active", "paused"]
6413
+ ]) {
6414
+ const included = group.filter((f) => filterStates.get(f) === "include");
6415
+ if (included.length && !included.some((f) => inFilter(w, f))) return false;
6416
+ if (group.some((f) => filterStates.get(f) === "exclude" && inFilter(w, f))) return false;
6417
+ }
6418
+ return true;
6419
+ }),
6420
+ [workflows, filterStates, q]
5537
6421
  );
5538
6422
  const renderPerson = props.renderPerson ?? ((p) => /* @__PURE__ */ jsxRuntime.jsx(PersonPill, { person: p }));
5539
6423
  const actionText = (w) => {
6424
+ if (w.action)
6425
+ return w.action.type === "email_documents" ? "Email latest documents" : "AI Review";
5540
6426
  if (isSkillRow(w))
5541
6427
  return w.description || w.skill_ref && props.skillNames?.[w.skill_ref] || w.name;
5542
6428
  return w.skill_ref ? props.skillNames?.[w.skill_ref] ?? w.skill_ref : w.prompt?.trim() || l.reminder;
@@ -5559,7 +6445,7 @@ function WorkflowsTable(props) {
5559
6445
  "span",
5560
6446
  {
5561
6447
  className: ui.cn(
5562
- "truncate text-sm font-medium",
6448
+ "truncate text-sm font-normal",
5563
6449
  workflowStatus(w) === "paused" && "text-muted-foreground"
5564
6450
  ),
5565
6451
  "data-testid": `workflow-name-${w.external_id}`,
@@ -5575,7 +6461,7 @@ function WorkflowsTable(props) {
5575
6461
  }
5576
6462
  )
5577
6463
  ] }),
5578
- about && /* @__PURE__ */ jsxRuntime.jsx(
6464
+ about && !latest.current.props.automationsOnly && /* @__PURE__ */ jsxRuntime.jsx(
5579
6465
  "p",
5580
6466
  {
5581
6467
  className: "truncate text-xs text-muted-foreground",
@@ -5586,62 +6472,36 @@ function WorkflowsTable(props) {
5586
6472
  ] });
5587
6473
  },
5588
6474
  renderTrigger: (w) => {
5589
- const { props: p, l: lb } = latest.current;
6475
+ const { props: p } = latest.current;
5590
6476
  const after = w.after_conversation_ext_id;
5591
6477
  const skill = isSkillRow(w);
5592
- const next = !skill && w.active && hasTrigger(w) && !w.run_at && w.next_fire_at ? p.formatDate(w.next_fire_at) : "";
5593
- const agentId = w.agent_ext_id;
5594
- const agent = skill ? "" : agentId ? p.agentNames?.[agentId] || lb.agent : lb.myAssistant;
5595
- const detail = [next && `${lb.colNextRun}: ${next}`, agent].filter(Boolean).join(" \xB7 ");
5596
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 leading-tight", children: [
5597
- /* @__PURE__ */ jsxRuntime.jsx(
5598
- TaskTriggerChip,
5599
- {
5600
- id: w.external_id,
5601
- testId: `workflow-trigger-${w.external_id}`,
5602
- triggerType: workflowTriggerType(w),
5603
- summary: skill ? "" : p.describeTrigger(w),
5604
- afterTaskId: after,
5605
- afterTaskName: after ? p.taskNames?.[after] : void 0,
5606
- labels: p.triggerChipLabels
5607
- }
5608
- ),
5609
- detail && /* @__PURE__ */ jsxRuntime.jsx(
5610
- "p",
5611
- {
5612
- className: "truncate text-xs text-muted-foreground",
5613
- "data-testid": `workflow-next-run-${w.external_id}`,
5614
- children: detail
5615
- }
5616
- )
5617
- ] });
6478
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 leading-tight", children: /* @__PURE__ */ jsxRuntime.jsx(
6479
+ TaskTriggerChip,
6480
+ {
6481
+ id: w.external_id,
6482
+ testId: `workflow-trigger-${w.external_id}`,
6483
+ triggerType: workflowTriggerType(w),
6484
+ summary: skill ? "" : p.describeTrigger(w),
6485
+ afterTaskId: after,
6486
+ afterTaskName: after ? p.taskNames?.[after] : void 0,
6487
+ labels: p.triggerChipLabels
6488
+ }
6489
+ ) });
5618
6490
  },
5619
6491
  renderStatus: (w) => {
5620
6492
  const { props: p, l: lb } = latest.current;
5621
- const status = workflowStatus(w);
5622
- if (status === "on_demand") return null;
5623
6493
  const canEdit = w.is_owner !== false || Boolean(p.canEditShared);
5624
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [
5625
- /* @__PURE__ */ jsxRuntime.jsx(
5626
- ui.Switch,
5627
- {
5628
- checked: status === "active",
5629
- disabled: !canEdit || p.busyId === w.external_id,
5630
- onCheckedChange: (next) => p.onToggleActive(w, next),
5631
- "aria-label": lb.activeSwitch(w.name),
5632
- "data-testid": `workflow-active-${w.external_id}`
5633
- }
5634
- ),
5635
- /* @__PURE__ */ jsxRuntime.jsx(
5636
- "span",
5637
- {
5638
- className: "text-sm text-muted-foreground",
5639
- "data-testid": `workflow-status-${w.external_id}`,
5640
- "data-status": status,
5641
- children: status === "active" ? lb.statusActive : lb.statusPaused
5642
- }
5643
- )
5644
- ] });
6494
+ return /* @__PURE__ */ jsxRuntime.jsx(
6495
+ ui.Switch,
6496
+ {
6497
+ checked: hasTrigger(w) && !isSkillRow(w) && Boolean(w.active),
6498
+ disabled: !hasTrigger(w) || isSkillRow(w) || !canEdit || p.busyId === w.external_id,
6499
+ onCheckedChange: (next) => p.onToggleActive(w, next),
6500
+ className: "disabled:data-[state=unchecked]:bg-muted dark:disabled:data-[state=unchecked]:bg-muted",
6501
+ "aria-label": lb.activeSwitch(w.name),
6502
+ "data-testid": `workflow-active-${w.external_id}`
6503
+ }
6504
+ );
5645
6505
  },
5646
6506
  renderShared: (w) => {
5647
6507
  const { props: p, l: lb } = latest.current;
@@ -5661,41 +6521,37 @@ function WorkflowsTable(props) {
5661
6521
  },
5662
6522
  renderLastRun: (w) => {
5663
6523
  const { props: p, l: lb } = latest.current;
5664
- if (isSkillRow(w)) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: lb.none });
5665
- const last = p.lastRuns?.[w.external_id];
5666
- const at = w.last_fired_at ?? last?.at;
5667
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
5668
- last && at ? /* @__PURE__ */ jsxRuntime.jsx(
5669
- "button",
5670
- {
5671
- type: "button",
5672
- onClick: () => p.onOpenThread?.(last.conversationId),
5673
- title: lb.openLastRun,
5674
- className: "truncate text-sm text-primary hover:underline focus-visible:underline focus-visible:outline-none",
5675
- "data-testid": `workflow-last-run-${w.external_id}`,
5676
- children: p.formatDate(at)
5677
- }
5678
- ) : /* @__PURE__ */ jsxRuntime.jsx(
5679
- "span",
5680
- {
5681
- className: "truncate text-sm text-muted-foreground",
5682
- "data-testid": `workflow-last-run-${w.external_id}`,
5683
- children: at ? p.formatDate(at) : lb.never
5684
- }
5685
- ),
5686
- w.last_error && /* @__PURE__ */ jsxRuntime.jsxs(
5687
- "span",
5688
- {
5689
- className: "inline-flex shrink-0 items-center gap-1 text-xs text-red-text",
5690
- title: `${lb.lastRunFailed}: ${w.last_error}`,
5691
- "data-testid": `workflow-error-${w.external_id}`,
5692
- children: [
5693
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "size-3.5", "aria-hidden": true }),
5694
- lb.failed
5695
- ]
5696
- }
5697
- )
5698
- ] });
6524
+ const at = w.last_fired_at ?? p.lastRuns?.[w.external_id]?.at;
6525
+ return /* @__PURE__ */ jsxRuntime.jsx(
6526
+ "button",
6527
+ {
6528
+ type: "button",
6529
+ className: "h-full w-full truncate px-4 text-left text-sm hover:text-primary",
6530
+ onClick: () => p.onViewRuns?.(w),
6531
+ title: "View run history",
6532
+ "data-testid": `workflow-last-run-${w.external_id}`,
6533
+ children: at ? p.formatDate(at) : lb.never
6534
+ }
6535
+ );
6536
+ },
6537
+ renderResult: (w) => {
6538
+ const status = w.last_run_status;
6539
+ const label = workflowRunStatusLabel(status);
6540
+ return /* @__PURE__ */ jsxRuntime.jsx(
6541
+ "button",
6542
+ {
6543
+ type: "button",
6544
+ onClick: () => latest.current.props.onViewRuns?.(w),
6545
+ title: "View run history",
6546
+ className: ui.cn(
6547
+ ui.badgeVariants({ variant: "outline" }),
6548
+ "mx-4 cursor-pointer text-xs font-medium",
6549
+ status === "failed" ? "border-red-border bg-red-bg text-red-text hover:bg-red-bg/80" : status === "completed" || status === "success" ? "border-green-border bg-green-bg text-green-text hover:bg-green-bg/80" : status ? "border-primary/20 bg-primary/10 text-primary hover:bg-primary/15" : "border-border bg-muted text-muted-foreground hover:bg-muted/80"
6550
+ ),
6551
+ "data-testid": `workflow-result-${w.external_id}`,
6552
+ children: label
6553
+ }
6554
+ );
5699
6555
  },
5700
6556
  renderActions: (w) => {
5701
6557
  const { props: p, l: lb } = latest.current;
@@ -5823,61 +6679,73 @@ function WorkflowsTable(props) {
5823
6679
  (w) => hasTrigger(w) && (w.is_owner !== false || props.canEditShared)
5824
6680
  );
5825
6681
  const clearSelection = () => setSelected([]);
5826
- const hasSavedWorkflow = workflows.some((w) => !isSkillRow(w));
5827
6682
  return /* @__PURE__ */ jsxRuntime.jsxs(
5828
6683
  "div",
5829
6684
  {
5830
- className: "flex min-h-0 flex-1 flex-col gap-3",
6685
+ className: "flex min-h-0 flex-1 flex-col",
5831
6686
  "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "workflow-list" }),
5832
6687
  children: [
5833
- header,
5834
- !isLoading && !hasSavedWorkflow && workflows.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", "data-testid": "workflow-first-run", children: l.firstRun }),
5835
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
5836
- /* @__PURE__ */ jsxRuntime.jsx("div", { role: "tablist", "aria-label": "Filter workflows", className: "flex flex-wrap gap-1.5", children: [
5837
- ["all", l.filterAll],
5838
- ["skills", l.filterSkills],
5839
- ["workflows", l.filterWorkflows],
5840
- ["active", l.filterActive],
5841
- ["paused", l.filterPaused]
5842
- ].map(([key, label]) => {
5843
- const isSelected = filter === key;
5844
- return /* @__PURE__ */ jsxRuntime.jsxs(
5845
- "button",
6688
+ /* @__PURE__ */ jsxRuntime.jsx(
6689
+ chunk6DNYPLCD_cjs.TabHeader,
6690
+ {
6691
+ testId: "automations-tab-header",
6692
+ tabs: [
5846
6693
  {
5847
- type: "button",
5848
- role: "tab",
5849
- "aria-selected": isSelected,
5850
- onClick: () => setFilter(key),
5851
- className: ui.cn(
5852
- "inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
5853
- isSelected ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground hover:bg-accent"
5854
- ),
5855
- "data-testid": `workflow-filter-${key}`,
5856
- children: [
5857
- label,
5858
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums opacity-70", children: counts[key] })
5859
- ]
6694
+ id: "automations",
6695
+ label: "",
6696
+ count: shown.length,
6697
+ countIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "size-3.5" }),
6698
+ countPlacement: "leading",
6699
+ presentation: "count",
6700
+ hasActiveFilters: !!q || [...filterStates.values()].some(Boolean)
5860
6701
  },
5861
- key
5862
- );
5863
- }) }),
5864
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
5865
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" }),
5866
- /* @__PURE__ */ jsxRuntime.jsx(
5867
- ui.Input,
6702
+ ...props.tabs ?? []
6703
+ ],
6704
+ activeTabId: props.activeTabId ?? "automations",
6705
+ onTabChange: props.onTabChange ?? (() => {
6706
+ }),
6707
+ firstTabContent: /* @__PURE__ */ jsxRuntime.jsx(
6708
+ chunkMZL67U2E_cjs.FilterInput,
5868
6709
  {
5869
- type: "search",
5870
6710
  value: query,
5871
- onChange: (e) => setQuery(e.target.value),
5872
- placeholder: l.searchPlaceholder,
5873
- "aria-label": l.searchLabel,
5874
- className: "h-8 w-56 pl-8 text-xs pointer-coarse:h-11",
5875
- "data-testid": "workflow-search"
6711
+ onChange: setQuery,
6712
+ fields: ["text"],
6713
+ onFieldsChange: () => {
6714
+ },
6715
+ hideFieldPicker: true,
6716
+ ariaLabel: l.searchLabel,
6717
+ testIds: { input: "workflow-search" },
6718
+ filter: /* @__PURE__ */ jsxRuntime.jsx(
6719
+ chunk2QTT2RZE_cjs.TriStateFilterMenu,
6720
+ {
6721
+ testId: "automations-filter-button",
6722
+ open: filterOpen,
6723
+ onOpenChange: setFilterOpen,
6724
+ filterStates,
6725
+ onFiltersChange: setFilterStates,
6726
+ triggerClassName: "flex h-5 items-center gap-0.5 rounded px-1 text-muted-foreground hover:text-foreground pointer-coarse:h-11! pointer-coarse:min-w-11 pointer-coarse:justify-center",
6727
+ renderChevron: true,
6728
+ disableHoverOpen: true,
6729
+ options: [
6730
+ ...!props.automationsOnly ? [
6731
+ { id: "skills", label: l.filterSkills, count: counts.skills },
6732
+ {
6733
+ id: "workflows",
6734
+ label: l.filterWorkflows,
6735
+ count: counts.workflows
6736
+ }
6737
+ ] : [],
6738
+ { id: "active", label: l.filterActive, count: counts.active },
6739
+ { id: "paused", label: l.filterPaused, count: counts.paused }
6740
+ ]
6741
+ }
6742
+ )
5876
6743
  }
5877
- )
5878
- ] })
5879
- ] }),
5880
- workflows.length === 0 && !isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
6744
+ ),
6745
+ rightContent: header
6746
+ }
6747
+ ),
6748
+ props.content ? props.content : workflows.length === 0 && !isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
5881
6749
  chunkZW6FPIFC_cjs.EmptyState,
5882
6750
  {
5883
6751
  icon: lucideReact.Workflow,
@@ -5886,7 +6754,7 @@ function WorkflowsTable(props) {
5886
6754
  testId: "workflow-list-empty"
5887
6755
  }
5888
6756
  ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
5889
- chunkJGZTRLKL_cjs.GridView,
6757
+ chunkIA7RTPT3_cjs.GridView,
5890
6758
  {
5891
6759
  testId: "workflow-grid",
5892
6760
  gridId: props.gridId ?? "workflows-grid-v2",
@@ -5907,10 +6775,10 @@ function WorkflowsTable(props) {
5907
6775
  gridOptions: GRID_OPTIONS
5908
6776
  }
5909
6777
  ) }),
5910
- /* @__PURE__ */ jsxRuntime.jsx(chunkJGZTRLKL_cjs.SelectionBar, { count: selected.length, onClear: clearSelection, children: (isCompact) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6778
+ !props.content && /* @__PURE__ */ jsxRuntime.jsx(chunkIA7RTPT3_cjs.SelectionBar, { count: selected.length, onClear: clearSelection, children: (isCompact) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5911
6779
  props.onToggleActiveMany && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5912
6780
  /* @__PURE__ */ jsxRuntime.jsx(
5913
- chunkJGZTRLKL_cjs.SelectionBarAction,
6781
+ chunkIA7RTPT3_cjs.SelectionBarAction,
5914
6782
  {
5915
6783
  icon: lucideReact.Play,
5916
6784
  label: l.makeActive,
@@ -5924,7 +6792,7 @@ function WorkflowsTable(props) {
5924
6792
  }
5925
6793
  ),
5926
6794
  /* @__PURE__ */ jsxRuntime.jsx(
5927
- chunkJGZTRLKL_cjs.SelectionBarAction,
6795
+ chunkIA7RTPT3_cjs.SelectionBarAction,
5928
6796
  {
5929
6797
  icon: lucideReact.Workflow,
5930
6798
  label: l.makePaused,
@@ -5939,7 +6807,7 @@ function WorkflowsTable(props) {
5939
6807
  )
5940
6808
  ] }),
5941
6809
  props.onDeleteMany && /* @__PURE__ */ jsxRuntime.jsx(
5942
- chunkJGZTRLKL_cjs.SelectionBarAction,
6810
+ chunkIA7RTPT3_cjs.SelectionBarAction,
5943
6811
  {
5944
6812
  icon: lucideReact.Trash2,
5945
6813
  label: l.delete,
@@ -5958,16 +6826,7 @@ function WorkflowsTable(props) {
5958
6826
  }
5959
6827
  );
5960
6828
  }
5961
- var WIDTH_RULES2 = [
5962
- { colId: "shared", minWidth: 1060 },
5963
- { colId: "last_run", minWidth: 880 }
5964
- ];
5965
- var GRID_OPTIONS = {
5966
- suppressClickEdit: true,
5967
- suppressCellFocus: true,
5968
- suppressColumnVirtualisation: true,
5969
- onGridSizeChanged: (event) => applyColumnWidthRules(event.api, event.clientWidth, WIDTH_RULES2)
5970
- };
6829
+ var GRID_OPTIONS = { suppressClickEdit: true };
5971
6830
  var DEFAULT_TASK_ACTIVITY_LABELS = {
5972
6831
  title: "Activity",
5973
6832
  empty: "Nothing has happened yet.",
@@ -5997,11 +6856,19 @@ var ICONS = {
5997
6856
  awaiting_access: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { className: "size-3.5", "aria-hidden": true }),
5998
6857
  access_granted: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.KeyRound, { className: "size-3.5", "aria-hidden": true }),
5999
6858
  ready_for_review: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleDot, { className: "size-3.5", "aria-hidden": true }),
6859
+ reviewed: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "size-3.5", "aria-hidden": true }),
6000
6860
  handed_off: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserRoundCog, { className: "size-3.5", "aria-hidden": true }),
6001
6861
  changes_requested: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquareReply, { className: "size-3.5", "aria-hidden": true }),
6002
6862
  done: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "size-3.5", "aria-hidden": true }),
6003
6863
  reopened: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "size-3.5", "aria-hidden": true }),
6004
- failed: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "size-3.5", "aria-hidden": true })
6864
+ failed: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "size-3.5", "aria-hidden": true }),
6865
+ participant_joined: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserRoundCog, { className: "size-3.5", "aria-hidden": true }),
6866
+ assistant_responded: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "size-3.5", "aria-hidden": true }),
6867
+ artifact_created: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "size-3.5", "aria-hidden": true }),
6868
+ artifact_edited: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquareReply, { className: "size-3.5", "aria-hidden": true }),
6869
+ document_added: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "size-3.5", "aria-hidden": true }),
6870
+ document_removed: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "size-3.5", "aria-hidden": true }),
6871
+ notified: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserRoundCog, { className: "size-3.5", "aria-hidden": true })
6005
6872
  };
6006
6873
  var asString = (v) => typeof v === "string" && v.trim() ? v : null;
6007
6874
  function summarizeError(error) {
@@ -6025,6 +6892,20 @@ function TaskActivityTimeline({
6025
6892
  const agentId = asString(detail.agent_ext_id);
6026
6893
  const agent = agentId ? agentName?.(agentId) : void 0;
6027
6894
  switch (e.kind) {
6895
+ case "participant_joined":
6896
+ return { headline: "Joined the conversation" };
6897
+ case "assistant_responded":
6898
+ return { headline: "Responded" };
6899
+ case "artifact_created":
6900
+ return { headline: "Created a document" };
6901
+ case "artifact_edited":
6902
+ return { headline: "Edited a document" };
6903
+ case "document_added":
6904
+ return { headline: "Added a document" };
6905
+ case "document_removed":
6906
+ return { headline: "Removed a document" };
6907
+ case "notified":
6908
+ return { headline: "Sent a notification" };
6028
6909
  case "created":
6029
6910
  return { headline: detail.from_workflow ? l.createdFromWorkflow : l.created };
6030
6911
  case "run_started":
@@ -6035,6 +6916,8 @@ function TaskActivityTimeline({
6035
6916
  return { headline: l.accessGranted };
6036
6917
  case "ready_for_review":
6037
6918
  return { headline: l.readyForReview };
6919
+ case "reviewed":
6920
+ return { headline: "Approved this review stage" };
6038
6921
  case "handed_off":
6039
6922
  return {
6040
6923
  headline: l.handedOff,
@@ -6046,7 +6929,7 @@ function TaskActivityTimeline({
6046
6929
  extra: note ? /* @__PURE__ */ jsxRuntime.jsx(Quote, { text: l.sentBackNote(note) }) : void 0
6047
6930
  };
6048
6931
  case "done":
6049
- return { headline: l.done };
6932
+ return { headline: l.done, extra: note ? /* @__PURE__ */ jsxRuntime.jsx(Quote, { text: note }) : void 0 };
6050
6933
  case "reopened":
6051
6934
  return { headline: l.reopened };
6052
6935
  case "failed": {
@@ -6114,39 +6997,189 @@ function TaskActivityTimeline({
6114
6997
  );
6115
6998
  }) });
6116
6999
  }
6117
- function Quote({ text }) {
6118
- return /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: "border-l-2 pl-2 text-xs text-muted-foreground whitespace-pre-wrap", children: text });
7000
+ function Quote({ text }) {
7001
+ return /* @__PURE__ */ jsxRuntime.jsx("blockquote", { className: "border-l-2 pl-2 text-xs text-muted-foreground whitespace-pre-wrap", children: text });
7002
+ }
7003
+ function TaskActivityDialog({
7004
+ open,
7005
+ onOpenChange,
7006
+ taskName,
7007
+ events,
7008
+ isLoading,
7009
+ isError,
7010
+ labels,
7011
+ testId,
7012
+ ...timeline
7013
+ }) {
7014
+ const l = { ...DEFAULT_TASK_ACTIVITY_LABELS, ...labels };
7015
+ const id = chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "task-activity" });
7016
+ const count = events?.length ?? 0;
7017
+ const scrollToEnd = react.useCallback(
7018
+ (el) => {
7019
+ if (count >= 0) el?.scrollIntoView?.({ block: "end" });
7020
+ },
7021
+ [count]
7022
+ );
7023
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { presentation: "sheet", className: "max-h-[80dvh] sm:max-w-lg", "data-testid": id, children: [
7024
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
7025
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: l.title }),
7026
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { className: "truncate", children: taskName })
7027
+ ] }),
7028
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[55dvh] overflow-y-auto pr-1", "data-testid": `${id}-scroll`, children: [
7029
+ isLoading && !events ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: l.loading }) : isError && !events ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: l.error }) : count === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: l.empty }) : /* @__PURE__ */ jsxRuntime.jsx(TaskActivityTimeline, { events: events ?? [], labels, testId: id, ...timeline }),
7030
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollToEnd })
7031
+ ] })
7032
+ ] }) });
7033
+ }
7034
+ function TaskFlow({
7035
+ items,
7036
+ className
7037
+ }) {
7038
+ const scroll = react.useRef(null);
7039
+ const following = react.useRef(true);
7040
+ const latest = items.at(-1)?.id;
7041
+ react.useLayoutEffect(() => {
7042
+ const el = scroll.current;
7043
+ if (!el) return;
7044
+ const follow = () => {
7045
+ if (following.current) el.scrollLeft = el.scrollWidth;
7046
+ };
7047
+ follow();
7048
+ const resize = new ResizeObserver(follow);
7049
+ resize.observe(el);
7050
+ return () => resize.disconnect();
7051
+ }, [latest]);
7052
+ return /* @__PURE__ */ jsxRuntime.jsx(
7053
+ "div",
7054
+ {
7055
+ ref: scroll,
7056
+ className: ui.cn("min-w-0 flex-1 overflow-x-auto overscroll-x-contain", className),
7057
+ "data-testid": "thread-flow",
7058
+ role: "region",
7059
+ "aria-label": "Thread activity",
7060
+ tabIndex: 0,
7061
+ onScroll: (e) => {
7062
+ const el = e.currentTarget;
7063
+ following.current = el.scrollWidth - el.scrollLeft - el.clientWidth < 24;
7064
+ },
7065
+ children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex w-max min-w-full items-center gap-1", children: items.map((item, i) => {
7066
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7067
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: item.avatar }),
7068
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 text-left", children: [
7069
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block max-w-32 truncate text-[11px] leading-tight font-medium", children: item.label }),
7070
+ /* @__PURE__ */ jsxRuntime.jsx(
7071
+ "span",
7072
+ {
7073
+ className: "block text-[10px] leading-tight text-muted-foreground",
7074
+ title: item.exactTime,
7075
+ children: item.time
7076
+ }
7077
+ )
7078
+ ] })
7079
+ ] });
7080
+ const cls = ui.cn(
7081
+ "flex shrink-0 items-center gap-1.5 rounded-md px-1 py-0.5",
7082
+ item.current && "bg-accent text-accent-foreground"
7083
+ );
7084
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7085
+ "li",
7086
+ {
7087
+ className: "flex shrink-0 items-center gap-1",
7088
+ "data-testid": `thread-flow-${item.id}`,
7089
+ children: [
7090
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-3 shrink-0 text-muted-foreground", "aria-hidden": true }),
7091
+ item.onSelect ? /* @__PURE__ */ jsxRuntime.jsx(
7092
+ "button",
7093
+ {
7094
+ className: ui.cn(cls, "hover:bg-muted"),
7095
+ onClick: item.onSelect,
7096
+ title: item.description ?? item.label,
7097
+ children: content
7098
+ }
7099
+ ) : item.detail ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Popover, { children: [
7100
+ /* @__PURE__ */ jsxRuntime.jsx(ui.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
7101
+ "button",
7102
+ {
7103
+ className: ui.cn(cls, "hover:bg-muted"),
7104
+ title: item.description ?? item.label,
7105
+ children: content
7106
+ }
7107
+ ) }),
7108
+ /* @__PURE__ */ jsxRuntime.jsx(ui.PopoverContent, { className: "max-h-72 overflow-y-auto text-sm whitespace-pre-wrap", children: item.detail })
7109
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls, title: item.description ?? item.label, children: content })
7110
+ ]
7111
+ },
7112
+ item.id
7113
+ );
7114
+ }) })
7115
+ }
7116
+ );
7117
+ }
7118
+ function ThreadActivity({ item, children }) {
7119
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center px-3 py-2", "data-testid": `thread-activity-${item.id}`, children: /* @__PURE__ */ jsxRuntime.jsxs(
7120
+ "div",
7121
+ {
7122
+ className: "max-w-full text-center text-xs text-muted-foreground",
7123
+ title: item.description,
7124
+ children: [
7125
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-1.5", children: [
7126
+ item.avatar,
7127
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label }),
7128
+ /* @__PURE__ */ jsxRuntime.jsx("time", { title: item.exactTime, children: item.time })
7129
+ ] }),
7130
+ children,
7131
+ item.detail && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 whitespace-pre-wrap break-words text-left", children: item.detail })
7132
+ ]
7133
+ }
7134
+ ) });
6119
7135
  }
6120
- function TaskActivityDialog({
6121
- open,
6122
- onOpenChange,
6123
- taskName,
6124
- events,
6125
- isLoading,
6126
- isError,
6127
- labels,
6128
- testId,
6129
- ...timeline
6130
- }) {
6131
- const l = { ...DEFAULT_TASK_ACTIVITY_LABELS, ...labels };
6132
- const id = chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "task-activity" });
6133
- const count = events?.length ?? 0;
6134
- const scrollToEnd = react.useCallback(
6135
- (el) => {
6136
- if (count >= 0) el?.scrollIntoView?.({ block: "end" });
6137
- },
6138
- [count]
6139
- );
6140
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { presentation: "sheet", className: "max-h-[80dvh] sm:max-w-lg", "data-testid": id, children: [
6141
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
6142
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: l.title }),
6143
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { className: "truncate", children: taskName })
6144
- ] }),
6145
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-[55dvh] overflow-y-auto pr-1", "data-testid": `${id}-scroll`, children: [
6146
- isLoading && !events ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: l.loading }) : isError && !events ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: l.error }) : count === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: l.empty }) : /* @__PURE__ */ jsxRuntime.jsx(TaskActivityTimeline, { events: events ?? [], labels, testId: id, ...timeline }),
6147
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollToEnd })
6148
- ] })
6149
- ] }) });
7136
+
7137
+ // src/agents/tasks/compact-thread-activity.ts
7138
+ function compactThreadActivity(events) {
7139
+ const result = [];
7140
+ const batches = /* @__PURE__ */ new Map();
7141
+ for (const event of events) {
7142
+ if (event.kind === "notified") {
7143
+ if (["conversation_ready_for_review", "conversation_done"].includes(
7144
+ String(event.detail?.notification_type)
7145
+ ))
7146
+ continue;
7147
+ const source = event.detail?.batch_ext_id ?? event.detail?.message_ext_id;
7148
+ const key = typeof source === "string" && source ? `${event.actor_ext_id}:${source}` : event.external_id;
7149
+ let entry = batches.get(key);
7150
+ if (!entry) {
7151
+ entry = { event, label: "Notified 1 user", recipients: [] };
7152
+ batches.set(key, entry);
7153
+ result.push(entry);
7154
+ }
7155
+ if (event.to_ext_id && !entry.recipients.includes(event.to_ext_id))
7156
+ entry.recipients.push(event.to_ext_id);
7157
+ const count = Math.max(1, entry.recipients.length);
7158
+ entry.label = `Notified ${count} ${count === 1 ? "user" : "users"}`;
7159
+ } else if (["artifact_created", "artifact_edited", "document_added", "document_removed"].includes(
7160
+ event.kind
7161
+ )) {
7162
+ const labels = {
7163
+ artifact_created: "Generated",
7164
+ artifact_edited: "Edited document",
7165
+ document_added: "Added document",
7166
+ document_removed: "Removed document"
7167
+ };
7168
+ result.push({ event, label: labels[event.kind], recipients: [] });
7169
+ } else if (["created", "participant_joined", "assistant_responded", "done"].includes(event.kind)) {
7170
+ result.push({
7171
+ event,
7172
+ label: {
7173
+ created: "Started Task",
7174
+ participant_joined: "Followed Up",
7175
+ assistant_responded: "Answered",
7176
+ done: "Marked Done"
7177
+ }[event.kind],
7178
+ recipients: []
7179
+ });
7180
+ }
7181
+ }
7182
+ return result;
6150
7183
  }
6151
7184
  var DEFAULT_TASK_THREAD_CHIP_LABELS = {
6152
7185
  open: "Open thread",
@@ -6208,105 +7241,127 @@ var DEFAULT_TASK_RUNS_DIALOG_LABELS = {
6208
7241
  var STATUS_STYLE = {
6209
7242
  running: "bg-ai-soft text-ai-ink",
6210
7243
  success: "bg-green-bg text-green-text",
7244
+ completed: "bg-green-bg text-green-text",
6211
7245
  failed: "bg-red-bg text-red-text"
6212
7246
  };
6213
7247
  function TaskRunsDialog({
7248
+ inline = false,
7249
+ renderErrorReport,
7250
+ hideHeader = false,
6214
7251
  open,
6215
7252
  onOpenChange,
6216
7253
  taskName,
6217
- error,
6218
7254
  runs,
6219
7255
  isLoading,
6220
7256
  onOpenRun,
7257
+ onOpenResult,
6221
7258
  getRunHref,
6222
7259
  testIds,
6223
7260
  labels
6224
7261
  }) {
6225
7262
  const l = { ...DEFAULT_TASK_RUNS_DIALOG_LABELS, ...labels };
6226
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
6227
- ui.DialogContent,
6228
- {
6229
- presentation: "sheet",
6230
- className: "max-h-[calc(100dvh-2rem)] max-w-lg overflow-y-auto",
6231
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.modal, { testId: "task-runs-modal" }),
6232
- children: [
6233
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
6234
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogTitle, { className: "flex items-center gap-2", children: [
6235
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { size: 16 }),
6236
- " ",
6237
- l.title(taskName)
6238
- ] }),
6239
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: l.description })
6240
- ] }),
6241
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "rounded-md bg-red-bg p-3 text-sm text-red-text", children: error }),
6242
- isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 py-8 text-muted-foreground", children: [
6243
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin" }),
6244
- " ",
6245
- l.loading
6246
- ] }) : runs.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
6247
- "p",
7263
+ const columns = react.useMemo(
7264
+ () => [
7265
+ {
7266
+ colId: "status",
7267
+ field: "status",
7268
+ headerName: "Status",
7269
+ width: 160,
7270
+ minWidth: 140,
7271
+ cellRenderer: ({ data }) => data && /* @__PURE__ */ jsxRuntime.jsx(
7272
+ "span",
6248
7273
  {
6249
- className: "py-8 text-center text-sm text-muted-foreground",
6250
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.empty, { testId: "task-runs-empty" }),
6251
- children: l.empty
7274
+ className: ui.cn(
7275
+ "rounded-full px-2 py-0.5 text-xs font-medium capitalize",
7276
+ STATUS_STYLE[data.status] ?? "text-muted-foreground"
7277
+ ),
7278
+ children: workflowRunStatusLabel(data.status)
6252
7279
  }
6253
- ) : /* @__PURE__ */ jsxRuntime.jsx(
6254
- "ul",
6255
- {
6256
- className: "space-y-2",
6257
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.list, { testId: "task-runs-list" }),
6258
- children: runs.map((run) => /* @__PURE__ */ jsxRuntime.jsxs(
6259
- "li",
7280
+ )
7281
+ },
7282
+ { colId: "when", field: "when", headerName: "Run", flex: 2, minWidth: 240 },
7283
+ {
7284
+ colId: "result",
7285
+ headerName: "",
7286
+ width: 280,
7287
+ minWidth: 220,
7288
+ sortable: false,
7289
+ cellRenderer: ({ data: run }) => {
7290
+ if (!run) return null;
7291
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full items-center gap-2", children: [
7292
+ run.error && renderErrorReport?.(run),
7293
+ (run.conversationId || run.resultId && onOpenResult) && /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { asChild: true, variant: "ghost", size: "sm", className: "h-7 gap-1.5", children: /* @__PURE__ */ jsxRuntime.jsxs(
7294
+ chunkOB5F4577_cjs.ActionLink,
6260
7295
  {
6261
- className: "flex items-center gap-3 rounded-lg bg-muted p-3",
6262
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.row, { testId: "task-run-row" }),
7296
+ href: getRunHref?.(run),
7297
+ onSelect: () => {
7298
+ if (run.conversationId) onOpenRun(run.conversationId);
7299
+ else if (run.resultId) onOpenResult?.(run.resultId);
7300
+ onOpenChange(false);
7301
+ },
7302
+ "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.open, { testId: "task-run-open" }),
6263
7303
  children: [
6264
- /* @__PURE__ */ jsxRuntime.jsx(
6265
- "span",
6266
- {
6267
- className: ui.cn(
6268
- "shrink-0 rounded-full px-2 py-0.5 text-xs font-medium capitalize",
6269
- STATUS_STYLE[run.status] ?? "bg-background text-muted-foreground"
6270
- ),
6271
- children: run.status
6272
- }
6273
- ),
6274
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
6275
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-sm", children: run.when || "\u2014" }),
6276
- run.error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-xs text-red-text", title: run.error, children: run.error })
6277
- ] }),
6278
- run.conversationId && /* @__PURE__ */ jsxRuntime.jsx(
6279
- ui.Button,
6280
- {
6281
- asChild: true,
6282
- variant: "outline",
6283
- size: "sm",
6284
- className: "h-7 shrink-0 gap-1.5 pointer-coarse:h-11",
6285
- children: /* @__PURE__ */ jsxRuntime.jsxs(
6286
- chunkOB5F4577_cjs.ActionLink,
6287
- {
6288
- href: getRunHref?.(run),
6289
- onSelect: () => {
6290
- onOpenRun(run.conversationId);
6291
- onOpenChange(false);
6292
- },
6293
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.open, { testId: "task-run-open" }),
6294
- children: [
6295
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { size: 13 }),
6296
- " ",
6297
- l.open
6298
- ]
6299
- }
6300
- )
6301
- }
6302
- )
7304
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { size: 13 }),
7305
+ " ",
7306
+ l.open
6303
7307
  ]
6304
- },
6305
- run.id
6306
- ))
7308
+ }
7309
+ ) })
7310
+ ] });
7311
+ }
7312
+ }
7313
+ ],
7314
+ [onOpenRun, onOpenResult, getRunHref, onOpenChange, testIds?.open, l.open, renderErrorReport]
7315
+ );
7316
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7317
+ hideHeader ? null : inline ? /* @__PURE__ */ jsxRuntime.jsx(
7318
+ chunk6DNYPLCD_cjs.TabHeader,
7319
+ {
7320
+ tabs: [
7321
+ {
7322
+ id: "history",
7323
+ label: l.title(taskName),
7324
+ count: runs.length,
7325
+ countIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { size: 14 }),
7326
+ presentation: "count",
7327
+ onClose: () => onOpenChange(false)
6307
7328
  }
6308
- )
6309
- ]
7329
+ ],
7330
+ activeTabId: "history",
7331
+ onTabChange: () => {
7332
+ }
7333
+ }
7334
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
7335
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogTitle, { className: "flex items-center gap-2", children: [
7336
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { size: 16 }),
7337
+ " ",
7338
+ l.title(taskName)
7339
+ ] }),
7340
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: l.description })
7341
+ ] }),
7342
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
7343
+ chunkIA7RTPT3_cjs.GridView,
7344
+ {
7345
+ testId: chunkMHVNT4J3_cjs.testIdOr(testIds?.list, { testId: "task-runs-list" }),
7346
+ gridId: "workflow-runs",
7347
+ items: runs,
7348
+ columnDefs: columns,
7349
+ getItemId: (run) => run.id,
7350
+ getRowTestId: () => chunkMHVNT4J3_cjs.testIdOr(testIds?.row, { testId: "task-run-row" }),
7351
+ isLoading,
7352
+ loadingMessage: l.loading,
7353
+ emptyState: { title: l.empty },
7354
+ height: "100%"
7355
+ }
7356
+ ) })
7357
+ ] });
7358
+ return inline ? /* @__PURE__ */ jsxRuntime.jsx("section", { className: "flex min-h-0 flex-1 flex-col", "data-testid": "automation-history", children: content }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(
7359
+ ui.DialogContent,
7360
+ {
7361
+ presentation: "sheet",
7362
+ className: "flex h-[min(32rem,calc(100dvh-2rem))] min-h-0 max-w-3xl flex-col",
7363
+ "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.modal, { testId: "task-runs-modal" }),
7364
+ children: content
6310
7365
  }
6311
7366
  ) });
6312
7367
  }
@@ -6326,7 +7381,7 @@ function TasksToolbar({ count, onNewTask, testIds, labels }) {
6326
7381
  }
6327
7382
  ];
6328
7383
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-background", "data-slot": "tasks-toolbar", children: /* @__PURE__ */ jsxRuntime.jsx(
6329
- chunk5B4PXAKI_cjs.TabHeader,
7384
+ chunk6DNYPLCD_cjs.TabHeader,
6330
7385
  {
6331
7386
  tabs,
6332
7387
  activeTabId: "tasks",
@@ -6362,7 +7417,7 @@ function WorkflowsToolbar({ count, onNewWorkflow, testIds, labels }) {
6362
7417
  }
6363
7418
  ];
6364
7419
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-background", "data-slot": "workflows-toolbar", children: /* @__PURE__ */ jsxRuntime.jsx(
6365
- chunk5B4PXAKI_cjs.TabHeader,
7420
+ chunk6DNYPLCD_cjs.TabHeader,
6366
7421
  {
6367
7422
  tabs,
6368
7423
  activeTabId: "workflows",
@@ -6428,7 +7483,7 @@ var DEFAULT_TASK_COMPOSER_LABELS = {
6428
7483
  dueClear: "Clear date",
6429
7484
  parentTask: "Part of",
6430
7485
  parentTaskNone: "Nothing (top-level)",
6431
- visibility: "Visible to",
7486
+ visibility: "Visibility",
6432
7487
  visibilityWorkspace: "Workspace",
6433
7488
  visibilityPrivate: "Only me",
6434
7489
  assistant: "Task Assistant",
@@ -6478,8 +7533,8 @@ var DEFAULT_TASK_COMPOSER_LABELS = {
6478
7533
  empty: "No match.",
6479
7534
  cancel: "Cancel",
6480
7535
  addTask: "Add task",
6481
- addAndStart: "Add task and start",
6482
- addAndSchedule: "Save as workflow",
7536
+ addAndStart: "Start now",
7537
+ addAndSchedule: "Schedule",
6483
7538
  save: "Save changes",
6484
7539
  saving: "Saving\u2026"
6485
7540
  };
@@ -6498,7 +7553,7 @@ function defaultTaskComposerValues(workflows, initial) {
6498
7553
  afterTaskId: "",
6499
7554
  parentTaskId: "",
6500
7555
  signoffUserId: "",
6501
- shared: true,
7556
+ shared: false,
6502
7557
  description: "",
6503
7558
  dueAt: "",
6504
7559
  agentId: "",
@@ -6508,7 +7563,6 @@ function defaultTaskComposerValues(workflows, initial) {
6508
7563
  ...initial
6509
7564
  };
6510
7565
  }
6511
- var WHEN_ORDER = ["now", "once", "repeat", "event", "task"];
6512
7566
  var GLYPH2 = "size-3.5 shrink-0";
6513
7567
  function missingWhen(values, runAtPast) {
6514
7568
  if (values.when === "now" || values.when === "manual") return null;
@@ -6522,6 +7576,8 @@ function WorkflowComposer({
6522
7576
  open,
6523
7577
  onOpenChange,
6524
7578
  isEdit = false,
7579
+ saveOnly = false,
7580
+ hideRunLater = false,
6525
7581
  workflows,
6526
7582
  agents,
6527
7583
  people,
@@ -6530,6 +7586,8 @@ function WorkflowComposer({
6530
7586
  initialValues,
6531
7587
  onValuesChange,
6532
7588
  timezones = [],
7589
+ eventOptions,
7590
+ eventWorkflowOptions,
6533
7591
  goal,
6534
7592
  standingAccess,
6535
7593
  scopeSource,
@@ -6551,7 +7609,11 @@ function WorkflowComposer({
6551
7609
  const l = {
6552
7610
  ...DEFAULT_TASK_COMPOSER_LABELS,
6553
7611
  ...labels,
6554
- whenOptions: { ...DEFAULT_TASK_COMPOSER_LABELS.whenOptions, ...labels?.whenOptions },
7612
+ whenOptions: {
7613
+ ...DEFAULT_TASK_COMPOSER_LABELS.whenOptions,
7614
+ ...labels?.whenOptions,
7615
+ ...saveOnly ? { now: "When needed" } : {}
7616
+ },
6555
7617
  accessOptions: { ...DEFAULT_TASK_COMPOSER_LABELS.accessOptions, ...labels?.accessOptions }
6556
7618
  };
6557
7619
  const seed = react.useMemo(
@@ -6565,12 +7627,15 @@ function WorkflowComposer({
6565
7627
  seed,
6566
7628
  onValuesChange
6567
7629
  );
7630
+ const [runOnce, setRunOnce] = react.useState(false);
7631
+ const [automationWhen, setAutomationWhen] = react.useState(seed.when);
6568
7632
  const [planOpen, setPlanOpen] = react.useState(false);
6569
7633
  const [moreOpen, setMoreOpen] = react.useState(false);
6570
7634
  const [agentAutoSet, setAgentAutoSet] = react.useState(false);
6571
7635
  react.useEffect(() => {
6572
7636
  if (open) {
6573
7637
  if (valuesProp === void 0) setValues(seed);
7638
+ setRunOnce(false);
6574
7639
  setPlanOpen(false);
6575
7640
  setAgentAutoSet(false);
6576
7641
  }
@@ -6599,7 +7664,12 @@ function WorkflowComposer({
6599
7664
  const derivedName = workflow ? deriveWorkflowName(workflow, values.inputs) : "";
6600
7665
  const pickWorkflow = (next) => {
6601
7666
  const def = workflows.find((w) => w.id === next);
6602
- setValues({ ...values, workflowId: next, inputs: def ? defaultInputs(def) : {} });
7667
+ setValues({
7668
+ ...values,
7669
+ workflowId: next,
7670
+ inputs: def ? defaultInputs(def) : {},
7671
+ ...def?.documentAction ? { access: "standing" } : {}
7672
+ });
6603
7673
  };
6604
7674
  const pickWhen = (next) => {
6605
7675
  const goesScheduled = next !== "now" && next !== "manual";
@@ -6623,14 +7693,18 @@ function WorkflowComposer({
6623
7693
  setAgentAutoSet(false);
6624
7694
  set("agentId", agentId);
6625
7695
  };
6626
- const submit = () => onSubmit({
6627
- ...values,
6628
- // A scope pick is bound to explicit file ids before anything is sent.
6629
- inputs: workflow ? resolveScopeInputs(workflow, values.inputs, scopeSource) : values.inputs,
6630
- assignee: "agent",
6631
- notifyOnComplete: true,
6632
- name: values.name.trim()
6633
- });
7696
+ const submit = () => {
7697
+ const submitted = {
7698
+ ...values,
7699
+ // A scope pick is bound to explicit file ids before anything is sent.
7700
+ inputs: workflow && !workflow.documentAction ? resolveScopeInputs(workflow, values.inputs, scopeSource) : values.inputs,
7701
+ assignee: "agent",
7702
+ notifyOnComplete: true,
7703
+ name: values.name.trim()
7704
+ };
7705
+ if (runOnce) onSubmit(submitted, { runOnce: true });
7706
+ else onSubmit(submitted);
7707
+ };
6634
7708
  const pillLabels = { search: l.search, empty: l.empty };
6635
7709
  const personOptions = (people ?? []).map((p) => ({
6636
7710
  id: p.id,
@@ -6643,10 +7717,11 @@ function WorkflowComposer({
6643
7717
  label: t.name,
6644
7718
  icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownRight, { className: GLYPH2, "aria-hidden": true })
6645
7719
  }));
6646
- const whenOptions = (isEdit ? ["manual", ...WHEN_ORDER.slice(1)] : WHEN_ORDER.slice(1)).map((mode) => ({
6647
- id: mode,
6648
- label: l.whenOptions[mode]
6649
- }));
7720
+ const whenOptions = [
7721
+ { id: "manual", label: "Start now" },
7722
+ { id: "schedule", label: "Schedule" },
7723
+ { id: "event", label: "Notification" }
7724
+ ];
6650
7725
  const assistantOptions = agents.map((a) => ({ id: a.id, label: a.label }));
6651
7726
  if (values.agentId && !assistantOptions.some((a) => a.id === values.agentId)) {
6652
7727
  assistantOptions.push({ id: values.agentId, label: "Assigned agent" });
@@ -6654,18 +7729,42 @@ function WorkflowComposer({
6654
7729
  const goalNode = typeof goal === "function" ? goal(values) : goal;
6655
7730
  const pickedTemplate = workflows.find((w) => w.id === values.workflowId && !w.generic);
6656
7731
  const hint = (key) => l[key];
6657
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
7732
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { modal: false, open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
6658
7733
  ui.DialogContent,
6659
7734
  {
6660
- presentation: "sheet",
6661
- className: "flex max-h-[calc(100dvh-2rem)] flex-col overflow-hidden p-0 sm:max-w-xl",
7735
+ presentation: "right",
7736
+ hideCloseButton: true,
7737
+ onInteractOutside: (event) => event.preventDefault(),
7738
+ className: "flex flex-col gap-0 overflow-hidden p-0 shadow-lg",
6662
7739
  "data-testid": id,
6663
7740
  children: [
6664
- /* @__PURE__ */ jsxRuntime.jsxs(chunk2ZTONLT5_cjs.ModalHeader, { children: [
6665
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: isEdit ? l.titleEditWorkflow : pickedTemplate ? l.titleRunTemplate(pickedTemplate.title) : l.titleNewWorkflow }),
6666
- !isEdit && /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: l.descriptionWorkflow }),
6667
- isEdit && /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { className: "sr-only", children: l.descriptionWorkflow })
6668
- ] }),
7741
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { className: "sr-only", children: "Automation settings" }),
7742
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { className: "sr-only", children: l.descriptionWorkflow }),
7743
+ /* @__PURE__ */ jsxRuntime.jsx(
7744
+ chunk6DNYPLCD_cjs.TabHeader,
7745
+ {
7746
+ tabs: [
7747
+ {
7748
+ id: "automation-setup",
7749
+ label: isEdit ? l.titleEditWorkflow : pickedTemplate ? l.titleRunTemplate(pickedTemplate.title) : l.titleNewWorkflow,
7750
+ presentation: "count"
7751
+ },
7752
+ ...(saveOnly || isEdit) && !workflow?.documentAction ? [{ id: "start-task", label: "Start task" }] : []
7753
+ ],
7754
+ activeTabId: runOnce ? "start-task" : "automation-setup",
7755
+ onTabChange: (tab) => {
7756
+ if (tab === "start-task" && !runOnce) {
7757
+ setAutomationWhen(values.when);
7758
+ set("when", "now");
7759
+ setRunOnce(true);
7760
+ } else if (tab === "automation-setup" && runOnce) {
7761
+ set("when", automationWhen);
7762
+ setRunOnce(false);
7763
+ }
7764
+ },
7765
+ rightContent: /* @__PURE__ */ jsxRuntime.jsx(ui.DialogClose, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "ghost", size: "icon", "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4" }) }) })
7766
+ }
7767
+ ),
6669
7768
  /* @__PURE__ */ jsxRuntime.jsxs(
6670
7769
  "form",
6671
7770
  {
@@ -6702,7 +7801,7 @@ function WorkflowComposer({
6702
7801
  },
6703
7802
  "data-testid": `${id}-dropzone`,
6704
7803
  children: /* @__PURE__ */ jsxRuntime.jsx(
6705
- chunkZVPTFTGV_cjs.AddFilesFirst,
7804
+ chunkWBDK4PIA_cjs.AddFilesFirst,
6706
7805
  {
6707
7806
  reason: l.addFilesReason,
6708
7807
  action: addFilesAction,
@@ -6755,7 +7854,7 @@ function WorkflowComposer({
6755
7854
  goalNode
6756
7855
  ] })
6757
7856
  ] }),
6758
- (scheduled || isEdit) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7857
+ !runOnce && (scheduled || isEdit) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6759
7858
  /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "flex flex-col gap-2", "data-testid": `${id}-when-section`, children: [
6760
7859
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium", children: l.whenHeading }),
6761
7860
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6763,14 +7862,30 @@ function WorkflowComposer({
6763
7862
  {
6764
7863
  icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: GLYPH2, "aria-hidden": true }),
6765
7864
  prefix: l.start,
6766
- value: values.when,
7865
+ value: values.when === "once" || values.when === "repeat" ? "schedule" : values.when === "task" ? "event" : values.when === "now" ? "manual" : values.when,
6767
7866
  options: whenOptions,
6768
- onChange: (v) => pickWhen(v),
7867
+ onChange: (v) => pickWhen(v === "schedule" ? "once" : v),
6769
7868
  labels: pillLabels,
6770
7869
  testId: `${id}-when`,
6771
7870
  className: "self-start"
6772
7871
  }
6773
7872
  ),
7873
+ (values.when === "once" || values.when === "repeat") && /* @__PURE__ */ jsxRuntime.jsx(
7874
+ PillSelect,
7875
+ {
7876
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: GLYPH2, "aria-hidden": true }),
7877
+ prefix: "Schedule",
7878
+ value: values.when,
7879
+ options: [
7880
+ { id: "once", label: "Once" },
7881
+ { id: "repeat", label: "Repeat" }
7882
+ ],
7883
+ onChange: (value) => pickWhen(value),
7884
+ labels: pillLabels,
7885
+ testId: `${id}-schedule-mode`,
7886
+ className: "self-start"
7887
+ }
7888
+ ),
6774
7889
  values.when === "once" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
6775
7890
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "task-composer-runat", className: "sr-only", children: l.runAt }),
6776
7891
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6814,7 +7929,25 @@ function WorkflowComposer({
6814
7929
  ] }),
6815
7930
  values.when === "event" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
6816
7931
  /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "task-composer-event", className: "sr-only", children: l.event }),
6817
- /* @__PURE__ */ jsxRuntime.jsx(
7932
+ eventOptions ? /* @__PURE__ */ jsxRuntime.jsx(
7933
+ PillSelect,
7934
+ {
7935
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Zap, { className: GLYPH2, "aria-hidden": true }),
7936
+ prefix: l.event,
7937
+ value: values.eventKind,
7938
+ options: eventOptions.some((option) => option.id === values.eventKind) || !values.eventKind ? [...eventOptions] : [
7939
+ ...eventOptions,
7940
+ {
7941
+ id: values.eventKind,
7942
+ label: values.eventKind.replaceAll("_", " ")
7943
+ }
7944
+ ],
7945
+ onChange: (event) => set("eventKind", event),
7946
+ labels: pillLabels,
7947
+ testId: `${id}-event`,
7948
+ className: "self-start"
7949
+ }
7950
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
6818
7951
  ui.Input,
6819
7952
  {
6820
7953
  id: "task-composer-event",
@@ -6827,6 +7960,22 @@ function WorkflowComposer({
6827
7960
  ),
6828
7961
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: l.eventHint })
6829
7962
  ] }),
7963
+ values.when === "event" && values.eventKind === "workflow_completed" && eventWorkflowOptions && /* @__PURE__ */ jsxRuntime.jsx(
7964
+ PillSelect,
7965
+ {
7966
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Zap, { className: GLYPH2, "aria-hidden": true }),
7967
+ prefix: "Automation",
7968
+ value: typeof values.eventFilter?.workflow_ext_id === "string" ? values.eventFilter.workflow_ext_id : "",
7969
+ options: [{ id: "", label: "Any automation" }, ...eventWorkflowOptions],
7970
+ onChange: (id2) => set(
7971
+ "eventFilter",
7972
+ id2 ? { ...values.eventFilter, workflow_ext_id: id2 } : null
7973
+ ),
7974
+ labels: pillLabels,
7975
+ testId: `${id}-event-workflow`,
7976
+ className: "self-start"
7977
+ }
7978
+ ),
6830
7979
  values.when === "task" && /* @__PURE__ */ jsxRuntime.jsx(
6831
7980
  PillSelect,
6832
7981
  {
@@ -7021,7 +8170,7 @@ function WorkflowComposer({
7021
8170
  children: l.cancel
7022
8171
  }
7023
8172
  ),
7024
- !isEdit && /* @__PURE__ */ jsxRuntime.jsx(
8173
+ !isEdit && !saveOnly && !hideRunLater && /* @__PURE__ */ jsxRuntime.jsx(
7025
8174
  ui.Button,
7026
8175
  {
7027
8176
  type: "button",
@@ -7041,7 +8190,7 @@ function WorkflowComposer({
7041
8190
  className: "gap-1.5 pointer-coarse:min-h-11",
7042
8191
  children: [
7043
8192
  isPending && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin" }),
7044
- isPending ? l.saving : isEdit ? l.save : scheduled ? l.saveWorkflow : l.runNow
8193
+ isPending ? l.saving : runOnce ? "Start now" : isEdit ? l.save : saveOnly || scheduled ? l.saveWorkflow : l.runNow
7045
8194
  ]
7046
8195
  }
7047
8196
  )
@@ -7053,7 +8202,7 @@ function WorkflowComposer({
7053
8202
  }
7054
8203
  ) });
7055
8204
  }
7056
- var WHEN_ORDER2 = ["now", "once", "repeat", "event", "task"];
8205
+ var WHEN_ORDER = ["now", "once", "repeat", "event", "task"];
7057
8206
  function formatDue2(local) {
7058
8207
  const d = new Date(local);
7059
8208
  if (Number.isNaN(d.getTime())) return local;
@@ -7156,7 +8305,7 @@ function WorkTaskComposer({
7156
8305
  label: t.name,
7157
8306
  icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownRight, { className: GLYPH3, "aria-hidden": true })
7158
8307
  }));
7159
- const whenOptions = WHEN_ORDER2.map((mode) => ({
8308
+ const whenOptions = WHEN_ORDER.map((mode) => ({
7160
8309
  id: mode,
7161
8310
  label: l.whenOptions[mode]
7162
8311
  }));
@@ -7165,8 +8314,8 @@ function WorkTaskComposer({
7165
8314
  return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
7166
8315
  ui.DialogContent,
7167
8316
  {
7168
- presentation: "sheet",
7169
- className: "flex max-h-[calc(100dvh-2rem)] flex-col overflow-hidden p-0 sm:max-w-xl",
8317
+ presentation: "right",
8318
+ className: "flex flex-col overflow-hidden p-0",
7170
8319
  "data-testid": id,
7171
8320
  children: [
7172
8321
  /* @__PURE__ */ jsxRuntime.jsxs(chunk2ZTONLT5_cjs.ModalHeader, { children: [
@@ -7268,6 +8417,7 @@ function WorkTaskComposer({
7268
8417
  items: { shared: values.shared },
7269
8418
  onToggle: (share) => set("shared", share),
7270
8419
  label: l.visibility,
8420
+ presentation: "select",
7271
8421
  "data-testid": `${id}-visibility`
7272
8422
  }
7273
8423
  )
@@ -7521,6 +8671,210 @@ function WorkTaskComposer({
7521
8671
  function TaskComposer(props) {
7522
8672
  return props.kind === "workflow" ? /* @__PURE__ */ jsxRuntime.jsx(WorkflowComposer, { ...props }) : /* @__PURE__ */ jsxRuntime.jsx(WorkTaskComposer, { ...props });
7523
8673
  }
8674
+ function TaskReviewDialog(p) {
8675
+ const [action, setAction] = react.useState("forward");
8676
+ const [userId, setUserId] = react.useState("");
8677
+ const [note, setNote] = react.useState("");
8678
+ react.useEffect(() => {
8679
+ if (p.open) {
8680
+ setAction(p.people.length ? "forward" : p.canApprove ? "finish" : "revise");
8681
+ setUserId("");
8682
+ setNote("");
8683
+ }
8684
+ }, [p.open]);
8685
+ const valid = action === "forward" ? p.people.some((person) => person.id === userId) : action === "revise" ? p.canRevise && Boolean(note.trim()) : p.canApprove;
8686
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open: p.open, onOpenChange: (next) => !p.isPending && p.onOpenChange(next), children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { "data-testid": "task-review-dialog", className: "sm:max-w-lg", children: [
8687
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogTitle, { children: [
8688
+ "Review: ",
8689
+ p.taskName
8690
+ ] }),
8691
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: p.canApprove ? "Approve your review and send it on, request changes, or finish the task." : "Choose who should review this work next, or ask ARBI for changes." }),
8692
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 py-2", children: [
8693
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
8694
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "review-next-step", children: "Next step" }),
8695
+ /* @__PURE__ */ jsxRuntime.jsxs(
8696
+ ui.Select,
8697
+ {
8698
+ value: action,
8699
+ onValueChange: (value) => setAction(value),
8700
+ disabled: p.isPending,
8701
+ children: [
8702
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SelectTrigger, { id: "review-next-step", children: /* @__PURE__ */ jsxRuntime.jsx(ui.SelectValue, {}) }),
8703
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.SelectContent, { children: [
8704
+ p.people.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "forward", children: p.canApprove ? "Approve and send for review" : "Send for review" }),
8705
+ p.canRevise && /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "revise", children: "Ask ARBI for changes" }),
8706
+ p.canApprove && /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: "finish", children: "Approve and finish task" })
8707
+ ] })
8708
+ ]
8709
+ }
8710
+ )
8711
+ ] }),
8712
+ action === "forward" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
8713
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "review-recipient", children: "Next reviewer" }),
8714
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: userId, onValueChange: setUserId, disabled: p.isPending, children: [
8715
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SelectTrigger, { id: "review-recipient", children: /* @__PURE__ */ jsxRuntime.jsx(ui.SelectValue, { placeholder: "Choose a person" }) }),
8716
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SelectContent, { children: p.people.map((person) => /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: person.id, children: person.label }, person.id)) })
8717
+ ] })
8718
+ ] }),
8719
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
8720
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: "review-note", children: action === "revise" ? "What should ARBI change?" : "Review note (optional)" }),
8721
+ /* @__PURE__ */ jsxRuntime.jsx(
8722
+ ui.Textarea,
8723
+ {
8724
+ id: "review-note",
8725
+ value: note,
8726
+ onChange: (e) => setNote(e.target.value),
8727
+ disabled: p.isPending,
8728
+ placeholder: action === "revise" ? "Explain what needs changing in the same draft\u2026" : "Explain what you checked and what the next reviewer should focus on\u2026"
8729
+ }
8730
+ )
8731
+ ] }),
8732
+ p.error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive", children: p.error })
8733
+ ] }),
8734
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
8735
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "outline", onClick: () => p.onOpenChange(false), disabled: p.isPending, children: "Cancel" }),
8736
+ /* @__PURE__ */ jsxRuntime.jsx(
8737
+ ui.Button,
8738
+ {
8739
+ "data-testid": "task-review-submit",
8740
+ disabled: !valid || p.isPending,
8741
+ onClick: () => p.onSubmit({
8742
+ action,
8743
+ userId,
8744
+ note: note.trim(),
8745
+ approveCurrent: p.canApprove && action === "forward"
8746
+ }),
8747
+ children: p.isPending ? "Saving\u2026" : action === "forward" ? p.canApprove ? "Approve and send" : "Send for review" : action === "revise" ? "Send to ARBI" : "Finish task"
8748
+ }
8749
+ )
8750
+ ] })
8751
+ ] }) });
8752
+ }
8753
+ function ThreadNotifyDialog({
8754
+ open,
8755
+ onOpenChange,
8756
+ people,
8757
+ isShared,
8758
+ onNotify
8759
+ }) {
8760
+ const [selected, setSelected] = react.useState([]);
8761
+ const [query, setQuery] = react.useState("");
8762
+ const [busy, setBusy] = react.useState(false);
8763
+ const [error, setError] = react.useState(null);
8764
+ react.useEffect(() => {
8765
+ if (open) {
8766
+ setSelected([]);
8767
+ setQuery("");
8768
+ setError(null);
8769
+ }
8770
+ }, [open]);
8771
+ return /* @__PURE__ */ jsxRuntime.jsx(
8772
+ ui.Dialog,
8773
+ {
8774
+ open,
8775
+ onOpenChange: (value) => {
8776
+ if (!busy) onOpenChange(value);
8777
+ },
8778
+ children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { className: "max-w-sm", "data-testid": "thread-notify-dialog", children: [
8779
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: "Notify" }),
8780
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: isShared ? "Ask someone to follow up in this thread." : "Notifying someone shares this thread with your workspace." }),
8781
+ /* @__PURE__ */ jsxRuntime.jsx(
8782
+ ui.Input,
8783
+ {
8784
+ "aria-label": "Find people",
8785
+ placeholder: "Find someone\u2026",
8786
+ value: query,
8787
+ onChange: (event) => setQuery(event.target.value)
8788
+ }
8789
+ ),
8790
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-64 overflow-y-auto space-y-1", children: [
8791
+ people.filter((person) => person.label.toLowerCase().includes(query.toLowerCase())).map((person) => /* @__PURE__ */ jsxRuntime.jsxs(
8792
+ "label",
8793
+ {
8794
+ className: "flex cursor-pointer items-center gap-2 rounded px-2 py-2 hover:bg-muted",
8795
+ children: [
8796
+ /* @__PURE__ */ jsxRuntime.jsx(
8797
+ ui.Checkbox,
8798
+ {
8799
+ disabled: busy,
8800
+ checked: selected.includes(person.id),
8801
+ onCheckedChange: (checked) => setSelected(
8802
+ (old) => checked ? [...old, person.id] : old.filter((id) => id !== person.id)
8803
+ )
8804
+ }
8805
+ ),
8806
+ person.label
8807
+ ]
8808
+ },
8809
+ person.id
8810
+ )),
8811
+ !people.length && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "No other workspace members yet." })
8812
+ ] }),
8813
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive", children: error }),
8814
+ /* @__PURE__ */ jsxRuntime.jsx(
8815
+ ui.Button,
8816
+ {
8817
+ disabled: busy || !selected.length,
8818
+ "data-testid": "thread-notify-submit",
8819
+ onClick: async () => {
8820
+ setBusy(true);
8821
+ setError(null);
8822
+ try {
8823
+ await onNotify(selected);
8824
+ onOpenChange(false);
8825
+ } catch (failure) {
8826
+ setError(failure instanceof Error ? failure.message : "Could not notify people");
8827
+ } finally {
8828
+ setBusy(false);
8829
+ }
8830
+ },
8831
+ children: busy ? "Notifying\u2026" : "Notify"
8832
+ }
8833
+ )
8834
+ ] })
8835
+ }
8836
+ );
8837
+ }
8838
+ function ConversationTurnSpeaker({
8839
+ role,
8840
+ actor,
8841
+ currentUserId,
8842
+ colorClass,
8843
+ platformName = "ARBI",
8844
+ platformLogoSrc = "/favicon.svg"
8845
+ }) {
8846
+ if (!role) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "\u2014" });
8847
+ if (role === "assistant" && !actor)
8848
+ return /* @__PURE__ */ jsxRuntime.jsx(
8849
+ ui.UserEntity,
8850
+ {
8851
+ size: "sm",
8852
+ variant: "pill",
8853
+ interactive: false,
8854
+ picture: platformLogoSrc,
8855
+ avatarImageClassName: "object-contain p-0.5",
8856
+ initials: platformName.charAt(0),
8857
+ displayName: platformName
8858
+ }
8859
+ );
8860
+ if (!actor) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Unknown participant" });
8861
+ const isMe = actor.external_id === currentUserId;
8862
+ const displayName = isMe ? "You" : [actor.given_name, actor.family_name].filter(Boolean).join(" ");
8863
+ return /* @__PURE__ */ jsxRuntime.jsx(
8864
+ ui.UserEntity,
8865
+ {
8866
+ size: "sm",
8867
+ variant: "pill",
8868
+ interactive: false,
8869
+ isMe,
8870
+ isAgent: actor.external_id.startsWith("agt-"),
8871
+ displayName,
8872
+ initials: `${actor.given_name.charAt(0)}${actor.family_name?.charAt(0) ?? ""}`.toUpperCase(),
8873
+ picture: actor.picture,
8874
+ colorClass
8875
+ }
8876
+ );
8877
+ }
7524
8878
  var DEFAULT_TUPLE_ARRAY_FIELD_LABELS = {
7525
8879
  addRow: "Add Row",
7526
8880
  empty: 'No examples added yet. Click "Add Row" to start.',
@@ -9145,7 +10499,7 @@ function AgentCreateView({
9145
10499
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-normal text-muted-foreground", children: l.optional })
9146
10500
  ] }),
9147
10501
  /* @__PURE__ */ jsxRuntime.jsx(
9148
- chunkS5HZBXZA_cjs.MultiSelect,
10502
+ chunk2QTT2RZE_cjs.MultiSelect,
9149
10503
  {
9150
10504
  data: workspaces.map((ws) => ({ label: ws.name, value: ws.id })),
9151
10505
  value: selectedWorkspaces,
@@ -9210,6 +10564,8 @@ exports.ConsentPermissionList = ConsentPermissionList;
9210
10564
  exports.ConsentSection = ConsentSection;
9211
10565
  exports.ConsentStrong = ConsentStrong;
9212
10566
  exports.ConsentText = ConsentText;
10567
+ exports.ConversationListView = ConversationListView;
10568
+ exports.ConversationTurnSpeaker = ConversationTurnSpeaker;
9213
10569
  exports.CopyableUrl = CopyableUrl;
9214
10570
  exports.DEFAULT_AGENT_AVATAR_FIELD_LABELS = DEFAULT_AGENT_AVATAR_FIELD_LABELS;
9215
10571
  exports.DEFAULT_AGENT_BAR_LABELS = DEFAULT_AGENT_BAR_LABELS;
@@ -9256,6 +10612,7 @@ exports.DEFAULT_WORKFLOW_LIST_LABELS = DEFAULT_WORKFLOW_LIST_LABELS;
9256
10612
  exports.DERIVED_NAME_WORDS = DERIVED_NAME_WORDS;
9257
10613
  exports.EMPTY_NEW_THREAD = EMPTY_NEW_THREAD;
9258
10614
  exports.EMPTY_WORKFLOW_SCOPE = EMPTY_WORKFLOW_SCOPE;
10615
+ exports.EntityChip = EntityChip;
9259
10616
  exports.GoalCriteria = GoalCriteria;
9260
10617
  exports.MAX_TASK_DEPTH = MAX_TASK_DEPTH;
9261
10618
  exports.NewThreadDialog = NewThreadDialog;
@@ -9296,16 +10653,22 @@ exports.TRIGGER_LABELS = TRIGGER_LABELS;
9296
10653
  exports.TaskActivityDialog = TaskActivityDialog;
9297
10654
  exports.TaskActivityTimeline = TaskActivityTimeline;
9298
10655
  exports.TaskComposer = TaskComposer;
10656
+ exports.TaskFlow = TaskFlow;
10657
+ exports.TaskInbox = TaskInbox;
9299
10658
  exports.TaskMoveDialog = TaskMoveDialog;
9300
10659
  exports.TaskOutputsCell = TaskOutputsCell;
9301
10660
  exports.TaskPlan = TaskPlan;
9302
10661
  exports.TaskReviewActions = TaskReviewActions;
10662
+ exports.TaskReviewDialog = TaskReviewDialog;
9303
10663
  exports.TaskRunsDialog = TaskRunsDialog;
10664
+ exports.TaskStartDialog = TaskStartDialog;
9304
10665
  exports.TaskStatusPill = TaskStatusPill;
9305
10666
  exports.TaskTable = TaskTable;
9306
10667
  exports.TaskThreadChip = TaskThreadChip;
9307
10668
  exports.TaskTriggerChip = TaskTriggerChip;
9308
10669
  exports.TasksToolbar = TasksToolbar;
10670
+ exports.ThreadActivity = ThreadActivity;
10671
+ exports.ThreadNotifyDialog = ThreadNotifyDialog;
9309
10672
  exports.TupleArrayField = TupleArrayField;
9310
10673
  exports.UploadTaskItem = UploadTaskItem;
9311
10674
  exports.UploadTaskList = UploadTaskList;
@@ -9324,6 +10687,7 @@ exports.buildLaunch = buildLaunch;
9324
10687
  exports.buildRRule = buildRRule;
9325
10688
  exports.buildTaskRows = buildTaskRows;
9326
10689
  exports.buildWorkflowScopeSource = buildWorkflowScopeSource;
10690
+ exports.compactThreadActivity = compactThreadActivity;
9327
10691
  exports.composePersona = composePersona;
9328
10692
  exports.composeWorkflowPrompt = composeWorkflowPrompt;
9329
10693
  exports.composerToTaskQuery = composerToTaskQuery;
@@ -9340,6 +10704,7 @@ exports.deriveAgentName = deriveAgentName;
9340
10704
  exports.deriveWorkflowName = deriveWorkflowName;
9341
10705
  exports.descendantIds = descendantIds;
9342
10706
  exports.describeRRule = describeRRule;
10707
+ exports.filterConversationRows = filterConversationRows;
9343
10708
  exports.firstWords = firstWords;
9344
10709
  exports.formatElapsed = formatElapsed;
9345
10710
  exports.goalProgress = goalProgress;
@@ -9386,5 +10751,5 @@ exports.workflowTriggerType = workflowTriggerType;
9386
10751
  exports.workflowWhen = workflowWhen;
9387
10752
  exports.workflowsAccepting = workflowsAccepting;
9388
10753
  exports.workflowsForHost = workflowsForHost;
9389
- //# sourceMappingURL=chunk-PLGVMLBD.cjs.map
9390
- //# sourceMappingURL=chunk-PLGVMLBD.cjs.map
10754
+ //# sourceMappingURL=chunk-SEQWI6E4.cjs.map
10755
+ //# sourceMappingURL=chunk-SEQWI6E4.cjs.map