@arbidocs/blocks 0.5.38 → 0.5.39

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 (147) hide show
  1. package/README.md +10 -0
  2. package/dist/{ConnectedCallDock-V7DPSE6X.cjs → ConnectedCallDock-NGHSDLJS.cjs} +4 -4
  3. package/dist/{ConnectedCallDock-V7DPSE6X.cjs.map → ConnectedCallDock-NGHSDLJS.cjs.map} +1 -1
  4. package/dist/{ConnectedCallDock-CT3D6LLI.js → ConnectedCallDock-YJSO52N4.js} +4 -4
  5. package/dist/{ConnectedCallDock-CT3D6LLI.js.map → ConnectedCallDock-YJSO52N4.js.map} +1 -1
  6. package/dist/{ConnectedCallRoom-TNOCSTX2.cjs → ConnectedCallRoom-4XGFFYHE.cjs} +4 -4
  7. package/dist/{ConnectedCallRoom-TNOCSTX2.cjs.map → ConnectedCallRoom-4XGFFYHE.cjs.map} +1 -1
  8. package/dist/{ConnectedCallRoom-A27AM7IQ.js → ConnectedCallRoom-T6NS2MY4.js} +4 -4
  9. package/dist/{ConnectedCallRoom-A27AM7IQ.js.map → ConnectedCallRoom-T6NS2MY4.js.map} +1 -1
  10. package/dist/{ConnectedNativeDocxComparison-RWKFPJPJ.js → ConnectedNativeDocxComparison-52KQKJGY.js} +7 -7
  11. package/dist/{ConnectedNativeDocxComparison-RWKFPJPJ.js.map → ConnectedNativeDocxComparison-52KQKJGY.js.map} +1 -1
  12. package/dist/{ConnectedNativeDocxComparison-H2OZMWHT.cjs → ConnectedNativeDocxComparison-UVLZGS2V.cjs} +8 -8
  13. package/dist/{ConnectedNativeDocxComparison-H2OZMWHT.cjs.map → ConnectedNativeDocxComparison-UVLZGS2V.cjs.map} +1 -1
  14. package/dist/{ConnectedNativeDocxEditor-43BI5LN6.js → ConnectedNativeDocxEditor-BRBL3MOV.js} +6 -6
  15. package/dist/{ConnectedNativeDocxEditor-43BI5LN6.js.map → ConnectedNativeDocxEditor-BRBL3MOV.js.map} +1 -1
  16. package/dist/{ConnectedNativeDocxEditor-6DQEM6SD.cjs → ConnectedNativeDocxEditor-KHR5I7W6.cjs} +8 -8
  17. package/dist/{ConnectedNativeDocxEditor-6DQEM6SD.cjs.map → ConnectedNativeDocxEditor-KHR5I7W6.cjs.map} +1 -1
  18. package/dist/{ConnectedStreamedWordArtifact-3VKYIG6C.cjs → ConnectedStreamedWordArtifact-DSVFI7BX.cjs} +8 -8
  19. package/dist/ConnectedStreamedWordArtifact-DSVFI7BX.cjs.map +1 -0
  20. package/dist/{ConnectedStreamedWordArtifact-TEB332E3.js → ConnectedStreamedWordArtifact-EQUE6WT5.js} +7 -7
  21. package/dist/ConnectedStreamedWordArtifact-EQUE6WT5.js.map +1 -0
  22. package/dist/{WorkspaceTableView-KG546U7M.cjs → WorkspaceTableView-2CGEO5KK.cjs} +6 -6
  23. package/dist/{WorkspaceTableView-KG546U7M.cjs.map → WorkspaceTableView-2CGEO5KK.cjs.map} +1 -1
  24. package/dist/{WorkspaceTableView-OSFIWJ5C.js → WorkspaceTableView-3ARFQYNO.js} +4 -4
  25. package/dist/{WorkspaceTableView-OSFIWJ5C.js.map → WorkspaceTableView-3ARFQYNO.js.map} +1 -1
  26. package/dist/agents/index.cjs +376 -376
  27. package/dist/agents/index.js +2 -2
  28. package/dist/calls/index.cjs +35 -35
  29. package/dist/calls/index.js +7 -7
  30. package/dist/chat/index.cjs +89 -89
  31. package/dist/chat/index.js +2 -2
  32. package/dist/{chunk-BRYRZOS3.cjs → chunk-3YZ3RUSB.cjs} +4 -4
  33. package/dist/{chunk-BRYRZOS3.cjs.map → chunk-3YZ3RUSB.cjs.map} +1 -1
  34. package/dist/{chunk-VPWCARVO.js → chunk-4DDPMLGU.js} +4 -4
  35. package/dist/{chunk-VPWCARVO.js.map → chunk-4DDPMLGU.js.map} +1 -1
  36. package/dist/{chunk-24H5WTGM.js → chunk-4U4NXFV5.js} +4 -4
  37. package/dist/{chunk-24H5WTGM.js.map → chunk-4U4NXFV5.js.map} +1 -1
  38. package/dist/{chunk-6EQSP77K.cjs → chunk-5ZHAHJ4H.cjs} +5 -5
  39. package/dist/{chunk-6EQSP77K.cjs.map → chunk-5ZHAHJ4H.cjs.map} +1 -1
  40. package/dist/{chunk-BIWPXSGS.cjs → chunk-6AJJJ5HR.cjs} +7 -7
  41. package/dist/{chunk-BIWPXSGS.cjs.map → chunk-6AJJJ5HR.cjs.map} +1 -1
  42. package/dist/{chunk-2YCCCXYV.js → chunk-7LN3ISPG.js} +3 -3
  43. package/dist/{chunk-2YCCCXYV.js.map → chunk-7LN3ISPG.js.map} +1 -1
  44. package/dist/{chunk-5NTSJV5H.cjs → chunk-BY2EW2QU.cjs} +16 -91
  45. package/dist/chunk-BY2EW2QU.cjs.map +1 -0
  46. package/dist/{chunk-FHB4G77H.js → chunk-CEO7YI7I.js} +3 -3
  47. package/dist/{chunk-FHB4G77H.js.map → chunk-CEO7YI7I.js.map} +1 -1
  48. package/dist/{chunk-LTO4JYU3.cjs → chunk-DWWRLKEZ.cjs} +188 -2
  49. package/dist/chunk-DWWRLKEZ.cjs.map +1 -0
  50. package/dist/chunk-E3IEZMRK.cjs +507 -0
  51. package/dist/chunk-E3IEZMRK.cjs.map +1 -0
  52. package/dist/{chunk-MLHOG7YH.js → chunk-EFDZRAW6.js} +3 -3
  53. package/dist/{chunk-MLHOG7YH.js.map → chunk-EFDZRAW6.js.map} +1 -1
  54. package/dist/chunk-FOIDBAZB.js +497 -0
  55. package/dist/chunk-FOIDBAZB.js.map +1 -0
  56. package/dist/{chunk-MB3S2ETI.cjs → chunk-G2BKHCI2.cjs} +2 -2
  57. package/dist/chunk-G2BKHCI2.cjs.map +1 -0
  58. package/dist/{chunk-EFSL4O3B.cjs → chunk-GT5FCYV5.cjs} +7 -7
  59. package/dist/{chunk-EFSL4O3B.cjs.map → chunk-GT5FCYV5.cjs.map} +1 -1
  60. package/dist/{chunk-QWKT4DO6.cjs → chunk-GX5MKJ3F.cjs} +433 -2
  61. package/dist/chunk-GX5MKJ3F.cjs.map +1 -0
  62. package/dist/{chunk-C3YIVBTU.cjs → chunk-HDEOORSV.cjs} +9 -9
  63. package/dist/{chunk-C3YIVBTU.cjs.map → chunk-HDEOORSV.cjs.map} +1 -1
  64. package/dist/{chunk-T4P237N6.js → chunk-ILBBV2ZY.js} +2 -2
  65. package/dist/chunk-ILBBV2ZY.js.map +1 -0
  66. package/dist/{chunk-XFSEPGF7.cjs → chunk-K53QRFPJ.cjs} +4 -4
  67. package/dist/{chunk-XFSEPGF7.cjs.map → chunk-K53QRFPJ.cjs.map} +1 -1
  68. package/dist/{chunk-NOKTUWTN.cjs → chunk-K7S5BMAB.cjs} +7 -7
  69. package/dist/{chunk-NOKTUWTN.cjs.map → chunk-K7S5BMAB.cjs.map} +1 -1
  70. package/dist/{chunk-FY4C7HU5.cjs → chunk-O3MRE2HL.cjs} +2233 -8
  71. package/dist/chunk-O3MRE2HL.cjs.map +1 -0
  72. package/dist/{chunk-N3HVTMQK.js → chunk-OPZBIGW4.js} +3 -3
  73. package/dist/{chunk-N3HVTMQK.js.map → chunk-OPZBIGW4.js.map} +1 -1
  74. package/dist/{chunk-JVXHVFUA.cjs → chunk-P6HVJP6Z.cjs} +4 -4
  75. package/dist/{chunk-JVXHVFUA.cjs.map → chunk-P6HVJP6Z.cjs.map} +1 -1
  76. package/dist/{chunk-PXYP3DM5.js → chunk-PD4AKBYZ.js} +432 -6
  77. package/dist/chunk-PD4AKBYZ.js.map +1 -0
  78. package/dist/{chunk-VKY4SQMH.js → chunk-REHG7VRQ.js} +5 -5
  79. package/dist/{chunk-VKY4SQMH.js.map → chunk-REHG7VRQ.js.map} +1 -1
  80. package/dist/{chunk-M4MZPH2S.js → chunk-SEZEEHLU.js} +190 -6
  81. package/dist/chunk-SEZEEHLU.js.map +1 -0
  82. package/dist/{chunk-5JEM3BWT.js → chunk-SYP2A4GQ.js} +4 -4
  83. package/dist/{chunk-5JEM3BWT.js.map → chunk-SYP2A4GQ.js.map} +1 -1
  84. package/dist/{chunk-QFYRXQTD.js → chunk-TTPXMCJL.js} +6 -80
  85. package/dist/chunk-TTPXMCJL.js.map +1 -0
  86. package/dist/{chunk-VMLEISRZ.cjs → chunk-UZVXVTTB.cjs} +17 -17
  87. package/dist/{chunk-VMLEISRZ.cjs.map → chunk-UZVXVTTB.cjs.map} +1 -1
  88. package/dist/{chunk-YDY4GIC2.cjs → chunk-V7JDMKNQ.cjs} +4 -4
  89. package/dist/{chunk-YDY4GIC2.cjs.map → chunk-V7JDMKNQ.cjs.map} +1 -1
  90. package/dist/{chunk-YPR4FSDJ.js → chunk-VA3YYR7R.js} +8 -192
  91. package/dist/chunk-VA3YYR7R.js.map +1 -0
  92. package/dist/{chunk-NUV5F6MM.js → chunk-WAIHNFUH.js} +3 -3
  93. package/dist/{chunk-NUV5F6MM.js.map → chunk-WAIHNFUH.js.map} +1 -1
  94. package/dist/{chunk-H5BFOVVL.cjs → chunk-WRERJFEV.cjs} +2 -188
  95. package/dist/chunk-WRERJFEV.cjs.map +1 -0
  96. package/dist/{chunk-4DKI37QQ.js → chunk-YAGSGBVM.js} +2213 -13
  97. package/dist/chunk-YAGSGBVM.js.map +1 -0
  98. package/dist/{chunk-K6W2GWCN.js → chunk-ZAYUJFPI.js} +3 -3
  99. package/dist/{chunk-K6W2GWCN.js.map → chunk-ZAYUJFPI.js.map} +1 -1
  100. package/dist/connect/docx.cjs +10 -10
  101. package/dist/connect/docx.js +6 -6
  102. package/dist/connect/index.cjs +1237 -591
  103. package/dist/connect/index.cjs.map +1 -1
  104. package/dist/connect/index.d.ts +3 -0
  105. package/dist/connect/index.js +665 -23
  106. package/dist/connect/index.js.map +1 -1
  107. package/dist/connect/viewer.cjs +27 -27
  108. package/dist/connect/viewer.js +10 -10
  109. package/dist/connection/panels/ConnectedPanelHost.d.ts +48 -0
  110. package/dist/connection/panels/useSessionPanelMode.d.ts +18 -0
  111. package/dist/connection/threads-page/ConnectedThreadsPage.d.ts +14 -0
  112. package/dist/connection/threads-page/ThreadSearch.d.ts +24 -0
  113. package/dist/connection/workflows/index.d.ts +1 -0
  114. package/dist/connection/workflows/useWorkflowsPageState.d.ts +134 -0
  115. package/dist/index.cjs +601 -585
  116. package/dist/index.js +8 -8
  117. package/dist/provider/host.d.ts +3 -0
  118. package/dist/shell/PanelPortal.d.ts +30 -0
  119. package/dist/shell/index.cjs +78 -61
  120. package/dist/shell/index.d.ts +3 -0
  121. package/dist/shell/index.js +3 -2
  122. package/dist/shell/panel-host.d.ts +8 -0
  123. package/dist/shell/panel-windows.d.ts +33 -0
  124. package/dist/studio/index.cjs +5 -5
  125. package/dist/studio/index.js +3 -3
  126. package/dist/workflow-canvas/index.cjs +21 -21
  127. package/dist/workflow-canvas/index.js +5 -5
  128. package/node_modules/@arbidocs/coedit/package.json +1 -1
  129. package/package.json +5 -5
  130. package/dist/ConnectedStreamedWordArtifact-3VKYIG6C.cjs.map +0 -1
  131. package/dist/ConnectedStreamedWordArtifact-TEB332E3.js.map +0 -1
  132. package/dist/chunk-4DKI37QQ.js.map +0 -1
  133. package/dist/chunk-5NTSJV5H.cjs.map +0 -1
  134. package/dist/chunk-EZSYYENN.js +0 -2700
  135. package/dist/chunk-EZSYYENN.js.map +0 -1
  136. package/dist/chunk-FY4C7HU5.cjs.map +0 -1
  137. package/dist/chunk-H5BFOVVL.cjs.map +0 -1
  138. package/dist/chunk-LTO4JYU3.cjs.map +0 -1
  139. package/dist/chunk-M4MZPH2S.js.map +0 -1
  140. package/dist/chunk-MB3S2ETI.cjs.map +0 -1
  141. package/dist/chunk-PUX4M22Q.cjs +0 -2735
  142. package/dist/chunk-PUX4M22Q.cjs.map +0 -1
  143. package/dist/chunk-PXYP3DM5.js.map +0 -1
  144. package/dist/chunk-QFYRXQTD.js.map +0 -1
  145. package/dist/chunk-QWKT4DO6.cjs.map +0 -1
  146. package/dist/chunk-T4P237N6.js.map +0 -1
  147. package/dist/chunk-YPR4FSDJ.js.map +0 -1
@@ -1,2735 +0,0 @@
1
- "use client";
2
- 'use strict';
3
-
4
- var chunkFY4C7HU5_cjs = require('./chunk-FY4C7HU5.cjs');
5
- var chunk2QDNQM63_cjs = require('./chunk-2QDNQM63.cjs');
6
- var chunkAQPZ4QMV_cjs = require('./chunk-AQPZ4QMV.cjs');
7
- var chunkSIB6C7P7_cjs = require('./chunk-SIB6C7P7.cjs');
8
- var chunkDVUZTGVL_cjs = require('./chunk-DVUZTGVL.cjs');
9
- var chunkV4ISCZJ7_cjs = require('./chunk-V4ISCZJ7.cjs');
10
- var chunk2EI7NCUA_cjs = require('./chunk-2EI7NCUA.cjs');
11
- var chunkX6MGM3LH_cjs = require('./chunk-X6MGM3LH.cjs');
12
- var chunkLKK52DEY_cjs = require('./chunk-LKK52DEY.cjs');
13
- var chunkMEMWZ72Y_cjs = require('./chunk-MEMWZ72Y.cjs');
14
- var chunkZW6FPIFC_cjs = require('./chunk-ZW6FPIFC.cjs');
15
- var chunkEZLZ3MDU_cjs = require('./chunk-EZLZ3MDU.cjs');
16
- var chunkUFEXJIEY_cjs = require('./chunk-UFEXJIEY.cjs');
17
- var chunkFX3K6LNZ_cjs = require('./chunk-FX3K6LNZ.cjs');
18
- var chunkMHVNT4J3_cjs = require('./chunk-MHVNT4J3.cjs');
19
- var react = require('react');
20
- var lucideReact = require('lucide-react');
21
- var ui = require('@arbidocs/react/ui');
22
- var jsxRuntime = require('react/jsx-runtime');
23
-
24
- function useWorkflowPreview(workflow, { answer = "{prompt}", delayMs = 400, resolveWorkflow, compose } = {}) {
25
- const steps = chunkEZLZ3MDU_cjs.workflowSteps(workflow);
26
- const [inputs, setInputs] = react.useState(() => chunkEZLZ3MDU_cjs.initialRunInputs(workflow));
27
- const [states, setStates] = react.useState({});
28
- const set = (id, state) => setStates((s) => ({ ...s, [id]: state }));
29
- const timers = react.useRef(/* @__PURE__ */ new Map());
30
- react.useEffect(() => {
31
- const pending = timers.current;
32
- return () => {
33
- for (const t of pending.values()) clearTimeout(t);
34
- pending.clear();
35
- setStates(
36
- (s) => Object.fromEntries(
37
- Object.entries(s).map(([id, v]) => [
38
- id,
39
- v.status === "running" ? { status: "pending" } : v
40
- ])
41
- )
42
- );
43
- };
44
- }, []);
45
- react.useEffect(() => {
46
- if (Object.values(states).some((s) => s.status === "running")) return;
47
- const next = steps.find(
48
- (s) => (s.kind === "agent" || s.kind === "action") && chunkEZLZ3MDU_cjs.stepPhase(steps, states, s.id) === "ready"
49
- );
50
- if (!next || next.kind !== "agent" && next.kind !== "action") return;
51
- const prompt = next.kind === "agent" ? chunkEZLZ3MDU_cjs.composeStepPrompt(workflow, next, inputs, { resolveWorkflow, compose }) : "";
52
- set(next.id, { status: "running", startedAt: (/* @__PURE__ */ new Date()).toISOString() });
53
- timers.current.set(
54
- next.id,
55
- setTimeout(() => {
56
- timers.current.delete(next.id);
57
- set(
58
- next.id,
59
- next.kind === "agent" ? { status: "done", text: answer.replace("{prompt}", prompt) } : { status: "done" }
60
- );
61
- }, delayMs)
62
- );
63
- }, [states, steps, workflow]);
64
- return chunkFY4C7HU5_cjs.useWorkflowView({
65
- steps,
66
- states,
67
- inputs,
68
- setInput: (name, value) => setInputs((i) => ({ ...i, [name]: value })),
69
- complete: async (step) => set(step.id, { status: "done" }),
70
- skip: async (id) => set(id, { status: "skipped" }),
71
- retry: async (id) => set(id, { status: "pending" }),
72
- isLocked: (id) => states[id]?.status === "done"
73
- });
74
- }
75
- var DEFAULT_AGENT_CARD_LABELS = {
76
- running: "Running",
77
- runningIndicator: "Running",
78
- runningCount: (count) => `${count} running`,
79
- taskCount: (count) => count > 0 ? chunkUFEXJIEY_cjs.formatCount(count, { one: "task", other: "tasks" }) : "no tasks yet",
80
- goalMet: (met, total) => `\u2713 ${met}/${total} met`,
81
- watch: "Watch",
82
- message: "Message",
83
- assignTask: "Assign task",
84
- edit: "Edit",
85
- copyAddress: "Copy address",
86
- deleteAgent: (name) => `Delete agent ${name}`
87
- };
88
- var ACTION = "h-9 gap-1.5 px-2 text-sm pointer-coarse:h-11";
89
- function AgentCard({
90
- name,
91
- avatar,
92
- runningCount,
93
- taskCount,
94
- goalProgress: goalProgress2,
95
- details,
96
- onWatch,
97
- onMessage,
98
- onAssignTask,
99
- onEdit,
100
- onCopyAddress,
101
- onDelete,
102
- href,
103
- onSelect,
104
- labels,
105
- testIds,
106
- testId,
107
- className,
108
- ...rest
109
- }) {
110
- const l = { ...DEFAULT_AGENT_CARD_LABELS, ...labels };
111
- return /* @__PURE__ */ jsxRuntime.jsxs(
112
- "div",
113
- {
114
- ...rest,
115
- className: ui.cn("rounded-lg bg-muted p-4", className),
116
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId ?? testIds?.root, { testId: `agent-card-${name}` }),
117
- "data-slot": "agent-card",
118
- children: [
119
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
120
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
121
- avatar,
122
- runningCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
123
- "span",
124
- {
125
- className: "absolute -right-0.5 -top-0.5 size-2.5 rounded-full bg-ai-ink",
126
- role: "img",
127
- "aria-label": l.runningIndicator,
128
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 animate-ping rounded-full bg-ai-ink opacity-60" })
129
- }
130
- )
131
- ] }),
132
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
133
- href ? /* @__PURE__ */ jsxRuntime.jsx(
134
- chunkX6MGM3LH_cjs.ActionLink,
135
- {
136
- href,
137
- onSelect,
138
- className: "block max-w-full truncate text-left font-medium hover:underline",
139
- children: name
140
- }
141
- ) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate font-medium", children: name }),
142
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1 text-xs text-muted-foreground", children: [
143
- runningCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-ai-soft px-2 py-px text-ai-ink", children: l.runningCount(runningCount) }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-background px-2 py-px", children: l.taskCount(taskCount) }),
144
- goalProgress2 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-background px-2 py-px", children: l.goalMet(goalProgress2.met, goalProgress2.total) })
145
- ] }),
146
- details
147
- ] })
148
- ] }),
149
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-1 pt-1", children: [
150
- onMessage && /* @__PURE__ */ jsxRuntime.jsxs(
151
- ui.Button,
152
- {
153
- variant: "ghost",
154
- size: "sm",
155
- className: ACTION,
156
- onClick: onMessage,
157
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.message, { testId: `agent-message-${name}` }),
158
- children: [
159
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { size: 14 }),
160
- " ",
161
- l.message
162
- ]
163
- }
164
- ),
165
- onWatch && /* @__PURE__ */ jsxRuntime.jsxs(
166
- ui.Button,
167
- {
168
- variant: "ghost",
169
- size: "sm",
170
- className: ui.cn(ACTION, "text-ai-ink hover:text-ai-ink"),
171
- onClick: onWatch,
172
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.watch, { testId: `agent-watch-run-${name}` }),
173
- children: [
174
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { size: 14 }),
175
- " ",
176
- l.watch
177
- ]
178
- }
179
- ),
180
- onAssignTask && /* @__PURE__ */ jsxRuntime.jsxs(
181
- ui.Button,
182
- {
183
- variant: "ghost",
184
- size: "sm",
185
- className: ACTION,
186
- onClick: onAssignTask,
187
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.assignTask, { testId: `agent-assign-task-${name}` }),
188
- children: [
189
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClipboardList, { size: 14 }),
190
- " ",
191
- l.assignTask
192
- ]
193
- }
194
- ),
195
- onEdit && /* @__PURE__ */ jsxRuntime.jsxs(
196
- ui.Button,
197
- {
198
- variant: "ghost",
199
- size: "sm",
200
- className: ACTION,
201
- onClick: onEdit,
202
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.edit, { testId: `agent-edit-${name}` }),
203
- children: [
204
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { size: 14 }),
205
- " ",
206
- l.edit
207
- ]
208
- }
209
- ),
210
- onCopyAddress && /* @__PURE__ */ jsxRuntime.jsxs(
211
- ui.Button,
212
- {
213
- variant: "ghost",
214
- size: "sm",
215
- className: ui.cn(ACTION, "text-muted-foreground"),
216
- onClick: onCopyAddress,
217
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.copyAddress, { testId: `agent-copy-address-${name}` }),
218
- children: [
219
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { size: 14 }),
220
- " ",
221
- l.copyAddress
222
- ]
223
- }
224
- ),
225
- onDelete && /* @__PURE__ */ jsxRuntime.jsx(
226
- ui.Button,
227
- {
228
- variant: "ghost",
229
- size: "sm",
230
- className: ui.cn(ACTION, "ml-auto text-muted-foreground hover:text-red-text"),
231
- onClick: onDelete,
232
- "aria-label": l.deleteAgent(name),
233
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.delete, { testId: `agent-delete-${name}` }),
234
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { size: 14 })
235
- }
236
- )
237
- ] })
238
- ]
239
- }
240
- );
241
- }
242
- var DEFAULT_AGENT_GALLERY_LABELS = {
243
- description: "Personas that work for you, on demand.",
244
- emptyTitle: "Create your first agent",
245
- emptyDescription: "Describe a persona, pick its tools, generate an avatar, then hand it work from an agent card and watch it converge.",
246
- emptyCta: "Create an agent",
247
- newAgent: "New agent"
248
- };
249
- function AgentGallery({
250
- count,
251
- onCreate,
252
- children,
253
- description,
254
- labels,
255
- testIds,
256
- className
257
- }) {
258
- const l = { ...DEFAULT_AGENT_GALLERY_LABELS, ...labels };
259
- if (count === 0) {
260
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cn("mt-8", className), children: /* @__PURE__ */ jsxRuntime.jsx(
261
- chunkZW6FPIFC_cjs.EmptyState,
262
- {
263
- className: "rounded-lg border-0 bg-muted",
264
- icon: lucideReact.Bot,
265
- title: l.emptyTitle,
266
- description: l.emptyDescription,
267
- action: /* @__PURE__ */ jsxRuntime.jsxs(
268
- ui.Button,
269
- {
270
- onClick: onCreate,
271
- className: "gap-1.5",
272
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.emptyCta, { testId: "agent-empty-cta" }),
273
- children: [
274
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { size: 16 }),
275
- " ",
276
- l.emptyCta
277
- ]
278
- }
279
- )
280
- }
281
- ) });
282
- }
283
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
284
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-x-3 gap-y-2", children: [
285
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "min-w-0 text-sm text-muted-foreground", children: description ?? l.description }),
286
- /* @__PURE__ */ jsxRuntime.jsxs(
287
- ui.Button,
288
- {
289
- size: "sm",
290
- onClick: onCreate,
291
- className: "h-8 gap-1.5 pointer-coarse:h-11",
292
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.createButton, { testId: "agent-create-button" }),
293
- children: [
294
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 16 }),
295
- " ",
296
- l.newAgent
297
- ]
298
- }
299
- )
300
- ] }),
301
- /* @__PURE__ */ jsxRuntime.jsx(
302
- "div",
303
- {
304
- className: "grid grid-cols-[repeat(auto-fill,minmax(16rem,1fr))] gap-4",
305
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.gallery, { testId: "agent-gallery" }),
306
- "data-slot": "agent-gallery",
307
- children
308
- }
309
- )
310
- ] });
311
- }
312
- var DEFAULT_SKILL_CARD_LABELS = {
313
- global: "Global",
314
- globalTitle: "Shared with everyone in the marketplace",
315
- preview: "Preview skill",
316
- edit: "Edit skill",
317
- export: "Export skill",
318
- makePrivate: "Make private",
319
- makePrivateTooltip: "Make private (unpublish)",
320
- publish: "Publish to marketplace"
321
- };
322
- function SkillCard({
323
- name,
324
- description,
325
- type,
326
- visibility = "mine",
327
- isOwner = true,
328
- icon,
329
- onClick,
330
- onPreview,
331
- onEdit,
332
- onExport,
333
- onToggleVisibility,
334
- href,
335
- labels,
336
- testId,
337
- testIds,
338
- className,
339
- ...rest
340
- }) {
341
- const l = { ...DEFAULT_SKILL_CARD_LABELS, ...labels };
342
- const isGlobal = visibility === "global";
343
- return /* @__PURE__ */ jsxRuntime.jsxs(
344
- "div",
345
- {
346
- ...rest,
347
- role: "button",
348
- tabIndex: 0,
349
- className: ui.cn(
350
- "flex w-full cursor-pointer flex-wrap items-center gap-x-3 gap-y-1 rounded-lg bg-muted px-4 py-3 transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
351
- className
352
- ),
353
- onClick,
354
- onKeyDown: chunkFY4C7HU5_cjs.activateOnKey(onClick),
355
- "data-skill-name": name,
356
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId ?? testIds?.root, { testId: "skill-card" }),
357
- "data-slot": "skill-card",
358
- children: [
359
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-primary [&>svg]:size-5", children: icon }),
360
- href ? (
361
- // The link owns plain + modified clicks; stop the row handler from double-firing.
362
- /* @__PURE__ */ jsxRuntime.jsx("span", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(
363
- chunkX6MGM3LH_cjs.ActionLink,
364
- {
365
- href,
366
- onSelect: onClick,
367
- className: "whitespace-nowrap font-mono text-sm font-medium",
368
- children: [
369
- "/",
370
- name
371
- ]
372
- }
373
- ) })
374
- ) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "whitespace-nowrap font-mono text-sm font-medium", children: [
375
- "/",
376
- name
377
- ] }),
378
- type && type !== "markdown" && /* @__PURE__ */ jsxRuntime.jsx(chunkFY4C7HU5_cjs.SkillTypeBadge, { type }),
379
- isGlobal && /* @__PURE__ */ jsxRuntime.jsx(chunkFY4C7HU5_cjs.SkillGlobalBadge, { labels: l }),
380
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 text-sm text-muted-foreground max-sm:order-last max-sm:w-full max-sm:line-clamp-2 sm:flex-1 sm:truncate", children: description }),
381
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-auto flex shrink-0 items-center gap-1", "data-slot": "skill-card-actions", children: [
382
- /* @__PURE__ */ jsxRuntime.jsx(
383
- chunkFY4C7HU5_cjs.SkillActionButton,
384
- {
385
- label: l.preview,
386
- onClick: onPreview,
387
- testId: chunkMHVNT4J3_cjs.testIdOr(testIds?.preview, { testId: "preview-skill-button" }),
388
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "size-4 text-muted-foreground" })
389
- }
390
- ),
391
- /* @__PURE__ */ jsxRuntime.jsx(
392
- chunkFY4C7HU5_cjs.SkillActionButton,
393
- {
394
- label: l.edit,
395
- onClick: onEdit,
396
- testId: chunkMHVNT4J3_cjs.testIdOr(testIds?.edit, { testId: "edit-skill-button" }),
397
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "size-4 text-muted-foreground" })
398
- }
399
- ),
400
- /* @__PURE__ */ jsxRuntime.jsx(
401
- chunkFY4C7HU5_cjs.SkillActionButton,
402
- {
403
- label: l.export,
404
- onClick: onExport,
405
- testId: chunkMHVNT4J3_cjs.testIdOr(testIds?.export, { testId: "export-skill-button" }),
406
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "size-4 text-muted-foreground" })
407
- }
408
- ),
409
- isOwner && onToggleVisibility && /* @__PURE__ */ jsxRuntime.jsx(
410
- chunkFY4C7HU5_cjs.SkillActionButton,
411
- {
412
- label: isGlobal ? l.makePrivate : l.publish,
413
- tooltip: isGlobal ? l.makePrivateTooltip : l.publish,
414
- onClick: onToggleVisibility,
415
- testId: chunkMHVNT4J3_cjs.testIdOr(testIds?.toggleVisibility, {
416
- testId: "toggle-skill-visibility-button"
417
- }),
418
- children: isGlobal ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { className: "size-4 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "size-4 text-primary" })
419
- }
420
- )
421
- ] })
422
- ]
423
- }
424
- );
425
- }
426
- var DEFAULT_SKILL_ROW_LABELS = {
427
- global: "Global",
428
- globalTitle: "Shared with everyone in the marketplace",
429
- preview: "Preview",
430
- edit: "Edit",
431
- makePrivate: "Make private",
432
- publish: "Publish to marketplace",
433
- delete: "Delete",
434
- insertTitle: (name) => `Insert /${name} into the chat`
435
- };
436
- function SkillRow({
437
- name,
438
- description,
439
- type,
440
- isGlobal = false,
441
- icon,
442
- onInvoke,
443
- onPreview,
444
- onEdit,
445
- onTogglePublish,
446
- onDelete,
447
- href,
448
- labels,
449
- testId,
450
- className,
451
- ...rest
452
- }) {
453
- const l = { ...DEFAULT_SKILL_ROW_LABELS, ...labels };
454
- return /* @__PURE__ */ jsxRuntime.jsxs(
455
- "div",
456
- {
457
- ...rest,
458
- role: "button",
459
- tabIndex: 0,
460
- className: ui.cn(
461
- "flex cursor-pointer items-center gap-2 px-4 py-2 hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
462
- className
463
- ),
464
- onClick: onInvoke,
465
- onKeyDown: chunkFY4C7HU5_cjs.activateOnKey(onInvoke),
466
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: `skills-panel-row-${name}` }),
467
- "data-slot": "skill-row",
468
- title: l.insertTitle(name),
469
- children: [
470
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-primary [&>svg]:size-4", children: icon }),
471
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
472
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
473
- href ? (
474
- // The link owns plain + modified clicks; stop the row handler from double-firing.
475
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsxs(chunkX6MGM3LH_cjs.ActionLink, { href, onSelect: onInvoke, className: "truncate font-mono text-sm", children: [
476
- "/",
477
- name
478
- ] }) })
479
- ) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate font-mono text-sm", children: [
480
- "/",
481
- name
482
- ] }),
483
- type && type !== "markdown" && /* @__PURE__ */ jsxRuntime.jsx(chunkFY4C7HU5_cjs.SkillTypeBadge, { type }),
484
- isGlobal && /* @__PURE__ */ jsxRuntime.jsx(chunkFY4C7HU5_cjs.SkillGlobalBadge, { labels: l })
485
- ] }),
486
- description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-xs text-muted-foreground", children: description })
487
- ] }),
488
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-0.5", children: [
489
- /* @__PURE__ */ jsxRuntime.jsx(chunkFY4C7HU5_cjs.SkillActionButton, { label: l.preview, onClick: () => onPreview(), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "size-4" }) }),
490
- onEdit && /* @__PURE__ */ jsxRuntime.jsx(chunkFY4C7HU5_cjs.SkillActionButton, { label: l.edit, onClick: () => onEdit(), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "size-4" }) }),
491
- onTogglePublish && /* @__PURE__ */ jsxRuntime.jsx(
492
- chunkFY4C7HU5_cjs.SkillActionButton,
493
- {
494
- label: isGlobal ? l.makePrivate : l.publish,
495
- onClick: () => onTogglePublish(),
496
- children: isGlobal ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "size-4 text-primary" })
497
- }
498
- ),
499
- onDelete && /* @__PURE__ */ jsxRuntime.jsx(chunkFY4C7HU5_cjs.SkillActionButton, { label: l.delete, onClick: () => onDelete(), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "size-4 text-destructive" }) })
500
- ] })
501
- ]
502
- }
503
- );
504
- }
505
-
506
- // src/agents/tasks/elapsed.ts
507
- function formatElapsed(startTime, endTime) {
508
- const elapsedMs = (endTime || Date.now()) - startTime;
509
- if (elapsedMs < 1e3) return `${Math.round(elapsedMs)}ms`;
510
- if (elapsedMs < 6e4) return `${Math.round(elapsedMs / 1e3)}s`;
511
- if (elapsedMs < 36e5) {
512
- const minutes2 = Math.floor(elapsedMs / 6e4);
513
- const seconds = Math.round(elapsedMs % 6e4 / 1e3);
514
- return seconds > 0 ? `${minutes2}m ${seconds}s` : `${minutes2}m`;
515
- }
516
- const hours = Math.floor(elapsedMs / 36e5);
517
- const minutes = Math.round(elapsedMs % 36e5 / 6e4);
518
- return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
519
- }
520
- var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["parsing", "encrypting", "indexing", "analysing"]);
521
- var RUNNING_STATUSES = /* @__PURE__ */ new Set(["queued", ...ACTIVE_STATUSES]);
522
- var TONES = {
523
- completed: { text: "text-green-text", bar: "bg-green-text/90", Icon: lucideReact.Check },
524
- failed: { text: "text-red-text", bar: "bg-red-text/90", Icon: lucideReact.X },
525
- parsing: { text: "text-blue-text", bar: "bg-blue-text/90", Icon: lucideReact.Loader2 },
526
- encrypting: { text: "text-blue-text", bar: "bg-blue-text/90", Icon: lucideReact.Loader2 },
527
- indexing: { text: "text-blue-text", bar: "bg-blue-text/90", Icon: lucideReact.Loader2 },
528
- analysing: { text: "text-blue-text", bar: "bg-blue-text/90", Icon: lucideReact.Loader2 },
529
- queued: { text: "text-yellow-text", bar: "bg-yellow-text/90", Icon: lucideReact.Loader2 },
530
- skipped: { text: "text-gray-text", bar: "bg-gray-text/90", Icon: lucideReact.SkipForward },
531
- empty: { text: "text-yellow-text", bar: "bg-yellow-text/90", Icon: lucideReact.FileX },
532
- "low-content": { text: "text-yellow-text", bar: "bg-yellow-text/90", Icon: lucideReact.AlertTriangle }
533
- };
534
- var DEFAULT_TONE = { text: "text-gray-text", bar: "bg-blue-text/90", Icon: lucideReact.Loader2 };
535
- var DEFAULT_UPLOAD_TASK_ITEM_LABELS = {
536
- delete: "Delete",
537
- deleteTitle: "Delete file",
538
- progress: (fileName) => `${fileName} progress`,
539
- status: (status, percent) => `${status.charAt(0).toUpperCase() + status.slice(1)} - ${percent}%`
540
- };
541
- function UploadTaskItem({
542
- taskId,
543
- fileName,
544
- status,
545
- progress,
546
- startTime,
547
- endTime,
548
- fileIcon,
549
- onDelete,
550
- testIds,
551
- labels,
552
- className
553
- }) {
554
- const l = { ...DEFAULT_UPLOAD_TASK_ITEM_LABELS, ...labels };
555
- const [elapsed, setElapsed] = react.useState("");
556
- react.useEffect(() => {
557
- if (!startTime) {
558
- setElapsed("");
559
- return;
560
- }
561
- if (RUNNING_STATUSES.has(status)) {
562
- const tick = () => setElapsed(formatElapsed(startTime));
563
- tick();
564
- const interval = setInterval(tick, 1e3);
565
- return () => clearInterval(interval);
566
- }
567
- setElapsed(formatElapsed(startTime, endTime));
568
- }, [startTime, endTime, status]);
569
- const percent = progress > 1 ? progress : progress * 100;
570
- const tone = TONES[status] ?? DEFAULT_TONE;
571
- const StatusIcon2 = tone.Icon;
572
- return /* @__PURE__ */ jsxRuntime.jsxs(
573
- "div",
574
- {
575
- className: ui.cn(
576
- "mb-2 w-full max-w-full overflow-hidden rounded-md bg-muted p-2 box-border",
577
- className
578
- ),
579
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.item?.(taskId), { testId: `task-item-${taskId}` }),
580
- "data-slot": "upload-task-item",
581
- children: [
582
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1 flex w-full max-w-full items-center gap-2 overflow-hidden", children: [
583
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cn("shrink-0", tone.text), children: /* @__PURE__ */ jsxRuntime.jsx(StatusIcon2, { className: ui.cn("size-4", ACTIVE_STATUSES.has(status) && "animate-spin") }) }),
584
- fileIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: fileIcon }),
585
- /* @__PURE__ */ jsxRuntime.jsx(
586
- "div",
587
- {
588
- className: "min-w-0 flex-1 truncate text-sm font-medium",
589
- title: fileName,
590
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.fileName?.(taskId), { testId: `task-filename-${taskId}` }),
591
- children: fileName
592
- }
593
- )
594
- ] }),
595
- /* @__PURE__ */ jsxRuntime.jsx(
596
- "div",
597
- {
598
- className: "mb-1 h-2 w-full max-w-full overflow-hidden rounded-md bg-background",
599
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.progressBar?.(taskId), {
600
- testId: `task-progress-bar-${taskId}`
601
- }),
602
- role: "progressbar",
603
- "aria-valuemin": 0,
604
- "aria-valuemax": 100,
605
- "aria-valuenow": Math.round(percent),
606
- "aria-label": l.progress(fileName),
607
- children: /* @__PURE__ */ jsxRuntime.jsx(
608
- "div",
609
- {
610
- className: ui.cn("h-2 rounded-md transition-all duration-300 ease-in-out", tone.bar),
611
- style: { width: `${percent}%` }
612
- }
613
- )
614
- }
615
- ),
616
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-full items-center justify-between overflow-hidden text-sm", children: [
617
- /* @__PURE__ */ jsxRuntime.jsxs(
618
- "span",
619
- {
620
- className: "truncate text-gray-text",
621
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.status?.(taskId), { testId: `task-status-${taskId}` }),
622
- children: [
623
- l.status(status, Math.round(percent)),
624
- elapsed && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-2 text-muted-foreground", children: [
625
- "(",
626
- elapsed,
627
- ")"
628
- ] })
629
- ]
630
- }
631
- ),
632
- status === "failed" && onDelete && /* @__PURE__ */ jsxRuntime.jsx(
633
- "button",
634
- {
635
- type: "button",
636
- onClick: () => onDelete(taskId),
637
- className: "shrink-0 text-sm text-red-text hover:text-red-text/80 pointer-coarse:min-h-11 pointer-coarse:px-3",
638
- title: l.deleteTitle,
639
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.delete?.(taskId), { testId: `delete-task-${taskId}` }),
640
- children: l.delete
641
- }
642
- )
643
- ] })
644
- ]
645
- }
646
- );
647
- }
648
- var DEFAULT_UPLOAD_TASK_LIST_LABELS = {
649
- title: "Active Tasks",
650
- empty: "No documents in this category"
651
- };
652
- function UploadTaskList({
653
- tasks,
654
- filter,
655
- title,
656
- onDelete,
657
- renderFileIcon,
658
- showEmptyState = true,
659
- testIds,
660
- labels,
661
- itemLabels,
662
- className
663
- }) {
664
- const l = { ...DEFAULT_UPLOAD_TASK_LIST_LABELS, ...labels };
665
- const heading = title ?? l.title;
666
- const safeTasks = typeof tasks === "object" && tasks !== null ? tasks : {};
667
- let entries = Object.entries(safeTasks);
668
- if (filter) entries = entries.filter(([id, task]) => filter(id, task));
669
- if (entries.length === 0) {
670
- return showEmptyState ? /* @__PURE__ */ jsxRuntime.jsx(
671
- "div",
672
- {
673
- className: "text-sm italic text-muted-foreground",
674
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.empty, { testId: "task-list-empty-state" }),
675
- children: l.empty
676
- }
677
- ) : null;
678
- }
679
- return /* @__PURE__ */ jsxRuntime.jsxs(
680
- "div",
681
- {
682
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.root, { testId: "task-status-list" }),
683
- "data-slot": "upload-task-list",
684
- className: ui.cn("box-border w-full max-w-full", className),
685
- children: [
686
- heading && /* @__PURE__ */ jsxRuntime.jsx(
687
- "h3",
688
- {
689
- className: "mb-2 truncate text-sm font-semibold",
690
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.title, { testId: "task-list-title" }),
691
- children: heading
692
- }
693
- ),
694
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "box-border w-full max-w-full overflow-hidden", children: entries.map(([taskId, task]) => /* @__PURE__ */ jsxRuntime.jsx(
695
- UploadTaskItem,
696
- {
697
- taskId,
698
- fileName: task.fileName,
699
- status: task.status,
700
- progress: task.progress,
701
- startTime: task.startTime,
702
- endTime: task.endTime,
703
- fileIcon: renderFileIcon?.(task.fileName),
704
- onDelete,
705
- labels: itemLabels,
706
- className: "box-border max-w-full"
707
- },
708
- taskId
709
- )) })
710
- ]
711
- }
712
- );
713
- }
714
- var DEFAULT_TASK_OUTPUTS_CELL_LABELS = {
715
- none: "\u2014",
716
- open: (count) => `${count} ${count === 1 ? "output" : "outputs"}`,
717
- more: (count) => `+${count}`
718
- };
719
- function TaskOutputsCell({ id, outputs, onOpen, testId, labels }) {
720
- const l = { ...DEFAULT_TASK_OUTPUTS_CELL_LABELS, ...labels };
721
- const base = chunkMHVNT4J3_cjs.testIdOr(testId, { testId: `task-outputs-${id}` });
722
- if (!outputs || outputs.length === 0) {
723
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", "data-testid": base, "data-state": "none", children: l.none });
724
- }
725
- const [first] = outputs;
726
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
727
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
728
- ui.Button,
729
- {
730
- variant: "ghost",
731
- size: "sm",
732
- className: "h-7 max-w-full gap-1.5 px-2 text-xs",
733
- "aria-label": l.open(outputs.length),
734
- "data-testid": base,
735
- "data-count": outputs.length,
736
- children: [
737
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-3.5 shrink-0", "aria-hidden": true }),
738
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: first.name }),
739
- outputs.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-muted-foreground", children: l.more(outputs.length - 1) })
740
- ]
741
- }
742
- ) }),
743
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuContent, { align: "start", children: outputs.map((o) => /* @__PURE__ */ jsxRuntime.jsxs(
744
- ui.DropdownMenuItem,
745
- {
746
- onSelect: () => onOpen(o.id),
747
- "data-testid": `task-output-${id}-${o.id}`,
748
- children: [
749
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "mr-2 size-4", "aria-hidden": true }),
750
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: o.name })
751
- ]
752
- },
753
- o.id
754
- )) })
755
- ] });
756
- }
757
- function TaskMoveDialog({
758
- open,
759
- onOpenChange,
760
- options,
761
- currentParentId,
762
- onPick,
763
- labels,
764
- testId
765
- }) {
766
- const [query, setQuery] = react.useState("");
767
- const id = chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "task-move" });
768
- const q = query.trim().toLowerCase();
769
- const shown = q ? options.filter((o) => o.label.toLowerCase().includes(q)) : options;
770
- const pick = (parentId) => {
771
- onPick(parentId);
772
- onOpenChange(false);
773
- };
774
- return /* @__PURE__ */ jsxRuntime.jsx(
775
- ui.Dialog,
776
- {
777
- open,
778
- onOpenChange: (next) => {
779
- if (!next) setQuery("");
780
- onOpenChange(next);
781
- },
782
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { presentation: "sheet", className: "max-h-[80dvh] sm:max-w-md", "data-testid": id, children: [
783
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
784
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: labels.title }),
785
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { className: "sr-only", children: labels.title })
786
- ] }),
787
- /* @__PURE__ */ jsxRuntime.jsx(
788
- ui.Input,
789
- {
790
- value: query,
791
- placeholder: labels.search,
792
- "aria-label": labels.search,
793
- onChange: (e) => setQuery(e.target.value),
794
- "data-testid": `${id}-search`
795
- }
796
- ),
797
- /* @__PURE__ */ jsxRuntime.jsxs(
798
- "ul",
799
- {
800
- className: "flex max-h-[50dvh] flex-col gap-1 overflow-y-auto",
801
- "data-testid": `${id}-list`,
802
- children: [
803
- !q && /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
804
- ui.Button,
805
- {
806
- variant: "ghost",
807
- className: "h-9 w-full justify-start gap-2 pointer-coarse:h-11",
808
- disabled: !currentParentId,
809
- onClick: () => pick(null),
810
- "data-testid": `${id}-none`,
811
- children: labels.none
812
- }
813
- ) }),
814
- shown.map((o) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
815
- ui.Button,
816
- {
817
- variant: "ghost",
818
- className: "h-9 w-full justify-start gap-2 pointer-coarse:h-11",
819
- disabled: o.id === currentParentId,
820
- onClick: () => pick(o.id),
821
- "data-testid": `${id}-option-${o.id}`,
822
- children: [
823
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownRight, { className: "size-3.5 shrink-0", "aria-hidden": true }),
824
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: o.label })
825
- ]
826
- }
827
- ) }, o.id)),
828
- shown.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("li", { className: "px-2 py-4 text-center text-sm text-muted-foreground", children: labels.empty })
829
- ]
830
- }
831
- ),
832
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "outline", onClick: () => onOpenChange(false), children: labels.cancel }) })
833
- ] })
834
- }
835
- );
836
- }
837
- function TaskRowMenu({
838
- task,
839
- status,
840
- busy,
841
- isOwner,
842
- canAdmin,
843
- canEdit,
844
- labels,
845
- canMarkDone = canEdit,
846
- canReopen = canEdit,
847
- selected = false,
848
- onToggleSelected,
849
- onMarkDone,
850
- onReopen,
851
- onAddSubtask,
852
- onEdit,
853
- onDelete,
854
- onMoveTo,
855
- onOpenActivity,
856
- onToggleShared,
857
- onGrantAccess
858
- }) {
859
- const [open, setOpen] = react.useState(false);
860
- const id = task.external_id;
861
- const isChat = status === "chat";
862
- const done = status === "done";
863
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { open, onOpenChange: setOpen, children: [
864
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
865
- ui.Button,
866
- {
867
- variant: "ghost",
868
- size: "icon",
869
- className: "size-8 pointer-coarse:size-11",
870
- "aria-label": labels.moreActions,
871
- "data-testid": `task-menu-${id}`,
872
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { className: "size-4", "aria-hidden": true })
873
- }
874
- ) }),
875
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuContent, { align: "end", children: [
876
- onToggleSelected && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: onToggleSelected, "data-testid": `task-select-${id}`, children: selected ? "Deselect task" : "Select task" }),
877
- isOwner && onGrantAccess && task.pending_auth_request_id && /* @__PURE__ */ jsxRuntime.jsxs(
878
- ui.DropdownMenuItem,
879
- {
880
- onSelect: onGrantAccess,
881
- "data-testid": `task-grant-${id}`,
882
- className: "text-destructive",
883
- children: [
884
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.KeyRound, { className: "mr-2 size-4", "aria-hidden": true }),
885
- labels.grantAccess
886
- ]
887
- }
888
- ),
889
- isChat || !canEdit ? null : done ? canReopen && /* @__PURE__ */ jsxRuntime.jsxs(
890
- ui.DropdownMenuItem,
891
- {
892
- disabled: busy,
893
- onSelect: onReopen,
894
- "data-testid": `task-reopen-${id}`,
895
- children: [
896
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "mr-2 size-4", "aria-hidden": true }),
897
- labels.reopen
898
- ]
899
- }
900
- ) : canMarkDone && /* @__PURE__ */ jsxRuntime.jsxs(
901
- ui.DropdownMenuItem,
902
- {
903
- disabled: busy,
904
- onSelect: onMarkDone,
905
- "data-testid": `task-mark-done-${id}`,
906
- children: [
907
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCheck, { className: "mr-2 size-4", "aria-hidden": true }),
908
- labels.markDone
909
- ]
910
- }
911
- ),
912
- !isChat && onOpenActivity && /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuItem, { onSelect: onOpenActivity, "data-testid": `task-activity-${id}`, children: [
913
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "mr-2 size-4", "aria-hidden": true }),
914
- labels.activity
915
- ] }),
916
- isOwner && onToggleShared && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { disabled: busy, onSelect: onToggleShared, children: task.is_shared ? "Make private" : "Share with workspace" }),
917
- canEdit && onAddSubtask && /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuItem, { onSelect: onAddSubtask, "data-testid": `task-add-subtask-${id}`, children: [
918
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListPlus, { className: "mr-2 size-4", "aria-hidden": true }),
919
- labels.addSubtask
920
- ] }),
921
- canEdit && onMoveTo && /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuItem, { onSelect: onMoveTo, "data-testid": `task-move-${id}`, children: [
922
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownRight, { className: "mr-2 size-4", "aria-hidden": true }),
923
- labels.moveTo
924
- ] }),
925
- canEdit && /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuItem, { onSelect: onEdit, "data-testid": `task-edit-${id}`, children: [
926
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "mr-2 size-4", "aria-hidden": true }),
927
- isChat ? labels.rename : labels.edit
928
- ] }),
929
- canEdit && onDelete && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
930
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuSeparator, {}),
931
- /* @__PURE__ */ jsxRuntime.jsxs(
932
- ui.DropdownMenuItem,
933
- {
934
- disabled: busy || !canAdmin,
935
- onSelect: onDelete,
936
- title: canAdmin ? void 0 : labels.deleteOwnerOnly,
937
- className: "text-destructive focus:text-destructive",
938
- "data-testid": `task-delete-${id}`,
939
- children: [
940
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "mr-2 size-4", "aria-hidden": true }),
941
- labels.delete
942
- ]
943
- }
944
- )
945
- ] })
946
- ] })
947
- ] });
948
- }
949
- var DEFAULT_TASK_STATUS_PILL_LABELS = {
950
- waitingForAccess: "Waiting for access",
951
- lastRunFailed: "Last run failed",
952
- failed: "Failed"
953
- };
954
- var ICON = "size-3";
955
- function StatusIcon({ status }) {
956
- switch (status) {
957
- case "generating":
958
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: `${ICON} animate-spin`, "aria-hidden": true });
959
- case "done":
960
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: ICON, "aria-hidden": true });
961
- case "chat":
962
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: ICON, "aria-hidden": true });
963
- default:
964
- return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleDashed, { className: ICON, "aria-hidden": true });
965
- }
966
- }
967
- function useNow(active) {
968
- const [now, setNow] = react.useState(() => Date.now());
969
- react.useEffect(() => {
970
- if (!active) return;
971
- const timer = setInterval(() => setNow(Date.now()), 1e3);
972
- return () => clearInterval(timer);
973
- }, [active]);
974
- return now;
975
- }
976
- function TaskStatusPill({
977
- id,
978
- status,
979
- runStartedAt,
980
- lastError,
981
- awaitingAccess = false,
982
- testId,
983
- labels,
984
- hint
985
- }) {
986
- const l = { ...DEFAULT_TASK_STATUS_PILL_LABELS, ...labels };
987
- const key = chunkFY4C7HU5_cjs.asTaskStatus(status);
988
- const generating = key === "generating";
989
- const now = useNow(generating && Boolean(runStartedAt));
990
- const started = runStartedAt ? Date.parse(runStartedAt) : NaN;
991
- let text = chunkFY4C7HU5_cjs.STATUS_LABELS[key];
992
- let tone = chunkFY4C7HU5_cjs.STATUS_TONE[key];
993
- if (awaitingAccess) {
994
- text = l.waitingForAccess;
995
- tone = "danger";
996
- }
997
- const elapsed = generating && !Number.isNaN(started) ? formatElapsed(started, now) : null;
998
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5", "data-slot": "task-status", title: hint, children: [
999
- /* @__PURE__ */ jsxRuntime.jsxs(
1000
- chunkDVUZTGVL_cjs.ToneBadge,
1001
- {
1002
- tone,
1003
- icon: /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { status: key }),
1004
- "data-status": key,
1005
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: `task-status-${id}` }),
1006
- children: [
1007
- text,
1008
- elapsed && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums opacity-70", children: [
1009
- "\xB7 ",
1010
- elapsed
1011
- ] })
1012
- ]
1013
- }
1014
- ),
1015
- lastError && !generating && /* @__PURE__ */ jsxRuntime.jsxs(
1016
- "span",
1017
- {
1018
- role: "img",
1019
- "aria-label": l.lastRunFailed,
1020
- title: `${l.lastRunFailed}: ${lastError}`,
1021
- className: "inline-flex shrink-0 items-center gap-1 text-xs font-medium text-red-text",
1022
- "data-testid": `task-error-${id}`,
1023
- children: [
1024
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "size-3.5", "aria-hidden": true }),
1025
- l.failed
1026
- ]
1027
- }
1028
- )
1029
- ] });
1030
- }
1031
-
1032
- // src/agents/tasks/taskColumns.tsx
1033
- var ACTIONS_WIDTH = 160;
1034
- var NARROW_ACTIONS_WIDTH = 56;
1035
- var TASK_COLUMN_ORDER = [
1036
- "name",
1037
- "owner",
1038
- "due",
1039
- "status",
1040
- "outputs",
1041
- "shared",
1042
- "actions"
1043
- ];
1044
- var keepOrder = () => 0;
1045
- function cell(render) {
1046
- return (params) => params.data ? render(params.data) : null;
1047
- }
1048
- function createTaskColumns(o) {
1049
- const l = o.labels;
1050
- const sortable = {
1051
- sortable: true,
1052
- comparator: keepOrder,
1053
- sortingOrder: ["asc", "desc", null]
1054
- };
1055
- const base = {
1056
- sortable: false,
1057
- suppressMovable: true,
1058
- // Keyboard focus lands on the name cell only (arrow keys expand and collapse sub-tasks there).
1059
- suppressNavigable: true,
1060
- cellStyle: { display: "flex", alignItems: "center" }
1061
- };
1062
- const name = {
1063
- ...base,
1064
- colId: "name",
1065
- ...sortable,
1066
- suppressNavigable: false,
1067
- headerName: l.colTask,
1068
- flex: 3,
1069
- minWidth: 200,
1070
- cellRenderer: cell(o.renderName)
1071
- };
1072
- const shared = {
1073
- ...base,
1074
- colId: "shared",
1075
- headerName: l.colShared,
1076
- headerTooltip: l.shared,
1077
- width: 90,
1078
- cellStyle: { display: "flex", alignItems: "center", justifyContent: "center" },
1079
- valueGetter: (p) => p.data?.task.is_shared ?? false,
1080
- cellRenderer: cell(o.renderShared)
1081
- };
1082
- const actions = () => ({
1083
- ...base,
1084
- colId: "actions",
1085
- headerName: "",
1086
- // Always in view, even if the rest has to scroll.
1087
- pinned: "right",
1088
- lockPinned: true,
1089
- width: o.narrow ? NARROW_ACTIONS_WIDTH : ACTIONS_WIDTH,
1090
- minWidth: NARROW_ACTIONS_WIDTH,
1091
- cellStyle: { display: "flex", alignItems: "center", justifyContent: "flex-end" },
1092
- cellRenderer: cell(o.renderActions)
1093
- });
1094
- return [
1095
- name,
1096
- {
1097
- ...base,
1098
- colId: "owner",
1099
- ...sortable,
1100
- headerName: l.colOwner,
1101
- headerTooltip: l.ownerHint,
1102
- flex: 1.4,
1103
- minWidth: 150,
1104
- valueGetter: (p) => p.data ? o.getOwnerName(p.data) : "",
1105
- cellRenderer: cell(o.renderOwner)
1106
- },
1107
- {
1108
- ...base,
1109
- colId: "due",
1110
- ...sortable,
1111
- headerName: l.colDue,
1112
- flex: 1,
1113
- minWidth: 140,
1114
- valueGetter: (p) => p.data?.task.due_at ?? "",
1115
- cellRenderer: cell(o.renderDue)
1116
- },
1117
- {
1118
- ...base,
1119
- colId: "status",
1120
- ...sortable,
1121
- headerName: l.colStatus,
1122
- // Wide enough for "Generating" and "Waiting for access" in full, with the elapsed time.
1123
- flex: 1.3,
1124
- minWidth: 170,
1125
- valueGetter: (p) => p.data?.task.status ?? "",
1126
- cellRenderer: cell(o.renderStatus)
1127
- },
1128
- ...o.showOutputs ? [
1129
- {
1130
- ...base,
1131
- colId: "outputs",
1132
- headerName: l.colOutputs,
1133
- flex: 1.2,
1134
- minWidth: 130,
1135
- cellRenderer: cell(o.renderOutputs)
1136
- }
1137
- ] : [],
1138
- shared,
1139
- actions()
1140
- ];
1141
- }
1142
-
1143
- // src/agents/tasks/gridWidth.ts
1144
- function applyColumnWidthRules(api, gridWidth, rules) {
1145
- for (const rule of rules) {
1146
- if (api.getColumn(rule.colId)) api.setColumnsVisible([rule.colId], gridWidth >= rule.minWidth);
1147
- }
1148
- }
1149
-
1150
- // src/agents/tasks/taskTableLabels.ts
1151
- var DEFAULT_TASK_LIST_LABELS = {
1152
- filterAll: "All",
1153
- emptyTitle: "No tasks yet",
1154
- emptyMessage: "Use New to add one: just type what you need, or add a due date. Automations that create tasks live on the Workflows page. You always decide when a task is done.",
1155
- noMatches: "No tasks match.",
1156
- due: (when) => when,
1157
- overdue: (when) => `${when} \xB7 overdue`,
1158
- agent: "Agent",
1159
- colTask: "Task",
1160
- colOwner: "Owner",
1161
- ownerHint: "Who created the task. They are notified when its run finishes.",
1162
- colOutputs: "Outputs",
1163
- preparedBy: (agent) => `Prepared by ${agent}`,
1164
- colDue: "Due",
1165
- colStatus: "Status",
1166
- me: "Me",
1167
- someone: "Someone",
1168
- noDue: "\u2014",
1169
- colShared: "Shared",
1170
- shared: "Shared with the workspace",
1171
- sharedOwnerOnly: "Only the creator can change who can see this",
1172
- deleteOwnerOnly: "Only the creator or workspace owner can delete this",
1173
- goalMet: (met, total) => `${met}/${total} met`,
1174
- subtasksDone: (done, total) => `${done}/${total} sub-tasks done`,
1175
- expandSubtasks: "Show sub-tasks",
1176
- collapseSubtasks: "Hide sub-tasks",
1177
- selectAll: "Select all tasks",
1178
- selectTask: (name) => `Select ${name}`,
1179
- markDone: "Mark done",
1180
- reopen: "Reopen",
1181
- markDoneMany: "Mark done",
1182
- markDoneManyHint: "Marks the selected tasks done.",
1183
- deleteMany: "Delete",
1184
- moveTo: "Move to\u2026",
1185
- untitled: "Untitled task",
1186
- fromWorkflow: (name) => `From \u201C${name}\u201D`,
1187
- searchLabel: "Search tasks",
1188
- searchPlaceholder: "Search tasks\u2026",
1189
- expandAll: "Expand all",
1190
- collapseAll: "Collapse all",
1191
- moveToTitle: (name) => `Move \u201C${name}\u201D to\u2026`,
1192
- moveToNone: "No parent (top level)",
1193
- moveToSearch: "Search tasks\u2026",
1194
- moveToEmpty: "No task to move it under.",
1195
- moveToCancel: "Cancel",
1196
- subtasksSelected: (count) => `${count} ${count === 1 ? "sub-task" : "sub-tasks"} included`,
1197
- addSubtask: "Add sub-task",
1198
- edit: "Edit",
1199
- rename: "Rename",
1200
- delete: "Delete",
1201
- grantAccess: "Allow access and continue",
1202
- allowAccess: "Allow access",
1203
- moreActions: "More actions",
1204
- activity: "Activity",
1205
- statusHint: (status, ago) => `${status} \xB7 ${ago}`,
1206
- status: {}
1207
- };
1208
- var ROW_HEIGHT = 56;
1209
- var NARROW_ROW_HEIGHT = 76;
1210
- var MAX_INDENT_DEPTH = 4;
1211
- var ANIMATE_ROWS_UP_TO = 500;
1212
- var NARROW_GRID = 640;
1213
- var WIDTH_RULES = [
1214
- { colId: "shared", minWidth: 1050 },
1215
- { colId: "due", minWidth: 850 },
1216
- { colId: "outputs", minWidth: 930 },
1217
- { colId: "owner", minWidth: 730 },
1218
- { colId: "status", minWidth: NARROW_GRID }
1219
- ];
1220
- function statusHint(task, ctx) {
1221
- const { props: p, l } = ctx;
1222
- if (!p.formatRelative || !task.updated_at) return void 0;
1223
- const key = chunkFY4C7HU5_cjs.asTaskStatus(task.status);
1224
- const pill = { ...DEFAULT_TASK_STATUS_PILL_LABELS, ...p.statusPillLabels };
1225
- const label = task.pending_auth_request_id ? pill.waitingForAccess : chunkFY4C7HU5_cjs.STATUS_LABELS[key];
1226
- return l.statusHint(label, p.formatRelative(task.updated_at));
1227
- }
1228
- function TaskTable(props) {
1229
- const { tasks: allTasks, isLoading, busyId, header, testId } = props;
1230
- const l = {
1231
- ...DEFAULT_TASK_LIST_LABELS,
1232
- ...props.labels,
1233
- status: { ...chunkFY4C7HU5_cjs.STATUS_LABELS, ...props.labels?.status }
1234
- };
1235
- const [filter, setFilter] = react.useState("all");
1236
- const [query, setQuery] = react.useState("");
1237
- const [collapsed, setCollapsed] = react.useState(/* @__PURE__ */ new Set());
1238
- const [selectedIds, setSelectedIds] = react.useState(/* @__PURE__ */ new Set());
1239
- const [sort, setSort] = react.useState(null);
1240
- const [moving, setMoving] = react.useState(null);
1241
- const tasks = allTasks;
1242
- const apiRef = react.useRef(null);
1243
- const [narrow, setNarrow] = react.useState(false);
1244
- const rowCache = react.useRef(/* @__PURE__ */ new Map());
1245
- const tree = react.useMemo(() => chunkFY4C7HU5_cjs.indexTasks(tasks), [tasks]);
1246
- const peopleNames = react.useMemo(
1247
- () => new Map((props.people ?? []).map((p) => [p.id, p.label])),
1248
- [props.people]
1249
- );
1250
- const nameOf = (task) => task.title?.trim() || task.workflow_ext_id && props.workflowNames?.[task.workflow_ext_id] || l.untitled;
1251
- const owner = (task) => {
1252
- const id = chunkFY4C7HU5_cjs.ownerExtId(task);
1253
- const mine = task.is_owner !== false;
1254
- return {
1255
- id,
1256
- label: mine ? l.me : (id && peopleNames.get(id)) ?? l.someone,
1257
- isMe: mine
1258
- };
1259
- };
1260
- const starter = (task) => {
1261
- const id = task.created_by_ext_id ?? task.owner_ext_id;
1262
- const mine = task.is_owner !== false;
1263
- return {
1264
- id,
1265
- label: mine ? l.me : (id && peopleNames.get(id)) ?? l.someone,
1266
- isMe: mine
1267
- };
1268
- };
1269
- const renderPerson = props.renderPerson ?? ((person) => /* @__PURE__ */ jsxRuntime.jsx(chunk2QDNQM63_cjs.PersonPill, { person }));
1270
- const q = (query.trim() || (props.filterText ?? "").trim()).toLowerCase();
1271
- const counts = react.useMemo(() => {
1272
- const map = new Map(chunkFY4C7HU5_cjs.STATUS_ORDER.map((s) => [s, 0]));
1273
- let all = 0;
1274
- for (const task of tasks) {
1275
- const text = `${nameOf(task)} ${task.description ?? ""}`.toLowerCase();
1276
- if (q && !text.includes(q)) continue;
1277
- all += 1;
1278
- const s = chunkFY4C7HU5_cjs.asTaskStatus(task.status);
1279
- map.set(s, (map.get(s) ?? 0) + 1);
1280
- }
1281
- map.set("all", all);
1282
- return map;
1283
- }, [tasks, q, props.workflowNames, l.untitled]);
1284
- const compare = react.useMemo(() => {
1285
- if (!sort) return void 0;
1286
- const keys = /* @__PURE__ */ new Map();
1287
- const compute = (t) => {
1288
- switch (sort.colId) {
1289
- case "name":
1290
- return nameOf(t).toLowerCase();
1291
- case "owner":
1292
- return owner(t).label.toLowerCase();
1293
- case "updated":
1294
- return t.updated_at ? Date.parse(t.updated_at) : 0;
1295
- case "messages":
1296
- return t.message_count ?? 0;
1297
- case "due":
1298
- return t.due_at ? Date.parse(t.due_at) : Number.POSITIVE_INFINITY;
1299
- default:
1300
- return chunkFY4C7HU5_cjs.STATUS_ORDER.indexOf(chunkFY4C7HU5_cjs.asTaskStatus(t.status));
1301
- }
1302
- };
1303
- const key = (t) => {
1304
- let k = keys.get(t);
1305
- if (k === void 0) {
1306
- k = compute(t);
1307
- keys.set(t, k);
1308
- }
1309
- return k;
1310
- };
1311
- const sign = sort.dir === "asc" ? 1 : -1;
1312
- return (a, b) => {
1313
- const [x, y] = [key(a), key(b)];
1314
- if (typeof x === "number" && typeof y === "number") return (x - y) * sign;
1315
- return String(x).localeCompare(String(y)) * sign;
1316
- };
1317
- }, [
1318
- sort,
1319
- peopleNames,
1320
- props.agentNames,
1321
- props.workflowNames,
1322
- l.me,
1323
- l.agent,
1324
- l.someone,
1325
- l.untitled
1326
- ]);
1327
- const rows = react.useMemo(
1328
- () => chunkFY4C7HU5_cjs.buildTaskRows(tasks, filter, collapsed, compare, {
1329
- query: query.trim() || props.filterText,
1330
- titleOf: nameOf,
1331
- cache: rowCache.current
1332
- }),
1333
- // nameOf reads the labels and workflow names the table was given.
1334
- // eslint-disable-next-line react-hooks/exhaustive-deps
1335
- [tasks, filter, collapsed, compare, query, props.filterText, props.workflowNames, l.untitled]
1336
- );
1337
- const selectedRows = react.useMemo(
1338
- () => rows.filter((r) => selectedIds.has(r.external_id)),
1339
- [rows, selectedIds]
1340
- );
1341
- const selectedTasks = react.useMemo(
1342
- () => tasks.filter((t) => selectedIds.has(t.external_id)),
1343
- [tasks, selectedIds]
1344
- );
1345
- const subtasksIncluded = react.useMemo(
1346
- () => selectedTasks.filter((t) => {
1347
- const parent = tree.parentOf.get(t.external_id);
1348
- return parent !== void 0 && selectedIds.has(parent);
1349
- }).length,
1350
- [selectedTasks, selectedIds, tree]
1351
- );
1352
- const markable = selectedTasks.filter(
1353
- (t) => t.status != null && (t.is_owner !== false || props.canEditShared) && chunkFY4C7HU5_cjs.isPlainTodo(t) && chunkFY4C7HU5_cjs.asTaskStatus(t.status) !== "done"
1354
- );
1355
- const deletable = selectedTasks.filter((t) => t.is_owner !== false || props.isWorkspaceOwner);
1356
- const rowsRef = react.useRef(rows);
1357
- rowsRef.current = rows;
1358
- const handleSelectionChange = (picked) => {
1359
- const visible = new Set(rowsRef.current.map((r) => r.external_id));
1360
- const pickedIds = new Set(picked.map((r) => r.external_id));
1361
- setSelectedIds((prev) => {
1362
- const added = [...pickedIds].filter((id) => !prev.has(id));
1363
- const removed = [...prev].filter((id) => visible.has(id) && !pickedIds.has(id));
1364
- if (added.length === 0 && removed.length === 0) return prev;
1365
- const next = new Set(prev);
1366
- for (const id of added) {
1367
- next.add(id);
1368
- for (const d of chunkFY4C7HU5_cjs.descendantIds(tree, id)) next.add(d);
1369
- }
1370
- for (const id of removed) {
1371
- next.delete(id);
1372
- for (const d of chunkFY4C7HU5_cjs.descendantIds(tree, id)) next.delete(d);
1373
- for (let at = tree.parentOf.get(id); at; at = tree.parentOf.get(at)) next.delete(at);
1374
- }
1375
- return next;
1376
- });
1377
- };
1378
- const setExpanded = (id, expanded) => setCollapsed((prev) => {
1379
- if (prev.has(id) === !expanded) return prev;
1380
- const next = new Set(prev);
1381
- if (expanded) next.delete(id);
1382
- else next.add(id);
1383
- return next;
1384
- });
1385
- const expandAll = () => setCollapsed(/* @__PURE__ */ new Set());
1386
- const collapseAll = () => setCollapsed(new Set(tree.kids.keys()));
1387
- const latest = react.useRef({ props, l, owner, starter, renderPerson, nameOf, setExpanded, narrow });
1388
- latest.current = { props, l, owner, starter, renderPerson, nameOf, setExpanded, narrow };
1389
- const showOutputs = Object.values(props.outputsByTask ?? {}).some((o) => o.length > 0);
1390
- const columnDefs = react.useMemo(
1391
- () => createTaskColumns({
1392
- narrow,
1393
- labels: l,
1394
- getOwnerName: (row) => latest.current.owner(row.task).label,
1395
- renderName: (row) => {
1396
- const { l: lb, props: p, nameOf: name } = latest.current;
1397
- const { task, depth, childStats, expanded } = row;
1398
- const id = task.external_id;
1399
- const status = chunkFY4C7HU5_cjs.asTaskStatus(task.status);
1400
- const goal = chunkFY4C7HU5_cjs.goalProgress(task);
1401
- const workflowName = task.workflow_ext_id ? p.workflowNames?.[task.workflow_ext_id] : null;
1402
- return /* @__PURE__ */ jsxRuntime.jsxs(
1403
- "div",
1404
- {
1405
- className: "flex min-w-0 flex-1 items-center gap-1.5",
1406
- style: depth > 0 ? { paddingLeft: `${Math.min(depth, MAX_INDENT_DEPTH) * 1.5}rem` } : void 0,
1407
- "data-depth": depth,
1408
- "aria-level": depth + 1,
1409
- "aria-setsize": row.setSize,
1410
- "aria-posinset": row.posInSet,
1411
- "data-context": row.context || void 0,
1412
- children: [
1413
- childStats ? /* @__PURE__ */ jsxRuntime.jsx(
1414
- "button",
1415
- {
1416
- type: "button",
1417
- onClick: () => latest.current.setExpanded(id, !expanded),
1418
- "aria-expanded": expanded,
1419
- "aria-label": expanded ? lb.collapseSubtasks : lb.expandSubtasks,
1420
- className: "flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
1421
- "data-testid": `task-expand-${id}`,
1422
- children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4", "aria-hidden": true }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4", "aria-hidden": true })
1423
- }
1424
- ) : depth > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-5 shrink-0", "aria-hidden": true }) : null,
1425
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 leading-tight", children: [
1426
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
1427
- /* @__PURE__ */ jsxRuntime.jsx(
1428
- "button",
1429
- {
1430
- type: "button",
1431
- onClick: () => latest.current.props.onOpenThread(id, task),
1432
- title: task.agent_ext_id ? lb.preparedBy(p.agentNames?.[task.agent_ext_id] || lb.agent) : void 0,
1433
- className: ui.cn(
1434
- // The title has priority: it keeps at least 12 characters before it ellipsises.
1435
- "min-w-[12ch] truncate text-left text-sm font-medium hover:underline focus-visible:underline focus-visible:outline-none",
1436
- status === "done" && "text-muted-foreground line-through"
1437
- ),
1438
- "data-testid": `task-name-${id}`,
1439
- children: name(task)
1440
- }
1441
- ),
1442
- goal && /* @__PURE__ */ jsxRuntime.jsxs(
1443
- chunkDVUZTGVL_cjs.ToneBadge,
1444
- {
1445
- tone: goal.done ? "success" : "neutral",
1446
- "data-testid": `task-goal-progress-${id}`,
1447
- children: [
1448
- goal.done ? "\u2713 " : "",
1449
- lb.goalMet(goal.met, goal.total)
1450
- ]
1451
- }
1452
- )
1453
- ] }),
1454
- latest.current.narrow && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
1455
- TaskStatusPill,
1456
- {
1457
- id,
1458
- status,
1459
- runStartedAt: task.run_started_at,
1460
- lastError: task.last_error,
1461
- awaitingAccess: Boolean(task.pending_auth_request_id),
1462
- labels: p.statusPillLabels
1463
- }
1464
- ) }),
1465
- (task.description || workflowName || childStats) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2 text-xs text-muted-foreground", children: [
1466
- task.description ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "min-w-0 truncate", children: task.description }) : workflowName ? /* @__PURE__ */ jsxRuntime.jsxs(
1467
- "span",
1468
- {
1469
- className: "inline-flex min-w-0 items-center gap-1.5",
1470
- "data-testid": `task-workflow-${id}`,
1471
- children: [
1472
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "size-3.5 shrink-0", "aria-hidden": true }),
1473
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: lb.fromWorkflow(workflowName) })
1474
- ]
1475
- }
1476
- ) : null,
1477
- childStats && /* @__PURE__ */ jsxRuntime.jsx(
1478
- "span",
1479
- {
1480
- className: "shrink-0 tabular-nums",
1481
- "data-testid": `task-subtask-progress-${id}`,
1482
- children: lb.subtasksDone(childStats.done, childStats.total)
1483
- }
1484
- )
1485
- ] })
1486
- ] })
1487
- ]
1488
- }
1489
- );
1490
- },
1491
- // Who has the next step: the person pill, with the "Me" treatment. A plain chat is its starter's.
1492
- renderOwner: (row) => /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": `task-owner-${row.external_id}`, className: "flex min-w-0", children: latest.current.renderPerson(
1493
- row.task.status ? latest.current.owner(row.task) : latest.current.starter(row.task)
1494
- ) }),
1495
- renderDue: (row) => {
1496
- const { l: lb, props: p } = latest.current;
1497
- const { task } = row;
1498
- const dueMs = task.due_at ? Date.parse(task.due_at) : NaN;
1499
- const overdue = chunkFY4C7HU5_cjs.asTaskStatus(task.status) !== "done" && !Number.isNaN(dueMs) && dueMs < Date.now();
1500
- return /* @__PURE__ */ jsxRuntime.jsx(
1501
- "span",
1502
- {
1503
- className: ui.cn(
1504
- "truncate text-sm",
1505
- overdue ? "font-medium text-red-text" : "text-muted-foreground"
1506
- ),
1507
- "data-testid": `task-due-${task.external_id}`,
1508
- "data-overdue": overdue,
1509
- children: task.due_at ? overdue ? lb.overdue(p.formatDate(task.due_at)) : lb.due(p.formatDate(task.due_at)) : lb.noDue
1510
- }
1511
- );
1512
- },
1513
- renderShared: (row) => {
1514
- const { l: lb, props: p } = latest.current;
1515
- const { task } = row;
1516
- if (!p.onToggleShared) return null;
1517
- return /* @__PURE__ */ jsxRuntime.jsx(
1518
- ui.VisibilityToggle,
1519
- {
1520
- items: { shared: task.is_shared ?? false },
1521
- onToggle: (shouldShare) => latest.current.props.onToggleShared?.(task, shouldShare),
1522
- disabled: task.is_owner === false,
1523
- disabledTooltip: lb.sharedOwnerOnly,
1524
- showLabel: false,
1525
- "data-testid": `task-shared-${task.external_id}`
1526
- }
1527
- );
1528
- },
1529
- showOutputs,
1530
- renderOutputs: (row) => /* @__PURE__ */ jsxRuntime.jsx(
1531
- TaskOutputsCell,
1532
- {
1533
- id: row.external_id,
1534
- outputs: latest.current.props.outputsByTask?.[row.external_id],
1535
- onOpen: (docId) => latest.current.props.onOpenOutput?.(docId, row.task),
1536
- labels: latest.current.props.outputsLabels
1537
- }
1538
- ),
1539
- renderStatus: (row) => /* @__PURE__ */ jsxRuntime.jsx(
1540
- TaskStatusPill,
1541
- {
1542
- id: row.external_id,
1543
- status: chunkFY4C7HU5_cjs.asTaskStatus(row.task.status),
1544
- runStartedAt: row.task.run_started_at,
1545
- lastError: row.task.last_error,
1546
- awaitingAccess: Boolean(row.task.pending_auth_request_id),
1547
- labels: latest.current.props.statusPillLabels,
1548
- hint: statusHint(row.task, latest.current)
1549
- }
1550
- ),
1551
- renderActions: (row) => {
1552
- const { l: lb, props: p } = latest.current;
1553
- const { task } = row;
1554
- const id = task.external_id;
1555
- const status = chunkFY4C7HU5_cjs.asTaskStatus(task.status);
1556
- const busy = p.busyId === id;
1557
- const isOwner = task.is_owner !== false;
1558
- const canEdit = isOwner || Boolean(p.canEditShared);
1559
- const canAdmin = isOwner || Boolean(p.isWorkspaceOwner);
1560
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-2", children: [
1561
- !latest.current.narrow && isOwner && task.pending_auth_request_id && p.onGrantAccess && /* @__PURE__ */ jsxRuntime.jsxs(
1562
- ui.Button,
1563
- {
1564
- size: "sm",
1565
- className: "h-8 gap-1.5 pointer-coarse:h-11",
1566
- onClick: () => p.onGrantAccess?.(task),
1567
- "data-testid": `task-allow-access-${id}`,
1568
- children: [
1569
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.KeyRound, { className: "size-3.5", "aria-hidden": true }),
1570
- lb.allowAccess
1571
- ]
1572
- }
1573
- ),
1574
- /* @__PURE__ */ jsxRuntime.jsx(
1575
- TaskRowMenu,
1576
- {
1577
- task,
1578
- status,
1579
- busy,
1580
- isOwner,
1581
- canAdmin,
1582
- canEdit,
1583
- labels: lb,
1584
- onMarkDone: () => p.onMarkDone(task),
1585
- onReopen: () => p.onReopen(task),
1586
- onAddSubtask: p.onAddSubtask ? () => p.onAddSubtask?.(task) : void 0,
1587
- onMoveTo: p.onMove ? () => setMoving(task) : void 0,
1588
- onEdit: () => p.onEdit(task),
1589
- onDelete: () => p.onDelete(task),
1590
- onOpenActivity: p.onOpenActivity ? () => p.onOpenActivity?.(task) : void 0,
1591
- onGrantAccess: p.onGrantAccess ? () => p.onGrantAccess?.(task) : void 0
1592
- }
1593
- )
1594
- ] });
1595
- }
1596
- }),
1597
- // Stable on purpose: only the header texts rebuild the columns (see `latest`).
1598
- // eslint-disable-next-line react-hooks/exhaustive-deps
1599
- [
1600
- l.colTask,
1601
- l.colOwner,
1602
- l.colDue,
1603
- l.colStatus,
1604
- l.colShared,
1605
- l.colOutputs,
1606
- l.shared,
1607
- showOutputs,
1608
- narrow
1609
- ]
1610
- );
1611
- react.useEffect(() => {
1612
- apiRef.current?.refreshCells({ force: true });
1613
- }, [
1614
- busyId,
1615
- props.people,
1616
- props.agentNames,
1617
- props.workflowNames,
1618
- props.outputsByTask,
1619
- props.renderPerson,
1620
- props.labels,
1621
- props.canEditShared,
1622
- props.isWorkspaceOwner,
1623
- narrow
1624
- ]);
1625
- const animate = rows.length <= ANIMATE_ROWS_UP_TO;
1626
- const gridOptions = react.useMemo(
1627
- () => ({
1628
- suppressClickEdit: true,
1629
- // Keyboard focus lives on the name column only (the others are not navigable): ArrowRight
1630
- // opens a task's sub-tasks and ArrowLeft closes them, or steps up to the parent.
1631
- suppressCellFocus: false,
1632
- suppressColumnVirtualisation: true,
1633
- animateRows: animate,
1634
- getRowClass: (p) => p.data?.context ? "opacity-60" : void 0,
1635
- // The grid shows and reports the sort; the table orders each level (see buildTaskRows).
1636
- onSortChanged: (event) => {
1637
- const sorted = event.api.getColumnState().find((c) => c.sort);
1638
- setSort(
1639
- sorted?.colId ? { colId: sorted.colId, dir: sorted.sort ?? "asc" } : null
1640
- );
1641
- },
1642
- onGridSizeChanged: (event) => {
1643
- applyColumnWidthRules(event.api, event.clientWidth, WIDTH_RULES);
1644
- setNarrow(event.clientWidth < NARROW_GRID);
1645
- },
1646
- onCellKeyDown: (event) => {
1647
- const row = event.data;
1648
- const key = event.event?.key;
1649
- if (!row || event.column.getColId() !== "name") return;
1650
- if (key === "ArrowRight" && row.childStats && !row.expanded) {
1651
- event.event?.preventDefault();
1652
- latest.current.setExpanded(row.external_id, true);
1653
- } else if (key === "ArrowLeft") {
1654
- if (row.childStats && row.expanded) {
1655
- event.event?.preventDefault();
1656
- latest.current.setExpanded(row.external_id, false);
1657
- } else if (row.parentId) {
1658
- event.event?.preventDefault();
1659
- const parent = event.api.getRowNode(row.parentId);
1660
- if (parent?.rowIndex != null) {
1661
- event.api.ensureIndexVisible(parent.rowIndex);
1662
- event.api.setFocusedCell(parent.rowIndex, "name");
1663
- }
1664
- }
1665
- }
1666
- }
1667
- }),
1668
- [animate]
1669
- );
1670
- const clearSelection = () => setSelectedIds(/* @__PURE__ */ new Set());
1671
- const filterKeys = ["all", ...chunkFY4C7HU5_cjs.STATUS_ORDER].filter(
1672
- (key) => key !== "chat" || (counts.get(key) ?? 0) > 0
1673
- );
1674
- const hasChildren = tree.kids.size > 0;
1675
- return /* @__PURE__ */ jsxRuntime.jsxs(
1676
- "div",
1677
- {
1678
- className: "flex min-h-0 flex-1 flex-col gap-3",
1679
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "task-list" }),
1680
- children: [
1681
- header,
1682
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
1683
- /* @__PURE__ */ jsxRuntime.jsx("div", { role: "tablist", "aria-label": "Filter tasks", className: "flex flex-wrap gap-1.5", children: filterKeys.map((key) => {
1684
- const count = counts.get(key) ?? 0;
1685
- const isSelected = filter === key;
1686
- return /* @__PURE__ */ jsxRuntime.jsxs(
1687
- "button",
1688
- {
1689
- type: "button",
1690
- role: "tab",
1691
- "aria-selected": isSelected,
1692
- onClick: () => setFilter(key),
1693
- className: ui.cn(
1694
- "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",
1695
- isSelected ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground hover:bg-accent"
1696
- ),
1697
- "data-testid": `task-filter-${key}`,
1698
- children: [
1699
- key === "all" ? l.filterAll : l.status[key],
1700
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabular-nums opacity-70", children: count })
1701
- ]
1702
- },
1703
- key
1704
- );
1705
- }) }),
1706
- /* @__PURE__ */ jsxRuntime.jsx(
1707
- ui.Input,
1708
- {
1709
- type: "search",
1710
- value: query,
1711
- onChange: (e) => setQuery(e.target.value),
1712
- placeholder: l.searchPlaceholder,
1713
- "aria-label": l.searchLabel,
1714
- className: "h-8 max-w-56 text-xs pointer-coarse:h-11",
1715
- "data-testid": "task-search"
1716
- }
1717
- ),
1718
- hasChildren && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex gap-1", children: [
1719
- /* @__PURE__ */ jsxRuntime.jsxs(
1720
- ui.Button,
1721
- {
1722
- type: "button",
1723
- variant: "ghost",
1724
- size: "sm",
1725
- className: "h-8 gap-1.5 text-xs pointer-coarse:h-11",
1726
- onClick: expandAll,
1727
- "data-testid": "task-expand-all",
1728
- children: [
1729
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "size-3.5", "aria-hidden": true }),
1730
- l.expandAll
1731
- ]
1732
- }
1733
- ),
1734
- /* @__PURE__ */ jsxRuntime.jsxs(
1735
- ui.Button,
1736
- {
1737
- type: "button",
1738
- variant: "ghost",
1739
- size: "sm",
1740
- className: "h-8 gap-1.5 text-xs pointer-coarse:h-11",
1741
- onClick: collapseAll,
1742
- "data-testid": "task-collapse-all",
1743
- children: [
1744
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsDownUp, { className: "size-3.5", "aria-hidden": true }),
1745
- l.collapseAll
1746
- ]
1747
- }
1748
- )
1749
- ] })
1750
- ] }),
1751
- tasks.length === 0 && !isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
1752
- chunkZW6FPIFC_cjs.EmptyState,
1753
- {
1754
- icon: lucideReact.ListTodo,
1755
- title: l.emptyTitle,
1756
- description: l.emptyMessage,
1757
- testId: "task-list-empty"
1758
- }
1759
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
1760
- chunkLKK52DEY_cjs.GridView,
1761
- {
1762
- testId: "task-grid",
1763
- gridId: props.gridId ?? "tasks-grid-v4",
1764
- items: rows,
1765
- columnDefs,
1766
- getItemId: (row) => row.external_id,
1767
- getRowTestId: (row) => `task-row-${row.external_id}`,
1768
- isLoading,
1769
- showEmpty: rows.length === 0,
1770
- emptyState: { title: l.noMatches },
1771
- rowHeight: narrow ? NARROW_ROW_HEIGHT : ROW_HEIGHT,
1772
- height: "100%",
1773
- onGridReady: ({ api }) => {
1774
- apiRef.current = api;
1775
- },
1776
- selection: {
1777
- mode: "multiple",
1778
- controlled: true,
1779
- selected: selectedRows,
1780
- onSelectionChange: handleSelectionChange
1781
- },
1782
- gridOptions
1783
- }
1784
- ) }),
1785
- /* @__PURE__ */ jsxRuntime.jsx(
1786
- chunkV4ISCZJ7_cjs.SelectionBar,
1787
- {
1788
- count: selectedTasks.length,
1789
- onClear: clearSelection,
1790
- status: selectedTasks.length > 0 && subtasksIncluded > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", "data-testid": "task-selection-subtasks", children: l.subtasksSelected(subtasksIncluded) }) : void 0,
1791
- children: (isCompact) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1792
- props.selectionActions?.(selectedTasks, isCompact, clearSelection),
1793
- props.onMarkDoneMany && /* @__PURE__ */ jsxRuntime.jsx(
1794
- chunkV4ISCZJ7_cjs.SelectionBarAction,
1795
- {
1796
- icon: lucideReact.CheckCheck,
1797
- label: l.markDoneMany,
1798
- onClick: () => {
1799
- props.onMarkDoneMany?.(markable);
1800
- clearSelection();
1801
- },
1802
- disabled: markable.length === 0,
1803
- isCompact,
1804
- tooltip: l.markDoneManyHint,
1805
- testId: "task-bulk-done"
1806
- }
1807
- ),
1808
- props.onDeleteMany && /* @__PURE__ */ jsxRuntime.jsx(
1809
- chunkV4ISCZJ7_cjs.SelectionBarAction,
1810
- {
1811
- icon: lucideReact.Trash2,
1812
- label: l.deleteMany,
1813
- onClick: () => {
1814
- props.onDeleteMany?.(deletable);
1815
- clearSelection();
1816
- },
1817
- disabled: deletable.length === 0,
1818
- isCompact,
1819
- className: "border-red-border text-red-text hover:bg-red-bg hover:text-red-text",
1820
- testId: "task-bulk-delete"
1821
- }
1822
- )
1823
- ] })
1824
- }
1825
- ),
1826
- moving && props.onMove && /* @__PURE__ */ jsxRuntime.jsx(
1827
- TaskMoveDialog,
1828
- {
1829
- open: true,
1830
- onOpenChange: (open) => !open && setMoving(null),
1831
- options: chunkFY4C7HU5_cjs.moveTargets(tasks, moving).map((t) => ({ id: t.external_id, label: nameOf(t) })),
1832
- currentParentId: moving.parent_conversation_ext_id,
1833
- onPick: (parentId) => props.onMove?.(moving, parentId),
1834
- labels: {
1835
- title: l.moveToTitle(nameOf(moving)),
1836
- none: l.moveToNone,
1837
- search: l.moveToSearch,
1838
- empty: l.moveToEmpty,
1839
- cancel: l.moveToCancel
1840
- }
1841
- }
1842
- )
1843
- ]
1844
- }
1845
- );
1846
- }
1847
- function TaskInbox(p) {
1848
- const [filterOpen, setFilterOpen] = react.useState(false);
1849
- const [statusFilters, setStatusFilters] = react.useState(
1850
- () => /* @__PURE__ */ new Map([["done", "exclude"]])
1851
- );
1852
- const [localQuery, setLocalQuery] = react.useState("");
1853
- const [searchFields, setSearchFields] = react.useState(["text", "labels"]);
1854
- const [selected, setSelected] = react.useState(/* @__PURE__ */ new Set());
1855
- const [collapsed, setCollapsed] = react.useState(/* @__PURE__ */ new Set());
1856
- const [moving, setMoving] = react.useState(null);
1857
- const l = { ...DEFAULT_TASK_LIST_LABELS, ...p.labels };
1858
- const nameOf = (t) => t.title?.trim() || t.workflow_ext_id && p.workflowNames?.[t.workflow_ext_id] || l.untitled;
1859
- const all = p.tasks.filter((t) => t.status != null);
1860
- const filterText = p.filterText ?? localQuery;
1861
- const q = filterText.trim().toLowerCase();
1862
- const included = [...statusFilters].filter(([, state]) => state === "include").map(([id]) => id);
1863
- const statusMatches = (t) => statusFilters.get(chunkFY4C7HU5_cjs.asTaskStatus(t.status)) !== "exclude" && (!included.length || included.includes(chunkFY4C7HU5_cjs.asTaskStatus(t.status)));
1864
- const rows = all.filter(
1865
- (t) => statusMatches(t) && (!q || [
1866
- searchFields.includes("text") ? `${nameOf(t)} ${t.description ?? ""}` : "",
1867
- searchFields.includes("labels") && t.workflow_ext_id ? p.workflowNames?.[t.workflow_ext_id] ?? "" : ""
1868
- ].join(" ").toLowerCase().includes(q))
1869
- );
1870
- const hasActiveFilters = !!q || [...statusFilters.values()].some((state) => state != null);
1871
- const selectedTasks = all.filter((t) => selected.has(t.external_id));
1872
- const canEdit = (t) => t.is_owner !== false || Boolean(p.canEditShared);
1873
- const markable = (t) => t.status !== "done" && t.status !== "generating" && canEdit(t) && !t.in_progress;
1874
- const markableTasks = selectedTasks.filter(markable);
1875
- const deletableTasks = selectedTasks.filter((t) => t.is_owner !== false || p.isWorkspaceOwner);
1876
- const clearSelection = () => setSelected(/* @__PURE__ */ new Set());
1877
- const toggle = (set, id) => set((old) => {
1878
- const next = new Set(old);
1879
- if (next.has(id)) next.delete(id);
1880
- else next.add(id);
1881
- return next;
1882
- });
1883
- p.renderPerson ?? ((value) => /* @__PURE__ */ jsxRuntime.jsx(chunk2QDNQM63_cjs.PersonPill, { person: value }));
1884
- const taskById = new Map(all.map((t) => [t.external_id, t]));
1885
- const visible = new Set(rows.map((t) => t.external_id));
1886
- for (const task of rows) {
1887
- let id = task.parent_conversation_ext_id;
1888
- const seen = /* @__PURE__ */ new Set();
1889
- while (id && taskById.has(id) && !seen.has(id)) {
1890
- seen.add(id);
1891
- visible.add(id);
1892
- id = taskById.get(id)?.parent_conversation_ext_id;
1893
- }
1894
- }
1895
- const listed = all.filter((t) => visible.has(t.external_id));
1896
- const roots = listed.filter(
1897
- (t) => !t.parent_conversation_ext_id || !visible.has(t.parent_conversation_ext_id)
1898
- );
1899
- const workflows = (p.workflows ?? []).filter((w) => {
1900
- const runs = roots.filter((t) => t.workflow_ext_id === w.external_id);
1901
- return runs.length > 0 || !included.length && (!q || w.name.toLowerCase().includes(q));
1902
- });
1903
- const workflowIds = new Set(workflows.map((w) => w.external_id));
1904
- const order = (a, b) => {
1905
- const weight = (t) => t.pending_auth_request_id || t.last_error ? 0 : t.status === "todo" ? 1 : t.status === "generating" ? 2 : 3;
1906
- return weight(a) - weight(b) || (b.updated_at ?? "").localeCompare(a.updated_at ?? "");
1907
- };
1908
- const renderTask = (task, depth = 0) => {
1909
- const id = task.external_id;
1910
- const status = chunkFY4C7HU5_cjs.asTaskStatus(task.status);
1911
- const busy = p.busyId === id;
1912
- const children = listed.filter((t) => t.parent_conversation_ext_id === id).sort(order);
1913
- const outputs = p.outputsByTask?.[id] ?? [];
1914
- return /* @__PURE__ */ jsxRuntime.jsxs("li", { "data-testid": `task-inbox-row-${id}`, children: [
1915
- /* @__PURE__ */ jsxRuntime.jsxs(
1916
- "div",
1917
- {
1918
- className: ui.cn(
1919
- "relative flex cursor-pointer items-start gap-2 border-b py-3 hover:bg-muted/40",
1920
- selected.has(id) && "bg-muted/60"
1921
- ),
1922
- onClick: (event) => {
1923
- if (!event.target.closest(
1924
- 'button, a, input, select, textarea, [role="menuitem"], [role="checkbox"], [role="combobox"]'
1925
- )) {
1926
- p.onOpenThread(id, task);
1927
- }
1928
- },
1929
- style: { paddingLeft: `${Math.min(depth, 5) * 20}px` },
1930
- children: [
1931
- children.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1932
- ui.Button,
1933
- {
1934
- variant: "ghost",
1935
- size: "icon",
1936
- className: "size-7 shrink-0",
1937
- "aria-label": `${collapsed.has(id) ? "Expand" : "Collapse"} ${nameOf(task)}`,
1938
- onClick: () => toggle(setCollapsed, id),
1939
- children: collapsed.has(id) ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4" })
1940
- }
1941
- ),
1942
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
1943
- /* @__PURE__ */ jsxRuntime.jsx(
1944
- "button",
1945
- {
1946
- className: ui.cn(
1947
- "block w-full text-left text-sm font-medium hover:underline",
1948
- status === "done" && "text-muted-foreground"
1949
- ),
1950
- "data-testid": `task-open-${id}`,
1951
- onClick: () => p.onOpenThread(id, task),
1952
- children: nameOf(task)
1953
- }
1954
- ),
1955
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
1956
- status !== "todo" && /* @__PURE__ */ jsxRuntime.jsx(
1957
- TaskStatusPill,
1958
- {
1959
- id,
1960
- status: task.status,
1961
- runStartedAt: task.run_started_at,
1962
- lastError: task.last_error,
1963
- awaitingAccess: Boolean(task.pending_auth_request_id)
1964
- }
1965
- ),
1966
- task.due_at && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1967
- "Due ",
1968
- p.formatDate(task.due_at)
1969
- ] }),
1970
- children.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1971
- all.filter((t) => t.parent_conversation_ext_id === id && t.status === "done").length,
1972
- "/",
1973
- all.filter((t) => t.parent_conversation_ext_id === id).length,
1974
- " steps complete"
1975
- ] })
1976
- ] }),
1977
- 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(
1978
- ui.Button,
1979
- {
1980
- variant: "link",
1981
- size: "sm",
1982
- className: "h-auto max-w-full gap-1 px-0 py-1 text-xs",
1983
- disabled: !p.onOpenOutput,
1984
- onClick: () => p.onOpenOutput?.(output.id, task),
1985
- "data-testid": `task-output-${id}-${output.id}`,
1986
- children: [
1987
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "size-3.5 shrink-0" }),
1988
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: output.name })
1989
- ]
1990
- },
1991
- output.id
1992
- )) })
1993
- ] }),
1994
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
1995
- task.pending_auth_request_id && task.is_owner !== false && p.onGrantAccess && /* @__PURE__ */ jsxRuntime.jsx(
1996
- ui.Button,
1997
- {
1998
- size: "sm",
1999
- variant: "outline",
2000
- disabled: busy,
2001
- onClick: () => p.onGrantAccess?.(task),
2002
- children: "Allow access"
2003
- }
2004
- ),
2005
- /* @__PURE__ */ jsxRuntime.jsx(
2006
- TaskRowMenu,
2007
- {
2008
- task,
2009
- status,
2010
- busy,
2011
- isOwner: task.is_owner !== false,
2012
- canAdmin: task.is_owner !== false || Boolean(p.isWorkspaceOwner),
2013
- canEdit: canEdit(task),
2014
- canMarkDone: markable(task),
2015
- canReopen: canEdit(task),
2016
- selected: selected.has(id),
2017
- onToggleSelected: p.selectionActions || p.onMarkDoneMany || p.onDeleteMany ? () => toggle(setSelected, id) : void 0,
2018
- labels: l,
2019
- onMarkDone: () => p.onMarkDone(task),
2020
- onNotify: p.onNotify ? () => p.onNotify?.(task) : void 0,
2021
- onReopen: () => p.onReopen(task),
2022
- onEdit: () => p.onEdit(task),
2023
- onAddSubtask: p.onAddSubtask ? () => p.onAddSubtask?.(task) : void 0,
2024
- onMoveTo: p.onMove ? () => setMoving(task) : void 0,
2025
- onOpenActivity: p.onOpenActivity ? () => p.onOpenActivity?.(task) : void 0,
2026
- onToggleShared: p.onToggleShared ? () => p.onToggleShared?.(task, !task.is_shared) : void 0
2027
- }
2028
- )
2029
- ] })
2030
- ]
2031
- }
2032
- ),
2033
- children.length > 0 && !collapsed.has(id) && /* @__PURE__ */ jsxRuntime.jsx("ul", { children: children.map((child) => renderTask(child, depth + 1)) })
2034
- ] }, id);
2035
- };
2036
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col", "data-testid": p.testId ?? "task-inbox", children: [
2037
- /* @__PURE__ */ jsxRuntime.jsx(
2038
- chunkMEMWZ72Y_cjs.TabHeader,
2039
- {
2040
- testId: "tasks-tab-header",
2041
- tabs: [
2042
- {
2043
- id: "tasks",
2044
- label: "",
2045
- count: rows.length,
2046
- countPlacement: "leading",
2047
- countIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListTodo, { className: "size-3.5" }),
2048
- hasActiveFilters,
2049
- testId: "tasks-tab",
2050
- presentation: "count"
2051
- }
2052
- ],
2053
- activeTabId: "tasks",
2054
- onTabChange: () => {
2055
- },
2056
- firstTabContent: /* @__PURE__ */ jsxRuntime.jsx(
2057
- chunk2EI7NCUA_cjs.FilterInput,
2058
- {
2059
- value: filterText,
2060
- onChange: p.onFilterTextChange ?? setLocalQuery,
2061
- fields: searchFields,
2062
- onFieldsChange: setSearchFields,
2063
- labels: { fieldNames: { text: "Task", labels: "Workflow" } },
2064
- className: "w-44 max-w-[40vw]",
2065
- testIds: {
2066
- root: "tasks-filter",
2067
- input: "tasks-filter-input",
2068
- fieldsButton: "tasks-filter-fields"
2069
- },
2070
- filter: /* @__PURE__ */ jsxRuntime.jsx(
2071
- chunkAQPZ4QMV_cjs.TriStateFilterMenu,
2072
- {
2073
- testId: "tasks-status-filter",
2074
- open: filterOpen,
2075
- onOpenChange: setFilterOpen,
2076
- filterStates: statusFilters,
2077
- onFiltersChange: setStatusFilters,
2078
- options: [
2079
- {
2080
- id: "todo",
2081
- label: "To do",
2082
- count: all.filter((t) => t.status === "todo").length
2083
- },
2084
- {
2085
- id: "generating",
2086
- label: "Generating",
2087
- count: all.filter((t) => t.status === "generating").length
2088
- },
2089
- {
2090
- id: "done",
2091
- label: "Completed",
2092
- count: all.filter((t) => t.status === "done").length
2093
- }
2094
- ],
2095
- groups: [{ label: "Status", options: ["todo", "generating", "done"] }],
2096
- 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",
2097
- renderChevron: true,
2098
- disableHoverOpen: true
2099
- }
2100
- )
2101
- }
2102
- ),
2103
- rightContent: p.onCreate ? /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
2104
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { "data-testid": "new-task-button", children: [
2105
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "mr-1 size-4" }),
2106
- "New",
2107
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "ml-1 size-3" })
2108
- ] }) }),
2109
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuContent, { align: "end", children: [
2110
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: p.onCreate, children: "Task" }),
2111
- p.onCreateWorkflow && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: p.onCreateWorkflow, children: "Saved workflow" })
2112
- ] })
2113
- ] }) : p.header
2114
- }
2115
- ),
2116
- /* @__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(
2117
- chunkZW6FPIFC_cjs.EmptyState,
2118
- {
2119
- title: q ? "No matches" : all.length ? "You\u2019re all caught up" : "No work here yet",
2120
- description: "Create a task from a prompt or a saved workflow. Keep its drafts and outputs together."
2121
- }
2122
- ) : /* @__PURE__ */ jsxRuntime.jsxs("ul", { children: [
2123
- workflows.map((w) => {
2124
- const runs = roots.filter((t) => t.workflow_ext_id === w.external_id).sort(order);
2125
- const editable = w.is_owner !== false || p.canEditShared;
2126
- return /* @__PURE__ */ jsxRuntime.jsxs("li", { "data-testid": `task-workflow-${w.external_id}`, children: [
2127
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 border-b py-3", children: [
2128
- runs.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
2129
- ui.Button,
2130
- {
2131
- variant: "ghost",
2132
- size: "icon",
2133
- className: "size-7",
2134
- "aria-label": `${collapsed.has(w.external_id) ? "Expand" : "Collapse"} ${w.name}`,
2135
- onClick: () => toggle(setCollapsed, w.external_id),
2136
- children: collapsed.has(w.external_id) ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4" })
2137
- }
2138
- ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "mx-1 mt-1 size-4 shrink-0 text-muted-foreground" }),
2139
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
2140
- /* @__PURE__ */ jsxRuntime.jsx(
2141
- "button",
2142
- {
2143
- className: "block text-left text-sm font-medium hover:underline",
2144
- disabled: !editable,
2145
- onClick: () => p.onEditWorkflow?.(w.external_id),
2146
- children: w.name
2147
- }
2148
- ),
2149
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [
2150
- "Saved workflow \xB7 ",
2151
- w.summary ?? "Run when needed",
2152
- !w.active ? " \xB7 Paused" : "",
2153
- runs.length ? ` \xB7 ${runs.length} ${runs.length === 1 ? "task" : "tasks"}` : ""
2154
- ] }),
2155
- w.last_error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-destructive", children: w.last_error })
2156
- ] }),
2157
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
2158
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
2159
- ui.Button,
2160
- {
2161
- variant: "ghost",
2162
- size: "icon",
2163
- className: "size-8",
2164
- "aria-label": `Actions for ${w.name}`,
2165
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { className: "size-4" })
2166
- }
2167
- ) }),
2168
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuContent, { align: "end", children: [
2169
- p.onWorkflowHistory && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: () => p.onWorkflowHistory?.(w.external_id), children: "Run history" }),
2170
- editable && p.onToggleWorkflow && /* @__PURE__ */ jsxRuntime.jsx(
2171
- ui.DropdownMenuItem,
2172
- {
2173
- onSelect: () => p.onToggleWorkflow?.(w.external_id, !w.active),
2174
- children: w.active ? "Pause" : "Resume"
2175
- }
2176
- ),
2177
- (w.is_owner !== false || p.isWorkspaceOwner) && p.onDeleteWorkflow && /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuItem, { onSelect: () => p.onDeleteWorkflow?.(w.external_id), children: "Delete workflow" })
2178
- ] })
2179
- ] })
2180
- ] }),
2181
- !collapsed.has(w.external_id) && runs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ul", { children: runs.map((t) => renderTask(t, 1)) })
2182
- ] }, w.external_id);
2183
- }),
2184
- roots.filter((t) => !t.workflow_ext_id || !workflowIds.has(t.workflow_ext_id)).sort(order).map((t) => renderTask(t))
2185
- ] }) }),
2186
- /* @__PURE__ */ jsxRuntime.jsx(chunkV4ISCZJ7_cjs.SelectionBar, { count: selectedTasks.length, onClear: clearSelection, children: (isCompact) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2187
- p.selectionActions?.(selectedTasks, isCompact, clearSelection),
2188
- p.onMarkDoneMany && /* @__PURE__ */ jsxRuntime.jsx(
2189
- chunkV4ISCZJ7_cjs.SelectionBarAction,
2190
- {
2191
- icon: lucideReact.CheckCheck,
2192
- label: l.markDoneMany,
2193
- isCompact,
2194
- disabled: !markableTasks.length,
2195
- onClick: () => {
2196
- p.onMarkDoneMany?.(markableTasks);
2197
- clearSelection();
2198
- },
2199
- testId: "task-bulk-done"
2200
- }
2201
- ),
2202
- p.onDeleteMany && /* @__PURE__ */ jsxRuntime.jsx(
2203
- chunkV4ISCZJ7_cjs.SelectionBarAction,
2204
- {
2205
- icon: lucideReact.Trash2,
2206
- label: l.deleteMany,
2207
- isCompact,
2208
- disabled: !deletableTasks.length,
2209
- onClick: () => {
2210
- p.onDeleteMany?.(deletableTasks);
2211
- clearSelection();
2212
- },
2213
- className: "text-red-text hover:bg-red-bg hover:text-red-text",
2214
- testId: "task-bulk-delete"
2215
- }
2216
- )
2217
- ] }) }),
2218
- moving && p.onMove && /* @__PURE__ */ jsxRuntime.jsx(
2219
- TaskMoveDialog,
2220
- {
2221
- open: true,
2222
- onOpenChange: (open) => !open && setMoving(null),
2223
- options: chunkFY4C7HU5_cjs.moveTargets(all, moving).map((t) => ({ id: t.external_id, label: nameOf(t) })),
2224
- currentParentId: moving.parent_conversation_ext_id,
2225
- onPick: (id) => p.onMove?.(moving, id),
2226
- labels: {
2227
- title: l.moveToTitle(nameOf(moving)),
2228
- none: l.moveToNone,
2229
- search: l.moveToSearch,
2230
- empty: l.moveToEmpty,
2231
- cancel: l.moveToCancel
2232
- }
2233
- }
2234
- )
2235
- ] });
2236
- }
2237
- function filterConversationRows(conversations, query, labelText, doneFilter = "exclude", visibilityFilters, meetingFilter = null) {
2238
- const q = query.trim().toLowerCase();
2239
- return [...conversations].sort(
2240
- (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)
2241
- ).filter(
2242
- (row) => doneFilter === "exclude" ? row.status !== "done" : doneFilter === "include" ? row.status === "done" : true
2243
- ).filter((row) => {
2244
- const state = row.is_shared ? visibilityFilters?.workspace : visibilityFilters?.me;
2245
- const hasIncluded = visibilityFilters?.me === "include" || visibilityFilters?.workspace === "include";
2246
- return state !== "exclude" && (!hasIncluded || state === "include");
2247
- }).filter(
2248
- (row) => meetingFilter === "include" ? !!row.meeting_call_ext_id : meetingFilter === "exclude" ? !row.meeting_call_ext_id : true
2249
- ).filter((row) => !q || `${row.title ?? ""} ${labelText?.(row) ?? ""}`.toLowerCase().includes(q));
2250
- }
2251
- function ConversationListView(p) {
2252
- const liveProps = react.useRef(p);
2253
- liveProps.current = p;
2254
- const [query, setQuery] = react.useState("");
2255
- const [selected, setSelected] = react.useState(/* @__PURE__ */ new Set());
2256
- const q = `${query} ${p.filterText ?? ""}`.trim().toLowerCase();
2257
- const isPhone = chunkFX3K6LNZ_cjs.useIsPhone();
2258
- const rows = react.useMemo(
2259
- () => filterConversationRows(
2260
- p.conversations,
2261
- q,
2262
- p.labelText,
2263
- p.doneFilter,
2264
- p.visibilityFilters,
2265
- p.meetingFilter
2266
- ),
2267
- [p.conversations, q, p.labelText, p.doneFilter, p.visibilityFilters, p.meetingFilter]
2268
- );
2269
- const selectedRows = p.conversations.filter((c) => selected.has(c.external_id));
2270
- const hasLabels = p.conversations.some((c) => !!p.labelText?.(c));
2271
- const columns = react.useMemo(
2272
- () => [
2273
- {
2274
- colId: "name",
2275
- headerName: "Thread",
2276
- flex: 2,
2277
- minWidth: 200,
2278
- valueGetter: ({ data }) => data?.title?.trim() || "Untitled thread",
2279
- cellRenderer: ({ data }) => data && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group flex h-full min-w-0 items-center gap-2", children: [
2280
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: liveProps.current.renderThread ? liveProps.current.renderThread(data) : /* @__PURE__ */ jsxRuntime.jsx(
2281
- chunkFY4C7HU5_cjs.EntityChip,
2282
- {
2283
- icon: /* @__PURE__ */ jsxRuntime.jsx(ui.ThreadVisibilityIcon, { shared: data.is_shared ?? false, className: "size-4" }),
2284
- label: data.title?.trim() || "Untitled thread",
2285
- pillTooltip: "Open conversation",
2286
- labelMaxWidth: "max-w-full",
2287
- onClick: () => liveProps.current.onOpen(data),
2288
- testId: `thread-open-${data.external_id}`
2289
- }
2290
- ) }),
2291
- (data.message_count ?? 0) > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
2292
- "span",
2293
- {
2294
- className: "inline-flex h-5 shrink-0 items-center gap-0.5 self-center rounded-full bg-muted px-1.5 text-[10px] font-medium leading-none tabular-nums text-muted-foreground",
2295
- title: `${data.message_count} ${data.message_count === 1 ? "message" : "messages"}`,
2296
- "data-testid": `thread-messages-${data.external_id}`,
2297
- children: [
2298
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "size-3", "aria-hidden": true }),
2299
- data.message_count
2300
- ]
2301
- }
2302
- ),
2303
- (data.is_owner !== false || liveProps.current.canEditShared) && /* @__PURE__ */ jsxRuntime.jsx(
2304
- "button",
2305
- {
2306
- type: "button",
2307
- "aria-label": `Rename ${data.title?.trim() || "Untitled thread"}`,
2308
- onClick: () => liveProps.current.onRename(data),
2309
- "data-testid": `thread-rename-${data.external_id}`,
2310
- className: "shrink-0 pointer-coarse:flex pointer-coarse:size-11 pointer-coarse:items-center pointer-coarse:justify-center",
2311
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkSIB6C7P7_cjs.CellHoverIcon, {})
2312
- }
2313
- )
2314
- ] })
2315
- },
2316
- // Labels only when a thread has some (an empty column only takes the names' room), and never
2317
- // on a phone, where the status is what a row must say.
2318
- ...liveProps.current.renderLabels && hasLabels && !isPhone ? [
2319
- {
2320
- colId: "labels",
2321
- headerName: "Labels",
2322
- flex: 0.5,
2323
- minWidth: 100,
2324
- valueGetter: ({ data }) => data ? liveProps.current.labelText?.(data) ?? "" : "",
2325
- cellRenderer: ({ data }) => data && liveProps.current.renderLabels?.(data)
2326
- }
2327
- ] : [],
2328
- {
2329
- colId: "status",
2330
- headerName: "Status",
2331
- width: isPhone ? 170 : 240,
2332
- valueGetter: ({ data }) => data?.status,
2333
- cellRenderer: ({ data }) => data && (liveProps.current.renderStatus ? liveProps.current.renderStatus(data) : /* @__PURE__ */ jsxRuntime.jsx(
2334
- chunkFY4C7HU5_cjs.ThreadStatusLine,
2335
- {
2336
- state: data.status === "done" ? "done" : data.status === "todo" ? "todo" : "ready"
2337
- }
2338
- ))
2339
- },
2340
- // Who spoke last (their face) and when: the two read together, at the row's end.
2341
- ...liveProps.current.renderBy || liveProps.current.renderOwner ? [
2342
- {
2343
- colId: liveProps.current.renderBy ? "by" : "owner",
2344
- headerName: liveProps.current.renderBy ? "By" : "Owner",
2345
- width: 64,
2346
- hide: isPhone,
2347
- sortable: false,
2348
- resizable: false,
2349
- cellRenderer: ({ data }) => data && (liveProps.current.renderBy || liveProps.current.renderOwner)?.(data)
2350
- }
2351
- ] : [],
2352
- {
2353
- colId: "activity",
2354
- initialSort: "desc",
2355
- headerName: "Updated",
2356
- width: 128,
2357
- hide: isPhone,
2358
- valueGetter: ({ data }) => data?.last_message_updated_at || data?.updated_at || data?.created_at || "",
2359
- valueFormatter: ({ value }) => value ? liveProps.current.formatDate(value) : "\u2014",
2360
- cellClass: "flex items-center text-xs text-muted-foreground/80"
2361
- }
2362
- ],
2363
- [
2364
- Boolean(p.renderThread),
2365
- Boolean(p.renderLabels),
2366
- Boolean(p.renderOwner),
2367
- Boolean(p.renderBy),
2368
- Boolean(p.renderStatus),
2369
- isPhone,
2370
- hasLabels
2371
- ]
2372
- );
2373
- const centred = react.useMemo(
2374
- () => columns.map((c) => ({ cellClass: "flex items-center", ...c })),
2375
- [columns]
2376
- );
2377
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col", "data-testid": "conversation-list-view", children: [
2378
- p.showHeader !== false && /* @__PURE__ */ jsxRuntime.jsx(
2379
- chunkMEMWZ72Y_cjs.TabHeader,
2380
- {
2381
- testId: "threads-tab-header",
2382
- tabs: [
2383
- {
2384
- id: "threads",
2385
- label: "",
2386
- count: rows.length,
2387
- countIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "size-3.5" }),
2388
- countPlacement: "leading",
2389
- presentation: "count",
2390
- hasActiveFilters: !!q
2391
- }
2392
- ],
2393
- activeTabId: "threads",
2394
- onTabChange: () => {
2395
- },
2396
- firstTabContent: /* @__PURE__ */ jsxRuntime.jsx(
2397
- chunk2EI7NCUA_cjs.FilterInput,
2398
- {
2399
- value: query,
2400
- hideFieldPicker: true,
2401
- ariaLabel: "Search threads",
2402
- onChange: setQuery,
2403
- fields: ["text"],
2404
- onFieldsChange: () => {
2405
- },
2406
- labels: {
2407
- placeholder: "Find a thread\u2026",
2408
- fieldNames: { text: "Thread" }
2409
- },
2410
- className: "w-44 max-w-[40vw]"
2411
- }
2412
- ),
2413
- rightContent: p.header
2414
- }
2415
- ),
2416
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
2417
- chunkLKK52DEY_cjs.GridView,
2418
- {
2419
- testId: "threads-grid",
2420
- items: rows,
2421
- columnDefs: centred,
2422
- getItemId: (row) => row.external_id,
2423
- getRowTestId: (row) => `thread-row-${row.external_id}`,
2424
- onRowClick: p.onOpen,
2425
- height: "100%",
2426
- isLoading: p.isLoading,
2427
- loadingMessage: "Loading threads\u2026",
2428
- emptyState: {
2429
- title: q ? "No threads match" : "No conversations yet",
2430
- message: p.footer ? "Type below to ask ARBI, bring in people, or both." : "Use New Task to ask ARBI, bring in people, or both."
2431
- },
2432
- selection: p.selectionActions ? {
2433
- mode: "multiple",
2434
- controlled: true,
2435
- selected: selectedRows,
2436
- onSelectionChange: (items) => setSelected(new Set(items.map((item) => item.external_id)))
2437
- } : void 0,
2438
- gridOptions: {
2439
- suppressClickEdit: true,
2440
- onCellKeyDown: (event) => {
2441
- if (event.event?.key === "Enter" && "column" in event && event.column.getColId() === "name" && event.data)
2442
- p.onOpen(event.data);
2443
- }
2444
- }
2445
- }
2446
- ) }),
2447
- p.footer,
2448
- p.selectionActions && /* @__PURE__ */ jsxRuntime.jsx(chunkV4ISCZJ7_cjs.SelectionBar, { count: selectedRows.length, onClear: () => setSelected(/* @__PURE__ */ new Set()), children: (compact) => p.selectionActions?.(selectedRows, compact, () => setSelected(/* @__PURE__ */ new Set())) })
2449
- ] });
2450
- }
2451
- var DEFAULT_TASK_THREAD_CHIP_LABELS = {
2452
- open: "Open thread",
2453
- watch: "Watch live",
2454
- none: "No thread yet"
2455
- };
2456
- function TaskThreadChip({
2457
- id,
2458
- conversationId,
2459
- generating = false,
2460
- onOpen,
2461
- testId,
2462
- labels
2463
- }) {
2464
- const l = { ...DEFAULT_TASK_THREAD_CHIP_LABELS, ...labels };
2465
- if (!conversationId) {
2466
- return /* @__PURE__ */ jsxRuntime.jsxs(
2467
- "span",
2468
- {
2469
- className: "inline-flex items-center gap-1 text-xs text-muted-foreground",
2470
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: `task-thread-${id}` }),
2471
- "data-state": "none",
2472
- children: [
2473
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "size-3.5 opacity-50", "aria-hidden": true }),
2474
- l.none
2475
- ]
2476
- }
2477
- );
2478
- }
2479
- return /* @__PURE__ */ jsxRuntime.jsxs(
2480
- ui.Button,
2481
- {
2482
- variant: "ghost",
2483
- size: "sm",
2484
- className: ui.cn(
2485
- "h-7 gap-1.5 px-2 text-xs pointer-coarse:h-11",
2486
- generating && "text-ai-ink hover:text-ai-ink"
2487
- ),
2488
- onClick: () => onOpen(conversationId),
2489
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: `task-thread-${id}` }),
2490
- "data-state": generating ? "live" : "idle",
2491
- children: [
2492
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative flex size-3.5 items-center justify-center", children: [
2493
- generating && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inline-flex size-full animate-ping rounded-full bg-ai-soft" }),
2494
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "relative size-3.5", "aria-hidden": true })
2495
- ] }),
2496
- generating ? l.watch : l.open
2497
- ]
2498
- }
2499
- );
2500
- }
2501
- var DEFAULT_TASKS_CHROME_LABELS = {
2502
- tasksTab: "Tasks",
2503
- newTask: "New task"
2504
- };
2505
- function TasksToolbar({ count, onNewTask, testIds, labels }) {
2506
- const l = { ...DEFAULT_TASKS_CHROME_LABELS, ...labels };
2507
- const tabs = [
2508
- {
2509
- id: "tasks",
2510
- label: l.tasksTab,
2511
- icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListTodo, { className: "size-4" }),
2512
- count,
2513
- testId: chunkMHVNT4J3_cjs.testIdOr(testIds?.tab, { testId: "tasks-tab" })
2514
- }
2515
- ];
2516
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-background", "data-slot": "tasks-toolbar", children: /* @__PURE__ */ jsxRuntime.jsx(
2517
- chunkMEMWZ72Y_cjs.TabHeader,
2518
- {
2519
- tabs,
2520
- activeTabId: "tasks",
2521
- onTabChange: () => {
2522
- },
2523
- rightContent: /* @__PURE__ */ jsxRuntime.jsxs(
2524
- ui.Button,
2525
- {
2526
- onClick: onNewTask,
2527
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.newTask, { testId: "task-new" }),
2528
- children: [
2529
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 16, className: "mr-1.5" }),
2530
- l.newTask
2531
- ]
2532
- }
2533
- )
2534
- }
2535
- ) });
2536
- }
2537
- var DEFAULT_WORKFLOWS_CHROME_LABELS = {
2538
- workflowsTab: "Workflows",
2539
- newWorkflow: "New workflow"
2540
- };
2541
- function WorkflowsToolbar({ count, onNewWorkflow, testIds, labels }) {
2542
- const l = { ...DEFAULT_WORKFLOWS_CHROME_LABELS, ...labels };
2543
- const tabs = [
2544
- {
2545
- id: "workflows",
2546
- label: l.workflowsTab,
2547
- icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "size-4" }),
2548
- count,
2549
- testId: chunkMHVNT4J3_cjs.testIdOr(testIds?.tab, { testId: "workflows-tab" })
2550
- }
2551
- ];
2552
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-background", "data-slot": "workflows-toolbar", children: /* @__PURE__ */ jsxRuntime.jsx(
2553
- chunkMEMWZ72Y_cjs.TabHeader,
2554
- {
2555
- tabs,
2556
- activeTabId: "workflows",
2557
- onTabChange: () => {
2558
- },
2559
- rightContent: /* @__PURE__ */ jsxRuntime.jsxs(
2560
- ui.Button,
2561
- {
2562
- onClick: onNewWorkflow,
2563
- "data-testid": chunkMHVNT4J3_cjs.testIdOr(testIds?.newWorkflow, { testId: "workflow-new" }),
2564
- children: [
2565
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 16, className: "mr-1.5" }),
2566
- l.newWorkflow
2567
- ]
2568
- }
2569
- )
2570
- }
2571
- ) });
2572
- }
2573
- function ThreadNotifyDialog({
2574
- open,
2575
- onOpenChange,
2576
- people,
2577
- isShared,
2578
- onNotify
2579
- }) {
2580
- const [selected, setSelected] = react.useState([]);
2581
- const [query, setQuery] = react.useState("");
2582
- const [busy, setBusy] = react.useState(false);
2583
- const [error, setError] = react.useState(null);
2584
- react.useEffect(() => {
2585
- if (open) {
2586
- setSelected([]);
2587
- setQuery("");
2588
- setError(null);
2589
- }
2590
- }, [open]);
2591
- return /* @__PURE__ */ jsxRuntime.jsx(
2592
- ui.Dialog,
2593
- {
2594
- open,
2595
- onOpenChange: (value) => {
2596
- if (!busy) onOpenChange(value);
2597
- },
2598
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { className: "max-w-sm", "data-testid": "thread-notify-dialog", children: [
2599
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: "Notify" }),
2600
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: isShared ? "Ask someone to follow up in this thread." : "Notifying someone shares this thread with your workspace." }),
2601
- /* @__PURE__ */ jsxRuntime.jsx(
2602
- ui.Input,
2603
- {
2604
- "aria-label": "Find people",
2605
- placeholder: "Find someone\u2026",
2606
- value: query,
2607
- onChange: (event) => setQuery(event.target.value)
2608
- }
2609
- ),
2610
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-64 overflow-y-auto space-y-1", children: [
2611
- people.filter((person) => person.label.toLowerCase().includes(query.toLowerCase())).map((person) => /* @__PURE__ */ jsxRuntime.jsxs(
2612
- "label",
2613
- {
2614
- className: "flex cursor-pointer items-center gap-2 rounded px-2 py-2 hover:bg-muted",
2615
- children: [
2616
- /* @__PURE__ */ jsxRuntime.jsx(
2617
- ui.Checkbox,
2618
- {
2619
- disabled: busy,
2620
- checked: selected.includes(person.id),
2621
- onCheckedChange: (checked) => setSelected(
2622
- (old) => checked ? [...old, person.id] : old.filter((id) => id !== person.id)
2623
- )
2624
- }
2625
- ),
2626
- person.label
2627
- ]
2628
- },
2629
- person.id
2630
- )),
2631
- !people.length && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "No other workspace members yet." })
2632
- ] }),
2633
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive", children: error }),
2634
- /* @__PURE__ */ jsxRuntime.jsx(
2635
- ui.Button,
2636
- {
2637
- disabled: busy || !selected.length,
2638
- "data-testid": "thread-notify-submit",
2639
- onClick: async () => {
2640
- setBusy(true);
2641
- setError(null);
2642
- try {
2643
- await onNotify(selected);
2644
- onOpenChange(false);
2645
- } catch (failure) {
2646
- setError(failure instanceof Error ? failure.message : "Could not notify people");
2647
- } finally {
2648
- setBusy(false);
2649
- }
2650
- },
2651
- children: busy ? "Notifying\u2026" : "Notify"
2652
- }
2653
- )
2654
- ] })
2655
- }
2656
- );
2657
- }
2658
- function ConversationTurnSpeaker({
2659
- role,
2660
- actor,
2661
- currentUserId,
2662
- colorClass,
2663
- platformName = "ARBI",
2664
- platformLogoSrc = ui.ARBI_MARK_SRC,
2665
- variant = "pill"
2666
- }) {
2667
- if (!role) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "\u2014" });
2668
- if (role === "assistant" && !actor)
2669
- return /* @__PURE__ */ jsxRuntime.jsx(
2670
- ui.UserEntity,
2671
- {
2672
- size: "sm",
2673
- variant,
2674
- interactive: false,
2675
- picture: platformLogoSrc,
2676
- avatarImageClassName: "object-contain p-0.5",
2677
- initials: platformName.charAt(0),
2678
- displayName: platformName
2679
- }
2680
- );
2681
- if (!actor) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Unknown participant" });
2682
- const isMe = actor.external_id === currentUserId;
2683
- const displayName = isMe ? "You" : [actor.given_name, actor.family_name].filter(Boolean).join(" ");
2684
- return /* @__PURE__ */ jsxRuntime.jsx(
2685
- ui.UserEntity,
2686
- {
2687
- size: "sm",
2688
- variant,
2689
- interactive: false,
2690
- isMe,
2691
- isAgent: actor.external_id.startsWith("agt-"),
2692
- displayName,
2693
- initials: `${actor.given_name.charAt(0)}${actor.family_name?.charAt(0) ?? ""}`.toUpperCase(),
2694
- picture: actor.picture,
2695
- colorClass
2696
- }
2697
- );
2698
- }
2699
-
2700
- exports.AgentCard = AgentCard;
2701
- exports.AgentGallery = AgentGallery;
2702
- exports.ConversationListView = ConversationListView;
2703
- exports.ConversationTurnSpeaker = ConversationTurnSpeaker;
2704
- exports.DEFAULT_AGENT_CARD_LABELS = DEFAULT_AGENT_CARD_LABELS;
2705
- exports.DEFAULT_AGENT_GALLERY_LABELS = DEFAULT_AGENT_GALLERY_LABELS;
2706
- exports.DEFAULT_SKILL_CARD_LABELS = DEFAULT_SKILL_CARD_LABELS;
2707
- exports.DEFAULT_SKILL_ROW_LABELS = DEFAULT_SKILL_ROW_LABELS;
2708
- exports.DEFAULT_TASKS_CHROME_LABELS = DEFAULT_TASKS_CHROME_LABELS;
2709
- exports.DEFAULT_TASK_LIST_LABELS = DEFAULT_TASK_LIST_LABELS;
2710
- exports.DEFAULT_TASK_OUTPUTS_CELL_LABELS = DEFAULT_TASK_OUTPUTS_CELL_LABELS;
2711
- exports.DEFAULT_TASK_STATUS_PILL_LABELS = DEFAULT_TASK_STATUS_PILL_LABELS;
2712
- exports.DEFAULT_TASK_THREAD_CHIP_LABELS = DEFAULT_TASK_THREAD_CHIP_LABELS;
2713
- exports.DEFAULT_UPLOAD_TASK_ITEM_LABELS = DEFAULT_UPLOAD_TASK_ITEM_LABELS;
2714
- exports.DEFAULT_UPLOAD_TASK_LIST_LABELS = DEFAULT_UPLOAD_TASK_LIST_LABELS;
2715
- exports.DEFAULT_WORKFLOWS_CHROME_LABELS = DEFAULT_WORKFLOWS_CHROME_LABELS;
2716
- exports.SkillCard = SkillCard;
2717
- exports.SkillRow = SkillRow;
2718
- exports.TASK_COLUMN_ORDER = TASK_COLUMN_ORDER;
2719
- exports.TaskInbox = TaskInbox;
2720
- exports.TaskMoveDialog = TaskMoveDialog;
2721
- exports.TaskOutputsCell = TaskOutputsCell;
2722
- exports.TaskStatusPill = TaskStatusPill;
2723
- exports.TaskTable = TaskTable;
2724
- exports.TaskThreadChip = TaskThreadChip;
2725
- exports.TasksToolbar = TasksToolbar;
2726
- exports.ThreadNotifyDialog = ThreadNotifyDialog;
2727
- exports.UploadTaskItem = UploadTaskItem;
2728
- exports.UploadTaskList = UploadTaskList;
2729
- exports.WorkflowsToolbar = WorkflowsToolbar;
2730
- exports.createTaskColumns = createTaskColumns;
2731
- exports.filterConversationRows = filterConversationRows;
2732
- exports.formatElapsed = formatElapsed;
2733
- exports.useWorkflowPreview = useWorkflowPreview;
2734
- //# sourceMappingURL=chunk-PUX4M22Q.cjs.map
2735
- //# sourceMappingURL=chunk-PUX4M22Q.cjs.map