@arbidocs/blocks 0.4.142 → 0.4.143

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 (209) hide show
  1. package/dist/agents/index.cjs +438 -435
  2. package/dist/agents/index.js +10 -7
  3. package/dist/chat/index.cjs +139 -138
  4. package/dist/chat/index.js +4 -3
  5. package/dist/{chunk-S24XEVPS.cjs → chunk-464YPRAE.cjs} +33 -2
  6. package/dist/chunk-464YPRAE.cjs.map +1 -0
  7. package/dist/{chunk-7YLJHTDC.cjs → chunk-5A2QQAF5.cjs} +11 -11
  8. package/dist/{chunk-7YLJHTDC.cjs.map → chunk-5A2QQAF5.cjs.map} +1 -1
  9. package/dist/{chunk-ON3TKY5Y.js → chunk-5YHEHEJT.js} +242 -4
  10. package/dist/chunk-5YHEHEJT.js.map +1 -0
  11. package/dist/chunk-76L6LOP3.cjs +308 -0
  12. package/dist/chunk-76L6LOP3.cjs.map +1 -0
  13. package/dist/chunk-AOSUHWIL.js +98 -0
  14. package/dist/chunk-AOSUHWIL.js.map +1 -0
  15. package/dist/{chunk-PROK33G6.js → chunk-C44TDH54.js} +13 -1598
  16. package/dist/chunk-C44TDH54.js.map +1 -0
  17. package/dist/{chunk-YFY3TQ6Q.cjs → chunk-COCGRJLA.cjs} +7 -7
  18. package/dist/{chunk-YFY3TQ6Q.cjs.map → chunk-COCGRJLA.cjs.map} +1 -1
  19. package/dist/chunk-CQCC7LE7.js +210 -0
  20. package/dist/chunk-CQCC7LE7.js.map +1 -0
  21. package/dist/{chunk-UGCKUXRV.js → chunk-CSI2B2H5.js} +3 -3
  22. package/dist/{chunk-UGCKUXRV.js.map → chunk-CSI2B2H5.js.map} +1 -1
  23. package/dist/{chunk-R26BK7YL.cjs → chunk-DTROMMDX.cjs} +4 -4
  24. package/dist/{chunk-R26BK7YL.cjs.map → chunk-DTROMMDX.cjs.map} +1 -1
  25. package/dist/{chunk-65THHQVB.cjs → chunk-ECW2R2KF.cjs} +27 -27
  26. package/dist/{chunk-65THHQVB.cjs.map → chunk-ECW2R2KF.cjs.map} +1 -1
  27. package/dist/{chunk-RI6DZA5X.js → chunk-EF4ZLKRM.js} +3 -3
  28. package/dist/{chunk-RI6DZA5X.js.map → chunk-EF4ZLKRM.js.map} +1 -1
  29. package/dist/{chunk-WS5EX7DN.cjs → chunk-EYKISBDO.cjs} +5 -5
  30. package/dist/{chunk-WS5EX7DN.cjs.map → chunk-EYKISBDO.cjs.map} +1 -1
  31. package/dist/chunk-FJETR2AS.js +561 -0
  32. package/dist/chunk-FJETR2AS.js.map +1 -0
  33. package/dist/{chunk-JO3EMZ4X.js → chunk-GWSGIZQ5.js} +3 -3
  34. package/dist/{chunk-JO3EMZ4X.js.map → chunk-GWSGIZQ5.js.map} +1 -1
  35. package/dist/{chunk-I7WG3JRD.js → chunk-H4D7WKDY.js} +3 -3
  36. package/dist/{chunk-I7WG3JRD.js.map → chunk-H4D7WKDY.js.map} +1 -1
  37. package/dist/{chunk-GBS6QVGS.cjs → chunk-HAOKT4LC.cjs} +5 -5
  38. package/dist/{chunk-GBS6QVGS.cjs.map → chunk-HAOKT4LC.cjs.map} +1 -1
  39. package/dist/{chunk-N5X37J3D.js → chunk-IJST4EBM.js} +11 -8
  40. package/dist/chunk-IJST4EBM.js.map +1 -0
  41. package/dist/{chunk-3RJN2VTL.js → chunk-IXWJGOM2.js} +3 -3
  42. package/dist/{chunk-3RJN2VTL.js.map → chunk-IXWJGOM2.js.map} +1 -1
  43. package/dist/{chunk-CYNF5PZI.js → chunk-J5CWKFSC.js} +3 -3
  44. package/dist/{chunk-CYNF5PZI.js.map → chunk-J5CWKFSC.js.map} +1 -1
  45. package/dist/{chunk-OWCEQKAR.cjs → chunk-JSTKEZBS.cjs} +21 -318
  46. package/dist/chunk-JSTKEZBS.cjs.map +1 -0
  47. package/dist/{chunk-TP6PLDNM.cjs → chunk-KMZWKSKO.cjs} +8 -8
  48. package/dist/{chunk-TP6PLDNM.cjs.map → chunk-KMZWKSKO.cjs.map} +1 -1
  49. package/dist/{chunk-C4WSHRR6.cjs → chunk-KPZZ5FHE.cjs} +32 -12
  50. package/dist/chunk-KPZZ5FHE.cjs.map +1 -0
  51. package/dist/{chunk-CKCBBYTA.js → chunk-KSHKTOY2.js} +5 -205
  52. package/dist/chunk-KSHKTOY2.js.map +1 -0
  53. package/dist/chunk-LJJJ6CYH.cjs +62 -0
  54. package/dist/chunk-LJJJ6CYH.cjs.map +1 -0
  55. package/dist/chunk-LPYEUD2D.cjs +1627 -0
  56. package/dist/chunk-LPYEUD2D.cjs.map +1 -0
  57. package/dist/chunk-MHFF5N65.cjs +101 -0
  58. package/dist/chunk-MHFF5N65.cjs.map +1 -0
  59. package/dist/{chunk-GYAUJ4KT.js → chunk-MTSKK3BN.js} +32 -3
  60. package/dist/chunk-MTSKK3BN.js.map +1 -0
  61. package/dist/chunk-NHZK64TQ.js +75 -0
  62. package/dist/chunk-NHZK64TQ.js.map +1 -0
  63. package/dist/{chunk-BPBSSMRB.js → chunk-NRFAWUVD.js} +3 -3
  64. package/dist/{chunk-BPBSSMRB.js.map → chunk-NRFAWUVD.js.map} +1 -1
  65. package/dist/chunk-NWNVWO6L.cjs +80 -0
  66. package/dist/chunk-NWNVWO6L.cjs.map +1 -0
  67. package/dist/{chunk-HIJUXAWS.cjs → chunk-O2GW5IY6.cjs} +86 -83
  68. package/dist/chunk-O2GW5IY6.cjs.map +1 -0
  69. package/dist/{chunk-3BFGL2JL.cjs → chunk-ODRHHWHY.cjs} +4 -4
  70. package/dist/{chunk-3BFGL2JL.cjs.map → chunk-ODRHHWHY.cjs.map} +1 -1
  71. package/dist/{chunk-Y3KA6X7B.js → chunk-OVR3XMYL.js} +4 -4
  72. package/dist/{chunk-Y3KA6X7B.js.map → chunk-OVR3XMYL.js.map} +1 -1
  73. package/dist/{chunk-Y5KTM3V5.js → chunk-PDKM27DF.js} +17 -295
  74. package/dist/chunk-PDKM27DF.js.map +1 -0
  75. package/dist/{chunk-OAL3B2ZU.cjs → chunk-PLJ7PHWU.cjs} +5 -5
  76. package/dist/{chunk-OAL3B2ZU.cjs.map → chunk-PLJ7PHWU.cjs.map} +1 -1
  77. package/dist/{chunk-DPGFEMVT.cjs → chunk-RB7GX2VT.cjs} +57 -1665
  78. package/dist/chunk-RB7GX2VT.cjs.map +1 -0
  79. package/dist/chunk-RFIBUWLF.cjs +232 -0
  80. package/dist/chunk-RFIBUWLF.cjs.map +1 -0
  81. package/dist/{chunk-MIDXCYZB.cjs → chunk-RQ2Y7USX.cjs} +15 -235
  82. package/dist/chunk-RQ2Y7USX.cjs.map +1 -0
  83. package/dist/chunk-SV65E4QW.js +58 -0
  84. package/dist/chunk-SV65E4QW.js.map +1 -0
  85. package/dist/{chunk-LYUO3E6V.js → chunk-SZOFGU7W.js} +3 -3
  86. package/dist/{chunk-LYUO3E6V.js.map → chunk-SZOFGU7W.js.map} +1 -1
  87. package/dist/chunk-T5B7FM7S.js +1602 -0
  88. package/dist/chunk-T5B7FM7S.js.map +1 -0
  89. package/dist/{chunk-YNIBUKV5.js → chunk-TBEVGWY3.js} +32 -14
  90. package/dist/chunk-TBEVGWY3.js.map +1 -0
  91. package/dist/{chunk-MJCCBMM5.cjs → chunk-TC3RQNEX.cjs} +6 -80
  92. package/dist/chunk-TC3RQNEX.cjs.map +1 -0
  93. package/dist/chunk-TZGBRLPK.js +288 -0
  94. package/dist/chunk-TZGBRLPK.js.map +1 -0
  95. package/dist/chunk-U6YVZDOV.cjs +574 -0
  96. package/dist/chunk-U6YVZDOV.cjs.map +1 -0
  97. package/dist/{chunk-QIMVTGKS.cjs → chunk-U73KPFYH.cjs} +255 -2
  98. package/dist/chunk-U73KPFYH.cjs.map +1 -0
  99. package/dist/{chunk-HFGXA5CL.cjs → chunk-UTTTJSQU.cjs} +4 -4
  100. package/dist/{chunk-HFGXA5CL.cjs.map → chunk-UTTTJSQU.cjs.map} +1 -1
  101. package/dist/{chunk-DLBUFHLY.js → chunk-VTTZZ4FN.js} +4 -74
  102. package/dist/chunk-VTTZZ4FN.js.map +1 -0
  103. package/dist/{chunk-5FTIHRZH.cjs → chunk-XVUOMWMD.cjs} +4 -4
  104. package/dist/{chunk-5FTIHRZH.cjs.map → chunk-XVUOMWMD.cjs.map} +1 -1
  105. package/dist/{chunk-FXG7TFAG.js → chunk-Y4ATWQGV.js} +3 -3
  106. package/dist/{chunk-FXG7TFAG.js.map → chunk-Y4ATWQGV.js.map} +1 -1
  107. package/dist/{chunk-444XKG46.js → chunk-YKQ2DPIP.js} +3 -3
  108. package/dist/{chunk-444XKG46.js.map → chunk-YKQ2DPIP.js.map} +1 -1
  109. package/dist/{chunk-HEMU73OP.cjs → chunk-YSHIC4NJ.cjs} +4 -4
  110. package/dist/{chunk-HEMU73OP.cjs.map → chunk-YSHIC4NJ.cjs.map} +1 -1
  111. package/dist/{chunk-5BXEYYH6.js → chunk-ZM26YEOT.js} +3 -3
  112. package/dist/{chunk-5BXEYYH6.js.map → chunk-ZM26YEOT.js.map} +1 -1
  113. package/dist/citations/index.cjs +12 -12
  114. package/dist/citations/index.js +3 -3
  115. package/dist/connect/docx.cjs +36 -7
  116. package/dist/connect/docx.cjs.map +1 -1
  117. package/dist/connect/docx.d.ts +9 -2
  118. package/dist/connect/docx.js +30 -6
  119. package/dist/connect/docx.js.map +1 -1
  120. package/dist/connect/index.cjs +802 -628
  121. package/dist/connect/index.cjs.map +1 -1
  122. package/dist/connect/index.d.ts +2 -0
  123. package/dist/connect/index.js +636 -507
  124. package/dist/connect/index.js.map +1 -1
  125. package/dist/connection/ConnectedSettings.d.ts +3 -2
  126. package/dist/connection/docx/ConnectedNativeDocxComparison.d.ts +5 -0
  127. package/dist/connection/docx/ConnectedNativeDocxEditor.d.ts +16 -0
  128. package/dist/connection/{ConnectedStreamedWordArtifact.d.ts → docx/ConnectedStreamedWordArtifact.d.ts} +1 -1
  129. package/dist/connection/docx/support.d.ts +27 -0
  130. package/dist/connection/docx/useConnectedDocxReferences.d.ts +2 -0
  131. package/dist/connection/docx/useConnectedHouseTemplate.d.ts +2 -0
  132. package/dist/connection/settings-page/ConnectedAccountSettings.d.ts +35 -0
  133. package/dist/connection/settings-page/ConnectedMailSettings.d.ts +13 -0
  134. package/dist/connection/settings-page/ConnectedPremiumModels.d.ts +1 -0
  135. package/dist/connection/settings-page/ConnectedPrivacySettings.d.ts +12 -0
  136. package/dist/connection/settings-page/ConnectedSettingsPage.d.ts +29 -0
  137. package/dist/connection/settings-page/SessionStatusIcon.d.ts +7 -0
  138. package/dist/connection/settings-page/index.d.ts +6 -0
  139. package/dist/docx/index.cjs +17 -63
  140. package/dist/docx/index.cjs.map +1 -1
  141. package/dist/docx/index.d.ts +1 -0
  142. package/dist/docx/index.js +2 -64
  143. package/dist/docx/index.js.map +1 -1
  144. package/dist/docx/template/candidates.d.ts +16 -0
  145. package/dist/facts/index.cjs +3 -3
  146. package/dist/facts/index.js +2 -2
  147. package/dist/files/index.cjs +3 -3
  148. package/dist/files/index.js +2 -2
  149. package/dist/home/index.cjs +20 -20
  150. package/dist/home/index.js +4 -4
  151. package/dist/index.cjs +766 -741
  152. package/dist/index.cjs.map +1 -1
  153. package/dist/index.d.ts +2 -0
  154. package/dist/index.js +23 -18
  155. package/dist/index.js.map +1 -1
  156. package/dist/lib/deep-link.d.ts +46 -0
  157. package/dist/provider/BlocksProvider.d.ts +5 -1
  158. package/dist/provider/settings-section.d.ts +9 -0
  159. package/dist/retrieval/index.cjs +4 -4
  160. package/dist/retrieval/index.js +2 -2
  161. package/dist/settings/AppearanceSettings.d.ts +18 -0
  162. package/dist/settings/ServerConnectionControls.d.ts +16 -0
  163. package/dist/settings/SettingsPage.d.ts +31 -0
  164. package/dist/settings/index.cjs +188 -250
  165. package/dist/settings/index.cjs.map +1 -1
  166. package/dist/settings/index.d.ts +3 -1
  167. package/dist/settings/index.js +88 -199
  168. package/dist/settings/index.js.map +1 -1
  169. package/dist/shell/index.cjs +44 -44
  170. package/dist/shell/index.js +3 -3
  171. package/dist/site/index.cjs +74 -73
  172. package/dist/site/index.js +3 -2
  173. package/dist/studio/index.cjs +80 -78
  174. package/dist/studio/index.cjs.map +1 -1
  175. package/dist/studio/index.js +10 -8
  176. package/dist/studio/index.js.map +1 -1
  177. package/dist/workflow-canvas/index.cjs +62 -59
  178. package/dist/workflow-canvas/index.cjs.map +1 -1
  179. package/dist/workflow-canvas/index.js +10 -7
  180. package/dist/workflow-canvas/index.js.map +1 -1
  181. package/dist/workspaces/index.cjs +3 -3
  182. package/dist/workspaces/index.js +2 -2
  183. package/node_modules/@arbidocs/coedit/package.json +1 -1
  184. package/package.json +4 -4
  185. package/dist/chunk-4TR5QCCX.cjs +0 -43
  186. package/dist/chunk-4TR5QCCX.cjs.map +0 -1
  187. package/dist/chunk-7NDW4KF4.cjs +0 -112
  188. package/dist/chunk-7NDW4KF4.cjs.map +0 -1
  189. package/dist/chunk-C4WSHRR6.cjs.map +0 -1
  190. package/dist/chunk-CKCBBYTA.js.map +0 -1
  191. package/dist/chunk-DLBUFHLY.js.map +0 -1
  192. package/dist/chunk-DPGFEMVT.cjs.map +0 -1
  193. package/dist/chunk-ETXYVO6E.js +0 -109
  194. package/dist/chunk-ETXYVO6E.js.map +0 -1
  195. package/dist/chunk-GYAUJ4KT.js.map +0 -1
  196. package/dist/chunk-HIJUXAWS.cjs.map +0 -1
  197. package/dist/chunk-MCKOZACC.js +0 -41
  198. package/dist/chunk-MCKOZACC.js.map +0 -1
  199. package/dist/chunk-MIDXCYZB.cjs.map +0 -1
  200. package/dist/chunk-MJCCBMM5.cjs.map +0 -1
  201. package/dist/chunk-N5X37J3D.js.map +0 -1
  202. package/dist/chunk-ON3TKY5Y.js.map +0 -1
  203. package/dist/chunk-OWCEQKAR.cjs.map +0 -1
  204. package/dist/chunk-PROK33G6.js.map +0 -1
  205. package/dist/chunk-QIMVTGKS.cjs.map +0 -1
  206. package/dist/chunk-S24XEVPS.cjs.map +0 -1
  207. package/dist/chunk-Y5KTM3V5.js.map +0 -1
  208. package/dist/chunk-YNIBUKV5.js.map +0 -1
  209. package/dist/connection/ConnectedNativeDocxEditor.d.ts +0 -6
@@ -0,0 +1,1627 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkEYKISBDO_cjs = require('./chunk-EYKISBDO.cjs');
5
+ var chunkAHDJXIUB_cjs = require('./chunk-AHDJXIUB.cjs');
6
+ var chunkRQ2Y7USX_cjs = require('./chunk-RQ2Y7USX.cjs');
7
+ var chunkZW6FPIFC_cjs = require('./chunk-ZW6FPIFC.cjs');
8
+ var chunkV4ISCZJ7_cjs = require('./chunk-V4ISCZJ7.cjs');
9
+ var chunk2EI7NCUA_cjs = require('./chunk-2EI7NCUA.cjs');
10
+ var chunkC2CWWEHO_cjs = require('./chunk-C2CWWEHO.cjs');
11
+ var chunk7RGLTF76_cjs = require('./chunk-7RGLTF76.cjs');
12
+ var chunk76L6LOP3_cjs = require('./chunk-76L6LOP3.cjs');
13
+ var chunk32HW2Q33_cjs = require('./chunk-32HW2Q33.cjs');
14
+ var chunkMHVNT4J3_cjs = require('./chunk-MHVNT4J3.cjs');
15
+ var chunkKDG6FER6_cjs = require('./chunk-KDG6FER6.cjs');
16
+ var react = require('react');
17
+ var lucideReact = require('lucide-react');
18
+ var ui = require('@arbidocs/react/ui');
19
+ var jsxRuntime = require('react/jsx-runtime');
20
+
21
+ var DEFAULT_SCHEMA_FORM_LABELS = {
22
+ optional: "(optional)",
23
+ advanced: "More options",
24
+ errors: {
25
+ required: "This is needed to continue",
26
+ min: "Too small",
27
+ max: "Too large",
28
+ number: "Enter a number"
29
+ }
30
+ };
31
+ var TILE_MAX = 4;
32
+ function FieldControl({
33
+ field,
34
+ value,
35
+ error,
36
+ onChange,
37
+ l,
38
+ idFor,
39
+ renderScope,
40
+ renderDocuments,
41
+ renderIcon,
42
+ onEnterSubmit,
43
+ people
44
+ }) {
45
+ const id = `${idFor()}-control`;
46
+ const testId = idFor();
47
+ switch (field.type) {
48
+ case "text":
49
+ return /* @__PURE__ */ jsxRuntime.jsx(
50
+ ui.Input,
51
+ {
52
+ id,
53
+ "data-testid": testId,
54
+ value: String(value ?? ""),
55
+ placeholder: field.placeholder,
56
+ "aria-required": field.required || void 0,
57
+ "aria-invalid": error ? true : void 0,
58
+ "aria-describedby": error ? idFor("error") : void 0,
59
+ onChange: (e) => onChange(e.target.value)
60
+ }
61
+ );
62
+ case "longtext":
63
+ return /* @__PURE__ */ jsxRuntime.jsx(
64
+ ui.Textarea,
65
+ {
66
+ id,
67
+ "data-testid": testId,
68
+ value: String(value ?? ""),
69
+ placeholder: field.placeholder,
70
+ "aria-required": field.required || void 0,
71
+ "aria-invalid": error ? true : void 0,
72
+ "aria-describedby": error ? idFor("error") : void 0,
73
+ className: "min-h-[96px]",
74
+ onChange: (e) => onChange(e.target.value),
75
+ onKeyDown: (e) => {
76
+ if (onEnterSubmit && e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) {
77
+ e.preventDefault();
78
+ onEnterSubmit();
79
+ }
80
+ }
81
+ }
82
+ );
83
+ case "number":
84
+ return /* @__PURE__ */ jsxRuntime.jsx(
85
+ ui.Input,
86
+ {
87
+ id,
88
+ "data-testid": testId,
89
+ type: "number",
90
+ inputMode: "decimal",
91
+ min: field.min,
92
+ max: field.max,
93
+ value: value === void 0 ? "" : String(value),
94
+ placeholder: field.placeholder,
95
+ "aria-invalid": error ? true : void 0,
96
+ "aria-describedby": error ? idFor("error") : void 0,
97
+ onChange: (e) => onChange(e.target.value === "" ? "" : Number(e.target.value))
98
+ }
99
+ );
100
+ case "date":
101
+ return /* @__PURE__ */ jsxRuntime.jsx(
102
+ ui.Input,
103
+ {
104
+ id,
105
+ "data-testid": testId,
106
+ type: "date",
107
+ value: String(value ?? ""),
108
+ "aria-invalid": error ? true : void 0,
109
+ "aria-describedby": error ? idFor("error") : void 0,
110
+ onChange: (e) => onChange(e.target.value)
111
+ }
112
+ );
113
+ case "boolean":
114
+ return /* @__PURE__ */ jsxRuntime.jsx(
115
+ ui.Switch,
116
+ {
117
+ id,
118
+ "data-testid": testId,
119
+ checked: Boolean(value),
120
+ onCheckedChange: (checked) => onChange(checked)
121
+ }
122
+ );
123
+ case "select": {
124
+ const options = field.options ?? [];
125
+ if (options.length > 0 && options.length <= TILE_MAX) {
126
+ const compact = options.every((o) => !o.icon && !o.description);
127
+ return /* @__PURE__ */ jsxRuntime.jsx(
128
+ "div",
129
+ {
130
+ role: "radiogroup",
131
+ "aria-label": field.label,
132
+ className: "flex flex-wrap gap-2",
133
+ "data-testid": testId,
134
+ children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
135
+ ChoiceTile,
136
+ {
137
+ option,
138
+ selected: value === option.value,
139
+ compact,
140
+ renderIcon,
141
+ testId: chunkMHVNT4J3_cjs.prefixedTestId(testId, option.value, {
142
+ testId: `workflow-field-${field.name}-${option.value}`
143
+ }),
144
+ onSelect: () => onChange(option.value)
145
+ },
146
+ option.value
147
+ ))
148
+ }
149
+ );
150
+ }
151
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Select, { value: String(value ?? ""), onValueChange: (v) => onChange(v), children: [
152
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SelectTrigger, { id, "data-testid": testId, className: "pointer-coarse:min-h-11", children: /* @__PURE__ */ jsxRuntime.jsx(ui.SelectValue, { placeholder: field.placeholder }) }),
153
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SelectContent, { children: options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: o.value, children: o.label }, o.value)) })
154
+ ] });
155
+ }
156
+ case "scope": {
157
+ const scope = chunk76L6LOP3_cjs.isWorkflowScope(value) ? value : { folders: [], labels: [] };
158
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": testId, children: renderScope?.(field, scope, onChange) });
159
+ }
160
+ case "documents": {
161
+ const picked = chunk76L6LOP3_cjs.isWorkflowScope(value) ? value : { folders: [], labels: [], documents: [] };
162
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": testId, children: renderDocuments?.(field, picked, onChange) });
163
+ }
164
+ case "person":
165
+ return people?.length ? /* @__PURE__ */ jsxRuntime.jsxs(
166
+ "select",
167
+ {
168
+ id,
169
+ "data-testid": testId,
170
+ value: String(value ?? ""),
171
+ "aria-required": field.required || void 0,
172
+ "aria-invalid": error ? true : void 0,
173
+ onChange: (e) => onChange(e.target.value),
174
+ className: "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm",
175
+ children: [
176
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: field.placeholder ?? "" }),
177
+ people.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.value, children: p.label }, p.value))
178
+ ]
179
+ }
180
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
181
+ ui.Input,
182
+ {
183
+ id,
184
+ "data-testid": testId,
185
+ value: String(value ?? ""),
186
+ placeholder: field.placeholder ?? "usr-\u2026",
187
+ "aria-required": field.required || void 0,
188
+ "aria-invalid": error ? true : void 0,
189
+ onChange: (e) => onChange(e.target.value)
190
+ }
191
+ );
192
+ }
193
+ }
194
+ function ChoiceTile({
195
+ option,
196
+ selected,
197
+ compact,
198
+ renderIcon,
199
+ testId,
200
+ onSelect
201
+ }) {
202
+ const tone = option.tone;
203
+ return /* @__PURE__ */ jsxRuntime.jsxs(
204
+ "button",
205
+ {
206
+ type: "button",
207
+ role: "radio",
208
+ "aria-checked": selected,
209
+ "data-testid": testId,
210
+ "data-tone": tone,
211
+ onClick: onSelect,
212
+ className: ui.cn(
213
+ // Sized to its label (flex-basis auto), growing to share the row, never wider than it.
214
+ "flex max-w-full min-w-[min(4rem,100%)] flex-auto flex-col items-center justify-center gap-1.5 rounded-lg border text-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
215
+ compact ? "min-h-9 px-3 py-1.5 pointer-coarse:min-h-11" : "min-h-24 p-3 pointer-coarse:min-h-28",
216
+ tone ? selected ? ui.cn(chunk32HW2Q33_cjs.TONE_SURFACE[tone], chunk32HW2Q33_cjs.TONE_SOLID_BORDER[tone]) : ui.cn(chunk32HW2Q33_cjs.TONE_BORDER[tone], "bg-card [&:hover]:bg-muted") : selected ? "border-primary bg-primary/10" : "border-border bg-card [&:hover]:border-primary [&:hover]:bg-muted"
217
+ ),
218
+ children: [
219
+ option.icon && renderIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: renderIcon(option.icon) }),
220
+ /* @__PURE__ */ jsxRuntime.jsxs(
221
+ "span",
222
+ {
223
+ className: ui.cn(
224
+ "flex max-w-full items-center gap-1.5 text-sm font-medium",
225
+ tone && selected ? void 0 : "text-foreground"
226
+ ),
227
+ children: [
228
+ selected ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-3.5 shrink-0", "aria-hidden": true }) : tone && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: ui.cn("size-2 shrink-0 rounded-full", chunk32HW2Q33_cjs.TONE_DOT[tone]) }),
229
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 break-words", children: option.label })
230
+ ]
231
+ }
232
+ ),
233
+ option.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-full text-xs break-words text-muted-foreground", children: option.description })
234
+ ]
235
+ }
236
+ );
237
+ }
238
+ function FormField(props) {
239
+ const { field, error, l, idFor } = props;
240
+ const isBoolean = field.type === "boolean";
241
+ const showOptional = !field.required && field.type !== "boolean" && field.type !== "scope";
242
+ const label = /* @__PURE__ */ jsxRuntime.jsxs(
243
+ ui.Label,
244
+ {
245
+ htmlFor: `${idFor()}-control`,
246
+ className: isBoolean ? "cursor-pointer font-normal" : void 0,
247
+ children: [
248
+ field.label,
249
+ showOptional && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
250
+ " ",
251
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-normal text-muted-foreground", children: l.optional })
252
+ ] })
253
+ ]
254
+ }
255
+ );
256
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", "data-slot": "schema-field", "data-field": field.name, children: [
257
+ isBoolean ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 pointer-coarse:min-h-11", children: [
258
+ /* @__PURE__ */ jsxRuntime.jsx(FieldControl, { ...props }),
259
+ label
260
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
261
+ field.type !== "scope" && label,
262
+ /* @__PURE__ */ jsxRuntime.jsx(FieldControl, { ...props })
263
+ ] }),
264
+ field.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: field.description }),
265
+ error && /* @__PURE__ */ jsxRuntime.jsx(
266
+ "p",
267
+ {
268
+ id: idFor("error"),
269
+ role: "alert",
270
+ className: "text-xs text-destructive",
271
+ "data-testid": idFor("error"),
272
+ children: l.errors[error]
273
+ }
274
+ )
275
+ ] });
276
+ }
277
+ function SchemaForm({
278
+ fields,
279
+ values,
280
+ onChange,
281
+ errors,
282
+ renderScope,
283
+ renderDocuments,
284
+ renderIcon,
285
+ onEnterSubmit,
286
+ people,
287
+ testIdPrefix,
288
+ labels,
289
+ className
290
+ }) {
291
+ const l = {
292
+ ...DEFAULT_SCHEMA_FORM_LABELS,
293
+ ...labels,
294
+ errors: { ...DEFAULT_SCHEMA_FORM_LABELS.errors, ...labels?.errors }
295
+ };
296
+ const [advancedOpen, setAdvancedOpen] = react.useState(false);
297
+ const common = fields.filter((f) => !f.advanced);
298
+ const advanced = fields.filter((f) => f.advanced);
299
+ const render = (field) => /* @__PURE__ */ jsxRuntime.jsx(
300
+ FormField,
301
+ {
302
+ field,
303
+ value: values[field.name],
304
+ error: errors?.[field.name],
305
+ onChange: (v) => onChange(field.name, v),
306
+ l,
307
+ idFor: (suffix) => suffix ? `${chunkMHVNT4J3_cjs.testIdOr(testIdPrefix, { testId: "workflow-field" })}-${field.name}-${suffix}` : `${chunkMHVNT4J3_cjs.testIdOr(testIdPrefix, { testId: "workflow-field" })}-${field.name}`,
308
+ renderScope,
309
+ renderDocuments,
310
+ renderIcon,
311
+ onEnterSubmit,
312
+ people
313
+ },
314
+ field.name
315
+ );
316
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("flex flex-col gap-4", className), "data-slot": "schema-form", children: [
317
+ common.map(render),
318
+ advanced.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
319
+ chunkEYKISBDO_cjs.FoldSection,
320
+ {
321
+ label: l.advanced,
322
+ open: advancedOpen,
323
+ onOpenChange: setAdvancedOpen,
324
+ testId: `${chunkMHVNT4J3_cjs.testIdOr(testIdPrefix, { testId: "workflow-field" })}-advanced-toggle`,
325
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4", children: advanced.map(render) })
326
+ }
327
+ )
328
+ ] });
329
+ }
330
+ var DEFAULT_AGENT_SELECT_LABELS = {
331
+ label: "Run as",
332
+ myAssistant: "My assistant"
333
+ };
334
+ var ME = "__me__";
335
+ function AgentSelect({
336
+ agents,
337
+ value,
338
+ defaultValue = "",
339
+ onValueChange,
340
+ hideLabel,
341
+ disabled,
342
+ className,
343
+ labels,
344
+ testId,
345
+ optionTestId
346
+ }) {
347
+ const l = { ...DEFAULT_AGENT_SELECT_LABELS, ...labels };
348
+ const triggerId = react.useId();
349
+ const [current, setCurrent] = chunkAHDJXIUB_cjs.useControllableState(value, defaultValue, onValueChange);
350
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("flex flex-col gap-1.5", className), "data-slot": "agent-select", children: [
351
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: triggerId, className: hideLabel ? "sr-only" : void 0, children: l.label }),
352
+ /* @__PURE__ */ jsxRuntime.jsxs(
353
+ ui.Select,
354
+ {
355
+ value: current === "" ? ME : current,
356
+ onValueChange: (v) => setCurrent(v === ME ? "" : v),
357
+ disabled,
358
+ children: [
359
+ /* @__PURE__ */ jsxRuntime.jsx(
360
+ ui.SelectTrigger,
361
+ {
362
+ id: triggerId,
363
+ "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "agent-select" }),
364
+ className: "pointer-coarse:min-h-11",
365
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.SelectValue, {})
366
+ }
367
+ ),
368
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.SelectContent, { children: [
369
+ /* @__PURE__ */ jsxRuntime.jsx(
370
+ ui.SelectItem,
371
+ {
372
+ value: ME,
373
+ "data-testid": chunkMHVNT4J3_cjs.prefixedTestId(optionTestId, "me", {
374
+ testId: "agent-select-option-me"
375
+ }),
376
+ children: l.myAssistant
377
+ }
378
+ ),
379
+ agents.map((agent) => /* @__PURE__ */ jsxRuntime.jsx(
380
+ ui.SelectItem,
381
+ {
382
+ value: agent.id,
383
+ "data-testid": chunkMHVNT4J3_cjs.prefixedTestId(optionTestId, agent.id, {
384
+ testId: `agent-select-option-${agent.id}`
385
+ }),
386
+ children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2", children: [
387
+ agent.avatar,
388
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: agent.label }),
389
+ agent.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: agent.description })
390
+ ] })
391
+ },
392
+ agent.id
393
+ ))
394
+ ] })
395
+ ]
396
+ }
397
+ )
398
+ ] });
399
+ }
400
+ var DEFAULT_WORKFLOW_CONFIG_DIALOG_LABELS = {
401
+ start: "Start",
402
+ starting: "Starting\u2026",
403
+ addFilesReason: "This reads your files, and there is nothing to read yet.",
404
+ agentLabel: "Run as"
405
+ };
406
+ function WorkflowConfigDialog({
407
+ workflow,
408
+ open,
409
+ onOpenChange,
410
+ onLaunch,
411
+ initialInputs,
412
+ inputs: inputsProp,
413
+ onInputsChange,
414
+ scopeSource,
415
+ renderScope,
416
+ renderDocuments,
417
+ renderIcon,
418
+ addFilesAction,
419
+ agents,
420
+ agentId: agentIdProp,
421
+ onAgentChange,
422
+ isLaunching,
423
+ submitLabel,
424
+ fieldPlaceholder,
425
+ renderNotice,
426
+ labels,
427
+ formLabels,
428
+ agentLabels,
429
+ testId,
430
+ startTestId,
431
+ className
432
+ }) {
433
+ const l = { ...DEFAULT_WORKFLOW_CONFIG_DIALOG_LABELS, ...labels };
434
+ const initialKey = JSON.stringify(initialInputs ?? {});
435
+ const seedKey = JSON.stringify({ ...chunk76L6LOP3_cjs.defaultInputs(workflow), ...JSON.parse(initialKey) });
436
+ const seed = react.useMemo(() => JSON.parse(seedKey), [seedKey]);
437
+ const [inputs, setInputs] = chunkAHDJXIUB_cjs.useControllableState(inputsProp, seed, onInputsChange);
438
+ const [agentId, setAgentId] = chunkAHDJXIUB_cjs.useControllableState(
439
+ agentIdProp,
440
+ workflow.defaultAgentId ?? "",
441
+ onAgentChange
442
+ );
443
+ react.useEffect(() => {
444
+ if (open && inputsProp === void 0) setInputs(seed);
445
+ }, [open, seed]);
446
+ const setField = (name, value) => setInputs({ ...inputs, [name]: value });
447
+ const errors = chunk76L6LOP3_cjs.validateInputs(workflow, inputs);
448
+ const valid = Object.keys(errors).length === 0;
449
+ const visibleErrors = Object.fromEntries(
450
+ Object.entries(errors).filter(([, e]) => e !== "required")
451
+ );
452
+ const scopeField = workflow.inputs.find((f) => f.type === "scope");
453
+ const rawScope = scopeField ? inputs[scopeField.name] : void 0;
454
+ const scopeValue = rawScope && typeof rawScope === "object" ? rawScope : { folders: [], labels: [] };
455
+ const matchedCount = scopeSource && scopeField ? scopeSource.countMatching(scopeValue) : null;
456
+ const noFiles = Boolean(workflow.requiresFiles && scopeSource && scopeSource.totalCount === 0);
457
+ const blockedByScope = matchedCount !== null && matchedCount === 0 && Boolean(workflow.requiresFiles);
458
+ const showAgent = workflow.run.kind === "prompt" && workflow.options?.agent !== false && agents !== void 0 && agents.length > 0;
459
+ const launch = (values) => {
460
+ Promise.resolve(onLaunch(chunk76L6LOP3_cjs.buildLaunch(workflow, values, agentId))).catch(() => {
461
+ });
462
+ };
463
+ const submit = () => {
464
+ if (!valid || noFiles || blockedByScope || isLaunching) return;
465
+ launch(inputs);
466
+ };
467
+ const fields = react.useMemo(
468
+ () => workflow.inputs.map((f) => {
469
+ const placeholder = fieldPlaceholder?.(f, inputs, workflow);
470
+ return placeholder === void 0 ? f : { ...f, placeholder };
471
+ }),
472
+ [workflow, fieldPlaceholder, inputs]
473
+ );
474
+ const id = chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "workflow-dialog" });
475
+ const formRef = react.useRef(null);
476
+ const firstField = workflow.inputs.find((f) => !f.advanced);
477
+ const focusPromptFirst = firstField?.type === "text" || firstField?.type === "longtext";
478
+ const defaultScopeRender = scopeSource ? (_field, value, onChange) => /* @__PURE__ */ jsxRuntime.jsx(
479
+ chunkEYKISBDO_cjs.ScopePicker,
480
+ {
481
+ folders: scopeSource.folders,
482
+ unfiledCount: scopeSource.unfiledCount,
483
+ labels: scopeSource.labels,
484
+ totalCount: scopeSource.totalCount,
485
+ matchedCount: scopeSource.countMatching(value),
486
+ scope: value,
487
+ onScopeChange: onChange
488
+ }
489
+ ) : void 0;
490
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
491
+ ui.DialogContent,
492
+ {
493
+ presentation: "sheet",
494
+ className: `max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-xl ${className ?? ""}`,
495
+ "data-testid": id,
496
+ "data-workflow": workflow.id,
497
+ onOpenAutoFocus: (event) => {
498
+ if (!focusPromptFirst || !firstField) return;
499
+ const control = formRef.current?.querySelector(
500
+ `[data-testid="${id}-field-${firstField.name}"]`
501
+ );
502
+ if (!control) return;
503
+ event.preventDefault();
504
+ control.focus();
505
+ if (control instanceof HTMLInputElement || control instanceof HTMLTextAreaElement) {
506
+ const end = control.value.length;
507
+ control.setSelectionRange(end, end);
508
+ }
509
+ },
510
+ children: [
511
+ /* @__PURE__ */ jsxRuntime.jsx(
512
+ chunkEYKISBDO_cjs.QuickActionDialogHeader,
513
+ {
514
+ icon: workflow.icon && renderIcon ? renderIcon(workflow.icon) : null,
515
+ title: workflow.title,
516
+ description: workflow.details ?? workflow.description,
517
+ descriptionTestId: `${id}-description`
518
+ }
519
+ ),
520
+ /* @__PURE__ */ jsxRuntime.jsx(
521
+ "form",
522
+ {
523
+ ref: formRef,
524
+ className: "mt-2 flex flex-col gap-4",
525
+ onSubmit: (event) => {
526
+ event.preventDefault();
527
+ submit();
528
+ },
529
+ children: noFiles ? /* @__PURE__ */ jsxRuntime.jsx(
530
+ chunkEYKISBDO_cjs.AddFilesFirst,
531
+ {
532
+ reason: l.addFilesReason,
533
+ action: addFilesAction,
534
+ testId: `${id}-empty-state`
535
+ }
536
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
537
+ /* @__PURE__ */ jsxRuntime.jsx(
538
+ SchemaForm,
539
+ {
540
+ fields,
541
+ values: inputs,
542
+ onChange: setField,
543
+ errors: visibleErrors,
544
+ renderScope: renderScope ?? defaultScopeRender,
545
+ renderDocuments,
546
+ renderIcon,
547
+ labels: formLabels,
548
+ onEnterSubmit: submit,
549
+ testIdPrefix: `${id}-field`
550
+ }
551
+ ),
552
+ renderNotice?.({ workflow, inputs }),
553
+ /* @__PURE__ */ jsxRuntime.jsxs(
554
+ "div",
555
+ {
556
+ className: "flex flex-col gap-3 border-t border-border pt-3 sm:flex-row sm:items-end sm:justify-between",
557
+ "data-slot": "workflow-footer",
558
+ children: [
559
+ showAgent ? /* @__PURE__ */ jsxRuntime.jsx(
560
+ AgentSelect,
561
+ {
562
+ agents: agents ?? [],
563
+ value: agentId,
564
+ onValueChange: setAgentId,
565
+ labels: { label: l.agentLabel, ...agentLabels },
566
+ testId: `${id}-agent`,
567
+ className: "sm:w-56"
568
+ }
569
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
570
+ /* @__PURE__ */ jsxRuntime.jsxs(
571
+ ui.Button,
572
+ {
573
+ type: "submit",
574
+ className: "gap-1.5 px-5 pointer-coarse:min-h-11",
575
+ disabled: !valid || blockedByScope || isLaunching,
576
+ "data-testid": chunkMHVNT4J3_cjs.testIdOr(startTestId, { testId: "workflow-start-button" }),
577
+ children: [
578
+ isLaunching ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "size-4" }),
579
+ isLaunching ? l.starting : submitLabel?.({ workflow, inputs, matchedCount }) ?? workflow.startLabel ?? l.start
580
+ ]
581
+ }
582
+ )
583
+ ]
584
+ }
585
+ )
586
+ ] })
587
+ }
588
+ )
589
+ ]
590
+ }
591
+ ) });
592
+ }
593
+ function WorkflowLauncher({
594
+ workflows,
595
+ tileWorkflows,
596
+ onLaunch,
597
+ showTiles = true,
598
+ caption,
599
+ captionTestId,
600
+ tileTestId,
601
+ disabledReason,
602
+ activeId: activeIdProp,
603
+ onActiveIdChange,
604
+ initialInputsFor,
605
+ testId,
606
+ extraTiles = [],
607
+ className,
608
+ children,
609
+ renderIcon,
610
+ ...dialog
611
+ }) {
612
+ const [activeId, setActiveId] = chunkAHDJXIUB_cjs.useControllableState(
613
+ activeIdProp,
614
+ null,
615
+ onActiveIdChange
616
+ );
617
+ const [isLaunching, setIsLaunching] = react.useState(false);
618
+ const active = workflows.find((w) => w.id === activeId) ?? null;
619
+ const run = async (launch) => {
620
+ setIsLaunching(true);
621
+ try {
622
+ await onLaunch(launch);
623
+ setActiveId(null);
624
+ } finally {
625
+ setIsLaunching(false);
626
+ }
627
+ };
628
+ const select = (workflow) => {
629
+ if (workflow.run.kind === "operation" && workflow.inputs.length === 0) {
630
+ const inputs = chunk76L6LOP3_cjs.defaultInputs(workflow);
631
+ if (Object.keys(chunk76L6LOP3_cjs.validateInputs(workflow, inputs)).length === 0) {
632
+ Promise.resolve(onLaunch(chunk76L6LOP3_cjs.buildLaunch(workflow, inputs, void 0))).catch(() => {
633
+ });
634
+ return;
635
+ }
636
+ }
637
+ setActiveId(workflow.id);
638
+ };
639
+ const tiles = (tileWorkflows ?? workflows).map((workflow) => {
640
+ const reason = disabledReason?.(workflow);
641
+ return {
642
+ id: workflow.id,
643
+ iconNode: workflow.icon && renderIcon ? renderIcon(workflow.icon) : void 0,
644
+ title: workflow.title,
645
+ description: workflow.description,
646
+ onSelect: () => select(workflow),
647
+ disabled: reason !== void 0,
648
+ disabledReason: reason,
649
+ testId: tileTestId?.(workflow) ?? `workflow-tile-${workflow.id}`
650
+ };
651
+ });
652
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-slot": "workflow-launcher", children: [
653
+ showTiles && /* @__PURE__ */ jsxRuntime.jsx(
654
+ chunkEYKISBDO_cjs.StartTiles,
655
+ {
656
+ items: [...tiles, ...extraTiles],
657
+ caption,
658
+ captionTestId,
659
+ testId
660
+ }
661
+ ),
662
+ children,
663
+ active && /* @__PURE__ */ jsxRuntime.jsx(
664
+ WorkflowConfigDialog,
665
+ {
666
+ ...dialog,
667
+ renderIcon,
668
+ workflow: active,
669
+ open: true,
670
+ onOpenChange: (open) => !open && setActiveId(null),
671
+ onLaunch: run,
672
+ isLaunching,
673
+ initialInputs: initialInputsFor?.(active)
674
+ }
675
+ )
676
+ ] });
677
+ }
678
+ function documentScopeLabels(tags) {
679
+ return tags.filter((tag) => {
680
+ if (tag.kind === "search") return false;
681
+ const onDocs = (tag.doctag_count ?? 0) > 0;
682
+ const onFacts = (tag.facttag_count ?? 0) > 0;
683
+ return onDocs || !onFacts;
684
+ });
685
+ }
686
+ var canonical = (path) => (path ?? "").split("/").map((part) => part.trim()).filter(Boolean).join("/");
687
+ function matchWorkflowScope(docs, scope) {
688
+ if (scope.documents?.length) {
689
+ const ids = new Set(scope.documents);
690
+ return docs.filter((doc) => ids.has(doc.external_id));
691
+ }
692
+ if (!scope.folders.length && !scope.labels.length) return docs;
693
+ const folders = scope.folders.map(canonical);
694
+ const labels = new Set(scope.labels);
695
+ return docs.filter((doc) => {
696
+ const folder = canonical(doc.folder);
697
+ return folders.some(
698
+ (path) => path === "" ? folder === "" : folder === path || folder.startsWith(`${path}/`)
699
+ ) || doc.doctags?.some((tag) => labels.has(tag.tag_ext_id));
700
+ });
701
+ }
702
+ function buildWorkflowScopeSource(docs, labels = []) {
703
+ const counts = /* @__PURE__ */ new Map();
704
+ for (const doc of docs) {
705
+ const parts = canonical(doc.folder).split("/").filter(Boolean);
706
+ for (let i = 1; i <= parts.length; i++) {
707
+ const path = parts.slice(0, i).join("/");
708
+ counts.set(path, (counts.get(path) ?? 0) + 1);
709
+ }
710
+ }
711
+ return {
712
+ folders: [...counts].sort(([a], [b]) => a.localeCompare(b)).map(([path, count]) => ({
713
+ path,
714
+ count,
715
+ label: path.split("/").at(-1),
716
+ depth: path.split("/").length - 1
717
+ })),
718
+ unfiledCount: docs.filter((doc) => !canonical(doc.folder)).length,
719
+ labels: labels.map((label) => ({
720
+ id: label.external_id,
721
+ name: label.name,
722
+ color: label.color ?? ui.getEntityColor(label.external_id, "medium"),
723
+ count: docs.filter((doc) => doc.doctags?.some((tag) => tag.tag_ext_id === label.external_id)).length
724
+ })),
725
+ totalCount: docs.length,
726
+ countMatching: (scope) => matchWorkflowScope(docs, scope).length,
727
+ resolveDocuments: (scope) => matchWorkflowScope(docs, scope).map((doc) => doc.external_id)
728
+ };
729
+ }
730
+ var DEFAULT_WORKFLOW_DOCUMENTS_FIELD_LABELS = {
731
+ pickOne: "Pick a file",
732
+ pickMany: "Pick files",
733
+ allDocuments: "All documents",
734
+ addFiles: "Add files",
735
+ adding: "Adding\u2026",
736
+ empty: "No files in this workspace yet. Drop one here, or add it.",
737
+ remove: (name) => `Remove ${name}`,
738
+ pending: (name, status) => `${name}: ${status}. You can still pick it.`,
739
+ status: {
740
+ queued: "Queued",
741
+ uploading: "Uploading",
742
+ encrypting: "Encrypting",
743
+ processing: "Processing",
744
+ parsing: "Processing",
745
+ indexing: "Indexing",
746
+ analysing: "Analysing"
747
+ }
748
+ };
749
+ var isReady = (status) => !status || ["completed", "done", "ready", "success"].includes(status.toLowerCase());
750
+ var byTitle = (a, b) => a.title.toLowerCase().localeCompare(b.title.toLowerCase());
751
+ function WorkflowDocumentsField({
752
+ field,
753
+ value,
754
+ onChange,
755
+ documents,
756
+ loaded = true,
757
+ thumbnailOf,
758
+ onAddFiles,
759
+ adding,
760
+ labels
761
+ }) {
762
+ const l = { ...DEFAULT_WORKFLOW_DOCUMENTS_FIELD_LABELS, ...labels };
763
+ const ids = value.documents ?? [];
764
+ const max = field.max ?? 1;
765
+ const multiple = max > 1;
766
+ const [isOver, setIsOver] = react.useState(false);
767
+ const docOf = (id) => documents.find((d) => d.id === id);
768
+ const nameOf = (id) => docOf(id)?.title || id;
769
+ const set = (next) => onChange({ ...value, documents: next });
770
+ const toggle = (id) => set(ids.includes(id) ? ids.filter((d) => d !== id) : [...ids, id].slice(-max));
771
+ const offered = react.useMemo(
772
+ () => field.accept === "image" ? documents.filter((d) => d.isImage) : documents,
773
+ [documents, field.accept]
774
+ );
775
+ const awaitingAdd = react.useRef(false);
776
+ const known = react.useRef(null);
777
+ const latest = react.useRef({ ids, set });
778
+ latest.current = { ids, set };
779
+ react.useEffect(() => {
780
+ if (!loaded) return;
781
+ const current = new Set(documents.map((d) => d.id));
782
+ const before = known.current;
783
+ known.current = current;
784
+ if (!before || !awaitingAdd.current) return;
785
+ const fresh = [...current].filter((id) => !before.has(id));
786
+ if (fresh.length === 0) return;
787
+ awaitingAdd.current = false;
788
+ latest.current.set([...latest.current.ids, ...fresh].slice(-max));
789
+ }, [documents, loaded, max]);
790
+ const addFiles = (files) => {
791
+ if (!onAddFiles) return;
792
+ awaitingAdd.current = true;
793
+ onAddFiles(files?.length ? files : void 0);
794
+ };
795
+ const dropProps = onAddFiles ? {
796
+ onDragOver: (e) => {
797
+ e.preventDefault();
798
+ setIsOver(true);
799
+ },
800
+ onDragLeave: () => setIsOver(false),
801
+ onDrop: (e) => {
802
+ e.preventDefault();
803
+ setIsOver(false);
804
+ const files = Array.from(e.dataTransfer?.files ?? []);
805
+ if (files.length) addFiles(files);
806
+ }
807
+ } : {};
808
+ const dropClass = isOver ? "ring-2 ring-primary" : "";
809
+ const addButton = (className, variant = "outline") => onAddFiles && /* @__PURE__ */ jsxRuntime.jsx(
810
+ ui.Button,
811
+ {
812
+ type: "button",
813
+ size: "sm",
814
+ variant,
815
+ className,
816
+ disabled: adding,
817
+ onClick: () => addFiles(),
818
+ "data-testid": "workflow-add-files",
819
+ children: adding ? l.adding : l.addFiles
820
+ }
821
+ );
822
+ if (loaded && documents.length === 0) {
823
+ return /* @__PURE__ */ jsxRuntime.jsxs(
824
+ "div",
825
+ {
826
+ className: ui.cn(
827
+ "flex flex-col items-center gap-2 rounded-lg border border-dashed border-border bg-muted/40 px-4 py-6 text-center",
828
+ dropClass
829
+ ),
830
+ "data-testid": "workflow-documents-empty",
831
+ ...dropProps,
832
+ children: [
833
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderPlus, { className: "size-5 text-muted-foreground", "aria-hidden": true }),
834
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: l.empty }),
835
+ addButton(void 0, "default")
836
+ ]
837
+ }
838
+ );
839
+ }
840
+ const pending = ids.flatMap((id) => {
841
+ const status = docOf(id)?.status;
842
+ return isReady(status) ? [] : [{ id, label: l.status[String(status).toLowerCase()] ?? String(status) }];
843
+ });
844
+ const selected = multiple ? void 0 : docOf(ids[0] ?? "");
845
+ return /* @__PURE__ */ jsxRuntime.jsxs(
846
+ "div",
847
+ {
848
+ className: ui.cn("flex flex-col gap-3 rounded-lg", dropClass),
849
+ "data-testid": `workflow-documents-${field.name}`,
850
+ ...dropProps,
851
+ children: [
852
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
853
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
854
+ chunkRQ2Y7USX_cjs.DocumentPicker,
855
+ {
856
+ groups: [{ id: "all", heading: l.allDocuments, docs: [...offered].sort(byTitle) }],
857
+ value: multiple ? "" : ids[0] ?? "",
858
+ onValueChange: (id) => multiple ? toggle(id) : set([id]),
859
+ selected,
860
+ selectedIds: multiple ? ids : void 0,
861
+ labels: { placeholder: field.placeholder ?? (multiple ? l.pickMany : l.pickOne) }
862
+ }
863
+ ) }),
864
+ addButton("shrink-0 pointer-coarse:h-11")
865
+ ] }),
866
+ pending.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
867
+ "p",
868
+ {
869
+ className: "text-xs text-muted-foreground",
870
+ "data-testid": `workflow-document-status-${p.id}`,
871
+ children: l.pending(nameOf(p.id), p.label)
872
+ },
873
+ p.id
874
+ )),
875
+ multiple && ids.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
876
+ "div",
877
+ {
878
+ className: "grid grid-cols-2 gap-3 sm:grid-cols-3",
879
+ "data-testid": "workflow-documents-gallery",
880
+ children: ids.map((id) => {
881
+ const thumbnail = thumbnailOf?.(id);
882
+ return /* @__PURE__ */ jsxRuntime.jsxs(
883
+ "figure",
884
+ {
885
+ className: "relative overflow-hidden rounded-lg border border-border bg-muted/40",
886
+ "data-testid": `workflow-document-${id}`,
887
+ children: [
888
+ thumbnail ? /* @__PURE__ */ jsxRuntime.jsx(
889
+ "img",
890
+ {
891
+ src: thumbnail,
892
+ alt: nameOf(id),
893
+ className: "aspect-square w-full object-cover"
894
+ }
895
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex aspect-square w-full items-center justify-center text-muted-foreground/50", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ImageIcon, { className: "size-8" }) }),
896
+ /* @__PURE__ */ jsxRuntime.jsx("figcaption", { className: "truncate bg-background/90 px-2 py-1 text-xs text-muted-foreground", children: nameOf(id) }),
897
+ /* @__PURE__ */ jsxRuntime.jsx(
898
+ "button",
899
+ {
900
+ type: "button",
901
+ onClick: () => toggle(id),
902
+ "aria-label": l.remove(nameOf(id)),
903
+ className: "absolute right-1 top-1 flex size-6 items-center justify-center rounded-full bg-background/80 text-muted-foreground hover:text-foreground pointer-coarse:size-11",
904
+ "data-testid": `workflow-document-remove-${id}`,
905
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5" })
906
+ }
907
+ )
908
+ ]
909
+ },
910
+ id
911
+ );
912
+ })
913
+ }
914
+ )
915
+ ]
916
+ }
917
+ );
918
+ }
919
+ function PersonPill({ person, size = "sm", testId }) {
920
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": testId, className: "inline-flex min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
921
+ ui.UserEntity,
922
+ {
923
+ variant: "pill",
924
+ size,
925
+ interactive: false,
926
+ showTooltip: false,
927
+ initials: chunkKDG6FER6_cjs.initials(person.label),
928
+ displayName: person.label,
929
+ avatarStyle: person.id ? ui.getEntityColorStyles(person.id) : void 0,
930
+ isAgent: person.isAgent,
931
+ isMe: person.isMe
932
+ }
933
+ ) });
934
+ }
935
+ var DEFAULT_TASK_TRIGGER_CHIP_LABELS = {
936
+ after: (name) => `After \u201C${name}\u201D is done`,
937
+ afterUnknown: "After another task is done",
938
+ onDemand: "Manual"
939
+ };
940
+ function TriggerIcon({ type, chained }) {
941
+ const cls = "size-3.5 shrink-0 text-muted-foreground";
942
+ if (chained) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { className: cls, "aria-hidden": true });
943
+ switch (type) {
944
+ case "on_demand":
945
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MousePointerClick, { className: cls, "aria-hidden": true });
946
+ case "recurring":
947
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: cls, "aria-hidden": true });
948
+ case "event":
949
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bell, { className: cls, "aria-hidden": true });
950
+ default:
951
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: cls, "aria-hidden": true });
952
+ }
953
+ }
954
+ function TaskTriggerChip({
955
+ id,
956
+ triggerType,
957
+ summary,
958
+ afterTaskId,
959
+ afterTaskName,
960
+ testId,
961
+ labels
962
+ }) {
963
+ const l = { ...DEFAULT_TASK_TRIGGER_CHIP_LABELS, ...labels };
964
+ const chained = Boolean(afterTaskId);
965
+ const text = chained ? afterTaskName ? l.after(afterTaskName) : l.afterUnknown : triggerType === "on_demand" ? l.onDemand : summary;
966
+ return /* @__PURE__ */ jsxRuntime.jsxs(
967
+ "span",
968
+ {
969
+ className: "inline-flex min-w-0 max-w-full items-center gap-1.5 text-sm font-normal text-foreground",
970
+ "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: `task-trigger-${id}` }),
971
+ "data-trigger": chained ? "task" : triggerType,
972
+ children: [
973
+ /* @__PURE__ */ jsxRuntime.jsx(TriggerIcon, { type: triggerType, chained }),
974
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: text })
975
+ ]
976
+ }
977
+ );
978
+ }
979
+
980
+ // src/agents/tasks/workflowRows.ts
981
+ var isSkillRow = (row) => row.kind === "skill";
982
+ var hasTrigger = (row) => !row.on_demand && Boolean(row.rrule || row.run_at || row.event_kind || row.after_conversation_ext_id);
983
+ function workflowStatus(row) {
984
+ if (isSkillRow(row) || !hasTrigger(row)) return "on_demand";
985
+ return row.active ? "active" : "paused";
986
+ }
987
+ function workflowTriggerType(workflow) {
988
+ if (workflow.on_demand) return "on_demand";
989
+ if (workflow.after_conversation_ext_id) return "after";
990
+ if (workflow.event_kind) return "event";
991
+ if (workflow.rrule) return "recurring";
992
+ if (workflow.run_at) return "one_time";
993
+ return "on_demand";
994
+ }
995
+ function workflowRunStatusLabel(status) {
996
+ if (!status) return "None";
997
+ const labels = {
998
+ completed: "Success",
999
+ success: "Success",
1000
+ failed: "Failed",
1001
+ running: "In progress",
1002
+ awaiting_authorization: "Awaiting access"
1003
+ };
1004
+ return labels[status] ?? status.replaceAll("_", " ");
1005
+ }
1006
+ function listedRunStatus(status, threadStatus) {
1007
+ if (threadStatus === "done" && status === "running") return "completed";
1008
+ return status;
1009
+ }
1010
+
1011
+ // src/agents/tasks/workflowColumns.tsx
1012
+ var WORKFLOW_COLUMN_ORDER = [
1013
+ "name",
1014
+ "trigger",
1015
+ "last_run",
1016
+ "result",
1017
+ "status",
1018
+ "shared",
1019
+ "actions"
1020
+ ];
1021
+ function cell(render) {
1022
+ return (params) => params.data ? render(params.data) : null;
1023
+ }
1024
+ var time = (iso) => iso ? Date.parse(iso) : Number.POSITIVE_INFINITY;
1025
+ function createWorkflowColumns(o) {
1026
+ const l = o.labels;
1027
+ const base = {
1028
+ sortable: false,
1029
+ cellStyle: { display: "flex", alignItems: "center" }
1030
+ };
1031
+ return [
1032
+ {
1033
+ ...base,
1034
+ colId: "name",
1035
+ sortable: true,
1036
+ headerName: l.colName,
1037
+ flex: 3,
1038
+ minWidth: 210,
1039
+ valueGetter: (p) => p.data?.name.toLowerCase() ?? "",
1040
+ cellRenderer: cell(o.renderName)
1041
+ },
1042
+ {
1043
+ ...base,
1044
+ colId: "trigger",
1045
+ headerName: l.colTrigger,
1046
+ flex: 2.4,
1047
+ minWidth: 185,
1048
+ valueGetter: (p) => p.data ? o.getTriggerText(p.data) : "",
1049
+ cellRenderer: cell(o.renderTrigger)
1050
+ },
1051
+ {
1052
+ ...base,
1053
+ colId: "last_run",
1054
+ sortable: true,
1055
+ headerName: l.colLastRun,
1056
+ flex: 1.4,
1057
+ minWidth: 140,
1058
+ cellStyle: { display: "flex", alignItems: "center", padding: 0 },
1059
+ valueGetter: (p) => time(p.data?.last_fired_at),
1060
+ cellRenderer: cell(o.renderLastRun)
1061
+ },
1062
+ {
1063
+ ...base,
1064
+ colId: "result",
1065
+ headerName: "Result",
1066
+ width: 130,
1067
+ valueGetter: (p) => p.data?.last_run_status ?? "",
1068
+ cellStyle: { display: "flex", alignItems: "center", padding: 0 },
1069
+ cellRenderer: cell(o.renderResult)
1070
+ },
1071
+ {
1072
+ ...base,
1073
+ colId: "status",
1074
+ sortable: true,
1075
+ headerName: l.colStatus,
1076
+ width: 120,
1077
+ valueGetter: (p) => p.data ? workflowStatus(p.data) : "",
1078
+ cellRenderer: cell(o.renderStatus)
1079
+ },
1080
+ {
1081
+ ...base,
1082
+ colId: "shared",
1083
+ headerName: l.colShared,
1084
+ headerTooltip: l.shared,
1085
+ width: 96,
1086
+ cellStyle: { display: "flex", alignItems: "center", justifyContent: "center" },
1087
+ valueGetter: (p) => p.data?.shared ?? false,
1088
+ cellRenderer: cell(o.renderShared)
1089
+ },
1090
+ {
1091
+ ...base,
1092
+ colId: "actions",
1093
+ headerName: "",
1094
+ width: 180,
1095
+ minWidth: 180,
1096
+ cellStyle: { display: "flex", alignItems: "center", justifyContent: "flex-end" },
1097
+ cellRenderer: cell(o.renderActions)
1098
+ }
1099
+ ];
1100
+ }
1101
+
1102
+ // src/agents/tasks/workflowTableLabels.ts
1103
+ var DEFAULT_WORKFLOW_LIST_LABELS = {
1104
+ colName: "Name",
1105
+ colType: "Type",
1106
+ colTrigger: "When",
1107
+ colAction: "What it does",
1108
+ colAgent: "Agent",
1109
+ colStatus: "Active",
1110
+ colShared: "Shared",
1111
+ colLastRun: "Last run",
1112
+ colNextRun: "Next run",
1113
+ shared: "Shared with the workspace",
1114
+ sharedOwnerOnly: "Only the creator can change who can see this",
1115
+ deleteOwnerOnly: "Only the creator or workspace owner can delete this",
1116
+ typeSkill: "Skill",
1117
+ typeWorkflow: "Workflow",
1118
+ statusActive: "Active",
1119
+ statusPaused: "Inactive",
1120
+ statusOnDemand: "On demand",
1121
+ activeSwitch: (name) => `Active: \u201C${name}\u201D`,
1122
+ agent: "Agent",
1123
+ myAssistant: "My assistant",
1124
+ me: "Me",
1125
+ someone: "Someone",
1126
+ never: "Never",
1127
+ none: "\u2014",
1128
+ reminder: "Reminder",
1129
+ failed: "Failed",
1130
+ lastRunFailed: "Last run failed",
1131
+ openLastRun: "Open the task this run created",
1132
+ editWorkflow: "Edit",
1133
+ run: "Run",
1134
+ runLater: "Run later",
1135
+ runNow: "Run now",
1136
+ runs: "Runs",
1137
+ delete: "Delete",
1138
+ moreActions: "More actions",
1139
+ searchLabel: "Search workflows",
1140
+ searchPlaceholder: "Search workflows and skills\u2026",
1141
+ emptyTitle: "Nothing to run yet",
1142
+ emptyMessage: "Skills and workflows you can run will appear here.",
1143
+ firstRun: "Run a skill now, or choose Run later to save it as a workflow that runs on its own.",
1144
+ noMatches: "Nothing in this view.",
1145
+ filterAll: "All",
1146
+ filterSkills: "Skills",
1147
+ filterWorkflows: "Workflows",
1148
+ filterActive: "Active",
1149
+ filterPaused: "Inactive",
1150
+ makeActive: "Make active",
1151
+ makePaused: "Deactivate",
1152
+ selectAll: "Select all",
1153
+ selectWorkflow: (name) => `Select ${name}`
1154
+ };
1155
+ var ROW_HEIGHT = 40;
1156
+ function WorkflowsTable(props) {
1157
+ const { workflows, isLoading, busyId, header, testId } = props;
1158
+ const l = { ...DEFAULT_WORKFLOW_LIST_LABELS, ...props.labels };
1159
+ const [filterStates, setFilterStates] = react.useState(/* @__PURE__ */ new Map());
1160
+ const [filterOpen, setFilterOpen] = react.useState(false);
1161
+ const [query, setQuery] = react.useState("");
1162
+ const [selected, setSelected] = react.useState([]);
1163
+ const apiRef = react.useRef(null);
1164
+ const q = query.trim().toLowerCase();
1165
+ const matches = (w) => !q || `${w.name} ${w.description ?? ""} ${w.prompt ?? ""} ${w.skill_ref ?? ""}`.toLowerCase().includes(q);
1166
+ const inFilter = (w, f) => f === "all" || f === "skills" && isSkillRow(w) || f === "workflows" && !isSkillRow(w) || f === "active" && workflowStatus(w) === "active" || f === "paused" && workflowStatus(w) === "paused";
1167
+ const counts = react.useMemo(() => {
1168
+ const out = { all: 0, skills: 0, workflows: 0, active: 0, paused: 0 };
1169
+ for (const w of workflows) {
1170
+ if (!matches(w)) continue;
1171
+ for (const f of Object.keys(out)) if (inFilter(w, f)) out[f] += 1;
1172
+ }
1173
+ return out;
1174
+ }, [workflows, q]);
1175
+ const shown = react.useMemo(
1176
+ () => workflows.filter((w) => {
1177
+ if (!matches(w)) return false;
1178
+ for (const group of [
1179
+ ["skills", "workflows"],
1180
+ ["active", "paused"]
1181
+ ]) {
1182
+ const included = group.filter((f) => filterStates.get(f) === "include");
1183
+ if (included.length && !included.some((f) => inFilter(w, f))) return false;
1184
+ if (group.some((f) => filterStates.get(f) === "exclude" && inFilter(w, f))) return false;
1185
+ }
1186
+ return true;
1187
+ }),
1188
+ [workflows, filterStates, q]
1189
+ );
1190
+ const renderPerson = props.renderPerson ?? ((p) => /* @__PURE__ */ jsxRuntime.jsx(PersonPill, { person: p }));
1191
+ const actionText = (w) => {
1192
+ if (w.action)
1193
+ return w.action.type === "email_documents" ? "Email latest documents" : "AI Review";
1194
+ if (isSkillRow(w))
1195
+ return w.description || w.skill_ref && props.skillNames?.[w.skill_ref] || w.name;
1196
+ return w.skill_ref ? props.skillNames?.[w.skill_ref] ?? w.skill_ref : w.prompt?.trim() || l.reminder;
1197
+ };
1198
+ const latest = react.useRef({ props, l, renderPerson, actionText });
1199
+ latest.current = { props, l, renderPerson, actionText };
1200
+ const columnDefs = react.useMemo(
1201
+ () => createWorkflowColumns({
1202
+ labels: l,
1203
+ getTriggerText: (w) => isSkillRow(w) ? l.statusOnDemand : latest.current.props.describeTrigger(w),
1204
+ renderName: (w) => {
1205
+ const { l: lb } = latest.current;
1206
+ const skill = isSkillRow(w);
1207
+ const text = skill ? latest.current.actionText(w) : w.description || latest.current.actionText(w);
1208
+ const stem = w.name.replace(/…$/, "").trim();
1209
+ const about = text && text.trim() !== w.name.trim() && text.trim() !== stem ? text : "";
1210
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 leading-tight", children: [
1211
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
1212
+ /* @__PURE__ */ jsxRuntime.jsx(
1213
+ "span",
1214
+ {
1215
+ className: ui.cn(
1216
+ "truncate text-sm font-normal",
1217
+ workflowStatus(w) === "paused" && "text-muted-foreground"
1218
+ ),
1219
+ "data-testid": `workflow-name-${w.external_id}`,
1220
+ children: w.name
1221
+ }
1222
+ ),
1223
+ skill && /* @__PURE__ */ jsxRuntime.jsx(
1224
+ "span",
1225
+ {
1226
+ className: "shrink-0 rounded-full border border-border px-1.5 text-[11px] text-muted-foreground",
1227
+ "data-testid": `workflow-type-${w.external_id}`,
1228
+ children: lb.typeSkill
1229
+ }
1230
+ )
1231
+ ] }),
1232
+ about && !latest.current.props.automationsOnly && /* @__PURE__ */ jsxRuntime.jsx(
1233
+ "p",
1234
+ {
1235
+ className: "truncate text-xs text-muted-foreground",
1236
+ "data-testid": `workflow-action-${w.external_id}`,
1237
+ children: about
1238
+ }
1239
+ )
1240
+ ] });
1241
+ },
1242
+ renderTrigger: (w) => {
1243
+ const { props: p } = latest.current;
1244
+ const after = w.after_conversation_ext_id;
1245
+ const skill = isSkillRow(w);
1246
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 leading-tight", children: /* @__PURE__ */ jsxRuntime.jsx(
1247
+ TaskTriggerChip,
1248
+ {
1249
+ id: w.external_id,
1250
+ testId: `workflow-trigger-${w.external_id}`,
1251
+ triggerType: workflowTriggerType(w),
1252
+ summary: skill ? "" : p.describeTrigger(w),
1253
+ afterTaskId: after,
1254
+ afterTaskName: after ? p.taskNames?.[after] : void 0,
1255
+ labels: p.triggerChipLabels
1256
+ }
1257
+ ) });
1258
+ },
1259
+ renderStatus: (w) => {
1260
+ const { props: p, l: lb } = latest.current;
1261
+ const canEdit = w.is_owner !== false || Boolean(p.canEditShared);
1262
+ return /* @__PURE__ */ jsxRuntime.jsx(
1263
+ ui.Switch,
1264
+ {
1265
+ checked: hasTrigger(w) && !isSkillRow(w) && Boolean(w.active),
1266
+ disabled: !hasTrigger(w) || isSkillRow(w) || !canEdit || p.busyId === w.external_id,
1267
+ onCheckedChange: (next) => p.onToggleActive(w, next),
1268
+ className: "disabled:data-[state=unchecked]:bg-muted dark:disabled:data-[state=unchecked]:bg-muted",
1269
+ "aria-label": lb.activeSwitch(w.name),
1270
+ "data-testid": `workflow-active-${w.external_id}`
1271
+ }
1272
+ );
1273
+ },
1274
+ renderShared: (w) => {
1275
+ const { props: p, l: lb } = latest.current;
1276
+ if (!p.onToggleShared || isSkillRow(w)) return null;
1277
+ const isCreator = w.is_owner !== false;
1278
+ return /* @__PURE__ */ jsxRuntime.jsx(
1279
+ ui.VisibilityToggle,
1280
+ {
1281
+ items: { shared: w.shared ?? false },
1282
+ onToggle: (share) => latest.current.props.onToggleShared?.(w, share),
1283
+ disabled: !isCreator || p.busyId === w.external_id,
1284
+ disabledTooltip: lb.sharedOwnerOnly,
1285
+ showLabel: false,
1286
+ "data-testid": `workflow-shared-${w.external_id}`
1287
+ }
1288
+ );
1289
+ },
1290
+ renderLastRun: (w) => {
1291
+ const { props: p, l: lb } = latest.current;
1292
+ const at = w.last_fired_at ?? p.lastRuns?.[w.external_id]?.at;
1293
+ return /* @__PURE__ */ jsxRuntime.jsx(
1294
+ "button",
1295
+ {
1296
+ type: "button",
1297
+ className: "h-full w-full truncate px-4 text-left text-sm hover:text-primary",
1298
+ onClick: () => p.onViewRuns?.(w),
1299
+ title: "View run history",
1300
+ "data-testid": `workflow-last-run-${w.external_id}`,
1301
+ children: at ? p.formatDate(at) : lb.never
1302
+ }
1303
+ );
1304
+ },
1305
+ renderResult: (w) => {
1306
+ const status = listedRunStatus(
1307
+ w.last_run_status,
1308
+ latest.current.props.lastRuns?.[w.external_id]?.threadStatus
1309
+ );
1310
+ const label = workflowRunStatusLabel(status);
1311
+ return /* @__PURE__ */ jsxRuntime.jsx(
1312
+ "button",
1313
+ {
1314
+ type: "button",
1315
+ onClick: () => latest.current.props.onViewRuns?.(w),
1316
+ title: "View run history",
1317
+ className: ui.cn(
1318
+ ui.badgeVariants({ variant: "outline" }),
1319
+ "mx-4 cursor-pointer text-xs font-medium",
1320
+ status === "failed" ? "border-red-border bg-red-bg text-red-text hover:bg-red-bg/80" : status === "completed" || status === "success" ? "border-green-border bg-green-bg text-green-text hover:bg-green-bg/80" : status ? "border-primary/20 bg-primary/10 text-primary hover:bg-primary/15" : "border-border bg-muted text-muted-foreground hover:bg-muted/80"
1321
+ ),
1322
+ "data-testid": `workflow-result-${w.external_id}`,
1323
+ children: label
1324
+ }
1325
+ );
1326
+ },
1327
+ renderActions: (w) => {
1328
+ const { props: p, l: lb } = latest.current;
1329
+ const id = w.external_id;
1330
+ const skill = isSkillRow(w);
1331
+ const busy = p.busyId === id;
1332
+ const isOwner = w.is_owner !== false;
1333
+ const canEdit = isOwner || Boolean(p.canEditShared);
1334
+ const canAdmin = isOwner || Boolean(p.isWorkspaceOwner);
1335
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-1", children: [
1336
+ (skill || canEdit) && /* @__PURE__ */ jsxRuntime.jsxs(
1337
+ ui.Button,
1338
+ {
1339
+ size: "sm",
1340
+ variant: "outline",
1341
+ className: "h-8 gap-1.5 pointer-coarse:h-11",
1342
+ disabled: busy,
1343
+ onClick: () => p.onRun(w),
1344
+ "data-testid": `workflow-run-btn-${id}`,
1345
+ children: [
1346
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "size-3.5", "aria-hidden": true }),
1347
+ lb.run
1348
+ ]
1349
+ }
1350
+ ),
1351
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
1352
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1353
+ ui.Button,
1354
+ {
1355
+ variant: "ghost",
1356
+ size: "icon",
1357
+ className: "size-8 pointer-coarse:size-11",
1358
+ "aria-label": lb.moreActions,
1359
+ "data-testid": `workflow-menu-${id}`,
1360
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { className: "size-4", "aria-hidden": true })
1361
+ }
1362
+ ) }),
1363
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenuContent, { align: "end", children: [
1364
+ skill && p.onRunLater && /* @__PURE__ */ jsxRuntime.jsxs(
1365
+ ui.DropdownMenuItem,
1366
+ {
1367
+ onSelect: () => p.onRunLater?.(w),
1368
+ "data-testid": `workflow-run-later-${id}`,
1369
+ children: [
1370
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "mr-2 size-4", "aria-hidden": true }),
1371
+ lb.runLater
1372
+ ]
1373
+ }
1374
+ ),
1375
+ !skill && canEdit && /* @__PURE__ */ jsxRuntime.jsxs(
1376
+ ui.DropdownMenuItem,
1377
+ {
1378
+ onSelect: () => p.onEdit(w),
1379
+ "data-testid": `workflow-edit-${id}`,
1380
+ children: [
1381
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "mr-2 size-4", "aria-hidden": true }),
1382
+ lb.editWorkflow
1383
+ ]
1384
+ }
1385
+ ),
1386
+ !skill && p.onViewRuns && /* @__PURE__ */ jsxRuntime.jsxs(
1387
+ ui.DropdownMenuItem,
1388
+ {
1389
+ onSelect: () => p.onViewRuns?.(w),
1390
+ "data-testid": `workflow-runs-${id}`,
1391
+ children: [
1392
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "mr-2 size-4", "aria-hidden": true }),
1393
+ lb.runs
1394
+ ]
1395
+ }
1396
+ ),
1397
+ !skill && canEdit && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1398
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenuSeparator, {}),
1399
+ /* @__PURE__ */ jsxRuntime.jsxs(
1400
+ ui.DropdownMenuItem,
1401
+ {
1402
+ disabled: busy || !canAdmin,
1403
+ onSelect: () => p.onDelete(w),
1404
+ title: canAdmin ? void 0 : lb.deleteOwnerOnly,
1405
+ className: "text-destructive focus:text-destructive",
1406
+ "data-testid": `workflow-delete-${id}`,
1407
+ children: [
1408
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "mr-2 size-4", "aria-hidden": true }),
1409
+ lb.delete
1410
+ ]
1411
+ }
1412
+ )
1413
+ ] })
1414
+ ] })
1415
+ ] })
1416
+ ] });
1417
+ }
1418
+ }),
1419
+ // Stable on purpose: only the header texts rebuild the columns (see `latest`).
1420
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1421
+ [
1422
+ l.colName,
1423
+ l.colType,
1424
+ l.colTrigger,
1425
+ l.colAction,
1426
+ l.colAgent,
1427
+ l.colStatus,
1428
+ l.colShared,
1429
+ l.shared,
1430
+ l.colLastRun,
1431
+ l.colNextRun
1432
+ ]
1433
+ );
1434
+ react.useEffect(() => {
1435
+ apiRef.current?.refreshCells({ force: true });
1436
+ }, [
1437
+ busyId,
1438
+ props.agentNames,
1439
+ props.skillNames,
1440
+ props.taskNames,
1441
+ props.lastRuns,
1442
+ props.renderPerson,
1443
+ props.labels,
1444
+ props.canEditShared,
1445
+ props.isWorkspaceOwner
1446
+ ]);
1447
+ const mine = selected.filter((w) => !isSkillRow(w));
1448
+ const adminSelected = mine.filter((w) => w.is_owner !== false || props.isWorkspaceOwner);
1449
+ const editableSelected = mine.filter(
1450
+ (w) => hasTrigger(w) && (w.is_owner !== false || props.canEditShared)
1451
+ );
1452
+ const clearSelection = () => setSelected([]);
1453
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1454
+ "div",
1455
+ {
1456
+ className: "flex min-h-0 flex-1 flex-col",
1457
+ "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "workflow-list" }),
1458
+ children: [
1459
+ /* @__PURE__ */ jsxRuntime.jsx(
1460
+ chunk7RGLTF76_cjs.TabHeader,
1461
+ {
1462
+ testId: "automations-tab-header",
1463
+ tabs: [
1464
+ {
1465
+ id: "automations",
1466
+ label: "",
1467
+ count: shown.length,
1468
+ countIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Workflow, { className: "size-3.5" }),
1469
+ countPlacement: "leading",
1470
+ presentation: "count",
1471
+ hasActiveFilters: !!q || [...filterStates.values()].some(Boolean)
1472
+ },
1473
+ ...props.tabs ?? []
1474
+ ],
1475
+ activeTabId: props.activeTabId ?? "automations",
1476
+ onTabChange: props.onTabChange ?? (() => {
1477
+ }),
1478
+ firstTabContent: /* @__PURE__ */ jsxRuntime.jsx(
1479
+ chunk2EI7NCUA_cjs.FilterInput,
1480
+ {
1481
+ value: query,
1482
+ onChange: setQuery,
1483
+ fields: ["text"],
1484
+ onFieldsChange: () => {
1485
+ },
1486
+ hideFieldPicker: true,
1487
+ ariaLabel: l.searchLabel,
1488
+ testIds: { input: "workflow-search" },
1489
+ filter: /* @__PURE__ */ jsxRuntime.jsx(
1490
+ chunkRQ2Y7USX_cjs.TriStateFilterMenu,
1491
+ {
1492
+ testId: "automations-filter-button",
1493
+ open: filterOpen,
1494
+ onOpenChange: setFilterOpen,
1495
+ filterStates,
1496
+ onFiltersChange: setFilterStates,
1497
+ 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",
1498
+ renderChevron: true,
1499
+ disableHoverOpen: true,
1500
+ options: [
1501
+ ...!props.automationsOnly ? [
1502
+ { id: "skills", label: l.filterSkills, count: counts.skills },
1503
+ {
1504
+ id: "workflows",
1505
+ label: l.filterWorkflows,
1506
+ count: counts.workflows
1507
+ }
1508
+ ] : [],
1509
+ { id: "active", label: l.filterActive, count: counts.active },
1510
+ { id: "paused", label: l.filterPaused, count: counts.paused }
1511
+ ]
1512
+ }
1513
+ )
1514
+ }
1515
+ ),
1516
+ rightContent: header
1517
+ }
1518
+ ),
1519
+ props.content ? props.content : workflows.length === 0 && !isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
1520
+ chunkZW6FPIFC_cjs.EmptyState,
1521
+ {
1522
+ icon: lucideReact.Workflow,
1523
+ title: l.emptyTitle,
1524
+ description: l.emptyMessage,
1525
+ testId: "workflow-list-empty"
1526
+ }
1527
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
1528
+ chunkC2CWWEHO_cjs.GridView,
1529
+ {
1530
+ testId: "workflow-grid",
1531
+ gridId: props.gridId ?? "workflows-grid-v2",
1532
+ items: shown,
1533
+ columnDefs,
1534
+ getItemId: (w) => w.external_id,
1535
+ getRowTestId: (w) => `workflow-row-${w.external_id}`,
1536
+ isLoading,
1537
+ showEmpty: shown.length === 0,
1538
+ emptyState: { title: l.noMatches },
1539
+ rowHeight: ROW_HEIGHT,
1540
+ height: "100%",
1541
+ onGridReady: ({ api }) => {
1542
+ apiRef.current = api;
1543
+ },
1544
+ onRowClick: (row) => props.onOpenRow?.(row),
1545
+ selection: { mode: "multiple", selected, onSelectionChange: setSelected },
1546
+ gridOptions: GRID_OPTIONS
1547
+ }
1548
+ ) }),
1549
+ !props.content && /* @__PURE__ */ jsxRuntime.jsx(chunkV4ISCZJ7_cjs.SelectionBar, { count: selected.length, onClear: clearSelection, children: (isCompact) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1550
+ props.onToggleActiveMany && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1551
+ /* @__PURE__ */ jsxRuntime.jsx(
1552
+ chunkV4ISCZJ7_cjs.SelectionBarAction,
1553
+ {
1554
+ icon: lucideReact.Play,
1555
+ label: l.makeActive,
1556
+ onClick: () => {
1557
+ props.onToggleActiveMany?.(editableSelected, true);
1558
+ clearSelection();
1559
+ },
1560
+ disabled: editableSelected.length === 0,
1561
+ isCompact,
1562
+ testId: "workflow-bulk-activate"
1563
+ }
1564
+ ),
1565
+ /* @__PURE__ */ jsxRuntime.jsx(
1566
+ chunkV4ISCZJ7_cjs.SelectionBarAction,
1567
+ {
1568
+ icon: lucideReact.Workflow,
1569
+ label: l.makePaused,
1570
+ onClick: () => {
1571
+ props.onToggleActiveMany?.(editableSelected, false);
1572
+ clearSelection();
1573
+ },
1574
+ disabled: editableSelected.length === 0,
1575
+ isCompact,
1576
+ testId: "workflow-bulk-pause"
1577
+ }
1578
+ )
1579
+ ] }),
1580
+ props.onDeleteMany && /* @__PURE__ */ jsxRuntime.jsx(
1581
+ chunkV4ISCZJ7_cjs.SelectionBarAction,
1582
+ {
1583
+ icon: lucideReact.Trash2,
1584
+ label: l.delete,
1585
+ onClick: () => {
1586
+ props.onDeleteMany?.(adminSelected);
1587
+ clearSelection();
1588
+ },
1589
+ disabled: adminSelected.length === 0,
1590
+ isCompact,
1591
+ className: "border-red-border text-red-text hover:bg-red-bg hover:text-red-text",
1592
+ testId: "workflow-bulk-delete"
1593
+ }
1594
+ )
1595
+ ] }) })
1596
+ ]
1597
+ }
1598
+ );
1599
+ }
1600
+ var GRID_OPTIONS = { suppressClickEdit: true };
1601
+
1602
+ exports.AgentSelect = AgentSelect;
1603
+ exports.DEFAULT_AGENT_SELECT_LABELS = DEFAULT_AGENT_SELECT_LABELS;
1604
+ exports.DEFAULT_SCHEMA_FORM_LABELS = DEFAULT_SCHEMA_FORM_LABELS;
1605
+ exports.DEFAULT_TASK_TRIGGER_CHIP_LABELS = DEFAULT_TASK_TRIGGER_CHIP_LABELS;
1606
+ exports.DEFAULT_WORKFLOW_CONFIG_DIALOG_LABELS = DEFAULT_WORKFLOW_CONFIG_DIALOG_LABELS;
1607
+ exports.DEFAULT_WORKFLOW_DOCUMENTS_FIELD_LABELS = DEFAULT_WORKFLOW_DOCUMENTS_FIELD_LABELS;
1608
+ exports.DEFAULT_WORKFLOW_LIST_LABELS = DEFAULT_WORKFLOW_LIST_LABELS;
1609
+ exports.PersonPill = PersonPill;
1610
+ exports.SchemaForm = SchemaForm;
1611
+ exports.TaskTriggerChip = TaskTriggerChip;
1612
+ exports.WORKFLOW_COLUMN_ORDER = WORKFLOW_COLUMN_ORDER;
1613
+ exports.WorkflowConfigDialog = WorkflowConfigDialog;
1614
+ exports.WorkflowDocumentsField = WorkflowDocumentsField;
1615
+ exports.WorkflowLauncher = WorkflowLauncher;
1616
+ exports.WorkflowsTable = WorkflowsTable;
1617
+ exports.buildWorkflowScopeSource = buildWorkflowScopeSource;
1618
+ exports.createWorkflowColumns = createWorkflowColumns;
1619
+ exports.documentScopeLabels = documentScopeLabels;
1620
+ exports.hasTrigger = hasTrigger;
1621
+ exports.isSkillRow = isSkillRow;
1622
+ exports.matchWorkflowScope = matchWorkflowScope;
1623
+ exports.workflowRunStatusLabel = workflowRunStatusLabel;
1624
+ exports.workflowStatus = workflowStatus;
1625
+ exports.workflowTriggerType = workflowTriggerType;
1626
+ //# sourceMappingURL=chunk-LPYEUD2D.cjs.map
1627
+ //# sourceMappingURL=chunk-LPYEUD2D.cjs.map