@hotmeshio/long-tail 0.3.2 → 0.4.0

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 (337) hide show
  1. package/build/api/agents.d.ts +1 -1
  2. package/build/api/agents.js +1 -1
  3. package/build/api/controlplane.d.ts +33 -0
  4. package/build/api/controlplane.js +46 -0
  5. package/build/bin/ltc.js +16 -0
  6. package/build/lib/cli/commands/streams.d.ts +20 -0
  7. package/build/lib/cli/commands/streams.js +134 -0
  8. package/build/lib/db/schemas/003_agents.sql +1 -2
  9. package/build/lib/db/schemas/004_agent_subscriptions.sql +1 -1
  10. package/build/routes/agents.js +3 -3
  11. package/build/routes/controlplane.js +28 -0
  12. package/build/sdk/index.d.ts +1 -0
  13. package/build/sdk/index.js +1 -0
  14. package/build/services/agent/index.d.ts +2 -3
  15. package/build/services/agent/index.js +5 -12
  16. package/build/services/agent/sql.d.ts +3 -4
  17. package/build/services/agent/sql.js +16 -20
  18. package/build/services/agent/subscription-sql.d.ts +1 -1
  19. package/build/services/agent/subscription-sql.js +1 -1
  20. package/build/services/agent/trigger-registry.js +1 -1
  21. package/build/services/controlplane/index.d.ts +9 -1
  22. package/build/services/controlplane/index.js +39 -0
  23. package/build/services/controlplane/stream-messages-sql.d.ts +21 -0
  24. package/build/services/controlplane/stream-messages-sql.js +108 -0
  25. package/build/services/controlplane/types.d.ts +44 -0
  26. package/build/services/cron/index.js +5 -5
  27. package/build/services/export/post-process.js +14 -6
  28. package/build/services/mcp-runs/execution-builder.js +9 -4
  29. package/build/services/topics/index.js +1 -4
  30. package/build/services/topics/sql.d.ts +2 -2
  31. package/build/services/topics/sql.js +9 -2
  32. package/build/services/topics/system-topics.js +2 -3
  33. package/build/start/workers.js +11 -14
  34. package/build/tsconfig.tsbuildinfo +1 -1
  35. package/build/types/agent.d.ts +1 -1
  36. package/dashboard/dist/assets/AdminDashboard-CR0FtTE6.js +2 -0
  37. package/dashboard/dist/assets/{AdminDashboard-CbeSejVX.js.map → AdminDashboard-CR0FtTE6.js.map} +1 -1
  38. package/dashboard/dist/assets/AgentConfigPage-BVypgq9m.js +13 -0
  39. package/dashboard/dist/assets/AgentConfigPage-BVypgq9m.js.map +1 -0
  40. package/dashboard/dist/assets/AgentDetailPage-D64ath8c.js +4 -0
  41. package/dashboard/dist/assets/AgentDetailPage-D64ath8c.js.map +1 -0
  42. package/dashboard/dist/assets/AgentsPage-j-zblMNR.js +2 -0
  43. package/dashboard/dist/assets/AgentsPage-j-zblMNR.js.map +1 -0
  44. package/dashboard/dist/assets/AvailableEscalationsPage-DmUid1h0.js +2 -0
  45. package/dashboard/dist/assets/{AvailableEscalationsPage-DdrzePy4.js.map → AvailableEscalationsPage-DmUid1h0.js.map} +1 -1
  46. package/dashboard/dist/assets/BotPicker-DCScT8BN.js +2 -0
  47. package/dashboard/dist/assets/{BotPicker-kKBifD1w.js.map → BotPicker-DCScT8BN.js.map} +1 -1
  48. package/dashboard/dist/assets/CapabilitiesPage-g5iUvHRL.js +2 -0
  49. package/dashboard/dist/assets/{CapabilitiesPage-Ch5qY0I7.js.map → CapabilitiesPage-g5iUvHRL.js.map} +1 -1
  50. package/dashboard/dist/assets/CollapsibleSection-Dj1YOsVG.js +2 -0
  51. package/dashboard/dist/assets/{CollapsibleSection-kYTBL7dT.js.map → CollapsibleSection-Dj1YOsVG.js.map} +1 -1
  52. package/dashboard/dist/assets/ConfirmDeleteModal-dOxidrSR.js +2 -0
  53. package/dashboard/dist/assets/{ConfirmDeleteModal-CcaAapMl.js.map → ConfirmDeleteModal-dOxidrSR.js.map} +1 -1
  54. package/dashboard/dist/assets/CopyableId-DmLF-RqZ.js +2 -0
  55. package/dashboard/dist/assets/{CopyableId-B4CL12pv.js.map → CopyableId-DmLF-RqZ.js.map} +1 -1
  56. package/dashboard/dist/assets/CredentialsPage-Dvb4QelY.js +2 -0
  57. package/dashboard/dist/assets/{CredentialsPage-D1VAlwid.js.map → CredentialsPage-Dvb4QelY.js.map} +1 -1
  58. package/dashboard/dist/assets/CronLabel-sk1BkcJd.js +2 -0
  59. package/dashboard/dist/assets/{CronLabel-DRmO5rH0.js.map → CronLabel-sk1BkcJd.js.map} +1 -1
  60. package/dashboard/dist/assets/CustomDurationPicker-C0MV2Q06.js +2 -0
  61. package/dashboard/dist/assets/{CustomDurationPicker-C06QDDir.js.map → CustomDurationPicker-C0MV2Q06.js.map} +1 -1
  62. package/dashboard/dist/assets/DataTable-D9yuBv0w.js +2 -0
  63. package/dashboard/dist/assets/{DataTable-J5R6mepB.js.map → DataTable-D9yuBv0w.js.map} +1 -1
  64. package/dashboard/dist/assets/DropZone-DN8uwUtf.js +2 -0
  65. package/dashboard/dist/assets/{DropZone-DwNj3GiG.js.map → DropZone-DN8uwUtf.js.map} +1 -1
  66. package/dashboard/dist/assets/ElapsedCell-CFXhhKKc.js +2 -0
  67. package/dashboard/dist/assets/{ElapsedCell-ChyMzl9n.js.map → ElapsedCell-CFXhhKKc.js.map} +1 -1
  68. package/dashboard/dist/assets/EmptyState-BcsfPq9T.js +2 -0
  69. package/dashboard/dist/assets/{EmptyState-BXGvOADa.js.map → EmptyState-BcsfPq9T.js.map} +1 -1
  70. package/dashboard/dist/assets/EscalationsOverview-BEuUFGwC.js +2 -0
  71. package/dashboard/dist/assets/{EscalationsOverview-DM6zmE4g.js.map → EscalationsOverview-BEuUFGwC.js.map} +1 -1
  72. package/dashboard/dist/assets/EventTable-DcwVWOKb.js +2 -0
  73. package/dashboard/dist/assets/{EventTable-CvJ98E8s.js.map → EventTable-DcwVWOKb.js.map} +1 -1
  74. package/dashboard/dist/assets/EventTopicPill-CWCP1v1O.js +2 -0
  75. package/dashboard/dist/assets/{EventTopicPill-CB_rIGlL.js.map → EventTopicPill-CWCP1v1O.js.map} +1 -1
  76. package/dashboard/dist/assets/FilterBar-Ck4K4rzu.js +2 -0
  77. package/dashboard/dist/assets/{FilterBar-Bdssa-Xn.js.map → FilterBar-Ck4K4rzu.js.map} +1 -1
  78. package/dashboard/dist/assets/HomePage-BH-F5ws9.js +2 -0
  79. package/dashboard/dist/assets/HomePage-BH-F5ws9.js.map +1 -0
  80. package/dashboard/dist/assets/ListToolbar-CUxJlz__.js +2 -0
  81. package/dashboard/dist/assets/{ListToolbar-jy8NL6ll.js.map → ListToolbar-CUxJlz__.js.map} +1 -1
  82. package/dashboard/dist/assets/McpOverview-O8XrOzy0.js +2 -0
  83. package/dashboard/dist/assets/{McpOverview-xkaKuHbX.js.map → McpOverview-O8XrOzy0.js.map} +1 -1
  84. package/dashboard/dist/assets/McpQueryDetailPage-DhiR0Xrx.js +5 -0
  85. package/dashboard/dist/assets/{McpQueryDetailPage-D5ICn6cR.js.map → McpQueryDetailPage-DhiR0Xrx.js.map} +1 -1
  86. package/dashboard/dist/assets/McpQueryPage-Czot0nfl.js +2 -0
  87. package/dashboard/dist/assets/{McpQueryPage-C46fzfm5.js.map → McpQueryPage-Czot0nfl.js.map} +1 -1
  88. package/dashboard/dist/assets/McpRunDetailPage-B1kNnD_t.js +2 -0
  89. package/dashboard/dist/assets/{McpRunDetailPage-Znsl4Yc-.js.map → McpRunDetailPage-B1kNnD_t.js.map} +1 -1
  90. package/dashboard/dist/assets/McpRunsPage-QUY3pWp9.js +2 -0
  91. package/dashboard/dist/assets/McpRunsPage-QUY3pWp9.js.map +1 -0
  92. package/dashboard/dist/assets/Modal-DEODGeqx.js +2 -0
  93. package/dashboard/dist/assets/{Modal-C6k6_5KB.js.map → Modal-DEODGeqx.js.map} +1 -1
  94. package/dashboard/dist/assets/OperatorDashboard-BG1Q9qZk.js +2 -0
  95. package/dashboard/dist/assets/{OperatorDashboard-e5N3_dVl.js.map → OperatorDashboard-BG1Q9qZk.js.map} +1 -1
  96. package/dashboard/dist/assets/PageHeader-DlzOOM4Y.js +2 -0
  97. package/dashboard/dist/assets/{PageHeader-COcgWWf-.js.map → PageHeader-DlzOOM4Y.js.map} +1 -1
  98. package/dashboard/dist/assets/PageHeaderWithStats-C5cZ3IOO.js +2 -0
  99. package/dashboard/dist/assets/{PageHeaderWithStats-C0PCY3aJ.js.map → PageHeaderWithStats-C5cZ3IOO.js.map} +1 -1
  100. package/dashboard/dist/assets/PriorityBadge-DfQY9St9.js +2 -0
  101. package/dashboard/dist/assets/{PriorityBadge-BQCsYMpM.js.map → PriorityBadge-DfQY9St9.js.map} +1 -1
  102. package/dashboard/dist/assets/ProcessDetailPage-DS1AwTso.js +2 -0
  103. package/dashboard/dist/assets/{ProcessDetailPage-C03LOgI0.js.map → ProcessDetailPage-DS1AwTso.js.map} +1 -1
  104. package/dashboard/dist/assets/ProcessesListPage-CAmVcn1P.js +2 -0
  105. package/dashboard/dist/assets/{ProcessesListPage-iyPsmlhm.js.map → ProcessesListPage-CAmVcn1P.js.map} +1 -1
  106. package/dashboard/dist/assets/RolePill-BZaUpkHg.js +2 -0
  107. package/dashboard/dist/assets/{RolePill-CHwys1f9.js.map → RolePill-BZaUpkHg.js.map} +1 -1
  108. package/dashboard/dist/assets/RolesPage-CFdIXfmv.js +2 -0
  109. package/dashboard/dist/assets/{RolesPage-Bmc3XaUk.js.map → RolesPage-CFdIXfmv.js.map} +1 -1
  110. package/dashboard/dist/assets/RowActions-Dg-Fsm5O.js +2 -0
  111. package/dashboard/dist/assets/{RowActions-Bs4PF-Gd.js.map → RowActions-Dg-Fsm5O.js.map} +1 -1
  112. package/dashboard/dist/assets/RunAsSelector-BGww9lta.js +2 -0
  113. package/dashboard/dist/assets/{RunAsSelector-DXzAr2WW.js.map → RunAsSelector-BGww9lta.js.map} +1 -1
  114. package/dashboard/dist/assets/ServerName-DfS3pfon.js +2 -0
  115. package/dashboard/dist/assets/{ServerName-BIdLC1Ay.js.map → ServerName-DfS3pfon.js.map} +1 -1
  116. package/dashboard/dist/assets/StatCard-DlgF0CJC.js +2 -0
  117. package/dashboard/dist/assets/{StatCard-OKzRSSx4.js.map → StatCard-DlgF0CJC.js.map} +1 -1
  118. package/dashboard/dist/assets/StatusBadge-XQlNFwmH.js +2 -0
  119. package/dashboard/dist/assets/{StatusBadge-CQlF46RR.js.map → StatusBadge-XQlNFwmH.js.map} +1 -1
  120. package/dashboard/dist/assets/StepIndicator-CuUIGxKk.js +2 -0
  121. package/dashboard/dist/assets/{StepIndicator-CP7eycjI.js.map → StepIndicator-CuUIGxKk.js.map} +1 -1
  122. package/dashboard/dist/assets/StickyPagination-F9FZsRy9.js +2 -0
  123. package/dashboard/dist/assets/{StickyPagination-CGk8VAKt.js.map → StickyPagination-F9FZsRy9.js.map} +1 -1
  124. package/dashboard/dist/assets/SwimlaneTimeline-C2hGjy0V.js +2 -0
  125. package/dashboard/dist/assets/{SwimlaneTimeline-MEUPc3yJ.js.map → SwimlaneTimeline-C2hGjy0V.js.map} +1 -1
  126. package/dashboard/dist/assets/TagInput-D21mrQx6.js +2 -0
  127. package/dashboard/dist/assets/{TagInput-BGxXKiWD.js.map → TagInput-D21mrQx6.js.map} +1 -1
  128. package/dashboard/dist/assets/TaskDetailPage-B49WQj8W.js +2 -0
  129. package/dashboard/dist/assets/TaskDetailPage-B49WQj8W.js.map +1 -0
  130. package/dashboard/dist/assets/TaskQueuePill-D8UMH1rd.js +2 -0
  131. package/dashboard/dist/assets/{TaskQueuePill-bw8ieKsf.js.map → TaskQueuePill-D8UMH1rd.js.map} +1 -1
  132. package/dashboard/dist/assets/TasksListPage-CJB-EvKX.js +2 -0
  133. package/dashboard/dist/assets/{TasksListPage-D1INzcrA.js.map → TasksListPage-CJB-EvKX.js.map} +1 -1
  134. package/dashboard/dist/assets/TimeAgo-CnjY3XDt.js +2 -0
  135. package/dashboard/dist/assets/{TimeAgo-CywLVIBA.js.map → TimeAgo-CnjY3XDt.js.map} +1 -1
  136. package/dashboard/dist/assets/TimestampCell-u1YA8eA3.js +2 -0
  137. package/dashboard/dist/assets/{TimestampCell-B4Pc6f3A.js.map → TimestampCell-u1YA8eA3.js.map} +1 -1
  138. package/dashboard/dist/assets/ToolPill-Dmcwmqh2.js +2 -0
  139. package/dashboard/dist/assets/{ToolPill-DdLN3JOT.js.map → ToolPill-Dmcwmqh2.js.map} +1 -1
  140. package/dashboard/dist/assets/ToolTestPanel-B1T4Hk0t.js +2 -0
  141. package/dashboard/dist/assets/{ToolTestPanel-DusbUka5.js.map → ToolTestPanel-B1T4Hk0t.js.map} +1 -1
  142. package/dashboard/dist/assets/TopicDetailPage-ClibbST4.js +9 -0
  143. package/dashboard/dist/assets/TopicDetailPage-ClibbST4.js.map +1 -0
  144. package/dashboard/dist/assets/TopicsPage-KjODhitc.js +2 -0
  145. package/dashboard/dist/assets/{TopicsPage-DbtrnQON.js.map → TopicsPage-KjODhitc.js.map} +1 -1
  146. package/dashboard/dist/assets/UserName-DVqimwsO.js +2 -0
  147. package/dashboard/dist/assets/{UserName-CLbusknU.js.map → UserName-DVqimwsO.js.map} +1 -1
  148. package/dashboard/dist/assets/WorkflowExecutionPage-DYNPy7Gk.js +2 -0
  149. package/dashboard/dist/assets/{WorkflowExecutionPage-C61R-3Gg.js.map → WorkflowExecutionPage-DYNPy7Gk.js.map} +1 -1
  150. package/dashboard/dist/assets/WorkflowPill-h43nlUmM.js +2 -0
  151. package/dashboard/dist/assets/{WorkflowPill-7vt2F6wR.js.map → WorkflowPill-h43nlUmM.js.map} +1 -1
  152. package/dashboard/dist/assets/WorkflowsDashboard-DdJm6X7x.js +2 -0
  153. package/dashboard/dist/assets/{WorkflowsDashboard-BWiUNvyl.js.map → WorkflowsDashboard-DdJm6X7x.js.map} +1 -1
  154. package/dashboard/dist/assets/WorkflowsOverview-CBOYkfpD.js +2 -0
  155. package/dashboard/dist/assets/{WorkflowsOverview-DA2ZOs7D.js.map → WorkflowsOverview-CBOYkfpD.js.map} +1 -1
  156. package/dashboard/dist/assets/YamlWorkflowsPage-BZnD_hMw.js +2 -0
  157. package/dashboard/dist/assets/{YamlWorkflowsPage-CLebf2eL.js.map → YamlWorkflowsPage-BZnD_hMw.js.map} +1 -1
  158. package/dashboard/dist/assets/{agents-Dga6NU7U.js → agents-oHMkS1GD.js} +2 -2
  159. package/dashboard/dist/assets/agents-oHMkS1GD.js.map +1 -0
  160. package/dashboard/dist/assets/{bots-CtU4i4OQ.js → bots-BispbsY3.js} +2 -2
  161. package/dashboard/dist/assets/{bots-CtU4i4OQ.js.map → bots-BispbsY3.js.map} +1 -1
  162. package/dashboard/dist/assets/{controlplane-BVoALhbL.js → controlplane-CIbrx5rX.js} +2 -2
  163. package/dashboard/dist/assets/{controlplane-BVoALhbL.js.map → controlplane-CIbrx5rX.js.map} +1 -1
  164. package/dashboard/dist/assets/escalation-columns-Dh_0iVTH.js +2 -0
  165. package/dashboard/dist/assets/{escalation-columns-CoTmTpHp.js.map → escalation-columns-Dh_0iVTH.js.map} +1 -1
  166. package/dashboard/dist/assets/escalation-qhj4TxA3.js +2 -0
  167. package/dashboard/dist/assets/{escalation-_N5GfuIi.js.map → escalation-qhj4TxA3.js.map} +1 -1
  168. package/dashboard/dist/assets/helpers-BYw1qqKV.js +2 -0
  169. package/dashboard/dist/assets/{helpers-Dz2U3Ctb.js.map → helpers-BYw1qqKV.js.map} +1 -1
  170. package/dashboard/dist/assets/index-B9t_vpam.js +2 -0
  171. package/dashboard/dist/assets/{index-Dpjguclc.js.map → index-B9t_vpam.js.map} +1 -1
  172. package/dashboard/dist/assets/index-Bh9g-EOF.js +2 -0
  173. package/dashboard/dist/assets/{index-CS61sh5q.js.map → index-Bh9g-EOF.js.map} +1 -1
  174. package/dashboard/dist/assets/index-BhhWCADo.js +63 -0
  175. package/dashboard/dist/assets/index-BhhWCADo.js.map +1 -0
  176. package/dashboard/dist/assets/index-Bn-VSH41.js +2 -0
  177. package/dashboard/dist/assets/index-Bn-VSH41.js.map +1 -0
  178. package/dashboard/dist/assets/index-C2yJWps6.js +6 -0
  179. package/dashboard/dist/assets/{index-B9ealjkt.js.map → index-C2yJWps6.js.map} +1 -1
  180. package/dashboard/dist/assets/index-C4W1_Rfk.js +5 -0
  181. package/dashboard/dist/assets/{index-CtbG3UN-.js.map → index-C4W1_Rfk.js.map} +1 -1
  182. package/dashboard/dist/assets/index-CEF3Idec.js +2 -0
  183. package/dashboard/dist/assets/{index-6Kd78p_v.js.map → index-CEF3Idec.js.map} +1 -1
  184. package/dashboard/dist/assets/index-CHxvfc97.css +1 -0
  185. package/dashboard/dist/assets/index-CVRVw3g_.js +2 -0
  186. package/dashboard/dist/assets/{index-dM-OgCY3.js.map → index-CVRVw3g_.js.map} +1 -1
  187. package/dashboard/dist/assets/index-CY3EhrEA.js +2 -0
  188. package/dashboard/dist/assets/{index-QicYdUsl.js.map → index-CY3EhrEA.js.map} +1 -1
  189. package/dashboard/dist/assets/index-D-q2lzup.js +2 -0
  190. package/dashboard/dist/assets/{index-DWUunWxh.js.map → index-D-q2lzup.js.map} +1 -1
  191. package/dashboard/dist/assets/index-D6YjH5uG.js +15 -0
  192. package/dashboard/dist/assets/{index-BYwPVJv0.js.map → index-D6YjH5uG.js.map} +1 -1
  193. package/dashboard/dist/assets/index-ht5r_7jQ.js +2 -0
  194. package/dashboard/dist/assets/index-ht5r_7jQ.js.map +1 -0
  195. package/dashboard/dist/assets/index-zHicKKh9.js +2 -0
  196. package/dashboard/dist/assets/{index-D_H_Prht.js.map → index-zHicKKh9.js.map} +1 -1
  197. package/dashboard/dist/assets/{knowledge-DJlebU82.js → knowledge-B23TU6JN.js} +2 -2
  198. package/dashboard/dist/assets/{knowledge-DJlebU82.js.map → knowledge-B23TU6JN.js.map} +1 -1
  199. package/dashboard/dist/assets/{mcp-CsLJ5SRm.js → mcp-Cew_Sb-Q.js} +2 -2
  200. package/dashboard/dist/assets/{mcp-CsLJ5SRm.js.map → mcp-Cew_Sb-Q.js.map} +1 -1
  201. package/dashboard/dist/assets/{mcp-query-WNK1ItRV.js → mcp-query-So0Oz5Lx.js} +2 -2
  202. package/dashboard/dist/assets/{mcp-query-WNK1ItRV.js.map → mcp-query-So0Oz5Lx.js.map} +1 -1
  203. package/dashboard/dist/assets/{mcp-runs-DtTTsuPH.js → mcp-runs-4176y3SA.js} +2 -2
  204. package/dashboard/dist/assets/{mcp-runs-DtTTsuPH.js.map → mcp-runs-4176y3SA.js.map} +1 -1
  205. package/dashboard/dist/assets/namespaces-CqBbWsJx.js +2 -0
  206. package/dashboard/dist/assets/{namespaces-iRejH3_A.js.map → namespaces-CqBbWsJx.js.map} +1 -1
  207. package/dashboard/dist/assets/{roles-3Jm5KtKc.js → roles-BTxMgLE6.js} +2 -2
  208. package/dashboard/dist/assets/{roles-3Jm5KtKc.js.map → roles-BTxMgLE6.js.map} +1 -1
  209. package/dashboard/dist/assets/settings-CtQNxacL.js +2 -0
  210. package/dashboard/dist/assets/{settings-DmN2I-c6.js.map → settings-CtQNxacL.js.map} +1 -1
  211. package/dashboard/dist/assets/{tasks-Cc-QoITQ.js → tasks-CIRlUTbo.js} +2 -2
  212. package/dashboard/dist/assets/{tasks-Cc-QoITQ.js.map → tasks-CIRlUTbo.js.map} +1 -1
  213. package/dashboard/dist/assets/{topics-p8anbgi0.js → topics-C8YmK_j2.js} +2 -2
  214. package/dashboard/dist/assets/topics-C8YmK_j2.js.map +1 -0
  215. package/dashboard/dist/assets/{useEventHooks-VaJ52jMm.js → useEventHooks-BvMUy36X.js} +2 -2
  216. package/dashboard/dist/assets/{useEventHooks-VaJ52jMm.js.map → useEventHooks-BvMUy36X.js.map} +1 -1
  217. package/dashboard/dist/assets/{useExpandedRows-Cg9iq6Vy.js → useExpandedRows-CkcEntB-.js} +2 -2
  218. package/dashboard/dist/assets/{useExpandedRows-Cg9iq6Vy.js.map → useExpandedRows-CkcEntB-.js.map} +1 -1
  219. package/dashboard/dist/assets/{useFilterParams-CGRYFw_A.js → useFilterParams-DZCAaBC7.js} +2 -2
  220. package/dashboard/dist/assets/{useFilterParams-CGRYFw_A.js.map → useFilterParams-DZCAaBC7.js.map} +1 -1
  221. package/dashboard/dist/assets/{useYamlActivityEvents-BU4Uhksl.js → useYamlActivityEvents-DLEzqv-z.js} +2 -2
  222. package/dashboard/dist/assets/{useYamlActivityEvents-BU4Uhksl.js.map → useYamlActivityEvents-DLEzqv-z.js.map} +1 -1
  223. package/dashboard/dist/assets/{users-oXOlnold.js → users-C_bD6mzW.js} +2 -2
  224. package/dashboard/dist/assets/{users-oXOlnold.js.map → users-C_bD6mzW.js.map} +1 -1
  225. package/dashboard/dist/assets/{vendor-icons-CBOM6Es0.js → vendor-icons-DY1ctJgc.js} +111 -101
  226. package/dashboard/dist/assets/vendor-icons-DY1ctJgc.js.map +1 -0
  227. package/dashboard/dist/assets/vendor-query-B2UbickB.js +18 -0
  228. package/dashboard/dist/assets/vendor-query-B2UbickB.js.map +1 -0
  229. package/dashboard/dist/assets/vendor-react-CX88sFS5.js +22 -0
  230. package/dashboard/dist/assets/vendor-react-CX88sFS5.js.map +1 -0
  231. package/dashboard/dist/assets/{workflows-Yq7cK-vR.js → workflows-DFR0-hI3.js} +2 -2
  232. package/dashboard/dist/assets/{workflows-Yq7cK-vR.js.map → workflows-DFR0-hI3.js.map} +1 -1
  233. package/dashboard/dist/assets/{yaml-workflows-Ch53yD43.js → yaml-workflows-wXURdyjP.js} +2 -2
  234. package/dashboard/dist/assets/{yaml-workflows-Ch53yD43.js.map → yaml-workflows-wXURdyjP.js.map} +1 -1
  235. package/dashboard/dist/index.html +5 -5
  236. package/docs/agents.md +1 -1
  237. package/docs/api/http/agents.md +5 -7
  238. package/docs/api/http/controlplane.md +193 -0
  239. package/docs/api/sdk/agents.md +5 -5
  240. package/docs/api/sdk/controlplane.md +36 -0
  241. package/docs/dashboard.md +13 -0
  242. package/package.json +2 -2
  243. package/dashboard/dist/assets/AdminDashboard-CbeSejVX.js +0 -2
  244. package/dashboard/dist/assets/AgentConfigPage-CFJNOrlg.js +0 -13
  245. package/dashboard/dist/assets/AgentConfigPage-CFJNOrlg.js.map +0 -1
  246. package/dashboard/dist/assets/AgentDetailPage-Dbx2t-Uk.js +0 -4
  247. package/dashboard/dist/assets/AgentDetailPage-Dbx2t-Uk.js.map +0 -1
  248. package/dashboard/dist/assets/AgentsPage-Bz61Nl-x.js +0 -2
  249. package/dashboard/dist/assets/AgentsPage-Bz61Nl-x.js.map +0 -1
  250. package/dashboard/dist/assets/AvailableEscalationsPage-DdrzePy4.js +0 -2
  251. package/dashboard/dist/assets/BotPicker-kKBifD1w.js +0 -2
  252. package/dashboard/dist/assets/CapabilitiesPage-Ch5qY0I7.js +0 -2
  253. package/dashboard/dist/assets/CollapsibleSection-kYTBL7dT.js +0 -2
  254. package/dashboard/dist/assets/ConfirmDeleteModal-CcaAapMl.js +0 -2
  255. package/dashboard/dist/assets/CopyableId-B4CL12pv.js +0 -2
  256. package/dashboard/dist/assets/CredentialsPage-D1VAlwid.js +0 -2
  257. package/dashboard/dist/assets/CronLabel-DRmO5rH0.js +0 -2
  258. package/dashboard/dist/assets/CustomDurationPicker-C06QDDir.js +0 -2
  259. package/dashboard/dist/assets/DataTable-J5R6mepB.js +0 -2
  260. package/dashboard/dist/assets/DropZone-DwNj3GiG.js +0 -2
  261. package/dashboard/dist/assets/ElapsedCell-ChyMzl9n.js +0 -2
  262. package/dashboard/dist/assets/EmptyState-BXGvOADa.js +0 -2
  263. package/dashboard/dist/assets/EscalationsOverview-DM6zmE4g.js +0 -2
  264. package/dashboard/dist/assets/EventTable-CvJ98E8s.js +0 -2
  265. package/dashboard/dist/assets/EventTopicPill-CB_rIGlL.js +0 -2
  266. package/dashboard/dist/assets/FilterBar-Bdssa-Xn.js +0 -2
  267. package/dashboard/dist/assets/HomePage-BuZkdXZt.js +0 -2
  268. package/dashboard/dist/assets/HomePage-BuZkdXZt.js.map +0 -1
  269. package/dashboard/dist/assets/ListToolbar-jy8NL6ll.js +0 -2
  270. package/dashboard/dist/assets/McpOverview-xkaKuHbX.js +0 -2
  271. package/dashboard/dist/assets/McpQueryDetailPage-D5ICn6cR.js +0 -5
  272. package/dashboard/dist/assets/McpQueryPage-C46fzfm5.js +0 -2
  273. package/dashboard/dist/assets/McpRunDetailPage-Znsl4Yc-.js +0 -2
  274. package/dashboard/dist/assets/McpRunsPage-DT-armx5.js +0 -2
  275. package/dashboard/dist/assets/McpRunsPage-DT-armx5.js.map +0 -1
  276. package/dashboard/dist/assets/Modal-C6k6_5KB.js +0 -2
  277. package/dashboard/dist/assets/OperatorDashboard-e5N3_dVl.js +0 -2
  278. package/dashboard/dist/assets/PageHeader-COcgWWf-.js +0 -2
  279. package/dashboard/dist/assets/PageHeaderWithStats-C0PCY3aJ.js +0 -2
  280. package/dashboard/dist/assets/PriorityBadge-BQCsYMpM.js +0 -2
  281. package/dashboard/dist/assets/ProcessDetailPage-C03LOgI0.js +0 -2
  282. package/dashboard/dist/assets/ProcessesListPage-iyPsmlhm.js +0 -2
  283. package/dashboard/dist/assets/RolePill-CHwys1f9.js +0 -2
  284. package/dashboard/dist/assets/RolesPage-Bmc3XaUk.js +0 -2
  285. package/dashboard/dist/assets/RowActions-Bs4PF-Gd.js +0 -2
  286. package/dashboard/dist/assets/RunAsSelector-DXzAr2WW.js +0 -2
  287. package/dashboard/dist/assets/ServerName-BIdLC1Ay.js +0 -2
  288. package/dashboard/dist/assets/StatCard-OKzRSSx4.js +0 -2
  289. package/dashboard/dist/assets/StatusBadge-CQlF46RR.js +0 -2
  290. package/dashboard/dist/assets/StepIndicator-CP7eycjI.js +0 -2
  291. package/dashboard/dist/assets/StickyPagination-CGk8VAKt.js +0 -2
  292. package/dashboard/dist/assets/SwimlaneTimeline-MEUPc3yJ.js +0 -2
  293. package/dashboard/dist/assets/TagInput-BGxXKiWD.js +0 -2
  294. package/dashboard/dist/assets/TaskDetailPage-pN5BXzYA.js +0 -2
  295. package/dashboard/dist/assets/TaskDetailPage-pN5BXzYA.js.map +0 -1
  296. package/dashboard/dist/assets/TaskQueuePill-bw8ieKsf.js +0 -2
  297. package/dashboard/dist/assets/TasksListPage-D1INzcrA.js +0 -2
  298. package/dashboard/dist/assets/TimeAgo-CywLVIBA.js +0 -2
  299. package/dashboard/dist/assets/TimestampCell-B4Pc6f3A.js +0 -2
  300. package/dashboard/dist/assets/ToolPill-DdLN3JOT.js +0 -2
  301. package/dashboard/dist/assets/ToolTestPanel-DusbUka5.js +0 -2
  302. package/dashboard/dist/assets/TopicDetailPage-DadwM52Y.js +0 -9
  303. package/dashboard/dist/assets/TopicDetailPage-DadwM52Y.js.map +0 -1
  304. package/dashboard/dist/assets/TopicsPage-DbtrnQON.js +0 -2
  305. package/dashboard/dist/assets/UserName-CLbusknU.js +0 -2
  306. package/dashboard/dist/assets/WorkflowExecutionPage-C61R-3Gg.js +0 -2
  307. package/dashboard/dist/assets/WorkflowPill-7vt2F6wR.js +0 -2
  308. package/dashboard/dist/assets/WorkflowsDashboard-BWiUNvyl.js +0 -2
  309. package/dashboard/dist/assets/WorkflowsOverview-DA2ZOs7D.js +0 -2
  310. package/dashboard/dist/assets/YamlWorkflowsPage-CLebf2eL.js +0 -2
  311. package/dashboard/dist/assets/agents-Dga6NU7U.js.map +0 -1
  312. package/dashboard/dist/assets/escalation-_N5GfuIi.js +0 -2
  313. package/dashboard/dist/assets/escalation-columns-CoTmTpHp.js +0 -2
  314. package/dashboard/dist/assets/helpers-Dz2U3Ctb.js +0 -2
  315. package/dashboard/dist/assets/index-6Kd78p_v.js +0 -2
  316. package/dashboard/dist/assets/index-B9ealjkt.js +0 -6
  317. package/dashboard/dist/assets/index-BIUHY2Jz.css +0 -1
  318. package/dashboard/dist/assets/index-BWHDW_CF.js +0 -2
  319. package/dashboard/dist/assets/index-BWHDW_CF.js.map +0 -1
  320. package/dashboard/dist/assets/index-BYwPVJv0.js +0 -15
  321. package/dashboard/dist/assets/index-CCOSf1PY.js +0 -281
  322. package/dashboard/dist/assets/index-CCOSf1PY.js.map +0 -1
  323. package/dashboard/dist/assets/index-CS61sh5q.js +0 -2
  324. package/dashboard/dist/assets/index-CtbG3UN-.js +0 -5
  325. package/dashboard/dist/assets/index-DWUunWxh.js +0 -2
  326. package/dashboard/dist/assets/index-D_H_Prht.js +0 -2
  327. package/dashboard/dist/assets/index-Dpjguclc.js +0 -2
  328. package/dashboard/dist/assets/index-QicYdUsl.js +0 -2
  329. package/dashboard/dist/assets/index-dM-OgCY3.js +0 -2
  330. package/dashboard/dist/assets/namespaces-iRejH3_A.js +0 -2
  331. package/dashboard/dist/assets/settings-DmN2I-c6.js +0 -2
  332. package/dashboard/dist/assets/topics-p8anbgi0.js.map +0 -1
  333. package/dashboard/dist/assets/vendor-icons-CBOM6Es0.js.map +0 -1
  334. package/dashboard/dist/assets/vendor-query-DLp59M9_.js +0 -35
  335. package/dashboard/dist/assets/vendor-query-DLp59M9_.js.map +0 -1
  336. package/dashboard/dist/assets/vendor-react-Co3Y8ikm.js +0 -26
  337. package/dashboard/dist/assets/vendor-react-Co3Y8ikm.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index-Dpjguclc.js","sources":["../../src/api/files.ts","../../src/pages/files/FileBreadcrumbs.tsx","../../src/pages/files/FilePreviewContent.tsx","../../src/pages/files/FileListViews.tsx","../../src/pages/files/FilePreviewPanel.tsx","../../src/pages/files/FilesPage.tsx"],"sourcesContent":["import { useQuery, useMutation } from '@tanstack/react-query';\nimport { apiFetch } from './client';\n\nexport interface FileEntry {\n path: string;\n size: number;\n modified_at: string;\n}\n\nexport interface BrowseResponse {\n files: FileEntry[];\n directories: string[];\n nextToken?: string;\n}\n\nexport interface FileMetadata {\n path: string;\n size: number;\n modified_at: string;\n content_type: string;\n}\n\nexport interface SignedUrlResponse {\n url: string;\n expiresAt: string;\n}\n\nexport function useFileBrowse(prefix: string, pageSize = 100, continuationToken?: string) {\n const params = new URLSearchParams();\n if (prefix) params.set('prefix', prefix);\n params.set('pageSize', String(pageSize));\n if (continuationToken) params.set('continuationToken', continuationToken);\n const qs = params.toString();\n\n return useQuery<BrowseResponse>({\n queryKey: ['fileBrowse', prefix, pageSize, continuationToken],\n queryFn: () => apiFetch(`/file-browser/browse?${qs}`),\n });\n}\n\nexport function useFileMetadata(filePath: string | null) {\n return useQuery<FileMetadata>({\n queryKey: ['fileMetadata', filePath],\n queryFn: () => apiFetch(`/file-browser/metadata/${filePath}`),\n enabled: !!filePath,\n });\n}\n\nexport function useGenerateSignedUrl() {\n return useMutation<SignedUrlResponse, Error, { path: string; expiresIn: number }>({\n mutationFn: (data) =>\n apiFetch('/file-browser/signed-url', {\n method: 'POST',\n body: JSON.stringify(data),\n }),\n });\n}\n\nexport function useDeleteFile() {\n return useMutation<{ deleted: boolean; path: string }, Error, string>({\n mutationFn: (filePath) =>\n apiFetch(`/file-browser/delete/${filePath}`, { method: 'DELETE' }),\n });\n}\n\nexport function useUploadFile() {\n return useMutation<{ path: string; size: number; content_type: string }, Error, { path: string; file: File }>({\n mutationFn: async ({ path, file }) => {\n const buffer = await file.arrayBuffer();\n // Always send as octet-stream to bypass Express JSON body parser\n return apiFetch(`/file-browser/upload?path=${encodeURIComponent(path)}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/octet-stream' },\n body: buffer,\n });\n },\n });\n}\n\nexport function useFilePreviewUrl(filePath: string | null) {\n return useQuery<string>({\n queryKey: ['filePreviewUrl', filePath],\n queryFn: async () => {\n const result = await apiFetch<SignedUrlResponse>('/file-browser/signed-url', {\n method: 'POST',\n body: JSON.stringify({ path: filePath, expiresIn: 3600 }),\n });\n return result.url;\n },\n enabled: !!filePath,\n staleTime: 50 * 60 * 1000, // cache for 50 min (token valid for 60)\n });\n}\n\n/** @deprecated Use useFilePreviewUrl() for signed access */\nexport function getFilePreviewUrl(filePath: string): string {\n return `/api/files/${filePath.replace(/^\\/+/, '')}`;\n}\n\nexport function getFileDownloadUrl(filePath: string): string {\n return `/api/file-browser/download/${filePath.replace(/^\\/+/, '')}`;\n}\n","import { ChevronRight, FolderOpen } from 'lucide-react';\n\ninterface FileBreadcrumbsProps {\n prefix: string;\n onNavigate: (prefix: string) => void;\n}\n\nexport function FileBreadcrumbs({ prefix, onNavigate }: FileBreadcrumbsProps) {\n const segments = prefix ? prefix.replace(/\\/+$/, '').split('/').filter(Boolean) : [];\n\n return (\n <nav className=\"flex items-center gap-1 text-sm mb-6 min-h-[28px]\">\n <button\n onClick={() => onNavigate('')}\n className={`flex items-center gap-1.5 px-1.5 py-0.5 rounded transition-colors ${\n segments.length === 0\n ? 'text-text-primary font-medium'\n : 'text-text-secondary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n <FolderOpen className=\"w-4 h-4 text-accent/75\" strokeWidth={1.5} />\n <span>Root</span>\n </button>\n\n {segments.map((segment, i) => {\n const isLast = i === segments.length - 1;\n const targetPrefix = segments.slice(0, i + 1).join('/') + '/';\n return (\n <span key={targetPrefix} className=\"flex items-center gap-1\">\n <ChevronRight className=\"w-3.5 h-3.5 text-text-tertiary\" />\n <button\n onClick={() => onNavigate(targetPrefix)}\n className={`px-1.5 py-0.5 rounded transition-colors ${\n isLast\n ? 'text-text-primary font-medium'\n : 'text-text-secondary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n {segment}\n </button>\n </span>\n );\n })}\n </nav>\n );\n}\n","import { useState } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { TimeAgo } from '../../components/common/display/TimeAgo';\n\ninterface FileMetadata {\n path: string;\n content_type: string;\n size: number;\n modified_at: string;\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\nexport function fileName(filePath: string): string {\n return filePath.split('/').pop() || filePath;\n}\n\nexport function MetaRow({ label, value, mono, children }: {\n label: string;\n value?: string;\n mono?: boolean;\n children?: React.ReactNode;\n}) {\n return (\n <div>\n <dt className=\"text-[10px] uppercase tracking-wider text-text-tertiary mb-0.5\">{label}</dt>\n <dd className={`text-sm text-text-secondary ${mono ? 'font-mono text-xs break-all' : ''}`}>\n {children || value}\n </dd>\n </div>\n );\n}\n\nexport function TextPreview({ url }: { url: string }) {\n const [content, setContent] = useState<string | null>(null);\n const [error, setError] = useState(false);\n\n if (content === null && !error) {\n fetch(url)\n .then((res) => {\n if (!res.ok) throw new Error();\n return res.text();\n })\n .then((text) => setContent(text.slice(0, 100_000)))\n .catch(() => setError(true));\n }\n\n if (error) return <p className=\"text-xs text-text-tertiary\">Could not load preview</p>;\n if (content === null) {\n return <div className=\"animate-pulse h-32 bg-surface-sunken rounded\" />;\n }\n\n return (\n <pre className=\"font-mono text-xs text-text-secondary bg-surface-sunken rounded-md p-3 overflow-x-auto max-h-[400px] overflow-y-auto whitespace-pre-wrap break-words\">\n {content}\n </pre>\n );\n}\n\nexport function FileMetadataDisplay({ metadata }: {\n metadata: FileMetadata;\n}) {\n const [copied, setCopied] = useState<string | null>(null);\n\n async function copyToClipboard(text: string, label: string) {\n await navigator.clipboard.writeText(text);\n setCopied(label);\n setTimeout(() => setCopied(null), 2000);\n }\n\n return (\n <div className=\"space-y-3\">\n <div>\n <dt className=\"text-[10px] uppercase tracking-wider text-text-tertiary mb-0.5\">Path</dt>\n <dd\n onClick={() => copyToClipboard(metadata.path, 'path')}\n className=\"group flex items-center gap-1.5 text-xs font-mono text-text-secondary break-all cursor-pointer hover:text-text-primary transition-colors\"\n title=\"Click to copy\"\n >\n <span className=\"flex-1\">{metadata.path}</span>\n {copied === 'path'\n ? <Check className=\"w-3.5 h-3.5 text-status-success shrink-0\" />\n : <Copy className=\"w-3.5 h-3.5 opacity-0 group-hover:opacity-100 text-text-tertiary shrink-0 transition-opacity\" />}\n </dd>\n </div>\n <MetaRow label=\"Type\" value={metadata.content_type} />\n <MetaRow label=\"Size\" value={formatSize(metadata.size)} />\n <MetaRow label=\"Modified\">\n <TimeAgo date={metadata.modified_at} />\n </MetaRow>\n </div>\n );\n}\n\nexport async function triggerDownload(url: string, name: string) {\n const res = await fetch(url);\n const blob = await res.blob();\n const blobUrl = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = blobUrl;\n a.download = name;\n a.style.display = 'none';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(blobUrl);\n}\n","import {\n Folder,\n File,\n Image,\n FileText,\n FileJson2,\n FileSpreadsheet,\n} from 'lucide-react';\nimport { TimeAgo } from '../../components/common/display/TimeAgo';\nimport { getFilePreviewUrl } from '../../api/files';\n\nexport function formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\nexport function fileIcon(filePath: string) {\n const ext = filePath.split('.').pop()?.toLowerCase() || '';\n if (['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'].includes(ext)) {\n return <Image className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n }\n if (['json'].includes(ext)) {\n return <FileJson2 className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n }\n if (['csv', 'xlsx', 'xls'].includes(ext)) {\n return <FileSpreadsheet className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n }\n if (['txt', 'md', 'html', 'xml', 'yaml', 'yml', 'css', 'js', 'ts'].includes(ext)) {\n return <FileText className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n }\n return <File className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n}\n\nexport function isImagePath(filePath: string): boolean {\n const ext = filePath.split('.').pop()?.toLowerCase() || '';\n return ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'].includes(ext);\n}\n\nexport function dirName(dirPath: string): string {\n const stripped = dirPath.replace(/\\/+$/, '');\n return stripped.split('/').pop() || stripped;\n}\n\nexport function fileNameFromPath(filePath: string): string {\n return filePath.split('/').pop() || filePath;\n}\n\ninterface ViewProps {\n directories: string[];\n files: Array<{ path: string; size: number; modified_at: string }>;\n onNavigate: (prefix: string) => void;\n onSelect: (path: string) => void;\n selectedFile: string | null;\n}\n\nexport function ListView({ directories, files, onNavigate, onSelect, selectedFile }: ViewProps) {\n return (\n <table className=\"w-full mt-2\">\n <thead>\n <tr className=\"text-left text-[10px] uppercase tracking-wider text-text-tertiary\">\n <th className=\"pb-2 pl-2 font-medium\">Name</th>\n <th className=\"pb-2 font-medium w-24 text-right\">Size</th>\n <th className=\"pb-2 pr-2 font-medium w-40 text-right\">Modified</th>\n </tr>\n </thead>\n <tbody>\n {directories.map((dir) => (\n <tr\n key={dir}\n onClick={() => onNavigate(dir)}\n className=\"row-hover cursor-pointer group\"\n >\n <td className=\"py-2 pl-2\">\n <span className=\"flex items-center gap-2.5\">\n <Folder className=\"w-4 h-4 text-accent/75 shrink-0\" strokeWidth={1.5} />\n <span className=\"text-sm text-text-primary group-hover:text-accent transition-colors\">\n {dirName(dir)}\n </span>\n </span>\n </td>\n <td className=\"py-2 text-right text-xs text-text-tertiary\">&mdash;</td>\n <td className=\"py-2 pr-2 text-right text-xs text-text-tertiary\">&mdash;</td>\n </tr>\n ))}\n {files.map((file) => (\n <tr\n key={file.path}\n onClick={() => onSelect(file.path)}\n className={`row-hover cursor-pointer group ${\n selectedFile === file.path ? 'bg-surface-hover' : ''\n }`}\n >\n <td className=\"py-2 pl-2\">\n <span className=\"flex items-center gap-2.5\">\n {fileIcon(file.path)}\n <span className=\"text-sm text-text-primary truncate\">\n {fileNameFromPath(file.path)}\n </span>\n </span>\n </td>\n <td className=\"py-2 text-right text-xs text-text-secondary tabular-nums\">\n {formatSize(file.size)}\n </td>\n <td className=\"py-2 pr-2 text-right text-xs text-text-secondary\">\n <TimeAgo date={file.modified_at} />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n\nexport function GridView({ directories, files, onNavigate, onSelect, selectedFile }: ViewProps) {\n return (\n <div className=\"mt-4\">\n {/* Directories as compact list */}\n {directories.length > 0 && (\n <div className=\"flex flex-wrap gap-2 mb-6\">\n {directories.map((dir) => (\n <button\n key={dir}\n onClick={() => onNavigate(dir)}\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-md text-sm text-text-secondary hover:text-text-primary hover:bg-surface-hover transition-colors\"\n >\n <Folder className=\"w-4 h-4 text-accent/75\" strokeWidth={1.5} />\n <span>{dirName(dir)}</span>\n </button>\n ))}\n </div>\n )}\n\n {/* Files as thumbnail grid */}\n <div className=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3\">\n {files.map((file) => {\n const isImg = isImagePath(file.path);\n return (\n <button\n key={file.path}\n onClick={() => onSelect(file.path)}\n className={`group text-left rounded-lg overflow-hidden transition-all ${\n selectedFile === file.path\n ? 'ring-2 ring-accent/40 bg-surface-hover'\n : 'hover:bg-surface-hover'\n }`}\n >\n <div className=\"aspect-square bg-surface-sunken flex items-center justify-center overflow-hidden\">\n {isImg ? (\n <img\n src={getFilePreviewUrl(file.path)}\n alt={fileNameFromPath(file.path)}\n loading=\"lazy\"\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <div className=\"flex flex-col items-center gap-2 text-text-tertiary\">\n {fileIcon(file.path)}\n <span className=\"text-[10px] uppercase tracking-wider\">\n {file.path.split('.').pop()?.toUpperCase()}\n </span>\n </div>\n )}\n </div>\n <div className=\"px-2 py-1.5\">\n <p className=\"text-xs text-text-primary truncate\" title={fileNameFromPath(file.path)}>\n {fileNameFromPath(file.path)}\n </p>\n <p className=\"text-[10px] text-text-tertiary tabular-nums\">\n {formatSize(file.size)}\n </p>\n </div>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport {\n X,\n Download,\n ExternalLink,\n Link,\n Check,\n Trash2,\n} from 'lucide-react';\nimport { useFileMetadata, useFilePreviewUrl, useGenerateSignedUrl, useDeleteFile } from '../../api/files';\nimport { fileName, triggerDownload, TextPreview, FileMetadataDisplay } from './FilePreviewContent';\nimport { isImagePath } from './FileListViews';\n\ninterface FilePreviewPanelProps {\n filePath: string;\n onClose: () => void;\n onDeleted?: () => void;\n}\n\nconst EXPIRY_OPTIONS = [\n { label: '1 hour', value: 3600 },\n { label: '6 hours', value: 21600 },\n { label: '24 hours', value: 86400 },\n { label: '7 days', value: 604800 },\n { label: '30 days', value: 2592000 },\n];\n\nexport function FilePreviewPanel({ filePath, onClose, onDeleted }: FilePreviewPanelProps) {\n const { data: metadata, isLoading } = useFileMetadata(filePath);\n const signedUrlMutation = useGenerateSignedUrl();\n const deleteMutation = useDeleteFile();\n const [showShareMenu, setShowShareMenu] = useState(false);\n const [copied, setCopied] = useState(false);\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n const { data: previewUrl } = useFilePreviewUrl(filePath);\n const isImage = metadata?.content_type?.startsWith('image/') || isImagePath(filePath);\n const TEXT_EXTENSIONS = /\\.(ts|tsx|js|jsx|json|md|yaml|yml|toml|xml|csv|sql|sh|py|rb|go|rs|java|c|cpp|h|css|scss|html|txt|log|env|ini|cfg|conf)$/i;\n const isText = metadata?.content_type?.startsWith('text/')\n || metadata?.content_type === 'application/json'\n || metadata?.content_type === 'application/xml'\n || (metadata?.content_type === 'application/octet-stream' && TEXT_EXTENSIONS.test(filePath));\n const isPdf = metadata?.content_type === 'application/pdf';\n\n async function handleDownload() {\n try {\n const result = await signedUrlMutation.mutateAsync({ path: filePath, expiresIn: 3600 });\n const fullUrl = result.url.startsWith('http')\n ? result.url\n : `${window.location.origin}${result.url}`;\n triggerDownload(fullUrl, fileName(filePath));\n } catch {\n // handled by mutation state\n }\n }\n\n async function handleShare(expiresIn: number) {\n setShowShareMenu(false);\n try {\n const result = await signedUrlMutation.mutateAsync({ path: filePath, expiresIn });\n const fullUrl = result.url.startsWith('http')\n ? result.url\n : `${window.location.origin}${result.url}`;\n await navigator.clipboard.writeText(fullUrl);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n // handled by mutation state\n }\n }\n\n return (\n <>\n {/* Fullscreen — opens image in a new tab */}\n\n {/* Panel */}\n <div className=\"w-[380px] shrink-0 border-l border-surface-border bg-surface overflow-y-auto\">\n {/* Header */}\n <div className=\"sticky top-0 bg-surface z-10 px-5 pt-5 pb-3 border-b border-surface-border\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-medium text-text-primary truncate pr-2\" title={fileName(filePath)}>\n {fileName(filePath)}\n </h3>\n <button onClick={onClose} className=\"text-text-tertiary hover:text-text-primary shrink-0\">\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-1 flex-wrap\">\n <button\n onClick={handleDownload}\n className=\"btn-ghost flex items-center gap-1.5 !px-2.5 !py-1.5 text-xs\"\n title=\"Download\"\n >\n <Download className=\"w-3.5 h-3.5\" />\n <span>Download</span>\n </button>\n\n <a\n href={previewUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"btn-ghost flex items-center gap-1.5 !px-2.5 !py-1.5 text-xs\"\n title=\"Open in new tab\"\n >\n <ExternalLink className=\"w-3.5 h-3.5\" />\n <span>Open</span>\n </a>\n\n <div className=\"relative\">\n <button\n onClick={() => setShowShareMenu((v) => !v)}\n className=\"btn-ghost flex items-center gap-1.5 !px-2.5 !py-1.5 text-xs\"\n title=\"Share with signed URL\"\n >\n {copied ? <Check className=\"w-3.5 h-3.5 text-status-success\" /> : <Link className=\"w-3.5 h-3.5\" />}\n <span>{copied ? 'Copied' : 'Share'}</span>\n </button>\n {showShareMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-surface-raised border border-surface-border rounded-md shadow-lg py-1 z-20 min-w-[120px]\">\n {EXPIRY_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n onClick={() => handleShare(opt.value)}\n className=\"w-full text-left px-3 py-1.5 text-xs text-text-secondary hover:bg-surface-hover hover:text-text-primary transition-colors\"\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n <button\n onClick={() => setConfirmDelete(true)}\n className=\"btn-ghost flex items-center gap-1.5 !px-2.5 !py-1.5 text-xs text-status-error/70 hover:text-status-error\"\n title=\"Delete file\"\n >\n <Trash2 className=\"w-3.5 h-3.5\" />\n <span>Delete</span>\n </button>\n </div>\n\n {/* Delete confirmation */}\n {confirmDelete && (\n <div className=\"mt-3 p-3 bg-status-error/5 border border-status-error/20 rounded-md\">\n <p className=\"text-xs text-text-primary mb-2\">\n Permanently delete <span className=\"font-medium\">{fileName(filePath)}</span>? This cannot be undone.\n </p>\n <div className=\"flex gap-2\">\n <button\n onClick={() => setConfirmDelete(false)}\n className=\"btn-secondary text-xs\"\n disabled={deleteMutation.isPending}\n >\n Cancel\n </button>\n <button\n onClick={async () => {\n try {\n await deleteMutation.mutateAsync(filePath);\n setConfirmDelete(false);\n onDeleted?.();\n } catch {\n // error shown below\n }\n }}\n className=\"btn-primary text-xs !bg-status-error hover:!bg-status-error/90\"\n disabled={deleteMutation.isPending}\n >\n {deleteMutation.isPending ? 'Deleting...' : 'Delete'}\n </button>\n </div>\n {deleteMutation.isError && (\n <p className=\"text-xs text-status-error mt-2\">{deleteMutation.error.message}</p>\n )}\n </div>\n )}\n\n {signedUrlMutation.isError && (\n <p className=\"text-xs text-status-error mt-2\">{signedUrlMutation.error.message}</p>\n )}\n </div>\n\n {/* Preview area */}\n <div className=\"p-5\">\n {isLoading ? (\n <div className=\"animate-pulse space-y-3\">\n <div className=\"h-48 bg-surface-sunken rounded\" />\n <div className=\"h-4 bg-surface-sunken rounded w-2/3\" />\n </div>\n ) : (\n <>\n {isImage && previewUrl && (\n <div\n className=\"mb-5 rounded-md border border-surface-border bg-surface-sunken overflow-hidden\"\n style={{ maxHeight: '400px' }}\n >\n <img\n src={previewUrl}\n alt={fileName(filePath)}\n className=\"w-full object-cover object-top\"\n style={{ maxHeight: '400px' }}\n />\n </div>\n )}\n\n {isText && previewUrl && (\n <div className=\"mb-5\">\n <TextPreview url={previewUrl} />\n </div>\n )}\n\n {isPdf && previewUrl && (\n <div className=\"mb-5 p-4 bg-surface-sunken rounded-md text-center\">\n <a\n href={previewUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-accent hover:text-accent-hover text-sm font-medium\"\n >\n Open PDF in new tab\n </a>\n </div>\n )}\n\n {metadata && (\n <FileMetadataDisplay metadata={metadata} />\n )}\n </>\n )}\n </div>\n </div>\n </>\n );\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useSearchParams } from 'react-router-dom';\nimport {\n ChevronLeft,\n ChevronRight,\n Upload,\n UploadCloud,\n} from 'lucide-react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterInput } from '../../components/common/data/FilterBar';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { EmptyState } from '../../components/common/display/EmptyState';\nimport { DropZone } from '../../components/common/DropZone';\nimport { useFileBrowse, useUploadFile } from '../../api/files';\nimport { FileBreadcrumbs } from './FileBreadcrumbs';\nimport { FilePreviewPanel } from './FilePreviewPanel';\nimport { ListView } from './FileListViews';\n\nconst PAGE_SIZES = [25, 50, 100, 200];\n\nexport function FilesPage() {\n const [searchParams, setSearchParams] = useSearchParams();\n const prefix = searchParams.get('prefix') || '';\n const [search, setSearch] = useState('');\n const [debouncedSearch, setDebouncedSearch] = useState('');\n const [selectedFile, setSelectedFile] = useState<string | null>(null);\n const [pageSize, setPageSize] = useState(100);\n const [tokenStack, setTokenStack] = useState<string[]>([]);\n const [currentToken, setCurrentToken] = useState<string | undefined>();\n\n // Debounce search — refines the prefix sent to S3\n useEffect(() => {\n const t = setTimeout(() => {\n setDebouncedSearch(search);\n setCurrentToken(undefined);\n setTokenStack([]);\n }, 300);\n return () => clearTimeout(t);\n }, [search]);\n\n const effectivePrefix = debouncedSearch\n ? `${prefix}${debouncedSearch}`\n : prefix;\n\n const { data, isLoading, isFetching, refetch } = useFileBrowse(effectivePrefix, pageSize, currentToken);\n const uploadMutation = useUploadFile();\n const queryClient = useQueryClient();\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const [pendingFiles, setPendingFiles] = useState<File[] | null>(null);\n const [uploadPrefix, setUploadPrefix] = useState('');\n\n const handleUploadFiles = useCallback((files: File[]) => {\n setPendingFiles(files);\n setUploadPrefix(prefix);\n }, [prefix]);\n\n const [uploadError, setUploadError] = useState('');\n\n const confirmUpload = useCallback(() => {\n if (!pendingFiles) return;\n setUploadError('');\n let remaining = pendingFiles.length;\n for (const file of pendingFiles) {\n const targetPath = `${uploadPrefix}${file.name}`;\n uploadMutation.mutate({ path: targetPath, file }, {\n onSuccess: () => {\n remaining--;\n queryClient.invalidateQueries({ queryKey: ['fileBrowse'] });\n if (remaining <= 0) setPendingFiles(null);\n },\n onError: (err) => {\n remaining--;\n setUploadError(err.message);\n console.error('[Upload] failed:', targetPath, err);\n },\n });\n }\n }, [pendingFiles, uploadPrefix, uploadMutation, queryClient]);\n\n const directories = data?.directories ?? [];\n const files = data?.files ?? [];\n const nextToken = data?.nextToken;\n\n const navigateTo = useCallback((newPrefix: string) => {\n setSearch('');\n setDebouncedSearch('');\n setSelectedFile(null);\n setCurrentToken(undefined);\n setTokenStack([]);\n if (newPrefix) {\n setSearchParams({ prefix: newPrefix });\n } else {\n setSearchParams({});\n }\n }, [setSearchParams]);\n\n function goNextPage() {\n if (!nextToken) return;\n setTokenStack((prev) => [...prev, currentToken || '']);\n setCurrentToken(nextToken);\n }\n\n function goPrevPage() {\n if (tokenStack.length === 0) return;\n const prev = [...tokenStack];\n const token = prev.pop()!;\n setTokenStack(prev);\n setCurrentToken(token || undefined);\n }\n\n function changePageSize(size: number) {\n setPageSize(size);\n setCurrentToken(undefined);\n setTokenStack([]);\n }\n\n const isEmpty = directories.length === 0 && files.length === 0;\n const pageNum = tokenStack.length + 1;\n const hasNextPage = !!nextToken;\n const hasPrevPage = tokenStack.length > 0;\n\n const apiPath = `/file-browser/browse?prefix=${encodeURIComponent(effectivePrefix)}&pageSize=${pageSize}${currentToken ? `&continuationToken=${encodeURIComponent(currentToken)}` : ''}`;\n\n return (\n <DropZone onDrop={handleUploadFiles} label=\"Drop files to upload\">\n <div className=\"flex gap-0\">\n {/* Hidden file input for button-triggered upload */}\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n className=\"hidden\"\n onChange={(e) => {\n const files = Array.from(e.target.files || []);\n if (files.length) handleUploadFiles(files);\n e.target.value = '';\n }}\n />\n\n {/* Main content */}\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n <PageHeader\n title=\"Files\"\n docsHash=\"#docs:dashboard.md:files\"\n actions={\n <button\n onClick={() => fileInputRef.current?.click()}\n disabled={uploadMutation.isPending}\n className=\"btn-primary text-xs inline-flex items-center gap-1.5\"\n >\n <Upload className=\"w-3.5 h-3.5\" />\n {uploadMutation.isPending ? 'Uploading...' : 'Upload'}\n </button>\n }\n />\n\n <FileBreadcrumbs prefix={prefix} onNavigate={navigateTo} />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={apiPath}\n />\n }>\n <FilterInput\n label=\"Search\"\n value={search}\n onChange={setSearch}\n placeholder=\"Filter by prefix...\"\n />\n </FilterBar>\n\n {isLoading ? (\n <div className=\"animate-pulse space-y-2 mt-4\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"h-10 bg-surface-sunken rounded\" />\n ))}\n </div>\n ) : isEmpty ? (\n <div className=\"cursor-pointer\" onClick={() => fileInputRef.current?.click()}>\n <EmptyState\n icon={UploadCloud}\n title={search ? 'No matching files' : 'No files yet'}\n description={search ? undefined : 'Drop files here or click to upload'}\n />\n </div>\n ) : (\n <ListView\n directories={directories}\n files={files}\n onNavigate={navigateTo}\n onSelect={setSelectedFile}\n selectedFile={selectedFile}\n />\n )}\n\n {/* Cursor-based pagination */}\n {(hasPrevPage || hasNextPage || files.length > 0) && (\n <div className=\"flex items-center justify-between pt-4 pb-2\">\n <div className=\"flex items-center gap-4\">\n <p className=\"text-xs text-text-tertiary\">\n Page {pageNum} &middot; {files.length + directories.length} items\n </p>\n <select\n value={pageSize}\n onChange={(e) => changePageSize(parseInt(e.target.value))}\n className=\"select text-xs py-1\"\n >\n {PAGE_SIZES.map((size) => (\n <option key={size} value={size}>{size} / page</option>\n ))}\n </select>\n </div>\n {(hasPrevPage || hasNextPage) && (\n <div className=\"flex items-center gap-1\">\n <button\n onClick={goPrevPage}\n disabled={!hasPrevPage}\n className=\"btn-ghost text-xs disabled:opacity-30 disabled:cursor-not-allowed flex items-center gap-1\"\n >\n <ChevronLeft className=\"w-3.5 h-3.5\" />\n Previous\n </button>\n <button\n onClick={goNextPage}\n disabled={!hasNextPage}\n className=\"btn-ghost text-xs disabled:opacity-30 disabled:cursor-not-allowed flex items-center gap-1\"\n >\n Next\n <ChevronRight className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Preview panel */}\n {selectedFile && (\n <FilePreviewPanel\n filePath={selectedFile}\n onClose={() => setSelectedFile(null)}\n onDeleted={() => { setSelectedFile(null); refetch(); }}\n />\n )}\n </div>\n {/* Upload confirmation dialog */}\n {pendingFiles && createPortal(\n <>\n <div className=\"fixed inset-0 z-40 bg-black/30\" onClick={() => setPendingFiles(null)} />\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div className=\"bg-surface-raised border border-surface-border rounded-lg shadow-lg w-full max-w-sm\">\n <div className=\"px-5 py-4 border-b border-surface-border\">\n <h3 className=\"text-sm font-medium text-text-primary\">Upload {pendingFiles.length} file{pendingFiles.length > 1 ? 's' : ''}</h3>\n </div>\n <div className=\"px-5 py-4 space-y-3\">\n <div>\n <label className=\"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1\">Destination folder</label>\n <input\n type=\"text\"\n value={uploadPrefix}\n onChange={(e) => setUploadPrefix(e.target.value)}\n placeholder=\"e.g., images/ or leave empty for root\"\n className=\"input text-xs w-full font-mono\"\n />\n </div>\n <div className=\"text-[10px] text-text-quaternary space-y-0.5\">\n {pendingFiles.map((f, i) => (\n <p key={i} className=\"truncate\">{uploadPrefix}{f.name} <span className=\"text-text-tertiary\">({(f.size / 1024).toFixed(1)} KB)</span></p>\n ))}\n </div>\n {uploadError && <p className=\"text-xs text-status-error\">{uploadError}</p>}\n </div>\n <div className=\"flex justify-end gap-2 px-5 py-3 border-t border-surface-border\">\n <button onClick={() => setPendingFiles(null)} className=\"btn-ghost text-xs\">Cancel</button>\n <button onClick={confirmUpload} className=\"btn-primary text-xs\">\n <Upload className=\"w-3.5 h-3.5 mr-1.5 inline\" />\n Upload\n </button>\n </div>\n </div>\n </div>\n </>,\n document.body,\n )}\n </DropZone>\n );\n}\n"],"names":["useFileBrowse","prefix","pageSize","continuationToken","params","qs","useQuery","apiFetch","useFileMetadata","filePath","useGenerateSignedUrl","useMutation","data","useDeleteFile","useUploadFile","path","file","buffer","useFilePreviewUrl","FileBreadcrumbs","onNavigate","segments","jsxDEV","FolderOpen","segment","i","isLast","targetPrefix","ChevronRight","formatSize","bytes","fileName","MetaRow","label","value","mono","children","TextPreview","url","content","setContent","useState","error","setError","res","text","FileMetadataDisplay","metadata","copied","setCopied","copyToClipboard","Check","Copy","TimeAgo","triggerDownload","name","blob","blobUrl","a","fileIcon","ext","_a","Image","FileJson2","FileSpreadsheet","FileText","File","isImagePath","dirName","dirPath","stripped","fileNameFromPath","ListView","directories","files","onSelect","selectedFile","dir","Folder","EXPIRY_OPTIONS","FilePreviewPanel","onClose","onDeleted","isLoading","signedUrlMutation","deleteMutation","showShareMenu","setShowShareMenu","confirmDelete","setConfirmDelete","previewUrl","isImage","TEXT_EXTENSIONS","isText","_b","isPdf","handleDownload","result","fullUrl","handleShare","expiresIn","Fragment","X","Download","ExternalLink","v","Link","opt","Trash2","PAGE_SIZES","FilesPage","searchParams","setSearchParams","useSearchParams","search","setSearch","debouncedSearch","setDebouncedSearch","setSelectedFile","setPageSize","tokenStack","setTokenStack","currentToken","setCurrentToken","useEffect","t","effectivePrefix","isFetching","refetch","uploadMutation","queryClient","useQueryClient","fileInputRef","useRef","pendingFiles","setPendingFiles","uploadPrefix","setUploadPrefix","handleUploadFiles","useCallback","uploadError","setUploadError","confirmUpload","remaining","targetPath","err","nextToken","navigateTo","newPrefix","goNextPage","prev","goPrevPage","token","changePageSize","size","isEmpty","pageNum","hasNextPage","hasPrevPage","apiPath","DropZone","e","PageHeader","Upload","FilterBar","ListToolbar","FilterInput","_","EmptyState","UploadCloud","ChevronLeft","createPortal","f"],"mappings":"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"}
1
+ {"version":3,"file":"index-B9t_vpam.js","sources":["../../src/api/files.ts","../../src/pages/files/FileBreadcrumbs.tsx","../../src/pages/files/FilePreviewContent.tsx","../../src/pages/files/FileListViews.tsx","../../src/pages/files/FilePreviewPanel.tsx","../../src/pages/files/FilesPage.tsx"],"sourcesContent":["import { useQuery, useMutation } from '@tanstack/react-query';\nimport { apiFetch } from './client';\n\nexport interface FileEntry {\n path: string;\n size: number;\n modified_at: string;\n}\n\nexport interface BrowseResponse {\n files: FileEntry[];\n directories: string[];\n nextToken?: string;\n}\n\nexport interface FileMetadata {\n path: string;\n size: number;\n modified_at: string;\n content_type: string;\n}\n\nexport interface SignedUrlResponse {\n url: string;\n expiresAt: string;\n}\n\nexport function useFileBrowse(prefix: string, pageSize = 100, continuationToken?: string) {\n const params = new URLSearchParams();\n if (prefix) params.set('prefix', prefix);\n params.set('pageSize', String(pageSize));\n if (continuationToken) params.set('continuationToken', continuationToken);\n const qs = params.toString();\n\n return useQuery<BrowseResponse>({\n queryKey: ['fileBrowse', prefix, pageSize, continuationToken],\n queryFn: () => apiFetch(`/file-browser/browse?${qs}`),\n });\n}\n\nexport function useFileMetadata(filePath: string | null) {\n return useQuery<FileMetadata>({\n queryKey: ['fileMetadata', filePath],\n queryFn: () => apiFetch(`/file-browser/metadata/${filePath}`),\n enabled: !!filePath,\n });\n}\n\nexport function useGenerateSignedUrl() {\n return useMutation<SignedUrlResponse, Error, { path: string; expiresIn: number }>({\n mutationFn: (data) =>\n apiFetch('/file-browser/signed-url', {\n method: 'POST',\n body: JSON.stringify(data),\n }),\n });\n}\n\nexport function useDeleteFile() {\n return useMutation<{ deleted: boolean; path: string }, Error, string>({\n mutationFn: (filePath) =>\n apiFetch(`/file-browser/delete/${filePath}`, { method: 'DELETE' }),\n });\n}\n\nexport function useUploadFile() {\n return useMutation<{ path: string; size: number; content_type: string }, Error, { path: string; file: File }>({\n mutationFn: async ({ path, file }) => {\n const buffer = await file.arrayBuffer();\n // Always send as octet-stream to bypass Express JSON body parser\n return apiFetch(`/file-browser/upload?path=${encodeURIComponent(path)}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/octet-stream' },\n body: buffer,\n });\n },\n });\n}\n\nexport function useFilePreviewUrl(filePath: string | null) {\n return useQuery<string>({\n queryKey: ['filePreviewUrl', filePath],\n queryFn: async () => {\n const result = await apiFetch<SignedUrlResponse>('/file-browser/signed-url', {\n method: 'POST',\n body: JSON.stringify({ path: filePath, expiresIn: 3600 }),\n });\n return result.url;\n },\n enabled: !!filePath,\n staleTime: 50 * 60 * 1000, // cache for 50 min (token valid for 60)\n });\n}\n\n/** @deprecated Use useFilePreviewUrl() for signed access */\nexport function getFilePreviewUrl(filePath: string): string {\n return `/api/files/${filePath.replace(/^\\/+/, '')}`;\n}\n\nexport function getFileDownloadUrl(filePath: string): string {\n return `/api/file-browser/download/${filePath.replace(/^\\/+/, '')}`;\n}\n","import { ChevronRight, FolderOpen } from 'lucide-react';\n\ninterface FileBreadcrumbsProps {\n prefix: string;\n onNavigate: (prefix: string) => void;\n}\n\nexport function FileBreadcrumbs({ prefix, onNavigate }: FileBreadcrumbsProps) {\n const segments = prefix ? prefix.replace(/\\/+$/, '').split('/').filter(Boolean) : [];\n\n return (\n <nav className=\"flex items-center gap-1 text-sm mb-6 min-h-[28px]\">\n <button\n onClick={() => onNavigate('')}\n className={`flex items-center gap-1.5 px-1.5 py-0.5 rounded transition-colors ${\n segments.length === 0\n ? 'text-text-primary font-medium'\n : 'text-text-secondary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n <FolderOpen className=\"w-4 h-4 text-accent/75\" strokeWidth={1.5} />\n <span>Root</span>\n </button>\n\n {segments.map((segment, i) => {\n const isLast = i === segments.length - 1;\n const targetPrefix = segments.slice(0, i + 1).join('/') + '/';\n return (\n <span key={targetPrefix} className=\"flex items-center gap-1\">\n <ChevronRight className=\"w-3.5 h-3.5 text-text-tertiary\" />\n <button\n onClick={() => onNavigate(targetPrefix)}\n className={`px-1.5 py-0.5 rounded transition-colors ${\n isLast\n ? 'text-text-primary font-medium'\n : 'text-text-secondary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n {segment}\n </button>\n </span>\n );\n })}\n </nav>\n );\n}\n","import { useState } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { TimeAgo } from '../../components/common/display/TimeAgo';\n\ninterface FileMetadata {\n path: string;\n content_type: string;\n size: number;\n modified_at: string;\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\nexport function fileName(filePath: string): string {\n return filePath.split('/').pop() || filePath;\n}\n\nexport function MetaRow({ label, value, mono, children }: {\n label: string;\n value?: string;\n mono?: boolean;\n children?: React.ReactNode;\n}) {\n return (\n <div>\n <dt className=\"text-[10px] uppercase tracking-wider text-text-tertiary mb-0.5\">{label}</dt>\n <dd className={`text-sm text-text-secondary ${mono ? 'font-mono text-xs break-all' : ''}`}>\n {children || value}\n </dd>\n </div>\n );\n}\n\nexport function TextPreview({ url }: { url: string }) {\n const [content, setContent] = useState<string | null>(null);\n const [error, setError] = useState(false);\n\n if (content === null && !error) {\n fetch(url)\n .then((res) => {\n if (!res.ok) throw new Error();\n return res.text();\n })\n .then((text) => setContent(text.slice(0, 100_000)))\n .catch(() => setError(true));\n }\n\n if (error) return <p className=\"text-xs text-text-tertiary\">Could not load preview</p>;\n if (content === null) {\n return <div className=\"animate-pulse h-32 bg-surface-sunken rounded\" />;\n }\n\n return (\n <pre className=\"font-mono text-xs text-text-secondary bg-surface-sunken rounded-md p-3 overflow-x-auto max-h-[400px] overflow-y-auto whitespace-pre-wrap break-words\">\n {content}\n </pre>\n );\n}\n\nexport function FileMetadataDisplay({ metadata }: {\n metadata: FileMetadata;\n}) {\n const [copied, setCopied] = useState<string | null>(null);\n\n async function copyToClipboard(text: string, label: string) {\n await navigator.clipboard.writeText(text);\n setCopied(label);\n setTimeout(() => setCopied(null), 2000);\n }\n\n return (\n <div className=\"space-y-3\">\n <div>\n <dt className=\"text-[10px] uppercase tracking-wider text-text-tertiary mb-0.5\">Path</dt>\n <dd\n onClick={() => copyToClipboard(metadata.path, 'path')}\n className=\"group flex items-center gap-1.5 text-xs font-mono text-text-secondary break-all cursor-pointer hover:text-text-primary transition-colors\"\n title=\"Click to copy\"\n >\n <span className=\"flex-1\">{metadata.path}</span>\n {copied === 'path'\n ? <Check className=\"w-3.5 h-3.5 text-status-success shrink-0\" />\n : <Copy className=\"w-3.5 h-3.5 opacity-0 group-hover:opacity-100 text-text-tertiary shrink-0 transition-opacity\" />}\n </dd>\n </div>\n <MetaRow label=\"Type\" value={metadata.content_type} />\n <MetaRow label=\"Size\" value={formatSize(metadata.size)} />\n <MetaRow label=\"Modified\">\n <TimeAgo date={metadata.modified_at} />\n </MetaRow>\n </div>\n );\n}\n\nexport async function triggerDownload(url: string, name: string) {\n const res = await fetch(url);\n const blob = await res.blob();\n const blobUrl = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = blobUrl;\n a.download = name;\n a.style.display = 'none';\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(blobUrl);\n}\n","import {\n Folder,\n File,\n Image,\n FileText,\n FileJson2,\n FileSpreadsheet,\n} from 'lucide-react';\nimport { TimeAgo } from '../../components/common/display/TimeAgo';\nimport { getFilePreviewUrl } from '../../api/files';\n\nexport function formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\n\nexport function fileIcon(filePath: string) {\n const ext = filePath.split('.').pop()?.toLowerCase() || '';\n if (['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'].includes(ext)) {\n return <Image className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n }\n if (['json'].includes(ext)) {\n return <FileJson2 className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n }\n if (['csv', 'xlsx', 'xls'].includes(ext)) {\n return <FileSpreadsheet className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n }\n if (['txt', 'md', 'html', 'xml', 'yaml', 'yml', 'css', 'js', 'ts'].includes(ext)) {\n return <FileText className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n }\n return <File className=\"w-4 h-4 text-accent/60\" strokeWidth={1.5} />;\n}\n\nexport function isImagePath(filePath: string): boolean {\n const ext = filePath.split('.').pop()?.toLowerCase() || '';\n return ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'].includes(ext);\n}\n\nexport function dirName(dirPath: string): string {\n const stripped = dirPath.replace(/\\/+$/, '');\n return stripped.split('/').pop() || stripped;\n}\n\nexport function fileNameFromPath(filePath: string): string {\n return filePath.split('/').pop() || filePath;\n}\n\ninterface ViewProps {\n directories: string[];\n files: Array<{ path: string; size: number; modified_at: string }>;\n onNavigate: (prefix: string) => void;\n onSelect: (path: string) => void;\n selectedFile: string | null;\n}\n\nexport function ListView({ directories, files, onNavigate, onSelect, selectedFile }: ViewProps) {\n return (\n <table className=\"w-full mt-2\">\n <thead>\n <tr className=\"text-left text-[10px] uppercase tracking-wider text-text-tertiary\">\n <th className=\"pb-2 pl-2 font-medium\">Name</th>\n <th className=\"pb-2 font-medium w-24 text-right\">Size</th>\n <th className=\"pb-2 pr-2 font-medium w-40 text-right\">Modified</th>\n </tr>\n </thead>\n <tbody>\n {directories.map((dir) => (\n <tr\n key={dir}\n onClick={() => onNavigate(dir)}\n className=\"row-hover cursor-pointer group\"\n >\n <td className=\"py-2 pl-2\">\n <span className=\"flex items-center gap-2.5\">\n <Folder className=\"w-4 h-4 text-accent/75 shrink-0\" strokeWidth={1.5} />\n <span className=\"text-sm text-text-primary group-hover:text-accent transition-colors\">\n {dirName(dir)}\n </span>\n </span>\n </td>\n <td className=\"py-2 text-right text-xs text-text-tertiary\">&mdash;</td>\n <td className=\"py-2 pr-2 text-right text-xs text-text-tertiary\">&mdash;</td>\n </tr>\n ))}\n {files.map((file) => (\n <tr\n key={file.path}\n onClick={() => onSelect(file.path)}\n className={`row-hover cursor-pointer group ${\n selectedFile === file.path ? 'bg-surface-hover' : ''\n }`}\n >\n <td className=\"py-2 pl-2\">\n <span className=\"flex items-center gap-2.5\">\n {fileIcon(file.path)}\n <span className=\"text-sm text-text-primary truncate\">\n {fileNameFromPath(file.path)}\n </span>\n </span>\n </td>\n <td className=\"py-2 text-right text-xs text-text-secondary tabular-nums\">\n {formatSize(file.size)}\n </td>\n <td className=\"py-2 pr-2 text-right text-xs text-text-secondary\">\n <TimeAgo date={file.modified_at} />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n\nexport function GridView({ directories, files, onNavigate, onSelect, selectedFile }: ViewProps) {\n return (\n <div className=\"mt-4\">\n {/* Directories as compact list */}\n {directories.length > 0 && (\n <div className=\"flex flex-wrap gap-2 mb-6\">\n {directories.map((dir) => (\n <button\n key={dir}\n onClick={() => onNavigate(dir)}\n className=\"flex items-center gap-2 px-3 py-1.5 rounded-md text-sm text-text-secondary hover:text-text-primary hover:bg-surface-hover transition-colors\"\n >\n <Folder className=\"w-4 h-4 text-accent/75\" strokeWidth={1.5} />\n <span>{dirName(dir)}</span>\n </button>\n ))}\n </div>\n )}\n\n {/* Files as thumbnail grid */}\n <div className=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3\">\n {files.map((file) => {\n const isImg = isImagePath(file.path);\n return (\n <button\n key={file.path}\n onClick={() => onSelect(file.path)}\n className={`group text-left rounded-lg overflow-hidden transition-all ${\n selectedFile === file.path\n ? 'ring-2 ring-accent/40 bg-surface-hover'\n : 'hover:bg-surface-hover'\n }`}\n >\n <div className=\"aspect-square bg-surface-sunken flex items-center justify-center overflow-hidden\">\n {isImg ? (\n <img\n src={getFilePreviewUrl(file.path)}\n alt={fileNameFromPath(file.path)}\n loading=\"lazy\"\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <div className=\"flex flex-col items-center gap-2 text-text-tertiary\">\n {fileIcon(file.path)}\n <span className=\"text-[10px] uppercase tracking-wider\">\n {file.path.split('.').pop()?.toUpperCase()}\n </span>\n </div>\n )}\n </div>\n <div className=\"px-2 py-1.5\">\n <p className=\"text-xs text-text-primary truncate\" title={fileNameFromPath(file.path)}>\n {fileNameFromPath(file.path)}\n </p>\n <p className=\"text-[10px] text-text-tertiary tabular-nums\">\n {formatSize(file.size)}\n </p>\n </div>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","import { useState } from 'react';\nimport {\n X,\n Download,\n ExternalLink,\n Link,\n Check,\n Trash2,\n} from 'lucide-react';\nimport { useFileMetadata, useFilePreviewUrl, useGenerateSignedUrl, useDeleteFile } from '../../api/files';\nimport { fileName, triggerDownload, TextPreview, FileMetadataDisplay } from './FilePreviewContent';\nimport { isImagePath } from './FileListViews';\n\ninterface FilePreviewPanelProps {\n filePath: string;\n onClose: () => void;\n onDeleted?: () => void;\n}\n\nconst EXPIRY_OPTIONS = [\n { label: '1 hour', value: 3600 },\n { label: '6 hours', value: 21600 },\n { label: '24 hours', value: 86400 },\n { label: '7 days', value: 604800 },\n { label: '30 days', value: 2592000 },\n];\n\nexport function FilePreviewPanel({ filePath, onClose, onDeleted }: FilePreviewPanelProps) {\n const { data: metadata, isLoading } = useFileMetadata(filePath);\n const signedUrlMutation = useGenerateSignedUrl();\n const deleteMutation = useDeleteFile();\n const [showShareMenu, setShowShareMenu] = useState(false);\n const [copied, setCopied] = useState(false);\n const [confirmDelete, setConfirmDelete] = useState(false);\n\n const { data: previewUrl } = useFilePreviewUrl(filePath);\n const isImage = metadata?.content_type?.startsWith('image/') || isImagePath(filePath);\n const TEXT_EXTENSIONS = /\\.(ts|tsx|js|jsx|json|md|yaml|yml|toml|xml|csv|sql|sh|py|rb|go|rs|java|c|cpp|h|css|scss|html|txt|log|env|ini|cfg|conf)$/i;\n const isText = metadata?.content_type?.startsWith('text/')\n || metadata?.content_type === 'application/json'\n || metadata?.content_type === 'application/xml'\n || (metadata?.content_type === 'application/octet-stream' && TEXT_EXTENSIONS.test(filePath));\n const isPdf = metadata?.content_type === 'application/pdf';\n\n async function handleDownload() {\n try {\n const result = await signedUrlMutation.mutateAsync({ path: filePath, expiresIn: 3600 });\n const fullUrl = result.url.startsWith('http')\n ? result.url\n : `${window.location.origin}${result.url}`;\n triggerDownload(fullUrl, fileName(filePath));\n } catch {\n // handled by mutation state\n }\n }\n\n async function handleShare(expiresIn: number) {\n setShowShareMenu(false);\n try {\n const result = await signedUrlMutation.mutateAsync({ path: filePath, expiresIn });\n const fullUrl = result.url.startsWith('http')\n ? result.url\n : `${window.location.origin}${result.url}`;\n await navigator.clipboard.writeText(fullUrl);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n // handled by mutation state\n }\n }\n\n return (\n <>\n {/* Fullscreen — opens image in a new tab */}\n\n {/* Panel */}\n <div className=\"w-[380px] shrink-0 border-l border-surface-border bg-surface overflow-y-auto\">\n {/* Header */}\n <div className=\"sticky top-0 bg-surface z-10 px-5 pt-5 pb-3 border-b border-surface-border\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-medium text-text-primary truncate pr-2\" title={fileName(filePath)}>\n {fileName(filePath)}\n </h3>\n <button onClick={onClose} className=\"text-text-tertiary hover:text-text-primary shrink-0\">\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-1 flex-wrap\">\n <button\n onClick={handleDownload}\n className=\"btn-ghost flex items-center gap-1.5 !px-2.5 !py-1.5 text-xs\"\n title=\"Download\"\n >\n <Download className=\"w-3.5 h-3.5\" />\n <span>Download</span>\n </button>\n\n <a\n href={previewUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"btn-ghost flex items-center gap-1.5 !px-2.5 !py-1.5 text-xs\"\n title=\"Open in new tab\"\n >\n <ExternalLink className=\"w-3.5 h-3.5\" />\n <span>Open</span>\n </a>\n\n <div className=\"relative\">\n <button\n onClick={() => setShowShareMenu((v) => !v)}\n className=\"btn-ghost flex items-center gap-1.5 !px-2.5 !py-1.5 text-xs\"\n title=\"Share with signed URL\"\n >\n {copied ? <Check className=\"w-3.5 h-3.5 text-status-success\" /> : <Link className=\"w-3.5 h-3.5\" />}\n <span>{copied ? 'Copied' : 'Share'}</span>\n </button>\n {showShareMenu && (\n <div className=\"absolute top-full left-0 mt-1 bg-surface-raised border border-surface-border rounded-md shadow-lg py-1 z-20 min-w-[120px]\">\n {EXPIRY_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n onClick={() => handleShare(opt.value)}\n className=\"w-full text-left px-3 py-1.5 text-xs text-text-secondary hover:bg-surface-hover hover:text-text-primary transition-colors\"\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n <button\n onClick={() => setConfirmDelete(true)}\n className=\"btn-ghost flex items-center gap-1.5 !px-2.5 !py-1.5 text-xs text-status-error/70 hover:text-status-error\"\n title=\"Delete file\"\n >\n <Trash2 className=\"w-3.5 h-3.5\" />\n <span>Delete</span>\n </button>\n </div>\n\n {/* Delete confirmation */}\n {confirmDelete && (\n <div className=\"mt-3 p-3 bg-status-error/5 border border-status-error/20 rounded-md\">\n <p className=\"text-xs text-text-primary mb-2\">\n Permanently delete <span className=\"font-medium\">{fileName(filePath)}</span>? This cannot be undone.\n </p>\n <div className=\"flex gap-2\">\n <button\n onClick={() => setConfirmDelete(false)}\n className=\"btn-secondary text-xs\"\n disabled={deleteMutation.isPending}\n >\n Cancel\n </button>\n <button\n onClick={async () => {\n try {\n await deleteMutation.mutateAsync(filePath);\n setConfirmDelete(false);\n onDeleted?.();\n } catch {\n // error shown below\n }\n }}\n className=\"btn-primary text-xs !bg-status-error hover:!bg-status-error/90\"\n disabled={deleteMutation.isPending}\n >\n {deleteMutation.isPending ? 'Deleting...' : 'Delete'}\n </button>\n </div>\n {deleteMutation.isError && (\n <p className=\"text-xs text-status-error mt-2\">{deleteMutation.error.message}</p>\n )}\n </div>\n )}\n\n {signedUrlMutation.isError && (\n <p className=\"text-xs text-status-error mt-2\">{signedUrlMutation.error.message}</p>\n )}\n </div>\n\n {/* Preview area */}\n <div className=\"p-5\">\n {isLoading ? (\n <div className=\"animate-pulse space-y-3\">\n <div className=\"h-48 bg-surface-sunken rounded\" />\n <div className=\"h-4 bg-surface-sunken rounded w-2/3\" />\n </div>\n ) : (\n <>\n {isImage && previewUrl && (\n <div\n className=\"mb-5 rounded-md border border-surface-border bg-surface-sunken overflow-hidden\"\n style={{ maxHeight: '400px' }}\n >\n <img\n src={previewUrl}\n alt={fileName(filePath)}\n className=\"w-full object-cover object-top\"\n style={{ maxHeight: '400px' }}\n />\n </div>\n )}\n\n {isText && previewUrl && (\n <div className=\"mb-5\">\n <TextPreview url={previewUrl} />\n </div>\n )}\n\n {isPdf && previewUrl && (\n <div className=\"mb-5 p-4 bg-surface-sunken rounded-md text-center\">\n <a\n href={previewUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-accent hover:text-accent-hover text-sm font-medium\"\n >\n Open PDF in new tab\n </a>\n </div>\n )}\n\n {metadata && (\n <FileMetadataDisplay metadata={metadata} />\n )}\n </>\n )}\n </div>\n </div>\n </>\n );\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useSearchParams } from 'react-router-dom';\nimport {\n ChevronLeft,\n ChevronRight,\n Upload,\n UploadCloud,\n} from 'lucide-react';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterInput } from '../../components/common/data/FilterBar';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { EmptyState } from '../../components/common/display/EmptyState';\nimport { DropZone } from '../../components/common/DropZone';\nimport { useFileBrowse, useUploadFile } from '../../api/files';\nimport { FileBreadcrumbs } from './FileBreadcrumbs';\nimport { FilePreviewPanel } from './FilePreviewPanel';\nimport { ListView } from './FileListViews';\n\nconst PAGE_SIZES = [25, 50, 100, 200];\n\nexport function FilesPage() {\n const [searchParams, setSearchParams] = useSearchParams();\n const prefix = searchParams.get('prefix') || '';\n const [search, setSearch] = useState('');\n const [debouncedSearch, setDebouncedSearch] = useState('');\n const [selectedFile, setSelectedFile] = useState<string | null>(null);\n const [pageSize, setPageSize] = useState(100);\n const [tokenStack, setTokenStack] = useState<string[]>([]);\n const [currentToken, setCurrentToken] = useState<string | undefined>();\n\n // Debounce search — refines the prefix sent to S3\n useEffect(() => {\n const t = setTimeout(() => {\n setDebouncedSearch(search);\n setCurrentToken(undefined);\n setTokenStack([]);\n }, 300);\n return () => clearTimeout(t);\n }, [search]);\n\n const effectivePrefix = debouncedSearch\n ? `${prefix}${debouncedSearch}`\n : prefix;\n\n const { data, isLoading, isFetching, refetch } = useFileBrowse(effectivePrefix, pageSize, currentToken);\n const uploadMutation = useUploadFile();\n const queryClient = useQueryClient();\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const [pendingFiles, setPendingFiles] = useState<File[] | null>(null);\n const [uploadPrefix, setUploadPrefix] = useState('');\n\n const handleUploadFiles = useCallback((files: File[]) => {\n setPendingFiles(files);\n setUploadPrefix(prefix);\n }, [prefix]);\n\n const [uploadError, setUploadError] = useState('');\n\n const confirmUpload = useCallback(() => {\n if (!pendingFiles) return;\n setUploadError('');\n let remaining = pendingFiles.length;\n for (const file of pendingFiles) {\n const targetPath = `${uploadPrefix}${file.name}`;\n uploadMutation.mutate({ path: targetPath, file }, {\n onSuccess: () => {\n remaining--;\n queryClient.invalidateQueries({ queryKey: ['fileBrowse'] });\n if (remaining <= 0) setPendingFiles(null);\n },\n onError: (err) => {\n remaining--;\n setUploadError(err.message);\n console.error('[Upload] failed:', targetPath, err);\n },\n });\n }\n }, [pendingFiles, uploadPrefix, uploadMutation, queryClient]);\n\n const directories = data?.directories ?? [];\n const files = data?.files ?? [];\n const nextToken = data?.nextToken;\n\n const navigateTo = useCallback((newPrefix: string) => {\n setSearch('');\n setDebouncedSearch('');\n setSelectedFile(null);\n setCurrentToken(undefined);\n setTokenStack([]);\n if (newPrefix) {\n setSearchParams({ prefix: newPrefix });\n } else {\n setSearchParams({});\n }\n }, [setSearchParams]);\n\n function goNextPage() {\n if (!nextToken) return;\n setTokenStack((prev) => [...prev, currentToken || '']);\n setCurrentToken(nextToken);\n }\n\n function goPrevPage() {\n if (tokenStack.length === 0) return;\n const prev = [...tokenStack];\n const token = prev.pop()!;\n setTokenStack(prev);\n setCurrentToken(token || undefined);\n }\n\n function changePageSize(size: number) {\n setPageSize(size);\n setCurrentToken(undefined);\n setTokenStack([]);\n }\n\n const isEmpty = directories.length === 0 && files.length === 0;\n const pageNum = tokenStack.length + 1;\n const hasNextPage = !!nextToken;\n const hasPrevPage = tokenStack.length > 0;\n\n const apiPath = `/file-browser/browse?prefix=${encodeURIComponent(effectivePrefix)}&pageSize=${pageSize}${currentToken ? `&continuationToken=${encodeURIComponent(currentToken)}` : ''}`;\n\n return (\n <DropZone onDrop={handleUploadFiles} label=\"Drop files to upload\">\n <div className=\"flex gap-0\">\n {/* Hidden file input for button-triggered upload */}\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n className=\"hidden\"\n onChange={(e) => {\n const files = Array.from(e.target.files || []);\n if (files.length) handleUploadFiles(files);\n e.target.value = '';\n }}\n />\n\n {/* Main content */}\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n <PageHeader\n title=\"Files\"\n docsHash=\"#docs:dashboard.md:files\"\n actions={\n <button\n onClick={() => fileInputRef.current?.click()}\n disabled={uploadMutation.isPending}\n className=\"btn-primary text-xs inline-flex items-center gap-1.5\"\n >\n <Upload className=\"w-3.5 h-3.5\" />\n {uploadMutation.isPending ? 'Uploading...' : 'Upload'}\n </button>\n }\n />\n\n <FileBreadcrumbs prefix={prefix} onNavigate={navigateTo} />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={apiPath}\n />\n }>\n <FilterInput\n label=\"Search\"\n value={search}\n onChange={setSearch}\n placeholder=\"Filter by prefix...\"\n />\n </FilterBar>\n\n {isLoading ? (\n <div className=\"animate-pulse space-y-2 mt-4\">\n {Array.from({ length: 6 }).map((_, i) => (\n <div key={i} className=\"h-10 bg-surface-sunken rounded\" />\n ))}\n </div>\n ) : isEmpty ? (\n <div className=\"cursor-pointer\" onClick={() => fileInputRef.current?.click()}>\n <EmptyState\n icon={UploadCloud}\n title={search ? 'No matching files' : 'No files yet'}\n description={search ? undefined : 'Drop files here or click to upload'}\n />\n </div>\n ) : (\n <ListView\n directories={directories}\n files={files}\n onNavigate={navigateTo}\n onSelect={setSelectedFile}\n selectedFile={selectedFile}\n />\n )}\n\n {/* Cursor-based pagination */}\n {(hasPrevPage || hasNextPage || files.length > 0) && (\n <div className=\"flex items-center justify-between pt-4 pb-2\">\n <div className=\"flex items-center gap-4\">\n <p className=\"text-xs text-text-tertiary\">\n Page {pageNum} &middot; {files.length + directories.length} items\n </p>\n <select\n value={pageSize}\n onChange={(e) => changePageSize(parseInt(e.target.value))}\n className=\"select text-xs py-1\"\n >\n {PAGE_SIZES.map((size) => (\n <option key={size} value={size}>{size} / page</option>\n ))}\n </select>\n </div>\n {(hasPrevPage || hasNextPage) && (\n <div className=\"flex items-center gap-1\">\n <button\n onClick={goPrevPage}\n disabled={!hasPrevPage}\n className=\"btn-ghost text-xs disabled:opacity-30 disabled:cursor-not-allowed flex items-center gap-1\"\n >\n <ChevronLeft className=\"w-3.5 h-3.5\" />\n Previous\n </button>\n <button\n onClick={goNextPage}\n disabled={!hasNextPage}\n className=\"btn-ghost text-xs disabled:opacity-30 disabled:cursor-not-allowed flex items-center gap-1\"\n >\n Next\n <ChevronRight className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Preview panel */}\n {selectedFile && (\n <FilePreviewPanel\n filePath={selectedFile}\n onClose={() => setSelectedFile(null)}\n onDeleted={() => { setSelectedFile(null); refetch(); }}\n />\n )}\n </div>\n {/* Upload confirmation dialog */}\n {pendingFiles && createPortal(\n <>\n <div className=\"fixed inset-0 z-40 bg-black/30\" onClick={() => setPendingFiles(null)} />\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <div className=\"bg-surface-raised border border-surface-border rounded-lg shadow-lg w-full max-w-sm\">\n <div className=\"px-5 py-4 border-b border-surface-border\">\n <h3 className=\"text-sm font-medium text-text-primary\">Upload {pendingFiles.length} file{pendingFiles.length > 1 ? 's' : ''}</h3>\n </div>\n <div className=\"px-5 py-4 space-y-3\">\n <div>\n <label className=\"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1\">Destination folder</label>\n <input\n type=\"text\"\n value={uploadPrefix}\n onChange={(e) => setUploadPrefix(e.target.value)}\n placeholder=\"e.g., images/ or leave empty for root\"\n className=\"input text-xs w-full font-mono\"\n />\n </div>\n <div className=\"text-[10px] text-text-quaternary space-y-0.5\">\n {pendingFiles.map((f, i) => (\n <p key={i} className=\"truncate\">{uploadPrefix}{f.name} <span className=\"text-text-tertiary\">({(f.size / 1024).toFixed(1)} KB)</span></p>\n ))}\n </div>\n {uploadError && <p className=\"text-xs text-status-error\">{uploadError}</p>}\n </div>\n <div className=\"flex justify-end gap-2 px-5 py-3 border-t border-surface-border\">\n <button onClick={() => setPendingFiles(null)} className=\"btn-ghost text-xs\">Cancel</button>\n <button onClick={confirmUpload} className=\"btn-primary text-xs\">\n <Upload className=\"w-3.5 h-3.5 mr-1.5 inline\" />\n Upload\n </button>\n </div>\n </div>\n </div>\n </>,\n document.body,\n )}\n </DropZone>\n );\n}\n"],"names":["useFileBrowse","prefix","pageSize","continuationToken","params","qs","useQuery","apiFetch","useFileMetadata","filePath","useGenerateSignedUrl","useMutation","data","useDeleteFile","useUploadFile","path","file","buffer","useFilePreviewUrl","FileBreadcrumbs","onNavigate","segments","jsxs","jsx","FolderOpen","segment","i","isLast","targetPrefix","ChevronRight","formatSize","bytes","fileName","MetaRow","label","value","mono","children","TextPreview","url","content","setContent","useState","error","setError","res","text","FileMetadataDisplay","metadata","copied","setCopied","copyToClipboard","Check","Copy","TimeAgo","triggerDownload","name","blob","blobUrl","a","fileIcon","ext","_a","Image","FileJson2","FileSpreadsheet","FileText","File","isImagePath","dirName","dirPath","stripped","fileNameFromPath","ListView","directories","files","onSelect","selectedFile","dir","Folder","EXPIRY_OPTIONS","FilePreviewPanel","onClose","onDeleted","isLoading","signedUrlMutation","deleteMutation","showShareMenu","setShowShareMenu","confirmDelete","setConfirmDelete","previewUrl","isImage","TEXT_EXTENSIONS","isText","_b","isPdf","handleDownload","result","fullUrl","handleShare","expiresIn","Fragment","X","Download","ExternalLink","v","Link","opt","Trash2","PAGE_SIZES","FilesPage","searchParams","setSearchParams","useSearchParams","search","setSearch","debouncedSearch","setDebouncedSearch","setSelectedFile","setPageSize","tokenStack","setTokenStack","currentToken","setCurrentToken","useEffect","t","effectivePrefix","isFetching","refetch","uploadMutation","queryClient","useQueryClient","fileInputRef","useRef","pendingFiles","setPendingFiles","uploadPrefix","setUploadPrefix","handleUploadFiles","useCallback","uploadError","setUploadError","confirmUpload","remaining","targetPath","err","nextToken","navigateTo","newPrefix","goNextPage","prev","goPrevPage","token","changePageSize","size","isEmpty","pageNum","hasNextPage","hasPrevPage","apiPath","DropZone","e","PageHeader","Upload","FilterBar","ListToolbar","FilterInput","_","EmptyState","UploadCloud","ChevronLeft","createPortal","f"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{a as n,j as t}from"./vendor-query-B2UbickB.js";import{h}from"./workflows-DFR0-hI3.js";import{D as g}from"./DataTable-D9yuBv0w.js";import{F as y,b as j}from"./FilterBar-Ck4K4rzu.js";import{R as q,a as u}from"./RowActions-Dg-Fsm5O.js";import{u as C}from"./useFilterParams-DZCAaBC7.js";import{P as R}from"./PageHeader-DlzOOM4Y.js";import{T as b}from"./TaskQueuePill-D8UMH1rd.js";import{W as _}from"./WorkflowPill-h43nlUmM.js";import{a9 as v,ac as N,Y as I}from"./vendor-icons-DY1ctJgc.js";import{c as P}from"./vendor-react-CX88sFS5.js";import"./index-BhhWCADo.js";import"./EmptyState-BcsfPq9T.js";function H(){const r=P(),{data:c,isLoading:m}=h(),{filters:s,setFilter:i}=C({filters:{search:"",queue:""}}),[a,p]=n.useState(s.search);n.useEffect(()=>{if(a===s.search)return;const e=setTimeout(()=>i("search",a),300);return()=>clearTimeout(e)},[a,i,s.search]);const o=c??[],d=n.useMemo(()=>[...new Set(o.map(e=>e.task_queue).filter(Boolean))].sort(),[o]),f=n.useMemo(()=>{let e=o;if(s.search){const l=s.search.toLowerCase();e=e.filter(w=>w.name.toLowerCase().includes(l))}return s.queue&&(e=e.filter(l=>l.task_queue===s.queue)),e},[o,s]),k=[{key:"name",label:"Workflow",render:e=>t.jsx(_,{type:e.name})},{key:"task_queue",label:"Queue",render:e=>t.jsx(b,{queue:e.task_queue}),className:"whitespace-nowrap"},{key:"registered",label:"Status",render:e=>e.registered?t.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-accent/10 text-accent",children:[t.jsx(v,{className:"w-3 h-3"}),"Certified"]}):t.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-surface-sunken text-text-tertiary",children:"Durable"}),className:"whitespace-nowrap"},{key:"actions",label:"",render:e=>t.jsx(q,{children:e.registered?t.jsx(u,{icon:N,title:"View config",onClick:()=>r(`/workflows/registry/${encodeURIComponent(e.name)}`)}):t.jsx(u,{icon:I,title:"Register workflow",onClick:()=>r(`/workflows/registry/new?workflow_type=${encodeURIComponent(e.name)}&task_queue=${encodeURIComponent(e.task_queue)}`)})}),className:"w-16 text-right"}],x=e=>{e.registered?r(`/workflows/registry/${encodeURIComponent(e.name)}`):r(`/workflows/registry/new?workflow_type=${encodeURIComponent(e.name)}&task_queue=${encodeURIComponent(e.task_queue)}`)};return t.jsxs("div",{children:[t.jsx(R,{title:"Workers",docsHash:"#docs:dashboard.md:task-queues"}),t.jsxs(y,{children:[t.jsx("input",{type:"text",placeholder:"Search workers...",value:a,onChange:e=>p(e.target.value),className:"input text-[11px] py-1 px-2 w-56"}),t.jsx(j,{label:"Queue",value:s.queue,onChange:e=>i("queue",e),options:d.map(e=>({value:e,label:e}))})]}),t.jsx(g,{columns:k,data:f,keyFn:e=>e.name,onRowClick:x,isLoading:m,emptyMessage:"No active workers"})]})}export{H as WorkersPage};
2
+ //# sourceMappingURL=index-Bh9g-EOF.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-CS61sh5q.js","sources":["../../src/pages/workflows/workers/WorkersPage.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus, Eye, ShieldCheck } from 'lucide-react';\nimport { useActiveWorkers } from '../../../api/workflows';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport type { ActiveWorker } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { TaskQueuePill } from '../../../components/common/display/TaskQueuePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkersPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useActiveWorkers();\n const { filters, setFilter } = useFilterParams({\n filters: { search: '', queue: '' },\n });\n\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const allWorkers = data ?? [];\n\n const queues = useMemo(\n () => [...new Set(allWorkers.map((w) => w.task_queue).filter(Boolean))].sort(),\n [allWorkers],\n );\n\n const workers = useMemo(() => {\n let result = allWorkers;\n if (filters.search) {\n const q = filters.search.toLowerCase();\n result = result.filter((w) => w.name.toLowerCase().includes(q));\n }\n if (filters.queue) result = result.filter((w) => w.task_queue === filters.queue);\n return result;\n }, [allWorkers, filters]);\n\n const columns: Column<ActiveWorker>[] = [\n {\n key: 'name',\n label: 'Workflow',\n render: (row) => <WorkflowPill type={row.name} />,\n },\n {\n key: 'task_queue',\n label: 'Queue',\n render: (row) => <TaskQueuePill queue={row.task_queue} />,\n className: 'whitespace-nowrap',\n },\n {\n key: 'registered',\n label: 'Status',\n render: (row) => row.registered\n ? <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-accent/10 text-accent\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>\n : <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-surface-sunken text-text-tertiary\">Durable</span>,\n className: 'whitespace-nowrap',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n {row.registered ? (\n <RowAction\n icon={Eye}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.name)}`)}\n />\n ) : (\n <RowAction\n icon={Plus}\n title=\"Register workflow\"\n onClick={() => navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-16 text-right',\n },\n ];\n\n const handleRowClick = (row: ActiveWorker) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.name)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`);\n }\n };\n\n return (\n <div>\n <PageHeader title=\"Workers\" docsHash=\"#docs:dashboard.md:task-queues\" />\n\n <FilterBar>\n <input\n type=\"text\"\n placeholder=\"Search workers...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-[11px] py-1 px-2 w-56\"\n />\n <FilterSelect\n label=\"Queue\"\n value={filters.queue}\n onChange={(v) => setFilter('queue', v)}\n options={queues.map((q) => ({ value: q, label: q }))}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={workers}\n keyFn={(row) => row.name}\n onRowClick={handleRowClick}\n isLoading={isLoading}\n emptyMessage=\"No active workers\"\n />\n </div>\n );\n}\n"],"names":["WorkersPage","navigate","useNavigate","data","isLoading","useActiveWorkers","filters","setFilter","useFilterParams","searchInput","setSearchInput","useState","useEffect","timer","allWorkers","queues","useMemo","w","workers","result","q","columns","row","WorkflowPill","TaskQueuePill","jsxDEV","ShieldCheck","RowActionGroup","RowAction","Eye","Plus","handleRowClick","PageHeader","FilterBar","FilterSelect","v","DataTable"],"mappings":"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"}
1
+ {"version":3,"file":"index-Bh9g-EOF.js","sources":["../../src/pages/workflows/workers/WorkersPage.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus, Eye, ShieldCheck } from 'lucide-react';\nimport { useActiveWorkers } from '../../../api/workflows';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport type { ActiveWorker } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { TaskQueuePill } from '../../../components/common/display/TaskQueuePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkersPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useActiveWorkers();\n const { filters, setFilter } = useFilterParams({\n filters: { search: '', queue: '' },\n });\n\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const allWorkers = data ?? [];\n\n const queues = useMemo(\n () => [...new Set(allWorkers.map((w) => w.task_queue).filter(Boolean))].sort(),\n [allWorkers],\n );\n\n const workers = useMemo(() => {\n let result = allWorkers;\n if (filters.search) {\n const q = filters.search.toLowerCase();\n result = result.filter((w) => w.name.toLowerCase().includes(q));\n }\n if (filters.queue) result = result.filter((w) => w.task_queue === filters.queue);\n return result;\n }, [allWorkers, filters]);\n\n const columns: Column<ActiveWorker>[] = [\n {\n key: 'name',\n label: 'Workflow',\n render: (row) => <WorkflowPill type={row.name} />,\n },\n {\n key: 'task_queue',\n label: 'Queue',\n render: (row) => <TaskQueuePill queue={row.task_queue} />,\n className: 'whitespace-nowrap',\n },\n {\n key: 'registered',\n label: 'Status',\n render: (row) => row.registered\n ? <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-accent/10 text-accent\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>\n : <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-surface-sunken text-text-tertiary\">Durable</span>,\n className: 'whitespace-nowrap',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n {row.registered ? (\n <RowAction\n icon={Eye}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.name)}`)}\n />\n ) : (\n <RowAction\n icon={Plus}\n title=\"Register workflow\"\n onClick={() => navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-16 text-right',\n },\n ];\n\n const handleRowClick = (row: ActiveWorker) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.name)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`);\n }\n };\n\n return (\n <div>\n <PageHeader title=\"Workers\" docsHash=\"#docs:dashboard.md:task-queues\" />\n\n <FilterBar>\n <input\n type=\"text\"\n placeholder=\"Search workers...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-[11px] py-1 px-2 w-56\"\n />\n <FilterSelect\n label=\"Queue\"\n value={filters.queue}\n onChange={(v) => setFilter('queue', v)}\n options={queues.map((q) => ({ value: q, label: q }))}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={workers}\n keyFn={(row) => row.name}\n onRowClick={handleRowClick}\n isLoading={isLoading}\n emptyMessage=\"No active workers\"\n />\n </div>\n );\n}\n"],"names":["WorkersPage","navigate","useNavigate","data","isLoading","useActiveWorkers","filters","setFilter","useFilterParams","searchInput","setSearchInput","useState","useEffect","timer","allWorkers","queues","useMemo","w","workers","result","q","columns","row","WorkflowPill","TaskQueuePill","jsxs","jsx","ShieldCheck","RowActionGroup","RowAction","Eye","Plus","handleRowClick","PageHeader","FilterBar","FilterSelect","v","DataTable"],"mappings":"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"}