flujo-ai 3.19.0 → 3.20.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 (446) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +213 -206
  3. package/.next/app-path-routes-manifest.json +9 -8
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/prerender-manifest.json +18 -18
  6. package/.next/react-loadable-manifest.json +8 -8
  7. package/.next/routes-manifest.json +8 -0
  8. package/.next/server/app/_not-found/page.js +2 -2
  9. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  10. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  11. package/.next/server/app/_not-found.html +1 -1
  12. package/.next/server/app/_not-found.rsc +1 -1
  13. package/.next/server/app/api/backup/route.js +1 -1
  14. package/.next/server/app/api/backup/route.js.nft.json +1 -1
  15. package/.next/server/app/api/backup/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/browse/route.js +1 -1
  17. package/.next/server/app/api/browse/route.js.nft.json +1 -1
  18. package/.next/server/app/api/browse/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/cwd/route.js +1 -1
  20. package/.next/server/app/api/cwd/route.js.nft.json +1 -1
  21. package/.next/server/app/api/cwd/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/encryption/secure/route.js +1 -1
  23. package/.next/server/app/api/encryption/secure/route.js.nft.json +1 -1
  24. package/.next/server/app/api/encryption/secure/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/env/route.js +1 -1
  26. package/.next/server/app/api/env/route.js.nft.json +1 -1
  27. package/.next/server/app/api/env/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/flow/[id]/route.js +1 -1
  29. package/.next/server/app/api/flow/[id]/route.js.nft.json +1 -1
  30. package/.next/server/app/api/flow/[id]/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/flow/compile/route.js +1 -1
  32. package/.next/server/app/api/flow/compile/route.js.nft.json +1 -1
  33. package/.next/server/app/api/flow/compile/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/flow/generate/route.js +1 -1
  35. package/.next/server/app/api/flow/generate/route.js.nft.json +1 -1
  36. package/.next/server/app/api/flow/generate/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/flow/improve/route.js +1 -1
  38. package/.next/server/app/api/flow/improve/route.js.nft.json +1 -1
  39. package/.next/server/app/api/flow/improve/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/flow/prompt-renderer/route.js +1 -1
  41. package/.next/server/app/api/flow/prompt-renderer/route.js.nft.json +1 -1
  42. package/.next/server/app/api/flow/prompt-renderer/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/flow/quick-chat/route.js +1 -1
  44. package/.next/server/app/api/flow/quick-chat/route.js.nft.json +1 -1
  45. package/.next/server/app/api/flow/quick-chat/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/flow/repair/route.js +1 -1
  47. package/.next/server/app/api/flow/repair/route.js.nft.json +1 -1
  48. package/.next/server/app/api/flow/repair/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/flow/route.js +1 -1
  50. package/.next/server/app/api/flow/route.js.nft.json +1 -1
  51. package/.next/server/app/api/flow/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/git/route.js +1 -1
  53. package/.next/server/app/api/git/route.js.nft.json +1 -1
  54. package/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  55. package/.next/server/app/api/init/route.js +1 -1
  56. package/.next/server/app/api/init/route.js.nft.json +1 -1
  57. package/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/local-models/capability/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/local-models/pull/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/local-models/suggest/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/mcp/cancel/route.js +1 -1
  62. package/.next/server/app/api/mcp/cancel/route.js.nft.json +1 -1
  63. package/.next/server/app/api/mcp/cancel/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/mcp/servers/[name]/prompts/get/route.js +1 -1
  65. package/.next/server/app/api/mcp/servers/[name]/prompts/get/route.js.nft.json +1 -1
  66. package/.next/server/app/api/mcp/servers/[name]/prompts/get/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/mcp/servers/[name]/prompts/route.js +1 -1
  68. package/.next/server/app/api/mcp/servers/[name]/prompts/route.js.nft.json +1 -1
  69. package/.next/server/app/api/mcp/servers/[name]/prompts/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/mcp/servers/[name]/resources/read/route.js +1 -1
  71. package/.next/server/app/api/mcp/servers/[name]/resources/read/route.js.nft.json +1 -1
  72. package/.next/server/app/api/mcp/servers/[name]/resources/read/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/mcp/servers/[name]/resources/route.js +1 -1
  74. package/.next/server/app/api/mcp/servers/[name]/resources/route.js.nft.json +1 -1
  75. package/.next/server/app/api/mcp/servers/[name]/resources/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/mcp/servers/[name]/route.js +1 -1
  77. package/.next/server/app/api/mcp/servers/[name]/route.js.nft.json +1 -1
  78. package/.next/server/app/api/mcp/servers/[name]/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/mcp/servers/[name]/status/route.js +1 -1
  80. package/.next/server/app/api/mcp/servers/[name]/status/route.js.nft.json +1 -1
  81. package/.next/server/app/api/mcp/servers/[name]/status/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/mcp/servers/[name]/tools/[toolName]/route.js +1 -1
  83. package/.next/server/app/api/mcp/servers/[name]/tools/[toolName]/route.js.nft.json +1 -1
  84. package/.next/server/app/api/mcp/servers/[name]/tools/[toolName]/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/mcp/servers/[name]/tools/route.js +1 -1
  86. package/.next/server/app/api/mcp/servers/[name]/tools/route.js.nft.json +1 -1
  87. package/.next/server/app/api/mcp/servers/[name]/tools/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/mcp/servers/route.js +1 -1
  89. package/.next/server/app/api/mcp/servers/route.js.nft.json +1 -1
  90. package/.next/server/app/api/mcp/servers/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/mcp/test-connection/route.js +1 -1
  92. package/.next/server/app/api/mcp/test-connection/route.js.nft.json +1 -1
  93. package/.next/server/app/api/mcp/test-connection/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/mcp/test-connection/stream/route.js +1 -1
  95. package/.next/server/app/api/mcp/test-connection/stream/route.js.nft.json +1 -1
  96. package/.next/server/app/api/mcp/test-connection/stream/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/mcp-registry/route.js +1 -1
  98. package/.next/server/app/api/mcp-registry/route.js.nft.json +1 -1
  99. package/.next/server/app/api/mcp-registry/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/mcp-registry/spotlight/route.js +1 -1
  101. package/.next/server/app/api/mcp-registry/spotlight/route.js.nft.json +1 -1
  102. package/.next/server/app/api/mcp-registry/spotlight/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/model/[id]/route.js +1 -1
  104. package/.next/server/app/api/model/[id]/route.js.nft.json +1 -1
  105. package/.next/server/app/api/model/[id]/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/model/provider/route.js +1 -1
  107. package/.next/server/app/api/model/provider/route.js.nft.json +1 -1
  108. package/.next/server/app/api/model/provider/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/model/route.js +1 -1
  110. package/.next/server/app/api/model/route.js.nft.json +1 -1
  111. package/.next/server/app/api/model/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/model/test/route.js +1 -1
  113. package/.next/server/app/api/model/test/route.js.nft.json +1 -1
  114. package/.next/server/app/api/model/test/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/oauth/callback/route.js +1 -1
  116. package/.next/server/app/api/oauth/callback/route.js.nft.json +1 -1
  117. package/.next/server/app/api/oauth/callback/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/oauth/initiate/route.js +1 -1
  119. package/.next/server/app/api/oauth/initiate/route.js.nft.json +1 -1
  120. package/.next/server/app/api/oauth/initiate/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/oauth/reset/route.js +1 -1
  122. package/.next/server/app/api/oauth/reset/route.js.nft.json +1 -1
  123. package/.next/server/app/api/oauth/reset/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/planned-executions/[id]/route.js +1 -1
  125. package/.next/server/app/api/planned-executions/[id]/route.js.nft.json +1 -1
  126. package/.next/server/app/api/planned-executions/[id]/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/planned-executions/[id]/run/route.js +1 -1
  128. package/.next/server/app/api/planned-executions/[id]/run/route.js.nft.json +1 -1
  129. package/.next/server/app/api/planned-executions/[id]/run/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/planned-executions/[id]/runs/route.js +1 -1
  131. package/.next/server/app/api/planned-executions/[id]/runs/route.js.nft.json +1 -1
  132. package/.next/server/app/api/planned-executions/[id]/runs/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/planned-executions/preview-schedule/route.js +1 -1
  134. package/.next/server/app/api/planned-executions/preview-schedule/route.js.nft.json +1 -1
  135. package/.next/server/app/api/planned-executions/preview-schedule/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/planned-executions/route.js +1 -1
  137. package/.next/server/app/api/planned-executions/route.js.nft.json +1 -1
  138. package/.next/server/app/api/planned-executions/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/restore/route.js +1 -1
  140. package/.next/server/app/api/restore/route.js.nft.json +1 -1
  141. package/.next/server/app/api/restore/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/storage/route.js +1 -1
  143. package/.next/server/app/api/storage/route.js.nft.json +1 -1
  144. package/.next/server/app/api/storage/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/update/route.js +1 -1
  146. package/.next/server/app/api/update/route.js.nft.json +1 -1
  147. package/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/webhooks/[id]/route.js +1 -1
  149. package/.next/server/app/api/webhooks/[id]/route.js.nft.json +1 -1
  150. package/.next/server/app/api/webhooks/[id]/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/chat/page.js +7 -7
  152. package/.next/server/app/chat/page.js.nft.json +1 -1
  153. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  154. package/.next/server/app/chat.html +1 -1
  155. package/.next/server/app/chat.rsc +2 -2
  156. package/.next/server/app/docs/page.js +9 -2
  157. package/.next/server/app/docs/page.js.nft.json +1 -1
  158. package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  159. package/.next/server/app/docs.html +1 -1
  160. package/.next/server/app/docs.rsc +2 -2
  161. package/.next/server/app/executions/page.js +1 -1
  162. package/.next/server/app/executions/page.js.nft.json +1 -1
  163. package/.next/server/app/executions/page_client-reference-manifest.js +1 -1
  164. package/.next/server/app/executions.html +1 -1
  165. package/.next/server/app/executions.rsc +2 -2
  166. package/.next/server/app/flows/page.js +3 -3
  167. package/.next/server/app/flows/page.js.nft.json +1 -1
  168. package/.next/server/app/flows/page_client-reference-manifest.js +1 -1
  169. package/.next/server/app/flows.html +1 -1
  170. package/.next/server/app/flows.rsc +2 -2
  171. package/.next/server/app/index.html +1 -1
  172. package/.next/server/app/index.rsc +2 -2
  173. package/.next/server/app/mcp/page.js +2 -2
  174. package/.next/server/app/mcp/page.js.nft.json +1 -1
  175. package/.next/server/app/mcp/page_client-reference-manifest.js +1 -1
  176. package/.next/server/app/mcp-flows/route.js +1 -1
  177. package/.next/server/app/mcp-flows/route.js.nft.json +1 -1
  178. package/.next/server/app/mcp-flows/route_client-reference-manifest.js +1 -1
  179. package/.next/server/app/mcp-proxy/[server]/route.js +1 -1
  180. package/.next/server/app/mcp-proxy/[server]/route.js.nft.json +1 -1
  181. package/.next/server/app/mcp-proxy/[server]/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/mcp.html +1 -1
  183. package/.next/server/app/mcp.rsc +2 -2
  184. package/.next/server/app/models/page.js +1 -1
  185. package/.next/server/app/models/page.js.nft.json +1 -1
  186. package/.next/server/app/models/page_client-reference-manifest.js +1 -1
  187. package/.next/server/app/page.js +2 -2
  188. package/.next/server/app/page.js.nft.json +1 -1
  189. package/.next/server/app/page_client-reference-manifest.js +1 -1
  190. package/.next/server/app/settings/page.js +1 -1
  191. package/.next/server/app/settings/page.js.nft.json +1 -1
  192. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  193. package/.next/server/app/settings.html +1 -1
  194. package/.next/server/app/settings.rsc +2 -2
  195. package/.next/server/app/v1/chat/completions/route.js +1 -1
  196. package/.next/server/app/v1/chat/completions/route.js.nft.json +1 -1
  197. package/.next/server/app/v1/chat/completions/route_client-reference-manifest.js +1 -1
  198. package/.next/server/app/v1/chat/conversations/[conversationId]/breakpoints/route.js +2 -2
  199. package/.next/server/app/v1/chat/conversations/[conversationId]/breakpoints/route.js.nft.json +1 -1
  200. package/.next/server/app/v1/chat/conversations/[conversationId]/breakpoints/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/v1/chat/conversations/[conversationId]/cancel/route.js +1 -1
  202. package/.next/server/app/v1/chat/conversations/[conversationId]/cancel/route.js.nft.json +1 -1
  203. package/.next/server/app/v1/chat/conversations/[conversationId]/cancel/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/continue/route.js +1 -1
  205. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/continue/route.js.nft.json +1 -1
  206. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/continue/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/step/route.js +1 -1
  208. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/step/route.js.nft.json +1 -1
  209. package/.next/server/app/v1/chat/conversations/[conversationId]/debug/step/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/v1/chat/conversations/[conversationId]/edit-state/route.js +2 -2
  211. package/.next/server/app/v1/chat/conversations/[conversationId]/edit-state/route.js.nft.json +1 -1
  212. package/.next/server/app/v1/chat/conversations/[conversationId]/edit-state/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/v1/chat/conversations/[conversationId]/events/route.js +1 -1
  214. package/.next/server/app/v1/chat/conversations/[conversationId]/events/route.js.nft.json +1 -1
  215. package/.next/server/app/v1/chat/conversations/[conversationId]/events/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/v1/chat/conversations/[conversationId]/resources/route.js +1 -0
  217. package/.next/server/app/v1/chat/conversations/[conversationId]/resources/route.js.nft.json +1 -0
  218. package/.next/server/app/v1/chat/conversations/[conversationId]/resources/route_client-reference-manifest.js +1 -0
  219. package/.next/server/app/v1/chat/conversations/[conversationId]/respond/route.js +1 -1
  220. package/.next/server/app/v1/chat/conversations/[conversationId]/respond/route.js.nft.json +1 -1
  221. package/.next/server/app/v1/chat/conversations/[conversationId]/respond/route_client-reference-manifest.js +1 -1
  222. package/.next/server/app/v1/chat/conversations/[conversationId]/route.js +1 -1
  223. package/.next/server/app/v1/chat/conversations/[conversationId]/route.js.nft.json +1 -1
  224. package/.next/server/app/v1/chat/conversations/[conversationId]/route_client-reference-manifest.js +1 -1
  225. package/.next/server/app/v1/chat/conversations/route.js +1 -1
  226. package/.next/server/app/v1/chat/conversations/route.js.nft.json +1 -1
  227. package/.next/server/app/v1/chat/conversations/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/v1/models/route.js +1 -1
  229. package/.next/server/app/v1/models/route.js.nft.json +1 -1
  230. package/.next/server/app/v1/models/route_client-reference-manifest.js +1 -1
  231. package/.next/server/app-paths-manifest.json +9 -8
  232. package/.next/server/chunks/1083.js +1 -1
  233. package/.next/server/chunks/1197.js +2 -2
  234. package/.next/server/chunks/1373.js +1 -1
  235. package/.next/server/chunks/1690.js +1 -0
  236. package/.next/server/chunks/1746.js +1 -1
  237. package/.next/server/chunks/2261.js +1 -0
  238. package/.next/server/chunks/2350.js +1 -1
  239. package/.next/server/chunks/264.js +1 -1
  240. package/.next/server/chunks/2859.js +1 -1
  241. package/.next/server/chunks/289.js +1 -0
  242. package/.next/server/chunks/3574.js +2 -2
  243. package/.next/server/chunks/{3310.js → 3778.js} +2 -2
  244. package/.next/server/chunks/3953.js +1 -1
  245. package/.next/server/chunks/3984.js +4 -4
  246. package/.next/server/chunks/4045.js +1 -0
  247. package/.next/server/chunks/4322.js +1 -0
  248. package/.next/server/chunks/4436.js +1 -0
  249. package/.next/server/chunks/4498.js +40 -0
  250. package/.next/server/chunks/4637.js +13 -6
  251. package/.next/server/chunks/4671.js +1 -0
  252. package/.next/server/chunks/{1912.js → 4690.js} +2 -2
  253. package/.next/server/chunks/5708.js +7 -0
  254. package/.next/server/chunks/5734.js +4 -4
  255. package/.next/server/chunks/{6088.js → 6532.js} +2 -2
  256. package/.next/server/chunks/6772.js +1 -1
  257. package/.next/server/chunks/{6136.js → 6908.js} +2 -2
  258. package/.next/server/chunks/6981.js +1 -0
  259. package/.next/server/chunks/6996.js +3 -3
  260. package/.next/server/chunks/701.js +1 -1
  261. package/.next/server/chunks/7101.js +64 -0
  262. package/.next/server/chunks/7214.js +2 -2
  263. package/.next/server/chunks/724.js +3 -3
  264. package/.next/server/chunks/7362.js +4 -4
  265. package/.next/server/chunks/7463.js +6 -0
  266. package/.next/server/chunks/7506.js +1 -1
  267. package/.next/server/chunks/7635.js +1 -1
  268. package/.next/server/chunks/7821.js +1 -1
  269. package/.next/server/chunks/8298.js +1 -0
  270. package/.next/server/chunks/8739.js +2 -2
  271. package/.next/server/chunks/9509.js +2 -2
  272. package/.next/server/chunks/9957.js +1 -0
  273. package/.next/server/functions-config-manifest.json +3 -3
  274. package/.next/server/instrumentation.js.nft.json +1 -1
  275. package/.next/server/middleware-build-manifest.js +1 -1
  276. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  277. package/.next/server/pages/404.html +1 -1
  278. package/.next/server/pages/500.html +1 -1
  279. package/.next/server/server-reference-manifest.js +1 -1
  280. package/.next/server/server-reference-manifest.json +1 -1
  281. package/.next/static/chunks/{1892-a0f5ec7152540dc3.js → 1892-5c1e38d89e0a5a9c.js} +1 -1
  282. package/.next/static/chunks/{3272-ab88dd195ea61b65.js → 3272-fd8d59523f61da96.js} +1 -1
  283. package/.next/static/chunks/3381-5fd2417957ca0881.js +1 -0
  284. package/.next/static/chunks/{1634-d4019c4a5cac2ed0.js → 3648-733cf7ca4a5d1f19.js} +1 -1
  285. package/.next/static/chunks/422-268783d9ad5897e1.js +1 -0
  286. package/.next/static/chunks/{5501-7d6e38c7c8cc3c5a.js → 5501-c400aaeaf57e6297.js} +1 -1
  287. package/.next/static/chunks/7258-e27017c1b98f43f9.js +1 -0
  288. package/.next/static/chunks/{7583.5355a64005f2b265.js → 7583.26a8c1f6e6823daf.js} +1 -1
  289. package/.next/static/chunks/{8187.57929e3f925fe538.js → 8187.fd653767df53db87.js} +1 -1
  290. package/.next/static/chunks/{7829-b843e80f32a83256.js → 8755-9f375ec8740fecac.js} +1 -1
  291. package/.next/static/chunks/{9164-14dc5889cb7478c0.js → 9164-f54d3531ca1df5f7.js} +1 -1
  292. package/.next/static/chunks/{9747-ffb8be5e59700c27.js → 9587-706bfd1a692c4660.js} +3 -3
  293. package/.next/static/chunks/app/api/backup/route-b296683a5faf800a.js +1 -0
  294. package/.next/static/chunks/app/api/browse/route-b296683a5faf800a.js +1 -0
  295. package/.next/static/chunks/app/api/cwd/route-b296683a5faf800a.js +1 -0
  296. package/.next/static/chunks/app/api/encryption/secure/route-b296683a5faf800a.js +1 -0
  297. package/.next/static/chunks/app/api/env/route-b296683a5faf800a.js +1 -0
  298. package/.next/static/chunks/app/api/flow/[id]/route-b296683a5faf800a.js +1 -0
  299. package/.next/static/chunks/app/api/flow/compile/route-b296683a5faf800a.js +1 -0
  300. package/.next/static/chunks/app/api/flow/generate/route-b296683a5faf800a.js +1 -0
  301. package/.next/static/chunks/app/api/flow/improve/route-b296683a5faf800a.js +1 -0
  302. package/.next/static/chunks/app/api/flow/prompt-renderer/route-b296683a5faf800a.js +1 -0
  303. package/.next/static/chunks/app/api/flow/quick-chat/route-b296683a5faf800a.js +1 -0
  304. package/.next/static/chunks/app/api/flow/repair/route-b296683a5faf800a.js +1 -0
  305. package/.next/static/chunks/app/api/flow/route-b296683a5faf800a.js +1 -0
  306. package/.next/static/chunks/app/api/git/route-b296683a5faf800a.js +1 -0
  307. package/.next/static/chunks/app/api/init/route-b296683a5faf800a.js +1 -0
  308. package/.next/static/chunks/app/api/local-models/capability/route-b296683a5faf800a.js +1 -0
  309. package/.next/static/chunks/app/api/local-models/pull/route-b296683a5faf800a.js +1 -0
  310. package/.next/static/chunks/app/api/local-models/suggest/route-b296683a5faf800a.js +1 -0
  311. package/.next/static/chunks/app/api/mcp/cancel/route-b296683a5faf800a.js +1 -0
  312. package/.next/static/chunks/app/api/mcp/servers/[name]/prompts/get/route-b296683a5faf800a.js +1 -0
  313. package/.next/static/chunks/app/api/mcp/servers/[name]/prompts/route-b296683a5faf800a.js +1 -0
  314. package/.next/static/chunks/app/api/mcp/servers/[name]/resources/read/route-b296683a5faf800a.js +1 -0
  315. package/.next/static/chunks/app/api/mcp/servers/[name]/resources/route-b296683a5faf800a.js +1 -0
  316. package/.next/static/chunks/app/api/mcp/servers/[name]/route-b296683a5faf800a.js +1 -0
  317. package/.next/static/chunks/app/api/mcp/servers/[name]/status/route-b296683a5faf800a.js +1 -0
  318. package/.next/static/chunks/app/api/mcp/servers/[name]/tools/[toolName]/route-b296683a5faf800a.js +1 -0
  319. package/.next/static/chunks/app/api/mcp/servers/[name]/tools/route-b296683a5faf800a.js +1 -0
  320. package/.next/static/chunks/app/api/mcp/servers/route-b296683a5faf800a.js +1 -0
  321. package/.next/static/chunks/app/api/mcp/test-connection/route-b296683a5faf800a.js +1 -0
  322. package/.next/static/chunks/app/api/mcp/test-connection/stream/route-b296683a5faf800a.js +1 -0
  323. package/.next/static/chunks/app/api/mcp-registry/route-b296683a5faf800a.js +1 -0
  324. package/.next/static/chunks/app/api/mcp-registry/spotlight/route-b296683a5faf800a.js +1 -0
  325. package/.next/static/chunks/app/api/model/[id]/route-b296683a5faf800a.js +1 -0
  326. package/.next/static/chunks/app/api/model/provider/route-b296683a5faf800a.js +1 -0
  327. package/.next/static/chunks/app/api/model/route-b296683a5faf800a.js +1 -0
  328. package/.next/static/chunks/app/api/model/test/route-b296683a5faf800a.js +1 -0
  329. package/.next/static/chunks/app/api/oauth/callback/route-b296683a5faf800a.js +1 -0
  330. package/.next/static/chunks/app/api/oauth/initiate/route-b296683a5faf800a.js +1 -0
  331. package/.next/static/chunks/app/api/oauth/reset/route-b296683a5faf800a.js +1 -0
  332. package/.next/static/chunks/app/api/planned-executions/[id]/route-b296683a5faf800a.js +1 -0
  333. package/.next/static/chunks/app/api/planned-executions/[id]/run/route-b296683a5faf800a.js +1 -0
  334. package/.next/static/chunks/app/api/planned-executions/[id]/runs/route-b296683a5faf800a.js +1 -0
  335. package/.next/static/chunks/app/api/planned-executions/preview-schedule/route-b296683a5faf800a.js +1 -0
  336. package/.next/static/chunks/app/api/planned-executions/route-b296683a5faf800a.js +1 -0
  337. package/.next/static/chunks/app/api/restore/route-b296683a5faf800a.js +1 -0
  338. package/.next/static/chunks/app/api/storage/route-b296683a5faf800a.js +1 -0
  339. package/.next/static/chunks/app/api/update/route-b296683a5faf800a.js +1 -0
  340. package/.next/static/chunks/app/api/webhooks/[id]/route-b296683a5faf800a.js +1 -0
  341. package/.next/static/chunks/app/chat/page-a67ad3683443e7ad.js +1 -0
  342. package/.next/static/chunks/app/docs/page-097827ec4dae1d30.js +1 -0
  343. package/.next/static/chunks/app/executions/page-cb0dcc66d84c9bf8.js +1 -0
  344. package/.next/static/chunks/app/flows/page-abdd0642e378c5da.js +1 -0
  345. package/.next/static/chunks/app/mcp/{page-9a612d0be5a3336d.js → page-7d3a269dce68b529.js} +1 -1
  346. package/.next/static/chunks/app/mcp-flows/route-b296683a5faf800a.js +1 -0
  347. package/.next/static/chunks/app/mcp-proxy/[server]/route-b296683a5faf800a.js +1 -0
  348. package/.next/static/chunks/app/v1/chat/completions/route-b296683a5faf800a.js +1 -0
  349. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/breakpoints/route-b296683a5faf800a.js +1 -0
  350. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/cancel/route-b296683a5faf800a.js +1 -0
  351. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/debug/continue/route-b296683a5faf800a.js +1 -0
  352. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/debug/step/route-b296683a5faf800a.js +1 -0
  353. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/edit-state/route-b296683a5faf800a.js +1 -0
  354. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/events/route-b296683a5faf800a.js +1 -0
  355. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/resources/route-b296683a5faf800a.js +1 -0
  356. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/respond/route-b296683a5faf800a.js +1 -0
  357. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/route-b296683a5faf800a.js +1 -0
  358. package/.next/static/chunks/app/v1/chat/conversations/route-b296683a5faf800a.js +1 -0
  359. package/.next/static/chunks/app/v1/models/route-b296683a5faf800a.js +1 -0
  360. package/.next/static/chunks/webpack-ef5b2cef70829f42.js +1 -0
  361. package/.next/trace +9 -7
  362. package/.next/types/app/v1/chat/conversations/[conversationId]/resources/route.ts +347 -0
  363. package/.next/types/routes.d.ts +2 -1
  364. package/.next/types/validator.ts +9 -0
  365. package/README.md +1 -1
  366. package/package.json +1 -1
  367. package/.next/server/chunks/2194.js +0 -1
  368. package/.next/server/chunks/3648.js +0 -1
  369. package/.next/server/chunks/4239.js +0 -1
  370. package/.next/server/chunks/4372.js +0 -1
  371. package/.next/server/chunks/4681.js +0 -1
  372. package/.next/server/chunks/5148.js +0 -1
  373. package/.next/server/chunks/6465.js +0 -1
  374. package/.next/server/chunks/7403.js +0 -38
  375. package/.next/server/chunks/7865.js +0 -9
  376. package/.next/static/chunks/1711-ccf5eba61d618a1a.js +0 -1
  377. package/.next/static/chunks/3625-74c77250d64d1cd3.js +0 -1
  378. package/.next/static/chunks/924-64f908860caf1a35.js +0 -1
  379. package/.next/static/chunks/app/api/backup/route-ff084c1cc278df77.js +0 -1
  380. package/.next/static/chunks/app/api/browse/route-ff084c1cc278df77.js +0 -1
  381. package/.next/static/chunks/app/api/cwd/route-ff084c1cc278df77.js +0 -1
  382. package/.next/static/chunks/app/api/encryption/secure/route-ff084c1cc278df77.js +0 -1
  383. package/.next/static/chunks/app/api/env/route-ff084c1cc278df77.js +0 -1
  384. package/.next/static/chunks/app/api/flow/[id]/route-ff084c1cc278df77.js +0 -1
  385. package/.next/static/chunks/app/api/flow/compile/route-ff084c1cc278df77.js +0 -1
  386. package/.next/static/chunks/app/api/flow/generate/route-ff084c1cc278df77.js +0 -1
  387. package/.next/static/chunks/app/api/flow/improve/route-ff084c1cc278df77.js +0 -1
  388. package/.next/static/chunks/app/api/flow/prompt-renderer/route-ff084c1cc278df77.js +0 -1
  389. package/.next/static/chunks/app/api/flow/quick-chat/route-ff084c1cc278df77.js +0 -1
  390. package/.next/static/chunks/app/api/flow/repair/route-ff084c1cc278df77.js +0 -1
  391. package/.next/static/chunks/app/api/flow/route-ff084c1cc278df77.js +0 -1
  392. package/.next/static/chunks/app/api/git/route-ff084c1cc278df77.js +0 -1
  393. package/.next/static/chunks/app/api/init/route-ff084c1cc278df77.js +0 -1
  394. package/.next/static/chunks/app/api/local-models/capability/route-ff084c1cc278df77.js +0 -1
  395. package/.next/static/chunks/app/api/local-models/pull/route-ff084c1cc278df77.js +0 -1
  396. package/.next/static/chunks/app/api/local-models/suggest/route-ff084c1cc278df77.js +0 -1
  397. package/.next/static/chunks/app/api/mcp/cancel/route-ff084c1cc278df77.js +0 -1
  398. package/.next/static/chunks/app/api/mcp/servers/[name]/prompts/get/route-ff084c1cc278df77.js +0 -1
  399. package/.next/static/chunks/app/api/mcp/servers/[name]/prompts/route-ff084c1cc278df77.js +0 -1
  400. package/.next/static/chunks/app/api/mcp/servers/[name]/resources/read/route-ff084c1cc278df77.js +0 -1
  401. package/.next/static/chunks/app/api/mcp/servers/[name]/resources/route-ff084c1cc278df77.js +0 -1
  402. package/.next/static/chunks/app/api/mcp/servers/[name]/route-ff084c1cc278df77.js +0 -1
  403. package/.next/static/chunks/app/api/mcp/servers/[name]/status/route-ff084c1cc278df77.js +0 -1
  404. package/.next/static/chunks/app/api/mcp/servers/[name]/tools/[toolName]/route-ff084c1cc278df77.js +0 -1
  405. package/.next/static/chunks/app/api/mcp/servers/[name]/tools/route-ff084c1cc278df77.js +0 -1
  406. package/.next/static/chunks/app/api/mcp/servers/route-ff084c1cc278df77.js +0 -1
  407. package/.next/static/chunks/app/api/mcp/test-connection/route-ff084c1cc278df77.js +0 -1
  408. package/.next/static/chunks/app/api/mcp/test-connection/stream/route-ff084c1cc278df77.js +0 -1
  409. package/.next/static/chunks/app/api/mcp-registry/route-ff084c1cc278df77.js +0 -1
  410. package/.next/static/chunks/app/api/mcp-registry/spotlight/route-ff084c1cc278df77.js +0 -1
  411. package/.next/static/chunks/app/api/model/[id]/route-ff084c1cc278df77.js +0 -1
  412. package/.next/static/chunks/app/api/model/provider/route-ff084c1cc278df77.js +0 -1
  413. package/.next/static/chunks/app/api/model/route-ff084c1cc278df77.js +0 -1
  414. package/.next/static/chunks/app/api/model/test/route-ff084c1cc278df77.js +0 -1
  415. package/.next/static/chunks/app/api/oauth/callback/route-ff084c1cc278df77.js +0 -1
  416. package/.next/static/chunks/app/api/oauth/initiate/route-ff084c1cc278df77.js +0 -1
  417. package/.next/static/chunks/app/api/oauth/reset/route-ff084c1cc278df77.js +0 -1
  418. package/.next/static/chunks/app/api/planned-executions/[id]/route-ff084c1cc278df77.js +0 -1
  419. package/.next/static/chunks/app/api/planned-executions/[id]/run/route-ff084c1cc278df77.js +0 -1
  420. package/.next/static/chunks/app/api/planned-executions/[id]/runs/route-ff084c1cc278df77.js +0 -1
  421. package/.next/static/chunks/app/api/planned-executions/preview-schedule/route-ff084c1cc278df77.js +0 -1
  422. package/.next/static/chunks/app/api/planned-executions/route-ff084c1cc278df77.js +0 -1
  423. package/.next/static/chunks/app/api/restore/route-ff084c1cc278df77.js +0 -1
  424. package/.next/static/chunks/app/api/storage/route-ff084c1cc278df77.js +0 -1
  425. package/.next/static/chunks/app/api/update/route-ff084c1cc278df77.js +0 -1
  426. package/.next/static/chunks/app/api/webhooks/[id]/route-ff084c1cc278df77.js +0 -1
  427. package/.next/static/chunks/app/chat/page-1d764d1de5ad5d2f.js +0 -1
  428. package/.next/static/chunks/app/docs/page-d670c1ec8af5cb54.js +0 -1
  429. package/.next/static/chunks/app/executions/page-109274291811d467.js +0 -1
  430. package/.next/static/chunks/app/flows/page-df8eda0e83934fb2.js +0 -1
  431. package/.next/static/chunks/app/mcp-flows/route-ff084c1cc278df77.js +0 -1
  432. package/.next/static/chunks/app/mcp-proxy/[server]/route-ff084c1cc278df77.js +0 -1
  433. package/.next/static/chunks/app/v1/chat/completions/route-ff084c1cc278df77.js +0 -1
  434. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/breakpoints/route-ff084c1cc278df77.js +0 -1
  435. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/cancel/route-ff084c1cc278df77.js +0 -1
  436. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/debug/continue/route-ff084c1cc278df77.js +0 -1
  437. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/debug/step/route-ff084c1cc278df77.js +0 -1
  438. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/edit-state/route-ff084c1cc278df77.js +0 -1
  439. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/events/route-ff084c1cc278df77.js +0 -1
  440. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/respond/route-ff084c1cc278df77.js +0 -1
  441. package/.next/static/chunks/app/v1/chat/conversations/[conversationId]/route-ff084c1cc278df77.js +0 -1
  442. package/.next/static/chunks/app/v1/chat/conversations/route-ff084c1cc278df77.js +0 -1
  443. package/.next/static/chunks/app/v1/models/route-ff084c1cc278df77.js +0 -1
  444. package/.next/static/chunks/webpack-3e8560996ac8c1e0.js +0 -1
  445. /package/.next/static/{itJEX_uJ7hJ7oF-igwwK9 → dvSaKx6-EfRNi7Xj-cSv_}/_buildManifest.js +0 -0
  446. /package/.next/static/{itJEX_uJ7hJ7oF-igwwK9 → dvSaKx6-EfRNi7Xj-cSv_}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9040],{32651:(e,t,a)=>{Promise.resolve().then(a.bind(a,71113))},71113:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>E});var o=a(95155),s=a(94049),n=a(12115),r=a(28548),i=a(2300),l=a(25635),d=a(97322),p=a(9562),c=a(56422),m=a(21067),u=a(32683),h=a(51611);let f=[{id:"openai",name:"Chat — OpenAI-compatible",description:'A drop-in OpenAI-compatible surface. In OpenAI-compatible clients (Roo Code, Cline, Cursor, the OpenAI SDK, …) set the Base URL to this instance + "/v1" (e.g. http://localhost:4200/v1) and the model to a flow id (format flow-<NAME>, as listed by /v1/models).',endpoints:[{method:"POST",alsoMethods:["GET","OPTIONS"],path:"/v1/chat/completions",summary:"OpenAI-compatible chat completion. Runs a FLUJO flow as the model. Supports streaming and non-streaming. CORS-enabled; rate-limited (~6000 req/min).",paramsLabel:"Body",params:[{name:"model",type:"string",required:!0,description:"Flow to run, as flow-<NAME>."},{name:"messages",type:"ChatMessage[]",required:!0,description:"Conversation messages (OpenAI shape)."},{name:"stream",type:"boolean",description:"Stream the response as SSE chunks."},{name:"flujo",type:"boolean",description:"Enable FLUJO-specific behavior."},{name:"conversation_id",type:"string",description:"Reuse/continue an existing conversation."},{name:"requireApproval",type:"boolean",description:"Pause for manual tool-call approval."},{name:"flujodebug",type:"boolean",description:"Run in the visual debugger (single-step)."}],response:"OpenAI ChatCompletion object, or an SSE stream of chunks when stream=true."},{method:"GET",path:"/v1/models",summary:"List all flows as OpenAI-style models.",response:'{ object: "list", data: [{ id: "flow-<NAME>", object: "model" }, ...] }'}]},{id:"conversations",name:"Conversations & Execution",description:"Manage conversations and drive flow execution: live event streaming (SSE), tool-call approval, cancellation, and visual-debugger stepping.",endpoints:[{method:"GET",path:"/v1/chat/conversations",summary:"List all conversations (id, title, flowId, createdAt, updatedAt, status), newest first.",response:"Conversation summary array."},{method:"POST",path:"/v1/chat/conversations",summary:"Create a new conversation and initialize its execution state.",paramsLabel:"Body",params:[{name:"id",type:"string",required:!0,description:"Client-generated conversation id."},{name:"title",type:"string",required:!0,description:"Display title."},{name:"flowId",type:"string",required:!0,description:"Flow bound to this conversation."},{name:"createdAt",type:"number",required:!0,description:"Unix ms timestamp."},{name:"updatedAt",type:"number",required:!0,description:"Unix ms timestamp."}]},{method:"GET",alsoMethods:["PATCH","DELETE"],path:"/v1/chat/conversations/{conversationId}",summary:"GET the displayed conversation (messages + metadata); PATCH updates flowId; DELETE removes the conversation and its event log.",paramsLabel:"Body",params:[{name:"flowId",type:"string",description:"New flow id (PATCH only)."}],response:"Conversation with messages, plus usage (token totals, per-node breakdown), status, and contextInfo (latest prompt-token count + the bound model's context window — what the chat token counter and context meter display).",notes:["Messages are a projection of the append-only conversation log when one exists (legacy conversations without a log are served as stored). Node system prompts are never included.","Subflow steps appear inline as depth-tagged, display-only messages (nested in the chat UI); they are never part of the parent's model context."]},{method:"GET",path:"/v1/chat/conversations/{conversationId}/events",summary:"Server-Sent Events stream of execution events (node:enter/exit, message, usage, run:*). Supports Last-Event-ID reconnect.",paramsLabel:"Query",params:[{name:"fromSeq",type:"number",description:"Replay events from this sequence number."}],response:"text/event-stream of ExecutionEvent objects with monotonic seq ids."},{method:"POST",path:"/v1/chat/conversations/{conversationId}/respond",summary:"Approve or reject a pending tool call; resumes execution when all pending calls are handled.",paramsLabel:"Body",params:[{name:"action",type:'"approve" | "reject"',required:!0,description:"Decision for the tool call."},{name:"toolCallId",type:"string",required:!0,description:"Which pending tool call."}]},{method:"POST",path:"/v1/chat/conversations/{conversationId}/cancel",summary:"Request cancellation of an in-progress run (sets the isCancelled flag)."},{method:"PUT",path:"/v1/chat/conversations/{conversationId}/breakpoints",summary:"Set the visual-debugger breakpoint node ids.",paramsLabel:"Body",params:[{name:"breakpoints",type:"string[]",required:!0,description:"Node ids to break on."}]},{method:"POST",path:"/v1/chat/conversations/{conversationId}/debug/step",summary:"Execute exactly one productive step (only when status is paused_debug); pauses after advancing."},{method:"POST",path:"/v1/chat/conversations/{conversationId}/debug/continue",summary:"Resume a debug session — run freely to the next pause, tool approval, or completion."},{method:"PATCH",path:"/v1/chat/conversations/{conversationId}/edit-state",summary:"Edit paused debug state (a message's content, or the next node to run). Only when paused_debug.",paramsLabel:"Body",params:[{name:"messageId",type:"string",description:"Message to edit."},{name:"content",type:"string",description:"New message content."},{name:"currentNodeId",type:"string",description:"Override the next node."}]}]},{id:"model",name:"Models",description:"CRUD for model configurations and provider model discovery. API keys are encrypted at rest and never returned to the browser in clear text.",endpoints:[{method:"GET",alsoMethods:["POST"],path:"/api/model",summary:"GET lists all models; POST creates a model (409 on duplicate name, 201 on success).",paramsLabel:"Body",params:[{name:"model",type:"Model",required:!0,description:"Model config (POST). Secrets are stored encrypted."}],notes:["Stored API keys are masked before reaching the frontend — never expect a clear-text key in a response."]},{method:"GET",alsoMethods:["PUT","DELETE"],path:"/api/model/{id}",summary:"GET / PUT / DELETE a single model. The path id is authoritative on PUT. DELETE returns 204."},{method:"POST",path:"/api/model/provider",summary:"Fetch available models from a provider, using a supplied or stored API key (resolved server-side).",paramsLabel:"Body",params:[{name:"baseUrl",type:"string",required:!0,description:"Provider base URL."},{name:"modelId",type:"string",description:"Existing model whose stored key to reuse."},{name:"searchTerm",type:"string",description:"Filter the returned model list."}],notes:["Accepts an apiKey only inbound to query the provider; keys are never echoed back to the client."]}]},{id:"flow",name:"Flows",description:"CRUD for flow definitions, programmatic flow authoring (FlowSpec), LLM flow generation, and prompt rendering for individual nodes. For creating flows programmatically, prefer POST /api/flow/compile with a FlowSpec — the raw Flow format (ReactFlow JSON) is the internal canvas representation and easy to get subtly wrong.",endpoints:[{method:"POST",path:"/api/flow/compile",summary:"Compile a FlowSpec (the semantic authoring format — see below) into a complete flow, validate it, and optionally save it. Deterministic, no LLM: layout, ids, handles, and MCP wiring are generated for you. THE recommended way for external apps and agents to create flows. Also exposed as MCP tools (create_flow / validate_flow_spec) on /mcp-flows.",paramsLabel:"Body",params:[{name:"spec",type:"FlowSpec",required:!0,description:"The flow specification (format below)."},{name:"save",type:"boolean",description:"Persist the flow — only happens when validation finds ZERO errors."}],response:"{ flow, validation: { issues, errorCount, warningCount, isRunnable }, saved } — 201 when saved, 200 otherwise. Iterate on the issues until clean.",details:'A FlowSpec is a JSON object describing a FLUJO flow semantically — node keys and edges, no coordinates, no ids, no layout:\n{\n "name": "short_flow_name", // letters/digits/_/- only\n "description": "what the flow does",\n "nodes": [ ... ],\n "edges": [ ... ]\n}\n\nNODE TYPES:\n- { "key": "unique_key", "type": "start", "label": "...", "prompt": "system-level instructions for the whole flow" }\n- { "key": "...", "type": "process", "label": "...", "description": "what this step does",\n "model": "<model id or name from the catalog>",\n "prompt": "instructions for this step",\n "servers": [ { "name": "<server name>", "tools": ["tool_a"] } ], // optional; omit "tools" to enable all\n "inputMode": "full-history" | "latest-message" | "isolated", // optional, default full-history\n "isolatedPrompt": "...", // only with inputMode "isolated"\n "outputMode": "full-conversation" | "latest-message", // optional, default full-conversation; latest-message hides this step\'s tool calls/results from later steps (they see only its final response)\n "maxTurns": 20, // optional; per-step cap on agentic tool-loop turns (retry-until-done in ONE node). Unset = model/system default (50)\n "allowedTools": ["tool_a"], // optional; step-level tool allowlist (independent of servers[].tools)\n "captureVariable": "NAME", // optional; save this step\'s output into a run variable other steps inject with ${var:NAME}\n "captureResource": "NAME", // optional; ALSO save this step\'s output as a tracked run resource other steps inject with ${res:NAME} (see rule 9b)\n "excludeModelPrompt": true|false, // optional; drop the model\'s base prompt\n "excludeStartNodePrompt": true|false, // optional; drop the start node\'s prompt for this step\n "excludeSystemPrompt": true|false } // optional; drop the workflow/handoff guidance block\n- { "key": "...", "type": "subflow", "label": "...",\n "flow": "<existing flow name or id>", // reference an EXISTING flow, OR:\n "subflowSpec": { ...a nested FlowSpec... }, // define a brand-new child flow INLINE (compiled into its own flow and wired automatically), OR fan out concurrently:\n "parallelFlows": ["flow_a", "flow_b"], // run several EXISTING child flows CONCURRENTLY, same input to each, outputs joined; OR:\n "parallelSubflowSpecs": [ { ...FlowSpec... } ], // run several INLINE child flows concurrently\n "mapOverList": true | false, // optional; run the SINGLE child ("flow"/"subflowSpec") ONCE PER ITEM parsed from the input; mutually exclusive with parallelFlows/parallelSubflowSpecs\n "itemSplit": "json-array" | "lines", // optional (mapOverList only), how to split the input into items, default json-array\n "sequential": true | false, // optional (mapOverList only), run items one at a time in order instead of concurrently, default false\n "concurrencyLimit": 4, // optional (parallel / mapOverList), default 4\n "joinSeparator": "\\n\\n---\\n\\n", // optional (parallel / mapOverList), string between joined lane outputs, default "\\n\\n"\n "errorStrategy": "collect-all" | "fail-fast", // optional (parallel / mapOverList), default collect-all\n "inputMode": "full-history" | "latest-message" | "isolated",\n "allowCallerPrompt": true | false, // optional, only with inputMode "isolated"; when true a routing step may pass a "prompt" via its handoff tool that overrides the subflow\'s "prompt" (default)\n "captureVariable": "NAME", // optional; save the subflow\'s output into a run variable other steps inject with ${var:NAME}\n "captureResource": "NAME", // optional; ALSO save the subflow\'s output as a tracked run resource (${res:NAME}, rule 9b)\n "outputMode": "steps" | "final-only" }\n- { "key": "...", "type": "finish", "label": "..." }\n- { "key": "...", "type": "resource", "label": "...", // OPTIONAL/advanced (rule 9c): a data artifact shown in the graph\n "server": "<server name>", "uri": "<resource uri>", // EITHER a static MCP resource…\n "runName": "NAME" } // …OR a run artifact steps produce/consume\n\nEDGES: { "from": "<node key>", "to": "<node key>", "bidirectional": true|false,\n "condition": { "kind": "contains"|"regex"|"equals", "value": "...",\n "target": "last-assistant"|"last-message", // optional, default last-assistant\n "ignoreCase": true|false, "negate": true|false } } // condition optional; process-node edges only\n\nRULES:\n1. Exactly ONE start node; at least one finish node reachable from it.\n2. Every process node MUST reference a configured model (by id, display name, or name).\n3. A process step uses MCP tools ONLY via its "servers" list — never emit nodes of type "mcp".\n4. Do not embed ${tool:...} or ${resource:...} references in prompts — tools are wired through "servers".\n5. Branching: give a process node multiple outgoing edges; its model decides where to hand off at runtime. "bidirectional": true lets the target hand back to the source (agent <-> agent).\n5b. Deterministic routing: give a process node\'s outgoing edges a "condition" to route WITHOUT the model — the engine takes the first outgoing edge whose predicate matches the last message (default the step\'s own last assistant message), and a bare (condition-less) edge is the fallback. Use this for reliable data-driven branches (e.g. output contains "FAIL" -> fix step, else -> publish) instead of relying on a small model to emit a handoff. Only process-node edges may carry a condition. Without any condition on a node, that node keeps model-decided handoff (rule 5). If the model still calls a handoff tool, that wins over the condition.\n6. A subflow node may have only ONE outgoing edge. Give it EITHER a "flow" (naming an existing flow) OR a "subflowSpec" (an inline nested FlowSpec that becomes its own child flow) — not both. A "subflowSpec" may itself contain subflow nodes with their own "subflowSpec" (bounded nesting), so you can author whole multi-level flows in one object.\n7. A subflow node may instead fan out to SEVERAL child flows CONCURRENTLY via "parallelFlows" (existing flows) or "parallelSubflowSpecs" (inline). The same input is sent to every lane and their outputs are joined. This is about multiple CHILDREN, not successors — the single-outgoing-edge rule (rule 6) still holds. Prefer "parallelFlows" for large fan-outs.\n8. A subflow node may instead run its SINGLE child flow ONCE PER ITEM via "mapOverList": true. The input is split into items by "itemSplit" ("json-array" default, or "lines"), each item is sent to its own child run, and the per-item outputs are joined (same pool/tuning as parallel). Use "sequential": true to run items in order. Mutually exclusive with "parallelFlows"/"parallelSubflowSpecs".\n9. Named variables (scratchpad): a step can save its output with "captureVariable": "NAME" (process or subflow) and any LATER step injects it with ${var:NAME} inside its "prompt" / "isolatedPrompt" / subflow prompt. This survives "latest-message"/"isolated" scoping, unlike conversation history — use it to carry a todo list, a file path, a diff, or a captured result across steps that don\'t share history. ${var:NAME} is run-scoped and plaintext; it is DISTINCT from ${global:VAR} (configured secrets/config, resolved only for tool args). Capture a subflow\'s output on the PARENT subflow node — a variable set inside a child flow is not visible to the parent.\n9b. Run resources (tracked data): "captureResource": "NAME" (process or subflow) ALSO saves the step\'s output as a run-scoped RESOURCE — an addressable artifact (flujo://run/... URI) with lineage (which step produced it, which steps read it), readable via the built-in "flujo" MCP server. A later step injects it with ${res:NAME} exactly like ${var:NAME}. Prefer "captureVariable" for short strings; use "captureResource" when the output is a large document/report/dataset worth tracking, or when other tools/agents should be able to read it back. Large or binary MCP tool results (screenshots, files) are auto-captured as run resources without any spec field.\n9c. Resource nodes are OPTIONAL/advanced — most flows should not use them; prefer rule 9b\'s captureResource/${res:NAME}. Emit one only when the data artifact itself should be VISIBLE in the graph: an edge resource→process means the step READS the artifact (its contents are injected into the step\'s context); process→resource means the step\'s output is SAVED to it (run artifacts only, equivalent to captureResource with the node\'s runName). Resource edges are data wiring, not flow control — they never carry conditions and don\'t count as a step\'s successor.\n10. Keep flows minimal — only the steps the task needs. Write clear, specific prompts and labels; fill "description" on process nodes.'},{method:"POST",path:"/api/flow/generate",summary:"Generate a draft flow from a natural-language description using one of your configured models. The model authors a FlowSpec, FLUJO compiles + validates it and feeds problems back for a bounded number of repair rounds. The generator can always SEARCH the public MCP registry; with allowInstall it can also INSTALL servers it needs. Returns an UNSAVED draft (the UI opens it in the builder for review); persist via the normal save path or /api/flow/compile.",paramsLabel:"Body",params:[{name:"description",type:"string",required:!0,description:"What the flow should do, in plain language."},{name:"modelId",type:"string",required:!0,description:"Configured model that does the generating."},{name:"maxRepairs",type:"number",description:"Repair rounds after the first attempt (default 1, max 2)."},{name:"allowInstall",type:"boolean",description:"Let the generator install MCP servers from the public registry (downloads + RUNS third-party packages on this machine). Off by default."}],response:"{ flow, validation, attempts, installedServers } — the flow is a draft; nothing flow-related is persisted by this endpoint (installed servers ARE persisted).",notes:["allowInstall executes third-party code with this machine's user permissions — opt in deliberately."]},{method:"GET",alsoMethods:["POST"],path:"/api/flow",summary:"GET lists all flow definitions; POST creates a flow (create-only; 409 if the id exists). POST takes the raw internal Flow format — prefer /api/flow/compile for programmatic creation.",paramsLabel:"Body",params:[{name:"flow",type:"Flow",required:!0,description:"Flow object including id (POST)."}]},{method:"GET",alsoMethods:["PUT","DELETE"],path:"/api/flow/{id}",summary:"GET / PUT / DELETE a single flow. On PUT the path id wins over the body id (404 if missing)."},{method:"POST",path:"/api/flow/prompt-renderer",summary:"Render the assembled prompt for a node within a flow.",paramsLabel:"Body",params:[{name:"flowId",type:"string",required:!0,description:"Flow containing the node."},{name:"nodeId",type:"string",required:!0,description:"Node to render."},{name:"options",type:"object",description:"Render options."}]}]},{id:"planned-executions",name:"Planned Executions",description:"Run flows headlessly on triggers: schedules (cron), inbound webhooks, and more. Managed from the Executions page; each run is recorded in a per-execution run history.",endpoints:[{method:"GET",alsoMethods:["POST","PATCH"],path:"/api/planned-executions",summary:"GET lists all planned executions with live trigger status and last run; POST creates one; PATCH toggles the global pause switch ({ paused: boolean }).",response:"GET: { paused, executions: [{ execution, status, lastRun }] }."},{method:"GET",alsoMethods:["PATCH","DELETE"],path:"/api/planned-executions/{id}",summary:"GET / PATCH / DELETE a single planned execution. PATCH takes a partial config and re-arms the trigger."},{method:"POST",path:"/api/planned-executions/{id}/run",summary:"Run now: fire the execution immediately (even while disabled or paused) and wait for the run.",response:"{ record: RunRecord } with status, output preview, and token usage."},{method:"GET",path:"/api/planned-executions/{id}/runs",summary:"The execution’s run history (newest 100 runs, oldest first)."},{method:"POST",path:"/api/planned-executions/preview-schedule",summary:"Validate a cron pattern and preview its next fire times (editor helper).",paramsLabel:"Body",params:[{name:"cron",type:"string",required:!0,description:"Cron pattern (5 or 6 fields)."},{name:"timezone",type:"string",description:"IANA timezone name."}],response:"{ valid, error?, nextRuns: string[] }."},{method:"POST",path:"/api/webhooks/{id}",summary:"Inbound webhook trigger. Fires the planned execution with the request body as trigger context and responds 202 { runId } immediately (the flow runs in the background). For a synchronous answer use /v1/chat/completions instead.",paramsLabel:"Query",params:[{name:"token",type:"string",required:!0,description:"Per-execution secret (alternatively send the X-Flujo-Token header)."}],notes:["Localhost-only by default; external callers must be explicitly allowed per execution.","The webhook body is untrusted input to the flow — prompts should treat it as data."]}]},{id:"mcp",name:"MCP Servers",description:"Manage MCP server configurations, connection state, tool discovery, and tool invocation.",endpoints:[{method:"GET",alsoMethods:["POST"],path:"/api/mcp/servers",summary:"GET lists all MCP server configs; POST registers a new one (409 on duplicate name).",paramsLabel:"Body",params:[{name:"config",type:"MCPServerConfig",required:!0,description:"Server config (POST)."}]},{method:"GET",alsoMethods:["PUT","DELETE"],path:"/api/mcp/servers/{name}",summary:"GET / PUT / DELETE a server config. PUT merges fields; toggling disabled connects/disconnects; a new name triggers a validated rename."},{method:"GET",path:"/api/mcp/servers/{name}/status",summary:"Live connection status. Always 200, even when the server is down.",response:"{ status, ... }"},{method:"GET",path:"/api/mcp/servers/{name}/tools",summary:"List tools exposed by a connected server.",response:"{ tools, error? } (empty tools + error when disconnected)."},{method:"POST",path:"/api/mcp/servers/{name}/tools/{toolName}",summary:"Invoke a tool on a server. Status may reflect the tool itself (408 on timeout).",paramsLabel:"Body",params:[{name:"args",type:"Record<string, unknown>",required:!0,description:"Tool arguments."},{name:"timeout",type:"number",description:"Optional timeout (ms)."}]},{method:"POST",path:"/api/mcp/test-connection",summary:"Run a real MCP handshake against an unsaved config (tests custom CAs and headers) without registering it.",paramsLabel:"Body",params:[{name:"config",type:"MCPServerConfig",required:!0,description:"Config to test."}]},{method:"POST",path:"/api/mcp/cancel",summary:"Cancel an in-progress tool execution; force-reconnects if no token is supplied.",paramsLabel:"Body",params:[{name:"reason",type:"string",required:!0,description:"Cancellation reason."}]}]},{id:"mcp-proxy",name:"FLUJO as an MCP server (proxy)",description:'Re-expose a configured MCP server to EXTERNAL MCP clients (Claude Desktop, Cursor, Cline, mcp-inspector, …) so you configure the server once in FLUJO and reach it everywhere. Enable per server via the "Expose to external apps" toggle on its card. In your MCP client, add a Streamable-HTTP server with the URL below. One downstream server per endpoint, so tool names are unchanged. Localhost-only for now (no auth token in this version — see the security roadmap).',endpoints:[{method:"POST",alsoMethods:["GET","DELETE"],path:"/mcp-proxy/{server}",summary:'A Streamable-HTTP MCP endpoint that forwards tools/list and tools/call to the named downstream MCP server. {server} is the configured server name; it must have "Expose to external apps" enabled (otherwise 404). Rejects non-localhost requests.',response:"MCP JSON-RPC over Streamable HTTP (handled by your MCP client, not called directly)."}]},{id:"mcp-flows",name:"FLUJO as an MCP server (flows + authoring)",description:"A Streamable-HTTP MCP endpoint that exposes FLUJO itself to external MCP clients. Every saved flow is a callable tool (running it ephemerally and returning its output), and three authoring tools let an external agent CREATE flows by sending a semantic FlowSpec — no raw ReactFlow JSON required. Localhost-only (same posture as the proxy).",endpoints:[{method:"POST",alsoMethods:["GET","DELETE"],path:"/mcp-flows",summary:'MCP server with two tool families. Flow tools: one per saved flow (name = slug of the flow name; input = a single "input" string sent as the user turn; runs are ephemeral and never appear in the chat sidebar). Authoring tools: list_flow_building_blocks (models, MCP servers + tools, and existing flows a spec may reference — call first), validate_flow_spec (compile + validate without saving; iterate on the returned issues), create_flow (compile + validate + save; only saves when validation finds zero errors), plus capability acquisition: search_mcp_marketplace (search the public registry) and install_mcp_server (install + connect a registry server — downloads and RUNS third-party packages on the FLUJO host; required keys can be passed via its env argument). The FlowSpec format is documented on POST /api/flow/compile above and inside the tools\' own descriptions.',response:"MCP JSON-RPC over Streamable HTTP (handled by your MCP client, not called directly)."}]},{id:"oauth",name:"OAuth (for MCP)",description:"OAuth authorization flow for MCP servers that require it. Tokens are stored server-side and never sent to the browser.",endpoints:[{method:"POST",path:"/api/oauth/initiate",summary:"Begin the OAuth flow for a server; dynamically registers a client and returns an authorization URL.",paramsLabel:"Body",params:[{name:"serverName",type:"string",required:!0,description:"MCP server to authorize."}]},{method:"GET",alsoMethods:["POST"],path:"/api/oauth/callback",summary:"OAuth redirect target; exchanges the code for tokens, updates the config, and redirects to /mcp.",notes:["Tokens are persisted server-side only."]},{method:"POST",path:"/api/oauth/reset",summary:"Clear a server's OAuth tokens and force re-authentication on the next connection.",paramsLabel:"Body",params:[{name:"serverName",type:"string",required:!0,description:"Server to reset."}]}]},{id:"env",name:"Environment & Secrets",description:"Global environment variables and server-side encryption operations. Secret values are encrypted at rest and masked as ******** in responses.",endpoints:[{method:"GET",alsoMethods:["POST"],path:"/api/env",summary:"GET reads env vars (secrets masked); POST sets/deletes vars (secrets encrypted server-side).",paramsLabel:"Body",params:[{name:"action",type:'"set" | "setAll" | "delete"',required:!0,description:"Operation."},{name:"key",type:"string",description:"Variable name (set/delete)."},{name:"value",type:"string",description:"Value; the placeholder ******** is ignored."},{name:"metadata",type:"{ isSecret: boolean }",description:"Marks a value for encryption."}],notes:["GET masks secret values unless an internal includeSecrets flag is set; the browser never receives clear-text secrets."]},{method:"POST",path:"/api/encryption/secure",summary:"Server-side encryption operations: initialize, authenticate, change_password, encrypt, verify_password, check_initialized, and status queries.",paramsLabel:"Body",params:[{name:"action",type:"string",required:!0,description:"One of the encryption actions."}],notes:["Passwords and tokens are handled here and stay server-side — never log or surface them in the UI."]}]},{id:"storage",name:"Storage & Backup",description:"Generic key-value storage plus zip backup/restore of selected data.",endpoints:[{method:"GET",alsoMethods:["POST","DELETE"],path:"/api/storage",summary:"GET loads an item by StorageKey (with optional default); POST saves; DELETE clears.",paramsLabel:"Query",params:[{name:"key",type:"StorageKey",required:!0,description:"Storage key."},{name:"defaultValue",type:"JSON",description:"Returned when the key is missing (GET)."}]},{method:"POST",path:"/api/backup",summary:"Create a zip backup of selected items and download it.",paramsLabel:"Body",params:[{name:"selections",type:"string[]",required:!0,description:"e.g. models, mcpServers, flows, chatHistory, settings."}],notes:["A backup may include the encryption key and secrets — handle the downloaded file carefully."]},{method:"POST",path:"/api/restore",summary:"Restore data from a backup zip.",paramsLabel:"Form data",params:[{name:"file",type:"File (zip)",required:!0,description:"Backup archive."},{name:"selections",type:"JSON string[]",required:!0,description:"Which items to restore."}]}]},{id:"system",name:"System & Updates",description:"App initialization, working-directory info, repository operations, and self-update.",endpoints:[{method:"GET",path:"/api/init",summary:"Server-side initialization: verify storage and start enabled MCP servers."},{method:"GET",path:"/api/cwd",summary:"Return the current working directory and the mcp-servers directory path."},{method:"GET",path:"/api/browse",summary:"List a directory of the machine running FLUJO, for the folder-picker dialogs (file-watch triggers, MCP server paths). Defaults to the home directory; includes available drives on Windows.",paramsLabel:"Query",params:[{name:"path",type:"string",description:"Absolute directory path to list."}],response:"{ path, parent, home, sep, drives, entries: [{ name, path, isDirectory }] }",notes:["Exposes backend filesystem listings — like the rest of the API it assumes a single trusted user."]},{method:"POST",path:"/api/git",summary:"Repository operations for MCP servers: clone, install, build, run, exists, readFile, listDir, list, checkUpdates, checkUpdatesBatch, pullUpdates.",paramsLabel:"Body",params:[{name:"action",type:"string",required:!0,description:"Operation to perform."}]},{method:"GET",alsoMethods:["POST"],path:"/api/update",summary:'GET checks for a newer version (git fetch + behind count); POST { action: "apply" } pulls, rebuilds, and restarts.',response:"{ success, isGitRepo, updateAvailable, behindBy?, branch?, currentVersion }"}]}],y={GET:"#2e7d32",POST:"#1565c0",PUT:"#ed6c02",PATCH:"#9c27b0",DELETE:"#c62828",OPTIONS:"#616161"};function g(e){let{method:t}=e;return(0,o.jsx)(r.A,{label:t,size:"small",sx:{bgcolor:y[t],color:"#fff",fontWeight:700,fontFamily:"var(--font-geist-mono), monospace",fontSize:"0.7rem",height:22}})}function v(e){var t,a,n,r;let{endpoint:d}=e;return(0,o.jsxs)(i.A,{variant:"outlined",sx:{p:2,mb:1.5},children:[(0,o.jsxs)(s.default,{sx:{display:"flex",alignItems:"center",gap:1,flexWrap:"wrap",mb:1},children:[(0,o.jsx)(g,{method:d.method}),null==(t=d.alsoMethods)?void 0:t.map(e=>(0,o.jsx)(g,{method:e},e)),(0,o.jsx)(l.default,{component:"code",sx:{fontFamily:"var(--font-geist-mono), monospace",fontSize:"0.9rem",wordBreak:"break-all"},children:d.path})]}),(0,o.jsx)(l.default,{variant:"body2",color:"text.secondary",sx:{mb:1.5*(null!=(a=d.params)&&!!a.length)},children:d.summary}),d.params&&d.params.length>0&&(0,o.jsxs)(s.default,{sx:{mb:1},children:[(0,o.jsx)(l.default,{variant:"caption",sx:{fontWeight:700,textTransform:"uppercase",color:"text.secondary"},children:null!=(r=d.paramsLabel)?r:"Parameters"}),(0,o.jsx)(s.default,{component:"ul",sx:{m:0,mt:.5,pl:2.5},children:d.params.map(e=>(0,o.jsx)(s.default,{component:"li",sx:{mb:.25},children:(0,o.jsxs)(l.default,{variant:"body2",component:"span",children:[(0,o.jsx)(s.default,{component:"code",sx:{fontFamily:"var(--font-geist-mono), monospace",fontWeight:600},children:e.name}),(0,o.jsxs)(s.default,{component:"span",sx:{color:"text.secondary"},children:[" ",e.type,e.required?" \xb7 required":""," — ",e.description]})]})},e.name))})]}),d.response&&(0,o.jsxs)(l.default,{variant:"body2",sx:{mt:.5},children:[(0,o.jsxs)(s.default,{component:"span",sx:{fontWeight:600},children:["Response:"," "]}),(0,o.jsx)(s.default,{component:"span",sx:{color:"text.secondary"},children:d.response})]}),null==(n=d.notes)?void 0:n.map((e,t)=>(0,o.jsxs)(l.default,{variant:"caption",sx:{display:"block",mt:1,color:"warning.main"},children:["⚠ ",e]},t)),d.details&&(0,o.jsx)(s.default,{component:"pre",sx:{mt:1.5,p:1.5,bgcolor:"action.hover",borderRadius:1,fontSize:"0.75rem",fontFamily:"monospace",whiteSpace:"pre-wrap",overflowX:"auto",m:0,mb:0},children:d.details})]})}function w(){let[e,t]=(0,n.useState)(""),[a,r]=(0,n.useState)("");n.useEffect(()=>{r(window.location.origin)},[]);let y=(0,n.useMemo)(()=>{let t=e.trim().toLowerCase();return t?f.map(e=>{let a=e.endpoints.filter(a=>{var o;return"".concat(a.method," ").concat((null!=(o=a.alsoMethods)?o:[]).join(" ")," ").concat(a.path," ").concat(a.summary).toLowerCase().includes(t)||e.name.toLowerCase().includes(t)});return{...e,endpoints:a}}).filter(e=>e.endpoints.length>0):f},[e]);return(0,o.jsxs)(d.A,{maxWidth:"md",sx:{py:5},children:[(0,o.jsx)(l.default,{variant:"h4",gutterBottom:!0,children:"API Documentation"}),(0,o.jsx)(l.default,{variant:"body1",color:"text.secondary",sx:{mb:2},children:"FLUJO exposes an OpenAI-compatible chat API and a REST surface for managing models, MCP servers, flows, and conversations. All endpoints are served from this instance."}),(0,o.jsxs)(i.A,{variant:"outlined",sx:{p:2,mb:3},children:[(0,o.jsx)(l.default,{variant:"subtitle2",gutterBottom:!0,children:"Base URL"}),(0,o.jsx)(s.default,{component:"code",sx:{fontFamily:"var(--font-geist-mono), monospace",fontSize:"0.9rem"},children:a||"http://localhost:4200"}),(0,o.jsxs)(l.default,{variant:"body2",color:"text.secondary",sx:{mt:1},children:["Point any OpenAI SDK at"," ",(0,o.jsx)(s.default,{component:"code",sx:{fontFamily:"var(--font-geist-mono), monospace"},children:(a||"http://localhost:4200")+"/v1"})," ","and set the model to"," ",(0,o.jsx)(s.default,{component:"code",sx:{fontFamily:"var(--font-geist-mono), monospace"},children:"flow-<NAME>"}),". Any API key value is accepted locally."]})]}),(0,o.jsx)(p.A,{fullWidth:!0,size:"small",placeholder:"Search endpoints (path, method, description)…",value:e,onChange:e=>t(e.target.value),sx:{mb:3},InputProps:{startAdornment:(0,o.jsx)(c.A,{position:"start",children:(0,o.jsx)(h.A,{fontSize:"small"})})}}),0===y.length&&(0,o.jsxs)(l.default,{color:"text.secondary",children:["No endpoints match “",e,"”."]}),y.map(e=>(0,o.jsxs)(s.default,{sx:{mb:4},id:e.id,children:[(0,o.jsx)(l.default,{variant:"h6",gutterBottom:!0,children:e.name}),(0,o.jsx)(l.default,{variant:"body2",color:"text.secondary",sx:{mb:2},children:e.description}),e.endpoints.map(e=>(0,o.jsx)(v,{endpoint:e},"".concat(e.method," ").concat(e.path)))]},e.id)),(0,o.jsx)(m.A,{sx:{my:3}}),(0,o.jsxs)(l.default,{variant:"caption",color:"text.secondary",children:["Secrets (API keys, encryption passwords, OAuth tokens) are encrypted at rest and never returned to the browser in clear text. See the project"," ",(0,o.jsx)(u.A,{href:"https://github.com/mario-andreschak/FLUJO",target:"_blank",rel:"noopener",children:"repository"})," ","for source-level details."]})]})}let b=(0,a(87021).h)("app/docs/page");function E(){return b.debug("Rendering DocsPage"),(0,o.jsx)(s.default,{component:"main",sx:{minHeight:"100vh"},children:(0,o.jsx)(w,{})})}},87021:(e,t,a)=>{"use strict";a.d(t,{h:()=>l});let o={LOG_LEVEL:3},s={VERBOSE:-1,DEBUG:0,INFO:1,WARN:2,ERROR:3},n="number"==typeof o.LOG_LEVEL?o.LOG_LEVEL:s.ERROR;function r(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;if(t>6)return String(e);if(!(e instanceof Error))return e;let a={name:e.name,message:e.message};for(let o of Object.getOwnPropertyNames(e)){if("name"===o||"message"===o)continue;let s=e[o];"function"!=typeof s&&("stack"===o?a.stack=s:"cause"===o?a.cause=r(s,t+1):"errors"===o&&Array.isArray(s)?a.errors=s.map(e=>r(e,t+1)):a[o]=s)}return a}function i(e,t,a,o,i){if(e>=("number"==typeof i?i:n)){if("function"==typeof o)try{o=o()}catch(e){o="[lazy log data threw]"}let n=new Date().toISOString(),i="[".concat(n,"] [").concat(t,"]"),l="".concat(i," ").concat(a);if(void 0!==o)if(o instanceof Error||"object"==typeof o)try{let e=o instanceof Error?r(o):o,t=JSON.stringify(e,(e,t)=>t instanceof Error?r(t):t,2);l+=":\n".concat(t)}catch(e){l+=": [Object cannot be stringified]"}else l+=": ".concat(o);switch(e){case s.VERBOSE:console.debug("[VERBOSE] ".concat(l));break;case s.DEBUG:console.debug(l);break;case s.INFO:console.info(l);break;case s.WARN:console.warn(l);break;case s.ERROR:console.error(l);break;default:console.log(l)}}}function l(e,t){let a,o=((a=e.replace(/^src\//,"")).startsWith("/")&&(a=a.substring(1)),a);return{verbose:(e,a)=>{i(s.VERBOSE,o,e,a,t)},debug:(e,a)=>{i(s.DEBUG,o,e,a,t)},info:(e,a)=>{i(s.INFO,o,e,a,t)},warn:(e,a)=>{i(s.WARN,o,e,a,t)},error:(e,a)=>{i(s.ERROR,o,e,a,t)}}}}},e=>{e.O(0,[2678,4754,9244,8548,5501,488,8066,8441,1255,7358],()=>e(e.s=32651)),_N_E=e.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1488],{17325:(e,t,r)=>{"use strict";r.d(t,{A:()=>x});var a=r(12115),l=r(2821),n=r(57001),o=r(48116),s=r(16625),i=r(85795),c=r(95195);function d(e){return(0,c.Ay)("MuiFormGroup",e)}(0,i.A)("MuiFormGroup",["root","row","error"]);var u=r(45918),h=r(75108),p=r(95155);let m=(0,o.Ay)("div",{name:"MuiFormGroup",slot:"Root",overridesResolver:(e,t)=>{let{ownerState:r}=e;return[t.root,r.row&&t.row]}})({display:"flex",flexDirection:"column",flexWrap:"wrap",variants:[{props:{row:!0},style:{flexDirection:"row"}}]}),x=a.forwardRef(function(e,t){let r=(0,s.b)({props:e,name:"MuiFormGroup"}),{className:a,row:o=!1,...i}=r,c=(0,u.A)(),x=(0,h.A)({props:r,muiFormControl:c,states:["error"]}),f={...r,row:o,error:x.error},g=(e=>{let{classes:t,row:r,error:a}=e;return(0,n.A)({root:["root",r&&"row",a&&"error"]},d,t)})(f);return(0,p.jsx)(m,{className:(0,l.A)(g.root,a),ownerState:f,ref:t,...i})})},17427:(e,t,r)=>{"use strict";r.d(t,{A:()=>m});var a=r(95155),l=r(12115),n=r(25635),o=r(94049),s=r(99944),i=r(9957),c=r(52641),d=r(51221),u=r(55606),h=r(86973),p=r(9562);let m=e=>{var t;let{schema:r,values:m,onChange:x,size:f="small"}=e,[g,v]=(0,l.useState)({}),y=null!=(t=null==r?void 0:r.properties)?t:{},w=Array.isArray(null==r?void 0:r.required)?r.required:[],b=Object.keys(y);if(0===b.length)return(0,a.jsx)(n.default,{variant:"body2",color:"text.secondary",children:"This tool takes no parameters."});let j=(e,t)=>{let r={...m};void 0===t?delete r[e]:r[e]=t,x(r)};return(0,a.jsx)(o.default,{sx:{display:"flex",flexDirection:"column",gap:2},children:b.map(e=>{var t,r;let l=null!=(t=y[e])?t:{},x=w.includes(e)?"".concat(e," *"):e,b="string"==typeof l.description?l.description:"";if("boolean"===l.type)return(0,a.jsx)(s.A,{control:(0,a.jsx)(i.A,{size:f,checked:!0===m[e],onChange:t=>j(e,t.target.checked)}),label:(0,a.jsxs)(o.default,{children:[(0,a.jsx)(n.default,{variant:"body2",children:x}),b&&(0,a.jsx)(n.default,{variant:"caption",color:"text.secondary",children:b})]})},e);if(Array.isArray(l.enum)&&l.enum.length>0){let t=m[e];return(0,a.jsxs)(c.A,{size:f,fullWidth:!0,children:[(0,a.jsx)(d.A,{id:"schema-param-".concat(e),children:x}),(0,a.jsx)(u.A,{labelId:"schema-param-".concat(e),label:x,value:l.enum.includes(t)?t:"",onChange:t=>j(e,t.target.value),children:l.enum.map(e=>(0,a.jsx)(h.A,{value:e,children:String(e)},String(e)))}),b&&(0,a.jsx)(n.default,{variant:"caption",color:"text.secondary",sx:{mt:.5,mx:1.75},children:b})]},e)}if("number"===l.type||"integer"===l.type)return(0,a.jsx)(p.A,{fullWidth:!0,size:f,type:"number",label:x,value:void 0!==m[e]?String(m[e]):"",onChange:t=>{let r=t.target.value;if(""===r)return void j(e,void 0);let a="integer"===l.type?parseInt(r,10):parseFloat(r);j(e,Number.isNaN(a)?void 0:a)},helperText:b},e);if("object"===l.type||"array"===l.type){let t=null!=(r=g[e])?r:void 0!==m[e]?JSON.stringify(m[e],null,2):"",n=null;if(t.trim())try{JSON.parse(t)}catch(e){n="Not valid JSON yet"}return(0,a.jsx)(p.A,{fullWidth:!0,size:f,multiline:!0,minRows:2,label:"".concat(x," (JSON ").concat(l.type,")"),value:t,error:!!n,helperText:null!=n?n:b,onChange:t=>{let r=t.target.value;if(v(t=>({...t,[e]:r})),!r.trim())return void j(e,void 0);try{j(e,JSON.parse(r))}catch(e){}},slotProps:{input:{sx:{fontFamily:"monospace",fontSize:13}}}},e)}return(0,a.jsx)(p.A,{fullWidth:!0,size:f,label:x,value:void 0!==m[e]?String(m[e]):"",onChange:t=>j(e,""===t.target.value?void 0:t.target.value),helperText:b},e)})})}},27156:(e,t,r)=>{"use strict";r.d(t,{Z:()=>a});var a=function(e){return e.MODELS="models",e.FLOWS="flows",e.CHAT_HISTORY="history",e.THEME="theme",e.ENCRYPTION_KEY="encryption_key",e.MCP_SERVERS="mcp_servers",e.GLOBAL_ENV_VARS="global_env_vars",e.CURRENT_CONVERSATION_ID="current_conversation_id",e.SELECTED_FLOW_ID="selected_flow_id",e.SPEECH_SETTINGS="speech_settings",e.SPOTLIGHT_SERVERS="spotlight_servers",e.PLANNED_EXECUTIONS="planned_executions",e.MCP_AUTO_INSTALL_SETTINGS="mcp_auto_install_settings",e.MCP_QUALITY_SETTINGS="mcp_quality_settings",e.RUN_RESOURCE_SETTINGS="run_resource_settings",e}({})},29692:(e,t,r)=>{"use strict";r.d(t,{Zg:()=>a.Z,YM:()=>i,VH:()=>s,Mj:()=>o});var a=r(27156),l=r(12115);let n=(0,r(87021).h)("utils/storage/frontend.ts");function o(e,t){n.verbose("useLocalStorage: Entering method");let[r,a]=(0,l.useState)(t),[o,s]=(0,l.useState)(!0),i=(0,l.useRef)(r);return(0,l.useEffect)(()=>{i.current=r},[r]),(0,l.useEffect)(()=>{(async()=>{n.verbose("loadValue: Entering method");try{let r=await fetch("/api/storage?key=".concat(encodeURIComponent(e),"&defaultValue=").concat(encodeURIComponent(JSON.stringify(t)))),l=await r.json();r.ok&&a(l.value)}catch(t){n.warn('Error reading storage key "'.concat(e,'":'),t)}finally{s(!1)}})()},[e]),[r,(0,l.useCallback)(async t=>{n.verbose("setValue: Entering method");try{let r=t instanceof Function?t(i.current):t;if(a(r),!(await fetch("/api/storage",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:e,value:r})})).ok)throw Error("Failed to save value")}catch(t){n.warn('Error setting storage key "'.concat(e,'":'),t)}},[e]),o]}let s=async(e,t)=>{n.verbose("saveItem: Entering method");try{if(!(await fetch("/api/storage",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:e,value:t})})).ok)throw Error("Failed to save item")}catch(e){throw n.error("Error saving to storage:",e),e}},i=async(e,t)=>{n.verbose("loadItem: Entering method");try{let r=await fetch("/api/storage?key=".concat(encodeURIComponent(e),"&defaultValue=").concat(encodeURIComponent(JSON.stringify(t))));if(!r.ok)throw Error("Failed to load item");return(await r.json()).value}catch(e){return n.error("Error loading from storage:",e),t}}},45755:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>eW});var a=r(95155),l=r(94049),n=r(12115),o=r(25635),s=r(99944),i=r(9957),c=r(91871),d=r(2778),u=r(52363),h=r(65036),p=r(75912),m=r(86946),x=r(76530),f=r(78470),g=r(41983),v=r(87021);let y=(0,v.h)("frontend/services/plannedExecutions");class w{async list(){try{let e=await fetch("/api/planned-executions");if(!e.ok)throw Error("HTTP ".concat(e.status));return await e.json()}catch(e){return y.warn("Failed to list planned executions",e),{paused:!1,executions:[]}}}async create(e){try{let t=await fetch("/api/planned-executions",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),r=await t.json();if(!t.ok)return{success:!1,error:(null==r?void 0:r.error)||"HTTP ".concat(t.status)};return{success:!0,execution:r.execution}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Request failed"}}}async update(e,t){try{let r=await fetch("/api/planned-executions/".concat(e),{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),a=await r.json();if(!r.ok)return{success:!1,error:(null==a?void 0:a.error)||"HTTP ".concat(r.status)};return{success:!0,execution:a.execution}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Request failed"}}}async delete(e){try{let t=await fetch("/api/planned-executions/".concat(e),{method:"DELETE"});if(!t.ok){let e=await t.json().catch(()=>null);return{success:!1,error:(null==e?void 0:e.error)||"HTTP ".concat(t.status)}}return{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Request failed"}}}async setPaused(e){try{let t=await fetch("/api/planned-executions",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({paused:e})});if(!t.ok){let e=await t.json().catch(()=>null);return{success:!1,error:(null==e?void 0:e.error)||"HTTP ".concat(t.status)}}return{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Request failed"}}}async runNow(e){try{let t=await fetch("/api/planned-executions/".concat(e,"/run"),{method:"POST"}),r=await t.json();if(!t.ok)return{success:!1,error:(null==r?void 0:r.error)||"HTTP ".concat(t.status)};return{success:!0,record:r.record}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Request failed"}}}async loadRuns(e){try{let t=await fetch("/api/planned-executions/".concat(e,"/runs"));if(!t.ok)throw Error("HTTP ".concat(t.status));let r=await t.json();return Array.isArray(null==r?void 0:r.runs)?r.runs:[]}catch(t){return y.warn("Failed to load runs for ".concat(e),t),[]}}async previewSchedule(e,t){try{let r=await fetch("/api/planned-executions/preview-schedule",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cron:e,timezone:t})});if(!r.ok)throw Error("HTTP ".concat(r.status));return await r.json()}catch(e){return{valid:!1,error:e instanceof Error?e.message:"Preview failed",nextRuns:[]}}}}let b=new w;var j=r(2300),A=r(28548),k=r(4474),C=r(50430),S=r(55406),T=r(14915),N=r(4484),E=r(63186),I=r(62962),F=r(36697);let P=(0,F.A)((0,a.jsx)("path",{d:"M21 11V3h-8l3.29 3.29-10 10L3 13v8h8l-3.29-3.29 10-10z"}),"OpenInFull"),M=e=>String(e).padStart(2,"0"),U=e=>{switch(e){case"completed":return"success.main";case"error":return"error.main";case"skipped":return"warning.main";default:return"transparent"}},W=e=>e?new Date(e).toLocaleDateString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"",L=e=>{if(!e.finishedAt)return"";let t=new Date(e.finishedAt).getTime()-new Date(e.firedAt).getTime();return t<1e3?"<1s":t<6e4?"".concat(Math.round(t/1e3),"s"):"".concat(Math.round(t/6e4),"min")},O=e=>{var t;let{entry:r,onEdit:s,onDelete:m,onToggleEnabled:x,onRanNow:v}=e,{execution:y,status:w,lastRun:F}=r,[O,R]=(0,n.useState)(!1),[D,z]=(0,n.useState)(null),[_,H]=(0,n.useState)(!1),[J,G]=(0,n.useState)(!1),[K,V]=(0,n.useState)(null),[B,q]=(0,n.useState)(10),$=(0,n.useCallback)(async()=>{H(!0),z([...await b.loadRuns(y.id)].reverse()),q(10),H(!1)},[y.id]);(0,n.useEffect)(()=>{O&&$()},[O,$,null==F?void 0:F.runId]);let Z=async()=>{G(!0),await b.runNow(y.id),G(!1),O&&$(),v()};return(0,a.jsxs)(j.A,{variant:"outlined",sx:{p:2},children:[(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:1.5,flexWrap:"wrap"},children:[(0,a.jsxs)(l.default,{sx:{flexGrow:1,minWidth:220},children:[(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:1,flexWrap:"wrap"},children:[(0,a.jsx)(o.default,{variant:"subtitle1",sx:{fontWeight:600},children:y.name}),(0,a.jsx)(A.A,{size:"small",label:function(e){switch(e.type){case"schedule":{var t;let r,a=(t=e.cron,(r=/^\*\/(\d+) \* \* \* \* \*$/.exec(t))?"Every ".concat(r[1],"s"):(r=/^\*\/(\d+) \* \* \* \*$/.exec(t))?"Every ".concat(r[1]," min"):(r=/^0 \*\/(\d+) \* \* \*$/.exec(t))?1===Number(r[1])?"Every hour":"Every ".concat(r[1]," hours"):(r=/^(\d+) (\d+) \* \* \*$/.exec(t))?"Daily at ".concat(M(Number(r[2])),":").concat(M(Number(r[1]))):(r=/^(\d+) (\d+) \* \* 1-5$/.exec(t))?"Weekdays at ".concat(M(Number(r[2])),":").concat(M(Number(r[1]))):null);return null!=a?a:"Schedule: ".concat(e.cron)}case"webhook":return"Webhook";case"file-watch":return"Watching ".concat(e.path);case"mcp-poll":return"Watching ".concat(e.serverName," › ").concat(e.toolName);case"url-watch":try{return"Watching ".concat(new URL(e.url).hostname)}catch(e){return"Watching a URL"}default:return"Trigger"}}(y.trigger)}),!y.enabled&&(0,a.jsx)(A.A,{size:"small",label:"Off",variant:"outlined"})]}),w.running?(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:.75,mt:.5},children:[(0,a.jsx)(k.default,{size:12,thickness:6}),(0,a.jsxs)(o.default,{variant:"body2",color:"text.secondary",children:["Running…",w.runningSince?" — started ".concat(W(w.runningSince)):""]})]}):(0,a.jsxs)(o.default,{variant:"body2",color:"text.secondary",sx:{mt:.5},children:[w.nextRun&&y.enabled?"Next run: ".concat(W(w.nextRun)):y.enabled&&!w.armed?"Not armed":"",w.lastTriggerError?" — trigger error: ".concat(w.lastTriggerError):""]}),F&&(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:.75,mt:.5},children:[(0,a.jsx)(f.A,{title:F.status,children:(0,a.jsx)(l.default,{sx:{width:10,height:10,borderRadius:"50%",bgcolor:U(F.status),flexShrink:0}})}),(0,a.jsxs)(o.default,{variant:"body2",color:"text.secondary",children:["Last run ",W(F.firedAt),"error"===F.status&&F.error?" — ".concat(F.error):""]})]})]}),(0,a.jsx)(f.A,{title:"Run now",children:(0,a.jsx)("span",{children:(0,a.jsx)(g.A,{onClick:Z,disabled:J,color:"primary",children:J?(0,a.jsx)(k.default,{size:20}):(0,a.jsx)(S.A,{})})})}),(0,a.jsx)(f.A,{title:y.enabled?"Turn off":"Turn on",children:(0,a.jsx)(i.A,{checked:y.enabled,onChange:e=>x(e.target.checked)})}),(0,a.jsx)(f.A,{title:"Edit",children:(0,a.jsx)(g.A,{onClick:s,children:(0,a.jsx)(T.A,{})})}),(0,a.jsx)(f.A,{title:"Delete",children:(0,a.jsx)(g.A,{onClick:m,children:(0,a.jsx)(N.A,{})})}),(0,a.jsx)(f.A,{title:O?"Hide run history":"Show run history",children:(0,a.jsx)(g.A,{onClick:()=>R(e=>!e),children:O?(0,a.jsx)(I.A,{}):(0,a.jsx)(E.A,{})})})]}),(0,a.jsx)(C.A,{in:O,timeout:"auto",unmountOnExit:!0,children:(0,a.jsxs)(l.default,{sx:{mt:2,borderTop:1,borderColor:"divider",pt:1.5},children:[_&&!D&&(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",children:"Loading runs…"}),D&&0===D.length&&(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",children:"No runs yet. Use the play button to try it now."}),null==D?void 0:D.slice(0,B).map(e=>{var t;return(0,a.jsxs)(l.default,{sx:{display:"flex",gap:1,py:.75,alignItems:"flex-start","&:hover .run-detail-button":{opacity:1}},children:[(0,a.jsx)(l.default,{sx:{width:10,height:10,borderRadius:"50%",bgcolor:U(e.status),mt:"5px",flexShrink:0}}),(0,a.jsxs)(l.default,{sx:{minWidth:0,flexGrow:1},children:[(0,a.jsxs)(o.default,{variant:"body2",children:[W(e.firedAt),L(e)?" \xb7 ".concat(L(e)):""," \xb7 ",e.triggerSummary,(null==(t=e.usage)?void 0:t.totalTokens)?" \xb7 ".concat(e.usage.totalTokens.toLocaleString()," tokens"):""]}),e.error&&(0,a.jsx)(o.default,{variant:"body2",color:"error",children:e.error}),e.outputText&&(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",sx:{whiteSpace:"pre-wrap",display:"-webkit-box",WebkitLineClamp:3,WebkitBoxOrient:"vertical",overflow:"hidden"},children:e.outputText})]}),(0,a.jsx)(f.A,{title:"Show full output",children:(0,a.jsx)(g.A,{className:"run-detail-button",size:"small",onClick:()=>V(e),sx:{opacity:{xs:1,md:.35},transition:"opacity 120ms",flexShrink:0},children:(0,a.jsx)(P,{fontSize:"inherit"})})})]},e.runId)}),D&&D.length>B&&(0,a.jsxs)(c.A,{size:"small",onClick:()=>q(e=>e+10),sx:{mt:1},children:["Load more (",D.length-B," older)"]})]})}),(0,a.jsxs)(d.A,{open:null!==K,onClose:()=>V(null),maxWidth:"md",fullWidth:!0,children:[(0,a.jsx)(u.A,{component:"div",children:(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:1},children:[(0,a.jsx)(l.default,{sx:{width:10,height:10,borderRadius:"50%",bgcolor:K?U(K.status):"transparent",flexShrink:0}}),(0,a.jsxs)(o.default,{variant:"h6",children:[y.name," — ",K?W(K.firedAt):""]})]})}),(0,a.jsx)(h.A,{dividers:!0,children:K&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(o.default,{variant:"body2",color:"text.secondary",sx:{mb:1.5},children:[K.status,L(K)?" \xb7 ".concat(L(K)):""," \xb7 ",K.triggerSummary,(null==(t=K.usage)?void 0:t.totalTokens)?" \xb7 ".concat(K.usage.totalTokens.toLocaleString()," tokens (").concat(K.usage.promptTokens.toLocaleString()," in / ").concat(K.usage.completionTokens.toLocaleString()," out)"):""]}),K.error&&(0,a.jsx)(o.default,{variant:"body2",color:"error",sx:{mb:1.5,whiteSpace:"pre-wrap"},children:K.error}),K.outputText?(0,a.jsx)(l.default,{sx:{whiteSpace:"pre-wrap",wordBreak:"break-word",bgcolor:"action.hover",borderRadius:1,p:2,fontSize:14,maxHeight:"55vh",overflow:"auto"},children:K.outputText}):!K.error&&(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",children:"This run produced no output text."})]})}),(0,a.jsx)(p.A,{children:(0,a.jsx)(c.A,{onClick:()=>V(null),children:"Close"})})]})]})};var R=r(21067),D=r(9562),z=r(52641),_=r(51221),H=r(55606),J=r(86973),G=r(22003),K=r(77073);let V=(0,F.A)([(0,a.jsx)("path",{d:"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8"},"0"),(0,a.jsx)("path",{d:"M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"},"1")],"Schedule"),B=(0,F.A)((0,a.jsx)("path",{d:"M10 15h5.88c.27-.31.67-.5 1.12-.5.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5c-.44 0-.84-.19-1.12-.5H11.9c-.46 2.28-2.48 4-4.9 4-2.76 0-5-2.24-5-5 0-2.42 1.72-4.44 4-4.9v2.07c-1.16.41-2 1.53-2 2.83 0 1.65 1.35 3 3 3s3-1.35 3-3zm2.5-11c1.65 0 3 1.35 3 3h2c0-2.76-2.24-5-5-5s-5 2.24-5 5c0 1.43.6 2.71 1.55 3.62l-2.35 3.9c-.68.14-1.2.75-1.2 1.48 0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5c0-.16-.02-.31-.07-.45l3.38-5.63C10.49 9.61 9.5 8.42 9.5 7c0-1.65 1.35-3 3-3m4.5 9c-.64 0-1.23.2-1.72.54l-3.05-5.07C11.53 8.35 11 7.74 11 7c0-.83.67-1.5 1.5-1.5S14 6.17 14 7c0 .15-.02.29-.06.43l2.19 3.65c.28-.05.57-.08.87-.08 2.76 0 5 2.24 5 5s-2.24 5-5 5c-1.85 0-3.47-1.01-4.33-2.5h2.67c.48.32 1.05.5 1.66.5 1.65 0 3-1.35 3-3s-1.35-3-3-3"}),"Webhook");var q=r(79299);let $=(0,F.A)((0,a.jsx)("path",{d:"M19.3 16.9c.4-.7.7-1.5.7-2.4 0-2.5-2-4.5-4.5-4.5S11 12 11 14.5s2 4.5 4.5 4.5c.9 0 1.7-.3 2.4-.7l3.2 3.2 1.4-1.4zm-3.8.1c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5M12 20v2C6.48 22 2 17.52 2 12S6.48 2 12 2c4.84 0 8.87 3.44 9.8 8h-2.07c-.64-2.46-2.4-4.47-4.73-5.41V5c0 1.1-.9 2-2 2h-2v2c0 .55-.45 1-1 1H8v2h2v3H9l-4.79-4.79C4.08 10.79 4 11.38 4 12c0 4.41 3.59 8 8 8"}),"TravelExplore");var Z=r(53657),X=r(90057),Y=r(36741);let Q=e=>{let{selected:t,icon:r,title:n,description:s,onClick:i}=e;return(0,a.jsxs)(l.default,{role:"radio","aria-checked":t,tabIndex:0,onClick:i,onKeyDown:e=>{("Enter"===e.key||" "===e.key)&&(e.preventDefault(),i())},sx:{flex:1,minWidth:200,position:"relative",p:2,borderRadius:2,border:2,borderColor:t?"primary.main":"divider",bgcolor:t?"action.selected":"background.paper",cursor:"pointer",transition:"border-color 120ms, background-color 120ms","&:hover":{borderColor:t?"primary.main":"text.disabled"},outline:"none","&:focus-visible":{boxShadow:e=>"0 0 0 3px ".concat(e.palette.primary.light)}},children:[t&&(0,a.jsx)(Y.A,{color:"primary",fontSize:"small",sx:{position:"absolute",top:8,right:8}}),(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:1,mb:.5,color:t?"primary.main":"text.secondary"},children:[r,(0,a.jsx)(o.default,{variant:"subtitle1",sx:{fontWeight:600,color:"text.primary"},children:n})]}),(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",children:s})]})};var ee=r(22822),et=r(98267),er=r(20537),ea=r(37960);let el=e=>String(e).padStart(2,"0"),en=e=>{let{cron:t,timezone:r,onChange:i,verb:c="Runs",catchUp:d,onCatchUpChange:u}=e,h=(0,n.useMemo)(()=>(function(e){let t=/^\*\/(\d+) \* \* \* \* \*$/.exec(e);return t?{mode:"seconds",n:Number(t[1]),time:"09:00"}:(t=/^\*\/(\d+) \* \* \* \*$/.exec(e))?{mode:"minutes",n:Number(t[1]),time:"09:00"}:(t=/^0 \*\/(\d+) \* \* \*$/.exec(e))?{mode:"hours",n:Number(t[1]),time:"09:00"}:(t=/^(\d+) (\d+) \* \* \*$/.exec(e))?{mode:"daily",n:1,time:"".concat(el(Number(t[2])),":").concat(el(Number(t[1])))}:(t=/^(\d+) (\d+) \* \* 1-5$/.exec(e))?{mode:"weekdays",n:1,time:"".concat(el(Number(t[2])),":").concat(el(Number(t[1])))}:{mode:"custom",n:15,time:"09:00"}})(t),[]),[p,m]=(0,n.useState)(h.mode),[x,f]=(0,n.useState)(h.n),[g,v]=(0,n.useState)(h.time),[y,w]=(0,n.useState)(t),[j,A]=(0,n.useState)(null),k=function(e,t,r,a){let[l,n]=r.split(":").map(Number);switch(e){case"seconds":return"*/".concat(Math.max(1,Math.min(59,Math.floor(t)||1))," * * * * *");case"minutes":return"*/".concat(Math.max(1,Math.min(59,Math.floor(t)||1))," * * * *");case"hours":return"0 */".concat(Math.max(1,Math.min(23,Math.floor(t)||1))," * * *");case"daily":return"".concat(n||0," ").concat(l||0," * * *");case"weekdays":return"".concat(n||0," ").concat(l||0," * * 1-5");default:return a}}(p,x,g,y);return(0,n.useEffect)(()=>{k!==t&&i({cron:k,timezone:r})},[k]),(0,n.useEffect)(()=>{let e=!1,t=setTimeout(()=>{b.previewSchedule(k,r).then(t=>{e||A(t)})},300);return()=>{e=!0,clearTimeout(t)}},[k,r]),(0,a.jsxs)(l.default,{children:[(0,a.jsxs)(l.default,{sx:{display:"flex",gap:2,flexWrap:"wrap",alignItems:"center",mt:1},children:[(0,a.jsxs)(z.A,{sx:{minWidth:180},children:[(0,a.jsx)(_.A,{id:"schedule-preset-label",children:c}),(0,a.jsxs)(H.A,{labelId:"schedule-preset-label",label:c,value:p,onChange:e=>m(e.target.value),children:[(0,a.jsx)(J.A,{value:"seconds",children:"Every N seconds"}),(0,a.jsx)(J.A,{value:"minutes",children:"Every N minutes"}),(0,a.jsx)(J.A,{value:"hours",children:"Every N hours"}),(0,a.jsx)(J.A,{value:"daily",children:"Daily at a time"}),(0,a.jsx)(J.A,{value:"weekdays",children:"Weekdays at a time"}),(0,a.jsx)(J.A,{value:"custom",children:"Custom (cron)"})]})]}),("seconds"===p||"minutes"===p||"hours"===p)&&(0,a.jsx)(D.A,{label:"seconds"===p?"Seconds":"minutes"===p?"Minutes":"Hours",type:"number",value:x,onChange:e=>f(Number(e.target.value)),inputProps:{min:1,max:"hours"===p?23:59},sx:{width:120}}),("daily"===p||"weekdays"===p)&&(0,a.jsx)(D.A,{label:"Time",type:"time",value:g,onChange:e=>v(e.target.value),sx:{width:150},InputLabelProps:{shrink:!0}}),"custom"===p&&(0,a.jsx)(D.A,{label:"Cron pattern",value:y,onChange:e=>w(e.target.value),sx:{minWidth:220},placeholder:"*/15 * * * *"})]}),j&&!j.valid&&(0,a.jsx)(G.A,{severity:"error",sx:{mt:2},children:j.error||"This schedule is not valid."}),j&&j.valid&&j.nextRuns.length>0&&(0,a.jsxs)(o.default,{variant:"body2",color:"text.secondary",sx:{mt:2},children:["Next: ",j.nextRuns.map(e=>new Date(e).toLocaleString()).join(" \xb7 ")]}),u&&(0,a.jsx)(s.A,{sx:{mt:1,display:"flex"},control:(0,a.jsx)(ee.A,{checked:!0===d,onChange:e=>u(e.target.checked)}),label:"If FLUJO was closed at a scheduled time, run once on startup"}),(0,a.jsxs)(et.A,{disableGutters:!0,elevation:0,sx:{mt:1,"&:before":{display:"none"}},children:[(0,a.jsx)(er.A,{expandIcon:(0,a.jsx)(E.A,{}),sx:{px:0},children:(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",children:"Advanced"})}),(0,a.jsx)(ea.A,{sx:{px:0},children:(0,a.jsxs)(l.default,{sx:{display:"flex",gap:2,flexWrap:"wrap"},children:[(0,a.jsx)(D.A,{label:"Timezone (optional)",value:r||"",onChange:e=>i({cron:k,timezone:e.target.value||void 0}),placeholder:"e.g. Europe/Berlin",helperText:"IANA timezone name. Empty = this computer's timezone.",sx:{minWidth:260}}),(0,a.jsx)(D.A,{label:"Generated cron pattern",value:k,InputProps:{readOnly:"custom"!==p},onChange:e=>{m("custom"),w(e.target.value)},helperText:"Editing switches to Custom mode.",sx:{minWidth:220}})]})})]})]})};var eo=r(52277),es=r(9693);let ei=e=>{let{config:t,onChange:r,executionId:i,saved:d}=e,[u,h]=(0,n.useState)(null),p=window.location.origin,m="".concat(p,"/api/webhooks/").concat(i),x=async(e,t)=>{try{await navigator.clipboard.writeText(t),h(e),setTimeout(()=>h(null),1500)}catch(e){}};return(0,a.jsxs)(l.default,{sx:{mt:1},children:[!d&&(0,a.jsx)(G.A,{severity:"info",sx:{mb:2},children:"This URL and token are ready to copy now — they become active when you save."}),(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:1},children:[(0,a.jsx)(D.A,{fullWidth:!0,label:"Webhook URL",value:m,InputProps:{readOnly:!0},size:"small"}),(0,a.jsx)(f.A,{title:"Copy URL",children:(0,a.jsx)(g.A,{onClick:()=>x("url",m),children:"url"===u?(0,a.jsx)(es.A,{color:"success"}):(0,a.jsx)(eo.A,{})})})]}),(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:1,mt:2},children:[(0,a.jsx)(D.A,{fullWidth:!0,label:"Secret token",value:t.token,InputProps:{readOnly:!0},size:"small",type:"password"}),(0,a.jsx)(f.A,{title:"Copy token",children:(0,a.jsx)(g.A,{onClick:()=>x("token",t.token),disabled:!t.token,children:"token"===u?(0,a.jsx)(es.A,{color:"success"}):(0,a.jsx)(eo.A,{})})}),(0,a.jsx)(c.A,{size:"small",onClick:()=>r({...t,token:crypto.randomUUID()}),sx:{whiteSpace:"nowrap"},children:"New token"})]}),(0,a.jsx)(o.default,{variant:"caption",color:"text.secondary",children:d?"A new token takes effect when you save — callers using the old one are cut off.":""}),(0,a.jsxs)(o.default,{variant:"body2",color:"text.secondary",sx:{mt:1.5},children:["Callers send a POST with the token in the ",(0,a.jsx)("code",{children:"X-Flujo-Token"})," ","header (or ",(0,a.jsx)("code",{children:"?token=…"}),"). The request body becomes part of the flow's input — treat it as untrusted data in your prompt."]}),(0,a.jsx)(s.A,{sx:{mt:1,display:"flex"},control:(0,a.jsx)(ee.A,{checked:!0===t.allowExternal,onChange:e=>r({...t,allowExternal:e.target.checked})}),label:"Allow calls from other machines (default: this computer only)"}),t.allowExternal&&(0,a.jsx)(G.A,{severity:"warning",children:"FLUJO assumes a single user on this machine. If you expose it beyond localhost (port forwarding, tunnels), securing that access is your responsibility — anyone with the URL and token can run this flow."})]})};var ec=r(56422),ed=r(17325),eu=r(80007),eh=r(62640);let ep=[{value:"add",label:"A file appears"},{value:"change",label:"A file changes"},{value:"unlink",label:"A file is deleted"}],em=e=>{var t;let{config:r,onChange:i}=e,[c,d]=(0,n.useState)(!1);return(0,a.jsxs)(l.default,{sx:{mt:1},children:[(0,a.jsx)(D.A,{fullWidth:!0,label:"Folder (or file) to watch",value:r.path,onChange:e=>i({...r,path:e.target.value}),placeholder:"e.g. C:\\Users\\me\\Documents\\inbox",margin:"normal",InputProps:{endAdornment:(0,a.jsx)(ec.A,{position:"end",children:(0,a.jsx)(f.A,{title:"Browse folders (on the FLUJO machine)",children:(0,a.jsx)(g.A,{edge:"end",onClick:()=>d(!0),children:(0,a.jsx)(eu.A,{})})})})}}),(0,a.jsx)(eh.A,{open:c,title:"Choose what to watch",selectFiles:!0,initialPath:r.path||void 0,onClose:()=>d(!1),onSelect:e=>i({...r,path:e})}),(0,a.jsx)(D.A,{fullWidth:!0,label:"Only files matching (optional)",value:r.glob||"",onChange:e=>i({...r,glob:e.target.value||void 0}),placeholder:"e.g. *.pdf or reports/**/*.csv",helperText:"Simple patterns: * matches within a folder, ** across folders, ? one character.",margin:"normal"}),(0,a.jsx)(o.default,{variant:"subtitle2",sx:{mt:1},children:"Run when…"}),(0,a.jsx)(ed.A,{row:!0,children:ep.map(e=>(0,a.jsx)(s.A,{control:(0,a.jsx)(ee.A,{checked:r.events.includes(e.value),onChange:t=>((e,t)=>{let a=t?[...r.events,e]:r.events.filter(t=>t!==e);i({...r,events:a})})(e.value,t.target.checked)}),label:e.label},e.value))}),(0,a.jsx)(G.A,{severity:"info",sx:{mt:1},children:"Bursts are batched: many files changing at once produce one run with all changes listed. If this flow writes into the watched folder, it will trigger itself in a loop — point its output somewhere else."}),(0,a.jsxs)(et.A,{disableGutters:!0,elevation:0,sx:{mt:1,"&:before":{display:"none"}},children:[(0,a.jsx)(er.A,{expandIcon:(0,a.jsx)(E.A,{}),sx:{px:0},children:(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",children:"Advanced"})}),(0,a.jsx)(ea.A,{sx:{px:0},children:(0,a.jsx)(D.A,{label:"Quiet window (ms)",type:"number",value:null!=(t=r.debounceMs)?t:2e3,onChange:e=>i({...r,debounceMs:Math.max(0,Number(e.target.value)||0)}),helperText:"How long to wait after the last change before running.",inputProps:{min:0,step:500},sx:{width:220}})})]})]})},ex=(0,F.A)((0,a.jsx)("path",{d:"M18 23H4c-1.1 0-2-.9-2-2V7h2v14h14zM15 1H8c-1.1 0-1.99.9-1.99 2L6 17c0 1.1.89 2 1.99 2H19c1.1 0 2-.9 2-2V7zm1.5 14h-6v-2h6zm0-6h-2v2h-2V9h-2V7h2V5h2v2h2z"}),"Difference"),ef=(0,F.A)([(0,a.jsx)("path",{d:"M13 8.57c-.79 0-1.43.64-1.43 1.43s.64 1.43 1.43 1.43 1.43-.64 1.43-1.43-.64-1.43-1.43-1.43"},"0"),(0,a.jsx)("path",{d:"M13 3C9.25 3 6.2 5.94 6.02 9.64L4.1 12.2c-.25.33-.01.8.4.8H6v3c0 1.1.9 2 2 2h1v3h7v-4.68c2.36-1.12 4-3.53 4-6.32 0-3.87-3.13-7-7-7m3 7c0 .13-.01.26-.02.39l.83.66c.08.06.1.16.05.25l-.8 1.39c-.05.09-.16.12-.24.09l-.99-.4c-.21.16-.43.29-.67.39L14 13.83c-.01.1-.1.17-.2.17h-1.6c-.1 0-.18-.07-.2-.17l-.15-1.06c-.25-.1-.47-.23-.68-.39l-.99.4c-.09.03-.2 0-.25-.09l-.8-1.39c-.05-.08-.03-.19.05-.25l.84-.66c-.01-.13-.02-.26-.02-.39s.02-.27.04-.39l-.85-.66c-.08-.06-.1-.16-.05-.26l.8-1.38c.05-.09.15-.12.24-.09l1 .4c.2-.15.43-.29.67-.39L12 6.17c.02-.1.1-.17.2-.17h1.6c.1 0 .18.07.2.17l.15 1.06c.24.1.46.23.67.39l1-.4c.09-.03.2 0 .24.09l.8 1.38c.05.09.03.2-.05.26l-.85.66c.03.12.04.25.04.39"},"1")],"Psychology");var eg=r(17897),ev=r(43076),ey=r(17427),ew=r(96362),eb=r(95906),ej=r(68503);let eA=(0,v.h)("frontend/components/PlannedExecutions/WatchToolPanel"),ek=e=>{var t,r;let{config:s,onChange:i}=e,[d,u]=(0,n.useState)([]),[h,p]=(0,n.useState)(!1),[m,x]=(0,n.useState)([]),[f,g]=(0,n.useState)(!1),[v,y]=(0,n.useState)(Object.keys(s.args||{}).length>0?JSON.stringify(s.args,null,2):""),[w,b]=(0,n.useState)(null),[j,A]=(0,n.useState)(!1),[C,S]=(0,n.useState)(null),[T,N]=(0,n.useState)(null),[E,I]=(0,n.useState)([]),[F,P]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=!1;return eg.S.loadServerConfigs().then(t=>{e||(Array.isArray(t)?u(t.filter(e=>!e.disabled)):(eA.warn("Failed to load MCP servers for watch-tool panel",t),u([])))}),()=>{e=!0}},[]),(0,n.useEffect)(()=>{if(!s.serverName)return void x([]);let e=!1;return g(!0),eg.S.listServerTools(s.serverName).then(t=>{let{tools:r}=t;e||x(r||[])}).finally(()=>{e||g(!1)}),()=>{e=!0}},[s.serverName]),(0,n.useEffect)(()=>{let e=!1;return ev.N.loadModels().then(t=>{e||I(Array.isArray(t)?t:[])}).catch(()=>{e||I([])}),X.g.loadFlows().then(t=>{e||P(t||[])}).catch(()=>{e||P([])}),()=>{e=!0}},[]);let M=async()=>{A(!0),S(null),N(null);try{let r=await eg.S.callTool(s.serverName,s.toolName,s.args||{});if(null==r?void 0:r.error)N("string"==typeof r.error?r.error:"Tool call failed");else{var e,t;let a=null!=(e=null==r?void 0:r.data)?e:r,l=null!=(t=JSON.stringify(a,null,2))?t:"";S(l.length>6e3?"".concat(l.slice(0,6e3),"\n… (truncated)"):l)}}catch(e){N(e instanceof Error?e.message:"Tool call failed")}finally{A(!1)}},U=s.evaluate,W=m.find(e=>e.name===s.toolName),L=(0,ej.E)("mcp",d),O=e=>({key:e.name,content:(e=>(0,a.jsx)(eb.A,{name:e.name,status:e.status||"disconnected",path:e.rootPath||"",enabled:!e.disabled,transport:e.transport||"stdio",pickerMode:!0,selected:s.serverName===e.name,onClick:()=>{var t;return t=e.name,void(i({...s,serverName:t,toolName:""}),p(!1))}}))(e)}),R=L.items.map(O),K=L.groups?L.groups.map(e=>({...e,items:e.items.map(O)})):null;return(0,a.jsxs)(l.default,{sx:{mt:1},children:[(0,a.jsxs)(l.default,{sx:{display:"flex",gap:2,flexWrap:"wrap"},children:[(0,a.jsxs)(l.default,{sx:{minWidth:220,flex:1,mt:2,mb:1},children:[(0,a.jsx)(o.default,{variant:"caption",color:"text.secondary",sx:{display:"block",mb:.5},children:"Server"}),(0,a.jsx)(c.A,{variant:"outlined",fullWidth:!0,onClick:()=>p(!0),sx:{justifyContent:"flex-start",textTransform:"none"},children:s.serverName?"".concat(s.serverName," — change"):"Choose an MCP server…"}),(0,a.jsx)(ew.A,{open:h,onClose:()=>p(!1),title:"Choose an MCP server",description:"Pick the server whose tool you want to watch.",emptyMessage:"No MCP servers configured.",searchable:!0,searchPlaceholder:"Search servers…",searchTerm:L.searchTerm,onSearchChange:L.setSearchTerm,columns:{xs:12,sm:6},items:R,groups:K,collapsedKeys:L.collapsedKeys,onToggleGroup:L.toggleGroup})]}),(0,a.jsxs)(z.A,{sx:{minWidth:220,flex:1},margin:"normal",disabled:!s.serverName,children:[(0,a.jsx)(_.A,{id:"watch-tool-label",children:"Tool"}),(0,a.jsxs)(H.A,{labelId:"watch-tool-label",label:"Tool",value:m.some(e=>e.name===s.toolName)?s.toolName:"",onChange:e=>i({...s,toolName:e.target.value,args:{}}),children:[0===m.length&&(0,a.jsx)(J.A,{value:"",disabled:!0,children:f?"Loading tools…":"Pick a server first"}),m.map(e=>(0,a.jsx)(J.A,{value:e.name,children:e.name},e.name))]})]})]}),(0,a.jsx)(o.default,{variant:"subtitle2",sx:{mt:1},children:"How often to check"}),(0,a.jsx)(en,{verb:"Check",cron:null!=(t=s.cron)?t:function(e){let t=Math.max(5,Math.round((null!=e?e:6e4)/1e3));if(t<60)return"*/".concat(t," * * * * *");let r=Math.max(1,Math.round(t/60));if(r<60)return"*/".concat(r," * * * *");let a=Math.max(1,Math.min(23,Math.round(r/60)));return"0 */".concat(a," * * *")}(s.intervalMs),timezone:s.timezone,onChange:e=>{let{cron:t,timezone:r}=e;return i({...s,cron:t,timezone:r})}}),W?(0,a.jsxs)(l.default,{sx:{my:1.5},children:[(0,a.jsx)(o.default,{variant:"subtitle2",sx:{mb:1.5},children:"Tool parameters — sent on every check"}),(0,a.jsx)(ey.A,{schema:W.inputSchema,values:s.args||{},onChange:e=>i({...s,args:e})})]}):(0,a.jsx)(D.A,{fullWidth:!0,label:"Tool arguments (JSON, optional)",value:v,onChange:e=>(e=>{if(y(e),!e.trim()){b(null),i({...s,args:{}});return}try{let t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))return void b('Arguments must be a JSON object, e.g. { "query": "…" }');b(null),i({...s,args:t})}catch(e){b("Not valid JSON yet")}})(e.target.value),margin:"normal",multiline:!0,minRows:2,placeholder:'{ "query": "is:unread" }',error:!!w,helperText:null!=w?w:"Sent to the tool on every check.",slotProps:{input:{sx:{fontFamily:"monospace",fontSize:14}}}}),(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:2,mb:1},children:[(0,a.jsx)(c.A,{variant:"outlined",size:"small",onClick:M,disabled:!s.serverName||!s.toolName||j||!!w,startIcon:j?(0,a.jsx)(k.default,{size:16}):void 0,children:"Test: call the tool now"}),(0,a.jsx)(o.default,{variant:"caption",color:"text.secondary",children:"See what the result looks like — useful for the settings below."})]}),T&&(0,a.jsx)(G.A,{severity:"error",sx:{mb:1},children:T}),C&&(0,a.jsx)(l.default,{component:"pre",sx:{maxHeight:240,overflow:"auto",bgcolor:"action.hover",borderRadius:1,p:1.5,fontSize:12,m:0,mb:1},children:C}),(0,a.jsx)(o.default,{variant:"subtitle2",sx:{mt:2,mb:1},children:"Run the flow when…"}),(0,a.jsxs)(l.default,{role:"radiogroup","aria-label":"Poll condition",sx:{display:"flex",gap:2,flexWrap:"wrap"},children:[(0,a.jsx)(Q,{selected:"on-change"===U.mode,onClick:()=>i({...s,evaluate:{mode:"on-change"}}),icon:(0,a.jsx)(ex,{}),title:"The result changes",description:"Any difference from the last check runs the flow. Simplest — no setup."}),(0,a.jsx)(Q,{selected:"llm-gate"===U.mode||"flow-gate"===U.mode,onClick:()=>{"llm-gate"!==U.mode&&"flow-gate"!==U.mode&&i({...s,evaluate:{mode:"llm-gate",condition:"",modelId:""}})},icon:(0,a.jsx)(ef,{}),title:"AI decides",description:"Describe the condition in plain language; a model — or one of your flows — checks the result whenever it changes."})]}),("llm-gate"===U.mode||"flow-gate"===U.mode)&&(0,a.jsxs)(l.default,{sx:{mt:1},children:[(0,a.jsx)(D.A,{fullWidth:!0,label:"Run the flow if…",value:U.condition,onChange:e=>i({...s,evaluate:{...U,condition:e.target.value}}),multiline:!0,minRows:2,margin:"normal",placeholder:"e.g. any email mentions an invoice or a payment reminder"}),(0,a.jsxs)(l.default,{sx:{display:"flex",gap:2,flexWrap:"wrap",alignItems:"flex-start"},children:[(0,a.jsxs)(z.A,{sx:{minWidth:170},children:[(0,a.jsx)(_.A,{id:"gate-checker-label",children:"Checked by"}),(0,a.jsxs)(H.A,{labelId:"gate-checker-label",label:"Checked by",value:U.mode,onChange:e=>{let t=e.target.value;if(t===U.mode)return;let r={condition:U.condition,maxCallsPerDay:U.maxCallsPerDay};i({...s,evaluate:"llm-gate"===t?{mode:t,...r,modelId:""}:{mode:t,...r,flowId:""}})},children:[(0,a.jsx)(J.A,{value:"llm-gate",children:"A model"}),(0,a.jsx)(J.A,{value:"flow-gate",children:"One of my flows"})]})]}),"llm-gate"===U.mode&&(0,a.jsxs)(z.A,{sx:{minWidth:240,flex:1},children:[(0,a.jsx)(_.A,{id:"gate-model-label",children:"Model that checks"}),(0,a.jsxs)(H.A,{labelId:"gate-model-label",label:"Model that checks",value:E.some(e=>e.id===U.modelId)?U.modelId:"",onChange:e=>i({...s,evaluate:{...U,modelId:e.target.value}}),children:[0===E.length&&(0,a.jsx)(J.A,{value:"",disabled:!0,children:"No models configured"}),E.map(e=>(0,a.jsx)(J.A,{value:e.id,children:e.displayName||e.name},e.id))]})]}),"flow-gate"===U.mode&&(0,a.jsxs)(z.A,{sx:{minWidth:240,flex:1},children:[(0,a.jsx)(_.A,{id:"gate-flow-label",children:"Flow that checks"}),(0,a.jsxs)(H.A,{labelId:"gate-flow-label",label:"Flow that checks",value:F.some(e=>e.id===U.flowId)?U.flowId:"",onChange:e=>i({...s,evaluate:{...U,flowId:e.target.value}}),children:[0===F.length&&(0,a.jsx)(J.A,{value:"",disabled:!0,children:"No flows available"}),F.map(e=>(0,a.jsx)(J.A,{value:e.id,children:e.name},e.id))]})]}),(0,a.jsx)(D.A,{label:"Max checks per day",type:"number",value:null!=(r=U.maxCallsPerDay)?r:500,onChange:e=>i({...s,evaluate:{...U,maxCallsPerDay:Math.max(1,Number(e.target.value)||1)}}),inputProps:{min:1},helperText:"Cost guard per check.",sx:{width:180}})]}),(0,a.jsx)(o.default,{variant:"caption",color:"text.secondary",sx:{display:"block",mt:.5},children:"flow-gate"===U.mode?'The checker flow runs invisibly (never in the chat), gets the condition + tool result, and must answer with {"fire": true/false, "reason": "…"} — it can use its own tools to verify before deciding.':"The model is only asked when the result actually changed since the last check — an idle feed costs nothing. Pick a small, cheap model."})]}),(0,a.jsx)(G.A,{severity:"info",sx:{mt:2},children:"The first check only takes a snapshot — the flow runs from the second check onwards, when something actually changed. FLUJO must be running for checks to happen."})]})},eC=e=>{let{config:t,onChange:r}=e;return(0,a.jsxs)(l.default,{sx:{mt:1},children:[(0,a.jsx)(D.A,{fullWidth:!0,label:"URL to watch",value:t.url,onChange:e=>r({...t,url:e.target.value}),placeholder:"https://example.com/status or an API/feed URL",margin:"normal",type:"url"}),(0,a.jsx)(o.default,{variant:"subtitle2",sx:{mt:1},children:"How often to check"}),(0,a.jsx)(en,{verb:"Check",cron:t.cron,timezone:t.timezone,onChange:e=>{let{cron:a,timezone:l}=e;return r({...t,cron:a,timezone:l})}}),(0,a.jsx)(G.A,{severity:"info",sx:{mt:1},children:"The first check only takes a snapshot; the flow runs when a later check finds different content, and the fetched content is handed to the flow. Pages that embed ever-changing bits (timestamps, session tokens) look “changed” on every check — plain APIs, feeds, and raw files work best."})]})},eS=(0,v.h)("frontend/components/PlannedExecutions/ExecutionModal"),eT={type:"schedule",cron:"0 9 * * *"},eN={type:"file-watch",path:"",events:["add","change"]},eE={type:"mcp-poll",serverName:"",toolName:"",args:{},cron:"*/5 * * * *",evaluate:{mode:"on-change"}},eI={type:"url-watch",url:"",cron:"*/15 * * * *"},eF=e=>{var t;let{open:r,execution:m,onClose:x,onSaved:f}=e,[v,y]=(0,n.useState)(""),[w,j]=(0,n.useState)(""),[A,k]=(0,n.useState)(""),[C,S]=(0,n.useState)(!1),[T,N]=(0,n.useState)(eT),[E,I]=(0,n.useState)(""),[F,P]=(0,n.useState)([]),[M,U]=(0,n.useState)(!1),[W,L]=(0,n.useState)(!1),[O,Y]=(0,n.useState)(null);(0,n.useEffect)(()=>{var e,t,a,l;r&&(Y(null),y(null!=(e=null==m?void 0:m.name)?e:""),j(null!=(t=null==m?void 0:m.flowId)?t:""),k(null!=(a=null==m?void 0:m.prompt)?a:""),S((null==m?void 0:m.saveConversations)===!0),N(null!=(l=null==m?void 0:m.trigger)?l:eT),I(m?"":crypto.randomUUID()))},[r,m]),(0,n.useEffect)(()=>{if(!r)return;let e=!1;return U(!0),X.g.loadFlows().then(t=>{e||P(t||[])}).catch(t=>{eS.warn("Failed to load flows for execution picker",t),e||P([])}).finally(()=>{e||U(!1)}),()=>{e=!0}},[r]);let ee=!!w&&!M&&F.length>0&&!F.some(e=>e.id===w),et=async()=>{var e;L(!0),Y(null);let t={name:v,flowId:w,prompt:A,saveConversations:C,trigger:T,enabled:null==(e=null==m?void 0:m.enabled)||e,...m?{}:{id:E}},r=m?await b.update(m.id,t):await b.create(t);if(L(!1),!r.success)return void Y(r.error||"Failed to save");f(),x()};return(0,a.jsxs)(d.A,{open:r,onClose:x,maxWidth:"md",fullWidth:!0,PaperProps:{sx:{borderTop:5,borderColor:"primary.main",maxWidth:"95vw",maxHeight:"90vh"}},children:[(0,a.jsx)(u.A,{component:"div",children:(0,a.jsxs)(l.default,{display:"flex",alignItems:"center",justifyContent:"space-between",children:[(0,a.jsx)(o.default,{variant:"h6",children:m?"Edit planned execution":"New planned execution"}),(0,a.jsx)(g.A,{edge:"end",color:"inherit",onClick:x,"aria-label":"close",children:(0,a.jsx)(K.A,{})})]})}),(0,a.jsx)(R.A,{}),(0,a.jsxs)(h.A,{sx:{p:3},children:[(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",sx:{mb:2},children:"A planned execution runs one of your flows automatically — on a schedule or when something happens — without anyone sitting in the chat. Results show up in its run history on the Executions page."}),(0,a.jsx)(D.A,{fullWidth:!0,label:"Name",value:v,onChange:e=>y(e.target.value),margin:"normal",placeholder:"e.g. Morning news digest"}),(0,a.jsx)(o.default,{variant:"subtitle1",sx:{mt:3,mb:1,fontWeight:600},children:"1 \xb7 When should it run?"}),(0,a.jsxs)(l.default,{role:"radiogroup","aria-label":"Trigger type",sx:{display:"flex",gap:2,flexWrap:"wrap"},children:[(0,a.jsx)(Q,{selected:"schedule"===T.type,onClick:()=>{"schedule"!==T.type&&N((null==m?void 0:m.trigger.type)==="schedule"?m.trigger:eT)},icon:(0,a.jsx)(V,{}),title:"On a schedule",description:"Run at fixed times — every few minutes, daily, on weekdays, or a custom rhythm."}),(0,a.jsx)(Q,{selected:"webhook"===T.type,onClick:()=>{"webhook"!==T.type&&N((null==m?void 0:m.trigger.type)==="webhook"?m.trigger:{type:"webhook",token:crypto.randomUUID()})},icon:(0,a.jsx)(B,{}),title:"When called (webhook)",description:"Other apps run this flow by calling a URL — GitHub, Stripe, Slack and most services can send webhooks."}),(0,a.jsx)(Q,{selected:"file-watch"===T.type,onClick:()=>{"file-watch"!==T.type&&N((null==m?void 0:m.trigger.type)==="file-watch"?m.trigger:eN)},icon:(0,a.jsx)(q.A,{}),title:"When files change",description:"Watch a folder on this computer and run when files appear, change, or disappear."}),(0,a.jsx)(Q,{selected:"mcp-poll"===T.type,onClick:()=>{"mcp-poll"!==T.type&&N((null==m?void 0:m.trigger.type)==="mcp-poll"?m.trigger:eE)},icon:(0,a.jsx)($,{}),title:"Watch a tool",description:"Check one of your MCP tools regularly — run when its result changes, or let AI decide."}),(0,a.jsx)(Q,{selected:"url-watch"===T.type,onClick:()=>{"url-watch"!==T.type&&N((null==m?void 0:m.trigger.type)==="url-watch"?m.trigger:eI)},icon:(0,a.jsx)(Z.A,{}),title:"When a website changes",description:"Check a URL regularly and run when its content is different from the last check."})]}),"schedule"===T.type&&(0,a.jsx)(en,{cron:T.cron,timezone:T.timezone,onChange:e=>{let{cron:t,timezone:r}=e;return N({...T,cron:t,timezone:r})},catchUp:!0===T.catchUp,onCatchUpChange:e=>N({...T,catchUp:e})}),"webhook"===T.type&&(0,a.jsx)(ei,{config:T,onChange:N,executionId:null!=(t=null==m?void 0:m.id)?t:E,saved:null!==m}),"file-watch"===T.type&&(0,a.jsx)(em,{config:T,onChange:N}),"mcp-poll"===T.type&&(0,a.jsx)(ek,{config:T,onChange:N}),"url-watch"===T.type&&(0,a.jsx)(eC,{config:T,onChange:N}),(0,a.jsx)(R.A,{sx:{mt:3}}),(0,a.jsx)(o.default,{variant:"subtitle1",sx:{mt:2,mb:0,fontWeight:600},children:"2 \xb7 What should it run?"}),(0,a.jsxs)(z.A,{fullWidth:!0,margin:"normal",children:[(0,a.jsx)(_.A,{id:"execution-flow-label",children:"Flow to run"}),(0,a.jsxs)(H.A,{labelId:"execution-flow-label",label:"Flow to run",value:ee?"":w,onChange:e=>j(e.target.value),displayEmpty:!0,children:[0===F.length&&(0,a.jsx)(J.A,{value:"",disabled:!0,children:M?"Loading flows…":"No flows available"}),F.map(e=>(0,a.jsx)(J.A,{value:e.id,children:e.name},e.id))]})]}),ee&&(0,a.jsx)(G.A,{severity:"warning",sx:{mt:1},children:"The previously selected flow no longer exists. Please choose another."}),(0,a.jsx)(D.A,{fullWidth:!0,label:"What should the flow do?",value:A,onChange:e=>k(e.target.value),margin:"normal",multiline:!0,rows:3,helperText:"Sent to the flow as the user message each time this runs. Run details are attached automatically: current time, what triggered it, the previous run, the next planned run, and any trigger data."}),(0,a.jsx)(s.A,{sx:{mt:1},control:(0,a.jsx)(i.A,{checked:C,onChange:e=>S(e.target.checked)}),label:"Save full conversations (each run appears in the chat sidebar — useful for debugging)"}),O&&(0,a.jsx)(G.A,{severity:"error",sx:{mt:2},children:O})]}),(0,a.jsxs)(p.A,{children:[(0,a.jsx)(c.A,{onClick:x,children:"Cancel"}),(0,a.jsx)(c.A,{onClick:et,variant:"contained",color:"primary",disabled:W||!v.trim()||!w,children:W?"Saving…":"Save"})]})]})},eP=(0,v.h)("frontend/components/PlannedExecutions"),eM=()=>{let[e,t]=(0,n.useState)([]),[r,v]=(0,n.useState)(!1),[y,w]=(0,n.useState)(!1),[j,A]=(0,n.useState)(!1),[k,C]=(0,n.useState)(null),[S,T]=(0,n.useState)(null),N=(0,n.useCallback)(async()=>{let e=await b.list();t(e.executions),v(e.paused),w(!0)},[]);(0,n.useEffect)(()=>{N()},[N]);let E=e.some(e=>e.status.running);(0,n.useEffect)(()=>{let e=setInterval(()=>{document.hidden||N()},E?3e3:1e4);return()=>clearInterval(e)},[N,E]);let I=async e=>{v(e);let t=await b.setPaused(e);t.success||eP.warn("Failed to toggle pause",t.error),N()},F=async(e,t)=>{await b.update(e.id,{enabled:t}),N()},P=async()=>{S&&(await b.delete(S.id),T(null),N())};return(0,a.jsxs)(l.default,{sx:{p:3,maxWidth:1100,mx:"auto",width:"100%"},children:[(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",justifyContent:"space-between",flexWrap:"wrap",gap:2,mb:1},children:[(0,a.jsx)(o.default,{variant:"h5",children:"Planned Executions"}),(0,a.jsxs)(l.default,{sx:{display:"flex",alignItems:"center",gap:2},children:[(0,a.jsx)(f.A,{title:"Refresh",children:(0,a.jsx)(g.A,{onClick:()=>void N(),children:(0,a.jsx)(x.A,{})})}),(0,a.jsx)(s.A,{control:(0,a.jsx)(i.A,{checked:!r,onChange:e=>I(!e.target.checked)}),label:r?"Paused":"Active"}),(0,a.jsx)(c.A,{variant:"contained",startIcon:(0,a.jsx)(m.A,{}),onClick:()=>{C(null),A(!0)},"data-tour":"add-execution",children:"Add"})]})]}),(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",sx:{mb:3},children:"Run your flows automatically — on a schedule or when something happens — without opening the chat. FLUJO must be running for triggers to fire."}),y&&0===e.length&&(0,a.jsxs)(l.default,{sx:{border:1,borderColor:"divider",borderRadius:2,borderStyle:"dashed",p:6,textAlign:"center"},children:[(0,a.jsx)(o.default,{variant:"h6",sx:{mb:1},children:"Nothing planned yet"}),(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",sx:{mb:2},children:"Create your first planned execution to run a flow on a schedule."}),(0,a.jsx)(c.A,{variant:"contained",startIcon:(0,a.jsx)(m.A,{}),onClick:()=>{C(null),A(!0)},children:"New planned execution"})]}),(0,a.jsx)(l.default,{sx:{display:"flex",flexDirection:"column",gap:2},children:e.map(e=>(0,a.jsx)(O,{entry:e,onEdit:()=>{C(e.execution),A(!0)},onDelete:()=>T(e.execution),onToggleEnabled:t=>F(e.execution,t),onRanNow:()=>void N()},e.execution.id))}),(0,a.jsx)(eF,{open:j,execution:k,onClose:()=>A(!1),onSaved:()=>void N()}),(0,a.jsxs)(d.A,{open:null!==S,onClose:()=>T(null),children:[(0,a.jsxs)(u.A,{children:["Delete “",null==S?void 0:S.name,"”?"]}),(0,a.jsx)(h.A,{children:(0,a.jsx)(o.default,{variant:"body2",color:"text.secondary",children:"This removes the planned execution and its run history. The flow itself is not affected."})}),(0,a.jsxs)(p.A,{children:[(0,a.jsx)(c.A,{onClick:()=>T(null),children:"Cancel"}),(0,a.jsx)(c.A,{color:"error",variant:"contained",onClick:P,children:"Delete"})]})]})]})},eU=(0,v.h)("app/executions/page");function eW(){return eU.debug("Rendering ExecutionsPage"),(0,a.jsx)(l.default,{sx:{height:"100%",display:"flex",flexDirection:"column"},children:(0,a.jsx)(eM,{})})}},48072:(e,t,r)=>{"use strict";r.d(t,{Lg:()=>o,eZ:()=>i,fC:()=>n,h5:()=>c});var a=r(88107),l=r(38459);let n={"name-asc":"Name (A-Z)","name-desc":"Name (Z-A)",provider:"Provider","context-desc":"Context (largest)","context-asc":"Context (smallest)"},o=e=>e.displayName||e.name||"",s=e=>(0,a.T_)(e.provider,e.adapter).label;function i(e,t){switch(t){case"provider":{let t=s(e);return{key:"provider:".concat(t),label:t}}case"context-asc":case"context-desc":var r;return"number"!=typeof(r=e.contextWindow)||Number.isNaN(r)?{key:"ctx:unknown",label:"Unknown context"}:r<=8e3?{key:"ctx:<=8k",label:"≤ 8K tokens"}:r<=32e3?{key:"ctx:8k-32k",label:"8K–32K tokens"}:r<=128e3?{key:"ctx:32k-128k",label:"32K–128K tokens"}:r<=1e6?{key:"ctx:128k-1m",label:"128K–1M tokens"}:{key:"ctx:>1m",label:"> 1M tokens"};default:return(0,l.po)(o(e))}}function c(e,t){return[...e].sort((e,r)=>{switch(t){case"name-asc":return o(e).localeCompare(o(r));case"name-desc":return o(r).localeCompare(o(e));case"provider":return s(e).localeCompare(s(r))||o(e).localeCompare(o(r));case"context-desc":case"context-asc":{let a="number"!=typeof e.contextWindow||Number.isNaN(e.contextWindow)?void 0:e.contextWindow,l="number"!=typeof r.contextWindow||Number.isNaN(r.contextWindow)?void 0:r.contextWindow;if(void 0===a&&void 0===l)return o(e).localeCompare(o(r));if(void 0===a)return 1;if(void 0===l)return -1;let n="context-desc"===t?l-a:a-l;return 0!==n?n:o(e).localeCompare(o(r))}default:return 0}})}},53657:(e,t,r)=>{"use strict";r.d(t,{A:()=>n});var a=r(36697),l=r(95155);let n=(0,a.A)((0,l.jsx)("path",{d:"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2m6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56M12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96M4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2s.06 1.34.14 2zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56m2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8M12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96M14.34 14H9.66c-.09-.66-.16-1.32-.16-2s.07-1.35.16-2h4.68c.09.65.16 1.32.16 2s-.07 1.34-.16 2m.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56M16.36 14c.08-.66.14-1.32.14-2s-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2z"}),"Language")},55406:(e,t,r)=>{"use strict";r.d(t,{A:()=>n});var a=r(36697),l=r(95155);let n=(0,a.A)((0,l.jsx)("path",{d:"M8 5v14l11-7z"}),"PlayArrow")},60187:(e,t,r)=>{Promise.resolve().then(r.bind(r,45755))},62962:(e,t,r)=>{"use strict";r.d(t,{A:()=>n});var a=r(36697),l=r(95155);let n=(0,a.A)((0,l.jsx)("path",{d:"m12 8-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"}),"ExpandLess")},68503:(e,t,r)=>{"use strict";r.d(t,{E:()=>d});var a=r(12115),l=r(97104),n=r(38459),o=r(48072),s=r(65818),i=r(88377);let c={models:{defaultSort:"name-asc",sort:(e,t)=>(0,o.h5)(e,t),deriveSortGroup:(e,t)=>(0,o.eZ)(e,t),getFolder:e=>e.folder,getSearchText:e=>{var t;return"".concat((0,o.Lg)(e)," ").concat(null!=(t=e.name)?t:"")}},mcp:{defaultSort:"name-asc",sort:(e,t)=>(0,s.rI)(e,t),deriveSortGroup:(e,t)=>(0,s.mO)(e,t),getFolder:e=>e.folder,getSearchText:e=>{var t,r,a;return"".concat(null!=(t=e.name)?t:""," ").concat(null!=(a=null!=(r=e.rootPath)?r:e.path)?a:"")}},flows:{defaultSort:"name-asc",sort:(e,t)=>(0,i.KT)(e,t),deriveSortGroup:(e,t)=>(0,i.ts)(e,t),getFolder:e=>e.folder,getSearchText:e=>{var t;return null!=(t=e.name)?t:""}}};function d(e,t){let r=c[e],[o,s]=(0,a.useState)(""),[i]=(0,l.Xk)("flujo-ui:".concat(e,":sort"),r.defaultSort),[d]=(0,l.Xk)("flujo-ui:".concat(e,":group"),"none"),[u,h]=(0,l.Xk)("flujo-ui:".concat(e,":collapsed"),[]),p=(0,a.useMemo)(()=>new Set(u),[u]),m=(0,a.useMemo)(()=>{let e=o.trim().toLowerCase(),a=e?t.filter(t=>r.getSearchText(t).toLowerCase().includes(e)):t;return r.sort([...a],i)},[t,o,i,r]),x=(0,a.useMemo)(()=>"folder"===d?(0,n.Je)(m,e=>r.getFolder(e)):"sort"===d?(0,n.Az)(m,e=>r.deriveSortGroup(e,i)):null,[d,m,i,r]);return{searchTerm:o,setSearchTerm:s,sortOption:i,groupMode:d,items:m,groups:x,collapsedKeys:p,toggleGroup:(0,a.useCallback)(e=>{h(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])},[h])}}},74879:(e,t,r)=>{"use strict";let a;r.d(t,{A:()=>s});let l={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)},n=new Uint8Array(16),o=[];for(let e=0;e<256;++e)o.push((e+256).toString(16).slice(1));let s=function(e,t,r){if(l.randomUUID&&!t&&!e)return l.randomUUID();let s=(e=e||{}).random??e.rng?.()??function(){if(!a){if("undefined"==typeof crypto||!crypto.getRandomValues)throw Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");a=crypto.getRandomValues.bind(crypto)}return a(n)}();if(s.length<16)throw Error("Random bytes length must be >= 16");if(s[6]=15&s[6]|64,s[8]=63&s[8]|128,t){if((r=r||0)<0||r+16>t.length)throw RangeError(`UUID byte range ${r}:${r+15} is out of buffer bounds`);for(let e=0;e<16;++e)t[r+e]=s[e];return t}return function(e,t=0){return(o[e[t+0]]+o[e[t+1]]+o[e[t+2]]+o[e[t+3]]+"-"+o[e[t+4]]+o[e[t+5]]+"-"+o[e[t+6]]+o[e[t+7]]+"-"+o[e[t+8]]+o[e[t+9]]+"-"+o[e[t+10]]+o[e[t+11]]+o[e[t+12]]+o[e[t+13]]+o[e[t+14]]+o[e[t+15]]).toLowerCase()}(s)}},88107:(e,t,r)=>{"use strict";r.d(t,{T_:()=>l,xx:()=>a});let a=[{id:"openai",label:"OpenAI",provider:"openai",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://api.openai.com/v1",showBaseUrl:!0},{id:"openrouter",label:"OpenRouter",provider:"openrouter",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://openrouter.ai/api/v1",showBaseUrl:!0},{id:"requesty",label:"Requesty",provider:"requesty",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://router.requesty.ai/v1",showBaseUrl:!0},{id:"xai",label:"X.ai",provider:"xai",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://api.x.ai/v1",showBaseUrl:!0},{id:"ollama",label:"Ollama",provider:"ollama",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"http://localhost:11434/v1",showBaseUrl:!0},{id:"litellm",label:"LiteLLM",provider:"litellm",adapter:"openai",sdkLabel:"OpenAI SDK (via LiteLLM Proxy)",baseUrl:"http://localhost:4000/v1",showBaseUrl:!0},{id:"gemini-openai",label:"Gemini (OpenAI Format)",provider:"gemini",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://generativelanguage.googleapis.com/v1beta/openai/",showBaseUrl:!0},{id:"gemini-native",label:"Gemini (Native)",provider:"gemini",adapter:"gemini",sdkLabel:"GenAI SDK",baseUrl:"",showBaseUrl:!1,defaultModels:["gemini-2.5-pro","gemini-2.5-flash","gemini-2.5-flash-lite","gemini-2.0-flash"]},{id:"anthropic-openai",label:"Anthropic (OpenAI Format)",provider:"anthropic",adapter:"openai",sdkLabel:"OpenAI SDK",baseUrl:"https://api.anthropic.com/v1/",showBaseUrl:!0},{id:"anthropic-native",label:"Anthropic (Native)",provider:"anthropic",adapter:"anthropic",sdkLabel:"Anthropic SDK",baseUrl:"",showBaseUrl:!1,defaultModels:["claude-opus-4-8","claude-sonnet-4-6","claude-haiku-4-5-20251001","claude-fable-5"]},{id:"claude-subscription",label:"Claude Subscription",provider:"claude-subscription",adapter:"claude-cli",sdkLabel:"Claude CLI",baseUrl:"",showBaseUrl:!1,defaultModels:["opus","sonnet","haiku","fable"]}];function l(e,t){let r=e||"openai",l=t||"openai";return a.find(e=>e.provider===r&&e.adapter===l)||a.find(e=>e.provider===r)||a[0]}},88377:(e,t,r)=>{"use strict";r.d(t,{KT:()=>n,ts:()=>l});var a=r(38459);function l(e,t){switch(t){case"name-asc":case"name-desc":return(0,a.po)(e.name);case"most-nodes":case"least-nodes":var r;return 0===(r=e.nodes.length)?{key:"nodes:0",label:"0 nodes"}:r<=2?{key:"nodes:1-2",label:"1–2 nodes"}:r<=5?{key:"nodes:3-5",label:"3–5 nodes"}:r<=10?{key:"nodes:6-10",label:"6–10 nodes"}:{key:"nodes:11+",label:"11+ nodes"};default:return{key:"all",label:"All flows"}}}function n(e,t){return[...e].sort((e,r)=>{switch(t){case"name-asc":return e.name.localeCompare(r.name);case"name-desc":return r.name.localeCompare(e.name);case"most-nodes":return r.nodes.length-e.nodes.length;case"least-nodes":return e.nodes.length-r.nodes.length;case"newest":return r.id.localeCompare(e.id);case"oldest":return e.id.localeCompare(r.id);default:return 0}})}},90057:(e,t,r)=>{"use strict";r.d(t,{g:()=>o});var a=r(74879);let l=(0,r(87021).h)("frontend/services/flow/index");class n{async loadFlows(){l.debug("loadFlows: Entering method");try{if(this.flowsCache)return l.debug("loadFlows: Using cached flows",{count:this.flowsCache.length}),this.flowsCache;let e=await fetch("/api/flow");if(!e.ok){let t=await e.json();throw Error(t.error||"Failed to load flows")}let t=await e.json();return l.debug("loadFlows: Loaded flows from API",{count:t.length}),this.flowsCache=t,t}catch(e){return l.warn("loadFlows: Failed to load flows:",e),[]}}async getFlow(e){l.debug("getFlow: Entering method",{flowId:e});try{if(this.flowsCache){let t=this.flowsCache.find(t=>t.id===e);if(t)return l.debug("getFlow: Using cached flow",{flowId:e}),t}let t=await fetch("/api/flow/".concat(encodeURIComponent(e)));if(!t.ok){if(404===t.status)return l.debug("getFlow: Flow ".concat(e," not found")),null;let r=await t.json();throw Error(r.error||"Failed to get flow: ".concat(e))}let r=await t.json();return l.debug("getFlow: Retrieved flow from API",{flowId:e}),r}catch(t){return l.warn("getFlow: Failed to get flow ".concat(e,":"),t),null}}async addFlow(e){l.debug("addFlow: Entering method",{flowId:e.id,flowName:e.name,nodeCount:e.nodes.length,edgeCount:e.edges.length});try{let t=await fetch("/api/flow",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){let e=await t.json();return{success:!1,error:e.error||"Failed to add flow"}}let r=await t.json();return this.flowsCache&&this.flowsCache.push(r),l.debug("addFlow: Flow added successfully",{flowId:e.id}),{success:!0}}catch(e){return l.warn("addFlow: Failed to add flow:",e),{success:!1,error:e instanceof Error?e.message:"Failed to add flow"}}}async generateFlow(e,t,r){l.debug("generateFlow: Entering method",{modelId:t,allowInstall:null==r?void 0:r.allowInstall,allowSubflows:null==r?void 0:r.allowSubflows,maxDepth:null==r?void 0:r.maxDepth});try{var a,n,o,s,i,c,d;let u=await fetch("/api/flow/generate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({description:e,modelId:t,allowInstall:(null==r?void 0:r.allowInstall)===!0,allowSubflows:(null==r?void 0:r.allowSubflows)===!0,..."number"==typeof(null==r?void 0:r.maxDepth)?{maxDepth:r.maxDepth}:{}})}),h=await u.json().catch(()=>null);if(!u.ok)return{success:!1,error:(null==h?void 0:h.error)||"Failed to generate flow"};let p=Array.isArray(h.flows)&&h.flows.length>0?h.flows:[{flow:h.flow,validation:h.validation}];return l.debug("generateFlow: Draft generated",{flowId:null==(a=h.flow)?void 0:a.id,flowCount:p.length,attempts:h.attempts,errorCount:null==(n=h.validation)?void 0:n.errorCount,installedServers:null!=(i=null==(o=h.installedServers)?void 0:o.length)?i:0}),{success:!0,flow:h.flow,validation:h.validation,flows:p,rootFlowId:null!=(c=h.rootFlowId)?c:null==(s=h.flow)?void 0:s.id,attempts:h.attempts,installedServers:null!=(d=h.installedServers)?d:[]}}catch(e){return l.warn("generateFlow: Failed to generate flow:",e),{success:!1,error:e instanceof Error?e.message:"Failed to generate flow"}}}async improveFlow(e,t,r,a){l.debug("improveFlow: Entering method",{flowId:null==e?void 0:e.id,modelId:r,allowInstall:null==a?void 0:a.allowInstall});try{var n,o,s,i,c;let d=await fetch("/api/flow/improve",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({flow:e,description:t,modelId:r,allowInstall:(null==a?void 0:a.allowInstall)===!0})}),u=await d.json().catch(()=>null);if(!d.ok)return{success:!1,error:(null==u?void 0:u.error)||"Failed to improve flow"};return l.debug("improveFlow: Draft revised",{flowId:null==(n=u.flow)?void 0:n.id,attempts:u.attempts,errorCount:null==(o=u.validation)?void 0:o.errorCount,installedServers:null!=(i=null==(s=u.installedServers)?void 0:s.length)?i:0}),{success:!0,flow:u.flow,validation:u.validation,attempts:u.attempts,installedServers:null!=(c=u.installedServers)?c:[]}}catch(e){return l.warn("improveFlow: Failed to improve flow:",e),{success:!1,error:e instanceof Error?e.message:"Failed to improve flow"}}}async updateFlow(e){l.debug("updateFlow: Entering method",{flowId:e.id,flowName:e.name,nodeCount:e.nodes.length,edgeCount:e.edges.length});try{let t=await fetch("/api/flow/".concat(encodeURIComponent(e.id)),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){let e=await t.json();return{success:!1,error:e.error||"Failed to update flow"}}let r=await t.json();if(this.flowsCache){let t=this.flowsCache.findIndex(t=>t.id===e.id);t>=0?this.flowsCache[t]=r:this.flowsCache.push(r)}return l.debug("updateFlow: Flow updated successfully",{flowId:e.id}),{success:!0}}catch(e){return l.warn("updateFlow: Failed to update flow:",e),{success:!1,error:e instanceof Error?e.message:"Failed to update flow"}}}async deleteFlow(e){l.debug("deleteFlow: Entering method",{flowId:e});try{let t=await fetch("/api/flow/".concat(encodeURIComponent(e)),{method:"DELETE"});if(!t.ok){let e=await t.json();return{success:!1,error:e.error||"Failed to delete flow"}}return this.flowsCache&&(this.flowsCache=this.flowsCache.filter(t=>t.id!==e)),l.debug("deleteFlow: Flow deleted successfully",{flowId:e}),{success:!0}}catch(e){return l.warn("deleteFlow: Failed to delete flow:",e),{success:!1,error:e instanceof Error?e.message:"Failed to delete flow"}}}createNode(e,t){return l.debug("createNode: Entering method",{type:e,position:t}),{id:(0,a.A)(),type:e,position:t,data:{label:"".concat("mcp"===e?"MCP":e.charAt(0).toUpperCase()+e.slice(1)," Node"),type:e,properties:{}}}}createStartNode(){return{id:(0,a.A)(),type:"start",position:{x:250,y:150},data:{label:"Start Node",type:"start",properties:{promptTemplate:""}}}}createNewFlow(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"NewFlow";return l.debug("createNewFlow: Entering method",{name:e}),{id:(0,a.A)(),name:e,nodes:[this.createStartNode()],edges:[]}}createHistoryEntry(e,t){return l.debug("createHistoryEntry: Entering method"),{nodes:[...e],edges:[...t]}}generateSampleFlow(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"Sample Flow";return l.debug("generateSampleFlow: Entering method",{name:e}),{id:(0,a.A)(),name:e,nodes:[{id:"1",type:"start",position:{x:250,y:50},data:{label:"Start Node",type:"start",properties:{prompt:"Enter your query here",systemMessage:"You are a helpful assistant",temperature:0}}},{id:"2",type:"process",position:{x:250,y:200},data:{label:"Process Node",type:"process",properties:{operation:"transform",enabled:!0}}},{id:"3",type:"finish",position:{x:250,y:350},data:{label:"Finish Node",type:"finish",properties:{format:"json",template:'{ "result": {{data}} }'}}},{id:"4",type:"mcp",position:{x:450,y:200},data:{label:"MCP Node",type:"mcp",properties:{channels:2,mode:"parallel"}}}],edges:[{id:"e1-2",source:"1",target:"2",type:"custom"},{id:"e2-3",source:"2",target:"3",type:"custom"}]}}constructor(){this.flowsCache=null}}let o=new n},96362:(e,t,r)=>{"use strict";r.d(t,{A:()=>x});var a=r(95155);r(12115);var l=r(2778),n=r(52363),o=r(94049),s=r(25635),i=r(41983),c=r(21067),d=r(65036),u=r(75912),h=r(91871),p=r(77073),m=r(99162);let x=e=>{let{open:t,onClose:r,title:x,description:f,maxWidth:g="md",...v}=e;return(0,a.jsxs)(l.A,{open:t,onClose:r,maxWidth:g,fullWidth:!0,children:[(0,a.jsx)(n.A,{component:"div",children:(0,a.jsxs)(o.default,{display:"flex",alignItems:"center",justifyContent:"space-between",children:[(0,a.jsx)(s.default,{variant:"h6",children:x}),(0,a.jsx)(i.A,{edge:"end",color:"inherit",onClick:r,"aria-label":"close",children:(0,a.jsx)(p.A,{})})]})}),(0,a.jsx)(c.A,{}),(0,a.jsxs)(d.A,{sx:{p:3},children:[f&&(0,a.jsx)(s.default,{variant:"body2",color:"text.secondary",sx:{mb:2},children:f}),(0,a.jsx)(m.A,{...v})]}),(0,a.jsx)(u.A,{children:(0,a.jsx)(h.A,{onClick:r,children:"Cancel"})})]})}},99162:(e,t,r)=>{"use strict";r.d(t,{A:()=>m});var a=r(95155),l=r(12115),n=r(33077),o=r(94049),s=r(9562),i=r(56422),c=r(4474),d=r(25635),u=r(51611),h=r(22573);let p={xs:12,sm:6,md:4},m=e=>{let{isLoading:t=!1,error:r=null,emptyMessage:m="Nothing to choose from.",loadingMessage:x="Loading…",skeleton:f,skeletonCount:g=4,columns:v=p,items:y,searchable:w=!1,searchPlaceholder:b="Search…",searchTerm:j,onSearchChange:A,groups:k,collapsedKeys:C,onToggleGroup:S}=e,T={...p,...v},[N,E]=(0,l.useState)(""),I=void 0!==j,F=I?j:N,[P,M]=(0,l.useState)(new Set),U=null!=C?C:P,W=e=>(0,a.jsx)(n.Ay,{container:!0,spacing:2,alignItems:"stretch",children:e.map(e=>(0,a.jsx)(n.Ay,{item:!0,xs:T.xs,sm:T.sm,md:T.md,lg:T.lg,sx:{display:"flex"},children:(0,a.jsx)(o.default,{sx:{width:"100%"},children:e.content})},e.key))}),L=w?(0,a.jsx)(s.A,{placeholder:b,variant:"outlined",size:"small",fullWidth:!0,value:F,onChange:e=>(e=>{null==A||A(e),I||E(e)})(e.target.value),sx:{mb:2},InputProps:{startAdornment:(0,a.jsx)(i.A,{position:"start",children:(0,a.jsx)(u.A,{fontSize:"small"})})}}):null,O=e=>(0,a.jsxs)(o.default,{children:[L,e]});if(t)return O(f?(0,a.jsx)(n.Ay,{container:!0,spacing:2,children:Array.from({length:g}).map((e,t)=>(0,a.jsx)(n.Ay,{item:!0,xs:T.xs,sm:T.sm,md:T.md,lg:T.lg,children:f},"skeleton-".concat(t)))}):(0,a.jsxs)(o.default,{sx:{display:"flex",alignItems:"center",gap:1,py:2},children:[(0,a.jsx)(c.default,{size:20}),(0,a.jsx)(d.default,{variant:"body2",color:"text.secondary",children:x})]}));if(r)return O((0,a.jsx)(d.default,{color:"error",variant:"body2",sx:{py:2},children:r}));let R=I?"":F.trim().toLowerCase(),D=e=>{var t;return!R||(null!=(t=e.searchText)?t:"").toLowerCase().includes(R)},z=(0,a.jsx)(d.default,{variant:"body2",color:"text.secondary",sx:{py:2},children:m});if(k){let e=k.map(e=>({...e,items:e.items.filter(D)})).filter(e=>e.items.length>0);return O(0===e.length?z:(0,a.jsx)(a.Fragment,{children:e.map(e=>(0,a.jsx)(h.A,{label:e.label,count:e.items.length,expanded:!U.has(e.key),onToggle:()=>(e=>{if(S)return void S(e);M(t=>{let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r})})(e.key),children:W(e.items)},e.key))}))}let _=(null!=y?y:[]).filter(D);return O(0===_.length?z:W(_))}}},e=>{e.O(0,[2678,4754,9244,8548,1871,5501,2003,488,3272,3077,8598,4365,2403,7687,9554,5134,6013,5619,8441,1255,7358],()=>e(e.s=60187)),_N_E=e.O()}]);