@jiggai/kitchen 0.1.12 → 0.2.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 (1083) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +21 -0
  3. package/.next/build-manifest.json +6 -6
  4. package/.next/prerender-manifest.json +11 -6
  5. package/.next/routes-manifest.json +146 -0
  6. package/.next/server/app/_global-error/page/build-manifest.json +4 -4
  7. package/.next/server/app/_global-error/page.js +3 -3
  8. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  9. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  10. package/.next/server/app/_global-error.html +2 -2
  11. package/.next/server/app/_global-error.rsc +2 -2
  12. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  14. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  17. package/.next/server/app/_not-found/page/build-manifest.json +4 -4
  18. package/.next/server/app/_not-found/page.js +10 -9
  19. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  20. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  21. package/.next/server/app/_not-found.html +1 -1
  22. package/.next/server/app/_not-found.rsc +5 -5
  23. package/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
  24. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  25. package/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  26. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  27. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  28. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  29. package/.next/server/app/agents/[agentId]/page/build-manifest.json +4 -4
  30. package/.next/server/app/agents/[agentId]/page.js +8 -8
  31. package/.next/server/app/agents/[agentId]/page.js.nft.json +1 -1
  32. package/.next/server/app/agents/[agentId]/page_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/agents/[id]/route.js +1 -1
  34. package/.next/server/app/api/agents/[id]/route.js.nft.json +1 -1
  35. package/.next/server/app/api/agents/add/route.js +1 -1
  36. package/.next/server/app/api/agents/add/route.js.nft.json +1 -1
  37. package/.next/server/app/api/agents/file/route.js +1 -1
  38. package/.next/server/app/api/agents/file/route.js.nft.json +1 -1
  39. package/.next/server/app/api/agents/files/route.js +1 -1
  40. package/.next/server/app/api/agents/files/route.js.nft.json +1 -1
  41. package/.next/server/app/api/agents/identity/route.js +1 -1
  42. package/.next/server/app/api/agents/identity/route.js.nft.json +1 -1
  43. package/.next/server/app/api/agents/route.js +1 -1
  44. package/.next/server/app/api/agents/route.js.nft.json +1 -1
  45. package/.next/server/app/api/agents/skills/install/route.js +1 -1
  46. package/.next/server/app/api/agents/skills/install/route.js.nft.json +1 -1
  47. package/.next/server/app/api/agents/skills/route.js +1 -1
  48. package/.next/server/app/api/agents/skills/route.js.nft.json +1 -1
  49. package/.next/server/app/api/agents/update/route.js +1 -1
  50. package/.next/server/app/api/agents/update/route.js.nft.json +1 -1
  51. package/.next/server/app/api/channels/bindings/route.js +1 -1
  52. package/.next/server/app/api/channels/bindings/route.js.nft.json +1 -1
  53. package/.next/server/app/api/cron/delete/route.js +1 -1
  54. package/.next/server/app/api/cron/delete/route.js.nft.json +1 -1
  55. package/.next/server/app/api/cron/job/route.js +1 -1
  56. package/.next/server/app/api/cron/job/route.js.nft.json +1 -1
  57. package/.next/server/app/api/cron/jobs/route.js +1 -1
  58. package/.next/server/app/api/cron/jobs/route.js.nft.json +1 -1
  59. package/.next/server/app/api/cron/recipe-installed/route.js +1 -1
  60. package/.next/server/app/api/cron/recipe-installed/route.js.nft.json +1 -1
  61. package/.next/server/app/api/gateway/restart/route.js +1 -1
  62. package/.next/server/app/api/gateway/restart/route.js.nft.json +1 -1
  63. package/.next/server/app/api/goals/[id]/promote/route.js +1 -1
  64. package/.next/server/app/api/goals/[id]/promote/route.js.nft.json +1 -1
  65. package/.next/server/app/api/goals/[id]/route.js +1 -1
  66. package/.next/server/app/api/goals/[id]/route.js.nft.json +1 -1
  67. package/.next/server/app/api/goals/route.js +1 -1
  68. package/.next/server/app/api/goals/route.js.nft.json +1 -1
  69. package/.next/server/app/api/ids/check/route.js +1 -1
  70. package/.next/server/app/api/ids/check/route.js.nft.json +1 -1
  71. package/.next/server/app/api/marketplace/recipes/[slug]/route.js +1 -1
  72. package/.next/server/app/api/marketplace/recipes/[slug]/route.js.nft.json +1 -1
  73. package/.next/server/app/api/marketplace/recipes/route.js +1 -1
  74. package/.next/server/app/api/marketplace/recipes/route.js.nft.json +1 -1
  75. package/.next/server/app/api/recipes/[id]/route.js +1 -1
  76. package/.next/server/app/api/recipes/[id]/route.js.nft.json +1 -1
  77. package/.next/server/app/api/recipes/clone/route.js +1 -1
  78. package/.next/server/app/api/recipes/clone/route.js.nft.json +1 -1
  79. package/.next/server/app/api/recipes/custom-team/route/app-paths-manifest.json +3 -0
  80. package/.next/server/app/api/recipes/custom-team/route/build-manifest.json +11 -0
  81. package/.next/server/app/api/recipes/custom-team/route/server-reference-manifest.json +4 -0
  82. package/.next/server/app/api/recipes/custom-team/route.js +6 -0
  83. package/.next/server/app/api/recipes/custom-team/route.js.map +5 -0
  84. package/.next/server/app/api/recipes/custom-team/route.js.nft.json +1 -0
  85. package/.next/server/app/api/recipes/custom-team/route_client-reference-manifest.js +2 -0
  86. package/.next/server/app/api/recipes/delete/route.js +1 -1
  87. package/.next/server/app/api/recipes/delete/route.js.nft.json +1 -1
  88. package/.next/server/app/api/recipes/route.js +1 -1
  89. package/.next/server/app/api/recipes/route.js.nft.json +1 -1
  90. package/.next/server/app/api/recipes/team-agents/route.js +1 -1
  91. package/.next/server/app/api/recipes/team-agents/route.js.nft.json +1 -1
  92. package/.next/server/app/api/scaffold/route.js +1 -2
  93. package/.next/server/app/api/scaffold/route.js.nft.json +1 -1
  94. package/.next/server/app/api/settings/cron-installation/route.js +1 -1
  95. package/.next/server/app/api/settings/cron-installation/route.js.nft.json +1 -1
  96. package/.next/server/app/api/skills/available/route.js +1 -1
  97. package/.next/server/app/api/skills/available/route.js.nft.json +1 -1
  98. package/.next/server/app/api/swarms/start/route/app-paths-manifest.json +3 -0
  99. package/.next/server/app/api/swarms/start/route/build-manifest.json +11 -0
  100. package/.next/server/app/api/swarms/start/route/server-reference-manifest.json +4 -0
  101. package/.next/server/app/api/swarms/start/route.js +6 -0
  102. package/.next/server/app/api/swarms/start/route.js.map +5 -0
  103. package/.next/server/app/api/swarms/start/route.js.nft.json +1 -0
  104. package/.next/server/app/api/swarms/start/route_client-reference-manifest.js +2 -0
  105. package/.next/server/app/api/swarms/status/route/app-paths-manifest.json +3 -0
  106. package/.next/server/app/api/swarms/status/route/build-manifest.json +11 -0
  107. package/.next/server/app/api/swarms/status/route/server-reference-manifest.json +4 -0
  108. package/.next/server/app/api/swarms/status/route.js +6 -0
  109. package/.next/server/app/api/swarms/status/route.js.map +5 -0
  110. package/.next/server/app/api/swarms/status/route.js.nft.json +1 -0
  111. package/.next/server/app/api/swarms/status/route_client-reference-manifest.js +2 -0
  112. package/.next/server/app/api/teams/[teamId]/tickets/assign/route/app-paths-manifest.json +3 -0
  113. package/.next/server/app/api/teams/[teamId]/tickets/assign/route/build-manifest.json +11 -0
  114. package/.next/server/app/api/teams/[teamId]/tickets/assign/route/server-reference-manifest.json +4 -0
  115. package/.next/server/app/api/teams/[teamId]/tickets/assign/route.js +6 -0
  116. package/.next/server/app/api/teams/[teamId]/tickets/assign/route.js.map +5 -0
  117. package/.next/server/app/api/teams/[teamId]/tickets/assign/route.js.nft.json +1 -0
  118. package/.next/server/app/api/teams/[teamId]/tickets/assign/route_client-reference-manifest.js +2 -0
  119. package/.next/server/app/api/teams/[teamId]/tickets/assignees/route/app-paths-manifest.json +3 -0
  120. package/.next/server/app/api/teams/[teamId]/tickets/assignees/route/build-manifest.json +11 -0
  121. package/.next/server/app/api/teams/[teamId]/tickets/assignees/route/server-reference-manifest.json +4 -0
  122. package/.next/server/app/api/teams/[teamId]/tickets/assignees/route.js +6 -0
  123. package/.next/server/app/api/teams/[teamId]/tickets/assignees/route.js.map +5 -0
  124. package/.next/server/app/api/teams/[teamId]/tickets/assignees/route.js.nft.json +1 -0
  125. package/.next/server/app/api/teams/[teamId]/tickets/assignees/route_client-reference-manifest.js +2 -0
  126. package/.next/server/app/api/teams/[teamId]/tickets/delete/route/app-paths-manifest.json +3 -0
  127. package/.next/server/app/api/teams/[teamId]/tickets/delete/route/build-manifest.json +11 -0
  128. package/.next/server/app/api/teams/[teamId]/tickets/delete/route/server-reference-manifest.json +4 -0
  129. package/.next/server/app/api/teams/[teamId]/tickets/delete/route.js +6 -0
  130. package/.next/server/app/api/teams/[teamId]/tickets/delete/route.js.map +5 -0
  131. package/.next/server/app/api/teams/[teamId]/tickets/delete/route.js.nft.json +1 -0
  132. package/.next/server/app/api/teams/[teamId]/tickets/delete/route_client-reference-manifest.js +2 -0
  133. package/.next/server/app/api/teams/[teamId]/tickets/move/route/app-paths-manifest.json +3 -0
  134. package/.next/server/app/api/teams/[teamId]/tickets/move/route/build-manifest.json +11 -0
  135. package/.next/server/app/api/teams/[teamId]/tickets/move/route/server-reference-manifest.json +4 -0
  136. package/.next/server/app/api/teams/[teamId]/tickets/move/route.js +6 -0
  137. package/.next/server/app/api/teams/[teamId]/tickets/move/route.js.map +5 -0
  138. package/.next/server/app/api/teams/[teamId]/tickets/move/route.js.nft.json +1 -0
  139. package/.next/server/app/api/teams/[teamId]/tickets/move/route_client-reference-manifest.js +2 -0
  140. package/.next/server/app/api/teams/[teamId]/tickets/move-to-goals/route/app-paths-manifest.json +3 -0
  141. package/.next/server/app/api/teams/[teamId]/tickets/move-to-goals/route/build-manifest.json +11 -0
  142. package/.next/server/app/api/teams/[teamId]/tickets/move-to-goals/route/server-reference-manifest.json +4 -0
  143. package/.next/server/app/api/teams/[teamId]/tickets/move-to-goals/route.js +6 -0
  144. package/.next/server/app/api/teams/[teamId]/tickets/move-to-goals/route.js.map +5 -0
  145. package/.next/server/app/api/teams/[teamId]/tickets/move-to-goals/route.js.nft.json +1 -0
  146. package/.next/server/app/api/teams/[teamId]/tickets/move-to-goals/route_client-reference-manifest.js +2 -0
  147. package/.next/server/app/api/teams/file/route.js +1 -1
  148. package/.next/server/app/api/teams/file/route.js.nft.json +1 -1
  149. package/.next/server/app/api/teams/files/route.js +1 -1
  150. package/.next/server/app/api/teams/files/route.js.nft.json +1 -1
  151. package/.next/server/app/api/teams/memory/route/app-paths-manifest.json +3 -0
  152. package/.next/server/app/api/teams/memory/route/build-manifest.json +11 -0
  153. package/.next/server/app/api/teams/memory/route/server-reference-manifest.json +4 -0
  154. package/.next/server/app/api/teams/memory/route.js +6 -0
  155. package/.next/server/app/api/teams/memory/route.js.map +5 -0
  156. package/.next/server/app/api/teams/memory/route.js.nft.json +1 -0
  157. package/.next/server/app/api/teams/memory/route_client-reference-manifest.js +2 -0
  158. package/.next/server/app/api/teams/meta/route.js +1 -1
  159. package/.next/server/app/api/teams/meta/route.js.nft.json +1 -1
  160. package/.next/server/app/api/teams/orchestrator/install/route/app-paths-manifest.json +3 -0
  161. package/.next/server/app/api/teams/orchestrator/install/route/build-manifest.json +11 -0
  162. package/.next/server/app/api/teams/orchestrator/install/route/server-reference-manifest.json +4 -0
  163. package/.next/server/app/api/teams/orchestrator/install/route.js +6 -0
  164. package/.next/server/app/api/teams/orchestrator/install/route.js.map +5 -0
  165. package/.next/server/app/api/teams/orchestrator/install/route.js.nft.json +1 -0
  166. package/.next/server/app/api/teams/orchestrator/install/route_client-reference-manifest.js +2 -0
  167. package/.next/server/app/api/teams/orchestrator/route/app-paths-manifest.json +3 -0
  168. package/.next/server/app/api/teams/orchestrator/route/build-manifest.json +11 -0
  169. package/.next/server/app/api/teams/orchestrator/route/server-reference-manifest.json +4 -0
  170. package/.next/server/app/api/teams/orchestrator/route.js +6 -0
  171. package/.next/server/app/api/teams/orchestrator/route.js.map +5 -0
  172. package/.next/server/app/api/teams/orchestrator/route.js.nft.json +1 -0
  173. package/.next/server/app/api/teams/orchestrator/route_client-reference-manifest.js +2 -0
  174. package/.next/server/app/api/teams/remove-team/route.js +2 -1
  175. package/.next/server/app/api/teams/remove-team/route.js.nft.json +1 -1
  176. package/.next/server/app/api/teams/skills/install/route.js +1 -1
  177. package/.next/server/app/api/teams/skills/install/route.js.nft.json +1 -1
  178. package/.next/server/app/api/teams/skills/route.js +1 -1
  179. package/.next/server/app/api/teams/skills/route.js.nft.json +1 -1
  180. package/.next/server/app/api/teams/workflow-runs/route/app-paths-manifest.json +3 -0
  181. package/.next/server/app/api/teams/workflow-runs/route/build-manifest.json +11 -0
  182. package/.next/server/app/api/teams/workflow-runs/route/server-reference-manifest.json +4 -0
  183. package/.next/server/app/api/teams/workflow-runs/route.js +7 -0
  184. package/.next/server/app/api/teams/workflow-runs/route.js.map +5 -0
  185. package/.next/server/app/api/teams/workflow-runs/route.js.nft.json +1 -0
  186. package/.next/server/app/api/teams/workflow-runs/route_client-reference-manifest.js +2 -0
  187. package/.next/server/app/api/teams/workflow-templates/route/app-paths-manifest.json +3 -0
  188. package/.next/server/app/api/teams/workflow-templates/route/build-manifest.json +11 -0
  189. package/.next/server/app/api/teams/workflow-templates/route/server-reference-manifest.json +4 -0
  190. package/.next/server/app/api/teams/workflow-templates/route.js +6 -0
  191. package/.next/server/app/api/teams/workflow-templates/route.js.map +5 -0
  192. package/.next/server/app/api/teams/workflow-templates/route.js.nft.json +1 -0
  193. package/.next/server/app/api/teams/workflow-templates/route_client-reference-manifest.js +2 -0
  194. package/.next/server/app/api/teams/workflows/route/app-paths-manifest.json +3 -0
  195. package/.next/server/app/api/teams/workflows/route/build-manifest.json +11 -0
  196. package/.next/server/app/api/teams/workflows/route/server-reference-manifest.json +4 -0
  197. package/.next/server/app/api/teams/workflows/route.js +6 -0
  198. package/.next/server/app/api/teams/workflows/route.js.map +5 -0
  199. package/.next/server/app/api/teams/workflows/route.js.nft.json +1 -0
  200. package/.next/server/app/api/teams/workflows/route_client-reference-manifest.js +2 -0
  201. package/.next/server/app/api/tickets/assign/route/app-paths-manifest.json +3 -0
  202. package/.next/server/app/api/tickets/assign/route/build-manifest.json +11 -0
  203. package/.next/server/app/api/tickets/assign/route/server-reference-manifest.json +4 -0
  204. package/.next/server/app/api/tickets/assign/route.js +6 -0
  205. package/.next/server/app/api/tickets/assign/route.js.map +5 -0
  206. package/.next/server/app/api/tickets/assign/route.js.nft.json +1 -0
  207. package/.next/server/app/api/tickets/assign/route_client-reference-manifest.js +2 -0
  208. package/.next/server/app/api/tickets/assignees/route/app-paths-manifest.json +3 -0
  209. package/.next/server/app/api/tickets/assignees/route/build-manifest.json +11 -0
  210. package/.next/server/app/api/tickets/assignees/route/server-reference-manifest.json +4 -0
  211. package/.next/server/app/api/tickets/assignees/route.js +6 -0
  212. package/.next/server/app/api/tickets/assignees/route.js.map +5 -0
  213. package/.next/server/app/api/tickets/assignees/route.js.nft.json +1 -0
  214. package/.next/server/app/api/tickets/assignees/route_client-reference-manifest.js +2 -0
  215. package/.next/server/app/api/tickets/move/route.js +1 -1
  216. package/.next/server/app/api/tickets/move/route.js.nft.json +1 -1
  217. package/.next/server/app/channels/page/build-manifest.json +4 -4
  218. package/.next/server/app/channels/page.js +8 -8
  219. package/.next/server/app/channels/page.js.nft.json +1 -1
  220. package/.next/server/app/channels/page_client-reference-manifest.js +1 -1
  221. package/.next/server/app/channels.html +2 -2
  222. package/.next/server/app/channels.rsc +6 -6
  223. package/.next/server/app/channels.segments/_full.segment.rsc +6 -6
  224. package/.next/server/app/channels.segments/_head.segment.rsc +1 -1
  225. package/.next/server/app/channels.segments/_index.segment.rsc +3 -3
  226. package/.next/server/app/channels.segments/_tree.segment.rsc +2 -2
  227. package/.next/server/app/channels.segments/channels/__PAGE__.segment.rsc +2 -2
  228. package/.next/server/app/channels.segments/channels.segment.rsc +1 -1
  229. package/.next/server/app/cron-jobs/page/build-manifest.json +4 -4
  230. package/.next/server/app/cron-jobs/page.js +8 -8
  231. package/.next/server/app/cron-jobs/page.js.nft.json +1 -1
  232. package/.next/server/app/cron-jobs/page_client-reference-manifest.js +1 -1
  233. package/.next/server/app/cron-jobs.html +1 -1
  234. package/.next/server/app/cron-jobs.rsc +7 -7
  235. package/.next/server/app/cron-jobs.segments/_full.segment.rsc +7 -7
  236. package/.next/server/app/cron-jobs.segments/_head.segment.rsc +1 -1
  237. package/.next/server/app/cron-jobs.segments/_index.segment.rsc +3 -3
  238. package/.next/server/app/cron-jobs.segments/_tree.segment.rsc +2 -2
  239. package/.next/server/app/cron-jobs.segments/cron-jobs/__PAGE__.segment.rsc +3 -3
  240. package/.next/server/app/cron-jobs.segments/cron-jobs.segment.rsc +1 -1
  241. package/.next/server/app/goals/[id]/page/build-manifest.json +4 -4
  242. package/.next/server/app/goals/[id]/page.js +8 -8
  243. package/.next/server/app/goals/[id]/page.js.nft.json +1 -1
  244. package/.next/server/app/goals/[id]/page_client-reference-manifest.js +1 -1
  245. package/.next/server/app/goals/new/page/build-manifest.json +4 -4
  246. package/.next/server/app/goals/new/page.js +8 -8
  247. package/.next/server/app/goals/new/page.js.nft.json +1 -1
  248. package/.next/server/app/goals/new/page_client-reference-manifest.js +1 -1
  249. package/.next/server/app/goals/new.html +2 -2
  250. package/.next/server/app/goals/new.rsc +6 -6
  251. package/.next/server/app/goals/new.segments/_full.segment.rsc +6 -6
  252. package/.next/server/app/goals/new.segments/_head.segment.rsc +1 -1
  253. package/.next/server/app/goals/new.segments/_index.segment.rsc +3 -3
  254. package/.next/server/app/goals/new.segments/_tree.segment.rsc +2 -2
  255. package/.next/server/app/goals/new.segments/goals/new/__PAGE__.segment.rsc +2 -2
  256. package/.next/server/app/goals/new.segments/goals/new.segment.rsc +1 -1
  257. package/.next/server/app/goals/new.segments/goals.segment.rsc +1 -1
  258. package/.next/server/app/goals/page/build-manifest.json +4 -4
  259. package/.next/server/app/goals/page.js +8 -8
  260. package/.next/server/app/goals/page.js.nft.json +1 -1
  261. package/.next/server/app/goals/page_client-reference-manifest.js +1 -1
  262. package/.next/server/app/goals.html +1 -1
  263. package/.next/server/app/goals.rsc +6 -6
  264. package/.next/server/app/goals.segments/_full.segment.rsc +6 -6
  265. package/.next/server/app/goals.segments/_head.segment.rsc +1 -1
  266. package/.next/server/app/goals.segments/_index.segment.rsc +3 -3
  267. package/.next/server/app/goals.segments/_tree.segment.rsc +2 -2
  268. package/.next/server/app/goals.segments/goals/__PAGE__.segment.rsc +2 -2
  269. package/.next/server/app/goals.segments/goals.segment.rsc +1 -1
  270. package/.next/server/app/manifest.webmanifest/route/app-paths-manifest.json +3 -0
  271. package/.next/server/app/manifest.webmanifest/route/build-manifest.json +11 -0
  272. package/.next/server/app/manifest.webmanifest/route/server-reference-manifest.json +4 -0
  273. package/.next/server/app/manifest.webmanifest/route.js +6 -0
  274. package/.next/server/app/manifest.webmanifest/route.js.map +5 -0
  275. package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -0
  276. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +2 -0
  277. package/.next/server/app/manifest.webmanifest.body +1 -0
  278. package/.next/server/app/manifest.webmanifest.meta +1 -0
  279. package/.next/server/app/page/build-manifest.json +4 -4
  280. package/.next/server/app/page.js +10 -9
  281. package/.next/server/app/page.js.nft.json +1 -1
  282. package/.next/server/app/page_client-reference-manifest.js +1 -1
  283. package/.next/server/app/recipes/[id]/page/build-manifest.json +4 -4
  284. package/.next/server/app/recipes/[id]/page.js +10 -9
  285. package/.next/server/app/recipes/[id]/page.js.nft.json +1 -1
  286. package/.next/server/app/recipes/[id]/page_client-reference-manifest.js +1 -1
  287. package/.next/server/app/recipes/page/build-manifest.json +4 -4
  288. package/.next/server/app/recipes/page.js +9 -9
  289. package/.next/server/app/recipes/page.js.nft.json +1 -1
  290. package/.next/server/app/recipes/page_client-reference-manifest.js +1 -1
  291. package/.next/server/app/settings/page/build-manifest.json +4 -4
  292. package/.next/server/app/settings/page.js +8 -8
  293. package/.next/server/app/settings/page.js.nft.json +1 -1
  294. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  295. package/.next/server/app/settings.html +1 -1
  296. package/.next/server/app/settings.rsc +6 -6
  297. package/.next/server/app/settings.segments/_full.segment.rsc +6 -6
  298. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  299. package/.next/server/app/settings.segments/_index.segment.rsc +3 -3
  300. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  301. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
  302. package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  303. package/.next/server/app/teams/[teamId]/page/build-manifest.json +4 -4
  304. package/.next/server/app/teams/[teamId]/page.js +10 -9
  305. package/.next/server/app/teams/[teamId]/page.js.nft.json +1 -1
  306. package/.next/server/app/teams/[teamId]/page_client-reference-manifest.js +1 -1
  307. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page/app-paths-manifest.json +3 -0
  308. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page/build-manifest.json +17 -0
  309. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page/next-font-manifest.json +11 -0
  310. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page/react-loadable-manifest.json +1 -0
  311. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page/server-reference-manifest.json +4 -0
  312. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page.js +18 -0
  313. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page.js.map +5 -0
  314. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page.js.nft.json +1 -0
  315. package/.next/server/app/teams/[teamId]/tickets/[ticket]/page_client-reference-manifest.js +2 -0
  316. package/.next/server/app/teams/[teamId]/tickets/page/app-paths-manifest.json +3 -0
  317. package/.next/server/app/teams/[teamId]/tickets/page/build-manifest.json +17 -0
  318. package/.next/server/app/teams/[teamId]/tickets/page/next-font-manifest.json +11 -0
  319. package/.next/server/app/teams/[teamId]/tickets/page/react-loadable-manifest.json +1 -0
  320. package/.next/server/app/teams/[teamId]/tickets/page/server-reference-manifest.json +4 -0
  321. package/.next/server/app/teams/[teamId]/tickets/page.js +18 -0
  322. package/.next/server/app/teams/[teamId]/tickets/page.js.map +5 -0
  323. package/.next/server/app/teams/[teamId]/tickets/page.js.nft.json +1 -0
  324. package/.next/server/app/teams/[teamId]/tickets/page_client-reference-manifest.js +2 -0
  325. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page/app-paths-manifest.json +3 -0
  326. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page/build-manifest.json +17 -0
  327. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page/next-font-manifest.json +11 -0
  328. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page/react-loadable-manifest.json +1 -0
  329. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page/server-reference-manifest.json +4 -0
  330. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page.js +19 -0
  331. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page.js.map +5 -0
  332. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page.js.nft.json +1 -0
  333. package/.next/server/app/teams/[teamId]/workflows/[workflowId]/page_client-reference-manifest.js +2 -0
  334. package/.next/server/app/teams/[teamId]/workflows/page/app-paths-manifest.json +3 -0
  335. package/.next/server/app/teams/[teamId]/workflows/page/build-manifest.json +17 -0
  336. package/.next/server/app/teams/[teamId]/workflows/page/next-font-manifest.json +11 -0
  337. package/.next/server/app/teams/[teamId]/workflows/page/react-loadable-manifest.json +1 -0
  338. package/.next/server/app/teams/[teamId]/workflows/page/server-reference-manifest.json +4 -0
  339. package/.next/server/app/teams/[teamId]/workflows/page.js +20 -0
  340. package/.next/server/app/teams/[teamId]/workflows/page.js.map +5 -0
  341. package/.next/server/app/teams/[teamId]/workflows/page.js.nft.json +1 -0
  342. package/.next/server/app/teams/[teamId]/workflows/page_client-reference-manifest.js +2 -0
  343. package/.next/server/app/tickets/[ticket]/page/build-manifest.json +4 -4
  344. package/.next/server/app/tickets/[ticket]/page.js +8 -8
  345. package/.next/server/app/tickets/[ticket]/page.js.nft.json +1 -1
  346. package/.next/server/app/tickets/[ticket]/page_client-reference-manifest.js +1 -1
  347. package/.next/server/app/tickets/page/build-manifest.json +4 -4
  348. package/.next/server/app/tickets/page.js +8 -8
  349. package/.next/server/app/tickets/page.js.nft.json +1 -1
  350. package/.next/server/app/tickets/page_client-reference-manifest.js +1 -1
  351. package/.next/server/app-paths-manifest.json +21 -0
  352. package/.next/server/chunks/[root-of-the-server]__04d535a1._.js +3 -0
  353. package/.next/server/chunks/[root-of-the-server]__04d535a1._.js.map +1 -0
  354. package/.next/server/chunks/[root-of-the-server]__0554d494._.js +3 -0
  355. package/.next/server/chunks/[root-of-the-server]__0554d494._.js.map +1 -0
  356. package/.next/server/chunks/[root-of-the-server]__05f5e243._.js +3 -0
  357. package/.next/server/chunks/[root-of-the-server]__05f5e243._.js.map +1 -0
  358. package/.next/server/chunks/[root-of-the-server]__0e5f94e2._.js +3 -0
  359. package/.next/server/chunks/[root-of-the-server]__0e5f94e2._.js.map +1 -0
  360. package/.next/server/chunks/[root-of-the-server]__107d374d._.js +3 -0
  361. package/.next/server/chunks/[root-of-the-server]__107d374d._.js.map +1 -0
  362. package/.next/server/chunks/[root-of-the-server]__1106aaf7._.js +8 -0
  363. package/.next/server/chunks/[root-of-the-server]__1106aaf7._.js.map +1 -0
  364. package/.next/server/chunks/[root-of-the-server]__1805932c._.js +3 -0
  365. package/.next/server/chunks/[root-of-the-server]__1805932c._.js.map +1 -0
  366. package/.next/server/chunks/[root-of-the-server]__26c618a3._.js +3 -0
  367. package/.next/server/chunks/[root-of-the-server]__26c618a3._.js.map +1 -0
  368. package/.next/server/chunks/[root-of-the-server]__2fa553db._.js +3 -0
  369. package/.next/server/chunks/[root-of-the-server]__2fa553db._.js.map +1 -0
  370. package/.next/server/chunks/[root-of-the-server]__392e585d._.js +18 -0
  371. package/.next/server/chunks/[root-of-the-server]__392e585d._.js.map +1 -0
  372. package/.next/server/chunks/[root-of-the-server]__3cddf0a5._.js +3 -0
  373. package/.next/server/chunks/[root-of-the-server]__3cddf0a5._.js.map +1 -0
  374. package/.next/server/chunks/[root-of-the-server]__3f7058b4._.js +3 -0
  375. package/.next/server/chunks/[root-of-the-server]__3f7058b4._.js.map +1 -0
  376. package/.next/server/chunks/[root-of-the-server]__477c3d5b._.js +3 -0
  377. package/.next/server/chunks/[root-of-the-server]__477c3d5b._.js.map +1 -0
  378. package/.next/server/chunks/[root-of-the-server]__47eb3111._.js +3 -0
  379. package/.next/server/chunks/[root-of-the-server]__47eb3111._.js.map +1 -0
  380. package/.next/server/chunks/[root-of-the-server]__4898071c._.js +2 -2
  381. package/.next/server/chunks/[root-of-the-server]__59a6cf09._.js +3 -0
  382. package/.next/server/chunks/[root-of-the-server]__59a6cf09._.js.map +1 -0
  383. package/.next/server/chunks/[root-of-the-server]__5ea38a67._.js +3 -0
  384. package/.next/server/chunks/[root-of-the-server]__5ea38a67._.js.map +1 -0
  385. package/.next/server/chunks/[root-of-the-server]__6629e914._.js +3 -0
  386. package/.next/server/chunks/[root-of-the-server]__6629e914._.js.map +1 -0
  387. package/.next/server/chunks/[root-of-the-server]__667c3a2d._.js +3 -0
  388. package/.next/server/chunks/[root-of-the-server]__667c3a2d._.js.map +1 -0
  389. package/.next/server/chunks/[root-of-the-server]__691a8e5d._.js +6 -0
  390. package/.next/server/chunks/[root-of-the-server]__691a8e5d._.js.map +1 -0
  391. package/.next/server/chunks/[root-of-the-server]__698cf062._.js +3 -0
  392. package/.next/server/chunks/[root-of-the-server]__698cf062._.js.map +1 -0
  393. package/.next/server/chunks/[root-of-the-server]__69be1758._.js +3 -0
  394. package/.next/server/chunks/[root-of-the-server]__69be1758._.js.map +1 -0
  395. package/.next/server/chunks/[root-of-the-server]__6d8e7b75._.js +6 -0
  396. package/.next/server/chunks/[root-of-the-server]__6d8e7b75._.js.map +1 -0
  397. package/.next/server/chunks/[root-of-the-server]__6e5826c5._.js +3 -0
  398. package/.next/server/chunks/[root-of-the-server]__6e5826c5._.js.map +1 -0
  399. package/.next/server/chunks/[root-of-the-server]__795578f0._.js +3 -0
  400. package/.next/server/chunks/[root-of-the-server]__795578f0._.js.map +1 -0
  401. package/.next/server/chunks/[root-of-the-server]__7a331e51._.js +8 -0
  402. package/.next/server/chunks/[root-of-the-server]__7a331e51._.js.map +1 -0
  403. package/.next/server/chunks/[root-of-the-server]__7e46fb06._.js +3 -0
  404. package/.next/server/chunks/[root-of-the-server]__7e46fb06._.js.map +1 -0
  405. package/.next/server/chunks/[root-of-the-server]__864a08dd._.js +10 -0
  406. package/.next/server/chunks/[root-of-the-server]__864a08dd._.js.map +1 -0
  407. package/.next/server/chunks/[root-of-the-server]__8a811a30._.js +3 -0
  408. package/.next/server/chunks/[root-of-the-server]__8a811a30._.js.map +1 -0
  409. package/.next/server/chunks/[root-of-the-server]__8e27e9f7._.js +8 -0
  410. package/.next/server/chunks/[root-of-the-server]__8e27e9f7._.js.map +1 -0
  411. package/.next/server/chunks/[root-of-the-server]__8ea22d0a._.js +3 -0
  412. package/.next/server/chunks/[root-of-the-server]__8ea22d0a._.js.map +1 -0
  413. package/.next/server/chunks/[root-of-the-server]__904a6d9f._.js +3 -0
  414. package/.next/server/chunks/[root-of-the-server]__904a6d9f._.js.map +1 -0
  415. package/.next/server/chunks/[root-of-the-server]__a12dc320._.js +3 -0
  416. package/.next/server/chunks/[root-of-the-server]__a12dc320._.js.map +1 -0
  417. package/.next/server/chunks/[root-of-the-server]__a6ade549._.js +3 -0
  418. package/.next/server/chunks/[root-of-the-server]__a6ade549._.js.map +1 -0
  419. package/.next/server/chunks/[root-of-the-server]__abcda400._.js +6 -0
  420. package/.next/server/chunks/[root-of-the-server]__abcda400._.js.map +1 -0
  421. package/.next/server/chunks/[root-of-the-server]__b002764e._.js +3 -0
  422. package/.next/server/chunks/[root-of-the-server]__b002764e._.js.map +1 -0
  423. package/.next/server/chunks/[root-of-the-server]__bc3630f4._.js +3 -0
  424. package/.next/server/chunks/[root-of-the-server]__bc3630f4._.js.map +1 -0
  425. package/.next/server/chunks/[root-of-the-server]__befb8c19._.js +3 -0
  426. package/.next/server/chunks/[root-of-the-server]__befb8c19._.js.map +1 -0
  427. package/.next/server/chunks/[root-of-the-server]__bf608f29._.js +3 -0
  428. package/.next/server/chunks/{[root-of-the-server]__be5f57b2._.js.map → [root-of-the-server]__bf608f29._.js.map} +1 -1
  429. package/.next/server/chunks/{[root-of-the-server]__74b80ca4._.js → [root-of-the-server]__c63a9f28._.js} +2 -2
  430. package/.next/server/chunks/[root-of-the-server]__c86c0469._.js +3 -0
  431. package/.next/server/chunks/[root-of-the-server]__c86c0469._.js.map +1 -0
  432. package/.next/server/chunks/[root-of-the-server]__c9e4c772._.js +3 -0
  433. package/.next/server/chunks/[root-of-the-server]__c9e4c772._.js.map +1 -0
  434. package/.next/server/chunks/[root-of-the-server]__cbe01b74._.js +3 -0
  435. package/.next/server/chunks/[root-of-the-server]__cbe01b74._.js.map +1 -0
  436. package/.next/server/chunks/[root-of-the-server]__ce9cfa39._.js +3 -0
  437. package/.next/server/chunks/[root-of-the-server]__ce9cfa39._.js.map +1 -0
  438. package/.next/server/chunks/[root-of-the-server]__d924e5ac._.js +3 -0
  439. package/.next/server/chunks/[root-of-the-server]__d924e5ac._.js.map +1 -0
  440. package/.next/server/chunks/[root-of-the-server]__e40409a2._.js +3 -0
  441. package/.next/server/chunks/[root-of-the-server]__e40409a2._.js.map +1 -0
  442. package/.next/server/chunks/[root-of-the-server]__e6fa5823._.js +3 -0
  443. package/.next/server/chunks/[root-of-the-server]__e6fa5823._.js.map +1 -0
  444. package/.next/server/chunks/[root-of-the-server]__e8bfeaba._.js +3 -0
  445. package/.next/server/chunks/[root-of-the-server]__e8bfeaba._.js.map +1 -0
  446. package/.next/server/chunks/[root-of-the-server]__e8f8017b._.js +3 -0
  447. package/.next/server/chunks/[root-of-the-server]__e8f8017b._.js.map +1 -0
  448. package/.next/server/chunks/[root-of-the-server]__ee5cefd8._.js +3 -0
  449. package/.next/server/chunks/[root-of-the-server]__ee5cefd8._.js.map +1 -0
  450. package/.next/server/chunks/[root-of-the-server]__ef60acef._.js +3 -0
  451. package/.next/server/chunks/[root-of-the-server]__ef60acef._.js.map +1 -0
  452. package/.next/server/chunks/[root-of-the-server]__fdda9176._.js +3 -0
  453. package/.next/server/chunks/{[root-of-the-server]__a6ac3ddf._.js.map → [root-of-the-server]__fdda9176._.js.map} +1 -1
  454. package/.next/server/chunks/[root-of-the-server]__fec14c75._.js +3 -0
  455. package/.next/server/chunks/[root-of-the-server]__fec14c75._.js.map +1 -0
  456. package/.next/server/chunks/[root-of-the-server]__fef7183d._.js +3 -0
  457. package/.next/server/chunks/[root-of-the-server]__fef7183d._.js.map +1 -0
  458. package/.next/server/chunks/_next-internal_server_app_api_recipes_custom-team_route_actions_861b1489.js +3 -0
  459. package/.next/server/chunks/_next-internal_server_app_api_swarms_start_route_actions_b79e9029.js +3 -0
  460. package/.next/server/chunks/_next-internal_server_app_api_swarms_start_route_actions_b79e9029.js.map +1 -0
  461. package/.next/server/chunks/_next-internal_server_app_api_swarms_status_route_actions_54826df0.js +3 -0
  462. package/.next/server/chunks/_next-internal_server_app_api_swarms_status_route_actions_54826df0.js.map +1 -0
  463. package/.next/server/chunks/_next-internal_server_app_api_teams_[teamId]_tickets_move_route_actions_b47d8708.js +3 -0
  464. package/.next/server/chunks/_next-internal_server_app_api_teams_[teamId]_tickets_move_route_actions_b47d8708.js.map +1 -0
  465. package/.next/server/chunks/_next-internal_server_app_api_teams_memory_route_actions_5b7dc699.js +3 -0
  466. package/.next/server/chunks/_next-internal_server_app_api_teams_memory_route_actions_5b7dc699.js.map +1 -0
  467. package/.next/server/chunks/_next-internal_server_app_api_teams_orchestrator_install_route_actions_49b6602b.js +3 -0
  468. package/.next/server/chunks/_next-internal_server_app_api_teams_orchestrator_install_route_actions_49b6602b.js.map +1 -0
  469. package/.next/server/chunks/_next-internal_server_app_api_teams_orchestrator_route_actions_1949c463.js +3 -0
  470. package/.next/server/chunks/_next-internal_server_app_api_teams_orchestrator_route_actions_1949c463.js.map +1 -0
  471. package/.next/server/chunks/_next-internal_server_app_api_teams_workflow-runs_route_actions_8327ac7d.js +3 -0
  472. package/.next/server/chunks/_next-internal_server_app_api_teams_workflow-runs_route_actions_8327ac7d.js.map +1 -0
  473. package/.next/server/chunks/_next-internal_server_app_api_teams_workflow-templates_route_actions_87b51d57.js +3 -0
  474. package/.next/server/chunks/_next-internal_server_app_api_teams_workflow-templates_route_actions_87b51d57.js.map +1 -0
  475. package/.next/server/chunks/_next-internal_server_app_api_teams_workflows_route_actions_43dd6e07.js +3 -0
  476. package/.next/server/chunks/_next-internal_server_app_api_teams_workflows_route_actions_43dd6e07.js.map +1 -0
  477. package/.next/server/chunks/_next-internal_server_app_api_tickets_assign_route_actions_629cc773.js +3 -0
  478. package/.next/server/chunks/_next-internal_server_app_api_tickets_assign_route_actions_629cc773.js.map +1 -0
  479. package/.next/server/chunks/_next-internal_server_app_api_tickets_assignees_route_actions_64d3d63e.js +3 -0
  480. package/.next/server/chunks/_next-internal_server_app_api_tickets_assignees_route_actions_64d3d63e.js.map +1 -0
  481. package/.next/server/chunks/_next-internal_server_app_manifest_webmanifest_route_actions_1bff3fca.js +3 -0
  482. package/.next/server/chunks/_next-internal_server_app_manifest_webmanifest_route_actions_1bff3fca.js.map +1 -0
  483. package/.next/server/chunks/ce889_server_app_api_teams_[teamId]_tickets_assign_route_actions_50521c46.js +3 -0
  484. package/.next/server/chunks/ce889_server_app_api_teams_[teamId]_tickets_assign_route_actions_50521c46.js.map +1 -0
  485. package/.next/server/chunks/ce889_server_app_api_teams_[teamId]_tickets_assignees_route_actions_75675d78.js +3 -0
  486. package/.next/server/chunks/ce889_server_app_api_teams_[teamId]_tickets_assignees_route_actions_75675d78.js.map +1 -0
  487. package/.next/server/chunks/ce889_server_app_api_teams_[teamId]_tickets_delete_route_actions_9d6ca9f4.js +3 -0
  488. package/.next/server/chunks/ce889_server_app_api_teams_[teamId]_tickets_delete_route_actions_9d6ca9f4.js.map +1 -0
  489. package/.next/server/chunks/ce889_server_app_api_teams_[teamId]_tickets_move-to-goals_route_actions_760612ca.js +3 -0
  490. package/.next/server/chunks/ce889_server_app_api_teams_[teamId]_tickets_move-to-goals_route_actions_760612ca.js.map +1 -0
  491. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_1fe98a49.js +16 -0
  492. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_1fe98a49.js.map +1 -0
  493. package/.next/server/chunks/ssr/[root-of-the-server]__0d4cb2ba._.js +3 -0
  494. package/.next/server/chunks/ssr/[root-of-the-server]__285ae6b7._.js +3 -0
  495. package/.next/server/chunks/ssr/{[root-of-the-server]__46e08d44._.js.map → [root-of-the-server]__285ae6b7._.js.map} +1 -1
  496. package/.next/server/chunks/ssr/[root-of-the-server]__28f5d174._.js +3 -0
  497. package/.next/server/chunks/ssr/[root-of-the-server]__28f5d174._.js.map +1 -0
  498. package/.next/server/chunks/ssr/[root-of-the-server]__2bef6884._.js +3 -0
  499. package/.next/server/chunks/ssr/{[root-of-the-server]__15600e29._.js.map → [root-of-the-server]__2bef6884._.js.map} +1 -1
  500. package/.next/server/chunks/ssr/[root-of-the-server]__37c705d4._.js +3 -0
  501. package/.next/server/chunks/ssr/[root-of-the-server]__37c705d4._.js.map +1 -0
  502. package/.next/server/chunks/ssr/[root-of-the-server]__3ec61b25._.js +3 -0
  503. package/.next/server/chunks/ssr/[root-of-the-server]__3ec61b25._.js.map +1 -0
  504. package/.next/server/chunks/ssr/[root-of-the-server]__3efd25c4._.js +3 -0
  505. package/.next/server/chunks/ssr/{[root-of-the-server]__2a6f1e3e._.js.map → [root-of-the-server]__3efd25c4._.js.map} +1 -1
  506. package/.next/server/chunks/ssr/[root-of-the-server]__44d2d5fa._.js +3 -0
  507. package/.next/server/chunks/ssr/[root-of-the-server]__44d2d5fa._.js.map +1 -0
  508. package/.next/server/chunks/ssr/[root-of-the-server]__49281b4c._.js +3 -0
  509. package/.next/server/chunks/ssr/[root-of-the-server]__49281b4c._.js.map +1 -0
  510. package/.next/server/chunks/ssr/[root-of-the-server]__4c4391c1._.js +3 -0
  511. package/.next/server/chunks/ssr/[root-of-the-server]__4c4391c1._.js.map +1 -0
  512. package/.next/server/chunks/ssr/[root-of-the-server]__4c6592ca._.js +3 -0
  513. package/.next/server/chunks/ssr/[root-of-the-server]__4c6592ca._.js.map +1 -0
  514. package/.next/server/chunks/ssr/[root-of-the-server]__682758bd._.js +3 -0
  515. package/.next/server/chunks/ssr/[root-of-the-server]__682758bd._.js.map +1 -0
  516. package/.next/server/chunks/ssr/[root-of-the-server]__6bd48d33._.js +1 -1
  517. package/.next/server/chunks/ssr/[root-of-the-server]__6bd48d33._.js.map +1 -1
  518. package/.next/server/chunks/ssr/[root-of-the-server]__78972f52._.js +3 -0
  519. package/.next/server/chunks/ssr/[root-of-the-server]__78972f52._.js.map +1 -0
  520. package/.next/server/chunks/ssr/{[root-of-the-server]__e2e52c6e._.js → [root-of-the-server]__78cdd31e._.js} +2 -2
  521. package/.next/server/chunks/ssr/[root-of-the-server]__92524828._.js +3 -0
  522. package/.next/server/chunks/ssr/{[root-of-the-server]__247198dc._.js.map → [root-of-the-server]__92524828._.js.map} +1 -1
  523. package/.next/server/chunks/ssr/[root-of-the-server]__9a7d79aa._.js +3 -0
  524. package/.next/server/chunks/ssr/[root-of-the-server]__9a7d79aa._.js.map +1 -0
  525. package/.next/server/chunks/ssr/[root-of-the-server]__9e1ab064._.js +3 -0
  526. package/.next/server/chunks/ssr/[root-of-the-server]__9e1ab064._.js.map +1 -0
  527. package/.next/server/chunks/ssr/[root-of-the-server]__ad654f09._.js +3 -0
  528. package/.next/server/chunks/ssr/[root-of-the-server]__ad654f09._.js.map +1 -0
  529. package/.next/server/chunks/ssr/[root-of-the-server]__b2617fbf._.js +3 -0
  530. package/.next/server/chunks/ssr/{[root-of-the-server]__fd669584._.js.map → [root-of-the-server]__b2617fbf._.js.map} +1 -1
  531. package/.next/server/chunks/ssr/[root-of-the-server]__b5f65083._.js +3 -0
  532. package/.next/server/chunks/ssr/[root-of-the-server]__b5f65083._.js.map +1 -0
  533. package/.next/server/chunks/ssr/{[root-of-the-server]__4c6cc96d._.js → [root-of-the-server]__de18d058._.js} +2 -2
  534. package/.next/server/chunks/ssr/{[root-of-the-server]__4c6cc96d._.js.map → [root-of-the-server]__de18d058._.js.map} +1 -1
  535. package/.next/server/chunks/ssr/{[root-of-the-server]__7180d770._.js → [root-of-the-server]__e364449b._.js} +2 -2
  536. package/.next/server/chunks/ssr/[root-of-the-server]__e364449b._.js.map +1 -0
  537. package/.next/server/chunks/ssr/[root-of-the-server]__e5d416d5._.js +3 -0
  538. package/.next/server/chunks/ssr/{[root-of-the-server]__3ad3e5b1._.js.map → [root-of-the-server]__e5d416d5._.js.map} +1 -1
  539. package/.next/server/chunks/ssr/[root-of-the-server]__e94ab521._.js +3 -0
  540. package/.next/server/chunks/ssr/[root-of-the-server]__e94ab521._.js.map +1 -0
  541. package/.next/server/chunks/ssr/{[root-of-the-server]__b9356576._.js → [root-of-the-server]__f62d412e._.js} +2 -2
  542. package/.next/server/chunks/ssr/{[root-of-the-server]__b9356576._.js.map → [root-of-the-server]__f62d412e._.js.map} +1 -1
  543. package/.next/server/chunks/ssr/[root-of-the-server]__f8a2f82d._.js +3 -0
  544. package/.next/server/chunks/ssr/[root-of-the-server]__f8a2f82d._.js.map +1 -0
  545. package/.next/server/chunks/ssr/[root-of-the-server]__fbe5ff69._.js +3 -0
  546. package/.next/server/chunks/ssr/{[root-of-the-server]__3575e6da._.js.map → [root-of-the-server]__fbe5ff69._.js.map} +1 -1
  547. package/.next/server/chunks/ssr/_018dfe6b._.js +27 -0
  548. package/.next/server/chunks/ssr/_018dfe6b._.js.map +1 -0
  549. package/.next/server/chunks/ssr/{_8c45edba._.js → _0bdae23a._.js} +3 -3
  550. package/.next/server/chunks/ssr/_0bdae23a._.js.map +1 -0
  551. package/.next/server/chunks/ssr/{_d27483a1._.js → _19aa68d3._.js} +3 -3
  552. package/.next/server/chunks/ssr/_19aa68d3._.js.map +1 -0
  553. package/.next/server/chunks/ssr/{_25e6aab8._.js → _347e2d56._.js} +3 -3
  554. package/.next/server/chunks/ssr/_347e2d56._.js.map +1 -0
  555. package/.next/server/chunks/ssr/_3c9015dc._.js +4 -0
  556. package/.next/server/chunks/ssr/_3c9015dc._.js.map +1 -0
  557. package/.next/server/chunks/ssr/_41ca4e70._.js +3 -0
  558. package/.next/server/chunks/ssr/_41ca4e70._.js.map +1 -0
  559. package/.next/server/chunks/ssr/{node_modules_next_dist_12287b3d._.js → _49fb12c2._.js} +3 -3
  560. package/.next/server/chunks/ssr/_49fb12c2._.js.map +1 -0
  561. package/.next/server/chunks/ssr/{_3c8b2df6._.js → _536983a4._.js} +3 -3
  562. package/.next/server/chunks/ssr/_536983a4._.js.map +1 -0
  563. package/.next/server/chunks/ssr/_5443093b._.js +3 -0
  564. package/.next/server/chunks/ssr/_5443093b._.js.map +1 -0
  565. package/.next/server/chunks/ssr/{_cd23c5af._.js → _5b282394._.js} +3 -3
  566. package/.next/server/chunks/ssr/_5b282394._.js.map +1 -0
  567. package/.next/server/chunks/ssr/{_6e70b5a4._.js → _5cc24343._.js} +3 -3
  568. package/.next/server/chunks/ssr/_5cc24343._.js.map +1 -0
  569. package/.next/server/chunks/ssr/_67830ad6._.js +3 -0
  570. package/.next/server/chunks/ssr/_67830ad6._.js.map +1 -0
  571. package/.next/server/chunks/ssr/{node_modules_next_dist_esm_build_templates_app-page_68c68167.js → _7eac37fb._.js} +3 -3
  572. package/.next/server/chunks/ssr/_7eac37fb._.js.map +1 -0
  573. package/.next/server/chunks/ssr/{_92140ca3._.js → _802ee40f._.js} +3 -3
  574. package/.next/server/chunks/ssr/{_25e6aab8._.js.map → _802ee40f._.js.map} +1 -1
  575. package/.next/server/chunks/ssr/{_8c8207c1._.js → _8062e992._.js} +3 -3
  576. package/.next/server/chunks/ssr/_8062e992._.js.map +1 -0
  577. package/.next/server/chunks/ssr/{_0808c2b9._.js → _99994c05._.js} +3 -3
  578. package/.next/server/chunks/ssr/_99994c05._.js.map +1 -0
  579. package/.next/server/chunks/ssr/{_b5e9afcc._.js → _aafc99aa._.js} +3 -3
  580. package/.next/server/chunks/ssr/_aafc99aa._.js.map +1 -0
  581. package/.next/server/chunks/ssr/{_39e6e769._.js → _b7f3caf7._.js} +3 -3
  582. package/.next/server/chunks/ssr/_b7f3caf7._.js.map +1 -0
  583. package/.next/server/chunks/ssr/_c2041f88._.js +4 -0
  584. package/.next/server/chunks/ssr/_c2041f88._.js.map +1 -0
  585. package/.next/server/chunks/ssr/_d2e9dda9._.js +4 -0
  586. package/.next/server/chunks/ssr/_d2e9dda9._.js.map +1 -0
  587. package/.next/server/chunks/ssr/{_3158c108._.js → _f4d8af3b._.js} +3 -3
  588. package/.next/server/chunks/ssr/_f4d8af3b._.js.map +1 -0
  589. package/.next/server/chunks/ssr/_next-internal_server_app_teams_[teamId]_tickets_[ticket]_page_actions_25ad633d.js +3 -0
  590. package/.next/server/chunks/ssr/_next-internal_server_app_teams_[teamId]_tickets_[ticket]_page_actions_25ad633d.js.map +1 -0
  591. package/.next/server/chunks/ssr/_next-internal_server_app_teams_[teamId]_tickets_page_actions_dffb2525.js +3 -0
  592. package/.next/server/chunks/ssr/_next-internal_server_app_teams_[teamId]_tickets_page_actions_dffb2525.js.map +1 -0
  593. package/.next/server/chunks/ssr/_next-internal_server_app_teams_[teamId]_workflows_page_actions_3defde35.js +3 -0
  594. package/.next/server/chunks/ssr/_next-internal_server_app_teams_[teamId]_workflows_page_actions_3defde35.js.map +1 -0
  595. package/.next/server/chunks/ssr/b1a17_app_teams_[teamId]_workflows_[workflowId]_workflows-editor-client_tsx_5e714aa2._.js +3 -0
  596. package/.next/server/chunks/ssr/b1a17_app_teams_[teamId]_workflows_[workflowId]_workflows-editor-client_tsx_5e714aa2._.js.map +1 -0
  597. package/.next/server/chunks/ssr/ce889_server_app_teams_[teamId]_workflows_[workflowId]_page_actions_880cbbc3.js +3 -0
  598. package/.next/server/chunks/ssr/ce889_server_app_teams_[teamId]_workflows_[workflowId]_page_actions_880cbbc3.js.map +1 -0
  599. package/.next/server/chunks/ssr/node_modules_ea845e5f._.js +3 -0
  600. package/.next/server/chunks/ssr/node_modules_ea845e5f._.js.map +1 -0
  601. package/.next/server/chunks/ssr/{_da6f800e._.js → node_modules_next_aefa2538._.js} +2 -2
  602. package/.next/server/chunks/ssr/node_modules_next_aefa2538._.js.map +1 -0
  603. package/.next/server/chunks/ssr/node_modules_next_dist_8a37abed._.js +4 -0
  604. package/.next/server/chunks/ssr/node_modules_next_dist_8a37abed._.js.map +1 -0
  605. package/.next/server/chunks/ssr/{node_modules_next_dist_client_components_9774470f._.js → node_modules_next_dist_client_components_2fffaa3a._.js} +2 -2
  606. package/.next/server/chunks/ssr/{node_modules_next_dist_client_components_9774470f._.js.map → node_modules_next_dist_client_components_2fffaa3a._.js.map} +1 -1
  607. package/.next/server/chunks/ssr/{_68793c1f._.js → node_modules_next_dist_esm_build_templates_app-page_b5ef32b4.js} +3 -3
  608. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_b5ef32b4.js.map +1 -0
  609. package/.next/server/chunks/ssr/src_13139e3d._.js +3 -0
  610. package/.next/server/chunks/ssr/src_13139e3d._.js.map +1 -0
  611. package/.next/server/chunks/ssr/src_2a73b867._.js +3 -0
  612. package/.next/server/chunks/ssr/src_2a73b867._.js.map +1 -0
  613. package/.next/server/chunks/ssr/src_2dbb3b7f._.js +3 -0
  614. package/.next/server/chunks/ssr/src_2dbb3b7f._.js.map +1 -0
  615. package/.next/server/chunks/ssr/src_417bc4a6._.js +3 -0
  616. package/.next/server/chunks/ssr/src_417bc4a6._.js.map +1 -0
  617. package/.next/server/chunks/ssr/src_59477309._.js +3 -0
  618. package/.next/server/chunks/ssr/src_59477309._.js.map +1 -0
  619. package/.next/server/chunks/ssr/src_79d55c05._.js +3 -0
  620. package/.next/server/chunks/ssr/src_79d55c05._.js.map +1 -0
  621. package/.next/server/chunks/ssr/src_app_HomeClient_tsx_f9f7568d._.js +1 -1
  622. package/.next/server/chunks/ssr/src_app_HomeClient_tsx_f9f7568d._.js.map +1 -1
  623. package/.next/server/chunks/ssr/src_app_agents_[agentId]_agent-editor_tsx_f85bbe65._.js +1 -1
  624. package/.next/server/chunks/ssr/src_app_agents_[agentId]_agent-editor_tsx_f85bbe65._.js.map +1 -1
  625. package/.next/server/chunks/ssr/src_app_global-error_tsx_aa661ba4._.js +3 -0
  626. package/.next/server/chunks/ssr/src_app_global-error_tsx_aa661ba4._.js.map +1 -0
  627. package/.next/server/chunks/ssr/src_app_not-found_tsx_3f23d179._.js +3 -0
  628. package/.next/server/chunks/ssr/src_app_not-found_tsx_3f23d179._.js.map +1 -0
  629. package/.next/server/chunks/ssr/src_app_recipes_[id]_RecipeEditor_index_tsx_98393217._.js +3 -0
  630. package/.next/server/chunks/ssr/src_app_recipes_[id]_RecipeEditor_index_tsx_98393217._.js.map +1 -0
  631. package/.next/server/chunks/ssr/src_app_recipes_recipes-client_tsx_8ed3ca94._.js +1 -1
  632. package/.next/server/chunks/ssr/src_app_recipes_recipes-client_tsx_8ed3ca94._.js.map +1 -1
  633. package/.next/server/chunks/ssr/src_app_teams_[teamId]_team-editor_index_tsx_e68e9cbc._.js +12 -0
  634. package/.next/server/chunks/ssr/src_app_teams_[teamId]_team-editor_index_tsx_e68e9cbc._.js.map +1 -0
  635. package/.next/server/chunks/ssr/src_app_tickets_TicketsBoardClient_tsx_5e156ef3._.js +1 -1
  636. package/.next/server/chunks/ssr/src_app_tickets_TicketsBoardClient_tsx_5e156ef3._.js.map +1 -1
  637. package/.next/server/chunks/ssr/src_e54f24fb._.js +3 -0
  638. package/.next/server/chunks/ssr/src_e54f24fb._.js.map +1 -0
  639. package/.next/server/middleware-build-manifest.js +4 -4
  640. package/.next/server/next-font-manifest.js +1 -1
  641. package/.next/server/next-font-manifest.json +16 -0
  642. package/.next/server/pages/404.html +1 -1
  643. package/.next/server/pages/500.html +2 -2
  644. package/.next/static/chunks/0edab8a24d59a626.js +2 -0
  645. package/.next/static/chunks/11da0a52793b005a.js +1 -0
  646. package/.next/static/chunks/150338287c7dae30.js +1 -0
  647. package/.next/static/chunks/236ef28eb649c432.js +1 -0
  648. package/.next/static/chunks/3e1fe6be993c61fb.js +1 -0
  649. package/.next/static/chunks/55a88f2071ebe766.js +1 -0
  650. package/.next/static/chunks/5cf42ef49ad071af.js +10 -0
  651. package/.next/static/chunks/62e0c437eb8fc2da.js +1 -0
  652. package/.next/static/chunks/{82abf2d65f5428ae.js → 68a088aa49e6124a.js} +3 -3
  653. package/.next/static/chunks/7bb0aafbf73524bf.js +1 -0
  654. package/.next/static/chunks/8d359fbce4ebb835.js +1 -0
  655. package/.next/static/chunks/9197ecb9606557f3.js +1 -0
  656. package/.next/static/chunks/93719e85369dd453.js +1 -0
  657. package/.next/static/chunks/b244476ded155cf9.css +3 -0
  658. package/.next/static/chunks/c75e00652e6b7d85.js +1 -0
  659. package/.next/static/chunks/c84580993f22c17a.js +1 -0
  660. package/.next/static/chunks/d73a47fc8def319c.js +1 -0
  661. package/.next/static/chunks/daa78a9d669e23f5.js +1 -0
  662. package/.next/static/chunks/db4da5ee45033817.js +1 -0
  663. package/.next/static/chunks/e8021fea9aee6b63.js +1 -0
  664. package/.next/static/chunks/e854e56ea8cb6236.js +1 -0
  665. package/.next/static/chunks/ffff6b5105288d2c.js +1 -0
  666. package/.next/static/chunks/{turbopack-ae1340e658f67df8.js → turbopack-0236a74c4f471967.js} +1 -1
  667. package/README.md +22 -1
  668. package/openclaw/index.ts +133 -26
  669. package/openclaw.plugin.json +9 -1
  670. package/package.json +24 -3
  671. package/public/android-chrome-192x192.png +0 -0
  672. package/public/android-chrome-512x512.png +0 -0
  673. package/public/apple-touch-icon.png +0 -0
  674. package/public/chef.jpg +0 -0
  675. package/public/favicon-16x16.png +0 -0
  676. package/public/favicon-32x32.png +0 -0
  677. package/public/favicon.ico +0 -0
  678. package/src/app/HomeClient.tsx +8 -9
  679. package/src/app/agents/[agentId]/agent-editor-tabs.tsx +298 -0
  680. package/src/app/agents/[agentId]/agent-editor.tsx +200 -428
  681. package/src/app/api/__tests__/agents-add-route.test.ts +143 -0
  682. package/src/app/api/__tests__/agents-file-route.test.ts +117 -0
  683. package/src/app/api/__tests__/agents-files-route.test.ts +61 -0
  684. package/src/app/api/__tests__/agents-id-route.test.ts +104 -0
  685. package/src/app/api/__tests__/agents-identity-route.test.ts +92 -0
  686. package/src/app/api/__tests__/agents-route.test.ts +54 -0
  687. package/src/app/api/__tests__/agents-skills-install-route.test.ts +131 -0
  688. package/src/app/api/__tests__/agents-skills-route.test.ts +64 -0
  689. package/src/app/api/__tests__/agents-update-route.test.ts +95 -0
  690. package/src/app/api/__tests__/channels-bindings-route.test.ts +143 -0
  691. package/src/app/api/__tests__/cron-delete-route.test.ts +93 -0
  692. package/src/app/api/__tests__/cron-job-route.test.ts +78 -0
  693. package/src/app/api/__tests__/cron-jobs-route.test.ts +116 -0
  694. package/src/app/api/__tests__/cron-recipe-installed-route.test.ts +114 -0
  695. package/src/app/api/__tests__/gateway-restart-route.test.ts +36 -0
  696. package/src/app/api/__tests__/goals-promote-route.test.ts +200 -0
  697. package/src/app/api/__tests__/goals-route.test.ts +184 -0
  698. package/src/app/api/__tests__/ids-check-route.test.ts +188 -0
  699. package/src/app/api/__tests__/marketplace-recipes-route.test.ts +123 -0
  700. package/src/app/api/__tests__/recipes-clone-route.test.ts +221 -0
  701. package/src/app/api/__tests__/recipes-delete-route.test.ts +248 -0
  702. package/src/app/api/__tests__/recipes-id-route.test.ts +166 -0
  703. package/src/app/api/__tests__/recipes-route.test.ts +57 -0
  704. package/src/app/api/__tests__/recipes-team-agents-route.test.ts +135 -0
  705. package/src/app/api/__tests__/scaffold-route.test.ts +173 -0
  706. package/src/app/api/__tests__/settings-cron-installation-route.test.ts +82 -0
  707. package/src/app/api/__tests__/skills-available-route.test.ts +47 -0
  708. package/src/app/api/__tests__/swarms-start-route.test.ts +79 -0
  709. package/src/app/api/__tests__/swarms-status-route.test.ts +42 -0
  710. package/src/app/api/__tests__/teams-file-route.test.ts +129 -0
  711. package/src/app/api/__tests__/teams-files-route.test.ts +57 -0
  712. package/src/app/api/__tests__/teams-meta-route.test.ts +113 -0
  713. package/src/app/api/__tests__/teams-orchestrator-install-route.test.ts +66 -0
  714. package/src/app/api/__tests__/teams-orchestrator-route.test.ts +59 -0
  715. package/src/app/api/__tests__/teams-remove-team-route.test.ts +122 -0
  716. package/src/app/api/__tests__/teams-skills-install-route.test.ts +78 -0
  717. package/src/app/api/__tests__/teams-skills-route.test.ts +73 -0
  718. package/src/app/api/__tests__/teams-workflow-runs-route.test.ts +85 -0
  719. package/src/app/api/__tests__/teams-workflows-route.test.ts +110 -0
  720. package/src/app/api/__tests__/tickets-move-route.test.ts +60 -0
  721. package/src/app/api/agents/[id]/route.ts +33 -29
  722. package/src/app/api/agents/add/route.ts +38 -33
  723. package/src/app/api/agents/file/route.ts +14 -27
  724. package/src/app/api/agents/files/route.ts +7 -62
  725. package/src/app/api/agents/route.ts +3 -10
  726. package/src/app/api/agents/skills/install/route.ts +2 -14
  727. package/src/app/api/agents/skills/route.ts +6 -18
  728. package/src/app/api/channels/bindings/route.ts +6 -15
  729. package/src/app/api/cron/__tests__/helpers.test.ts +164 -0
  730. package/src/app/api/cron/delete/route.ts +4 -63
  731. package/src/app/api/cron/helpers.ts +172 -0
  732. package/src/app/api/cron/jobs/route.ts +24 -113
  733. package/src/app/api/cron/recipe-installed/route.ts +6 -4
  734. package/src/app/api/gateway/restart/route.ts +2 -1
  735. package/src/app/api/goals/[id]/promote/route.ts +10 -43
  736. package/src/app/api/goals/[id]/route.ts +10 -16
  737. package/src/app/api/goals/route.ts +3 -6
  738. package/src/app/api/ids/check/route.ts +18 -26
  739. package/src/app/api/marketplace/recipes/[slug]/route.ts +2 -2
  740. package/src/app/api/recipes/[id]/route.ts +3 -9
  741. package/src/app/api/recipes/clone/route.ts +3 -38
  742. package/src/app/api/recipes/custom-team/route.ts +193 -0
  743. package/src/app/api/recipes/delete/helpers.ts +65 -0
  744. package/src/app/api/recipes/delete/route.ts +11 -78
  745. package/src/app/api/recipes/team-agents/__tests__/helpers.test.ts +156 -0
  746. package/src/app/api/recipes/team-agents/helpers.ts +151 -0
  747. package/src/app/api/recipes/team-agents/route.ts +27 -125
  748. package/src/app/api/scaffold/__tests__/helpers.test.ts +186 -0
  749. package/src/app/api/scaffold/helpers.ts +214 -0
  750. package/src/app/api/scaffold/route.ts +40 -274
  751. package/src/app/api/settings/cron-installation/route.ts +3 -2
  752. package/src/app/api/skills/available/route.ts +2 -1
  753. package/src/app/api/swarms/start/route.ts +100 -0
  754. package/src/app/api/swarms/status/route.ts +31 -0
  755. package/src/app/api/teams/[teamId]/tickets/assign/route.ts +105 -0
  756. package/src/app/api/teams/[teamId]/tickets/assignees/route.ts +27 -0
  757. package/src/app/api/teams/[teamId]/tickets/delete/route.ts +55 -0
  758. package/src/app/api/teams/[teamId]/tickets/move/route.ts +70 -0
  759. package/src/app/api/teams/[teamId]/tickets/move-to-goals/route.ts +56 -0
  760. package/src/app/api/teams/file/route.ts +26 -47
  761. package/src/app/api/teams/files/route.ts +13 -45
  762. package/src/app/api/teams/memory/route.ts +250 -0
  763. package/src/app/api/teams/meta/route.ts +16 -35
  764. package/src/app/api/teams/orchestrator/install/route.ts +129 -0
  765. package/src/app/api/teams/orchestrator/route.ts +216 -0
  766. package/src/app/api/teams/remove-team/route.ts +7 -15
  767. package/src/app/api/teams/skills/install/route.ts +2 -13
  768. package/src/app/api/teams/skills/route.ts +6 -17
  769. package/src/app/api/teams/workflow-runs/route.ts +534 -0
  770. package/src/app/api/teams/workflow-templates/route.ts +71 -0
  771. package/src/app/api/teams/workflows/route.ts +55 -0
  772. package/src/app/api/tickets/assign/route.ts +94 -0
  773. package/src/app/api/tickets/assignees/route.ts +24 -0
  774. package/src/app/api/tickets/move/route.ts +31 -0
  775. package/src/app/channels/channels-client.tsx +48 -47
  776. package/src/app/cron-jobs/cron-jobs-client.tsx +11 -14
  777. package/src/app/cron-jobs/page.tsx +1 -1
  778. package/src/app/global-error.tsx +50 -0
  779. package/src/app/goals/[id]/goal-editor.tsx +74 -179
  780. package/src/app/goals/goals-client.tsx +30 -39
  781. package/src/app/goals/new/page.tsx +45 -124
  782. package/src/app/layout.tsx +8 -0
  783. package/src/app/manifest.ts +15 -0
  784. package/src/app/not-found.tsx +8 -0
  785. package/src/app/page.tsx +4 -31
  786. package/src/app/recipes/CreateAgentModal.tsx +98 -153
  787. package/src/app/recipes/CreateCustomTeamModal.tsx +375 -0
  788. package/src/app/recipes/CreateModalShell.tsx +55 -0
  789. package/src/app/recipes/CreateTeamModal.tsx +54 -105
  790. package/src/app/recipes/[id]/RecipeEditor/RecipeEditorCreateModal.tsx +72 -0
  791. package/src/app/recipes/[id]/RecipeEditor/RecipeEditorPanel.tsx +216 -0
  792. package/src/app/recipes/[id]/RecipeEditor/index.tsx +271 -0
  793. package/src/app/recipes/[id]/RecipeEditor/recipe-editor-utils.ts +46 -0
  794. package/src/app/recipes/[id]/RecipeEditor/types.ts +52 -0
  795. package/src/app/recipes/[id]/page.tsx +4 -18
  796. package/src/app/recipes/page.tsx +9 -2
  797. package/src/app/recipes/recipes-client.tsx +266 -156
  798. package/src/app/settings/page.tsx +1 -1
  799. package/src/app/settings/settings-client.tsx +11 -10
  800. package/src/app/teams/[teamId]/CloneTeamModal.tsx +77 -111
  801. package/src/app/teams/[teamId]/OrchestratorPanel.tsx +255 -0
  802. package/src/app/teams/[teamId]/OrchestratorSetupModal.tsx +184 -0
  803. package/src/app/teams/[teamId]/PublishChangesModal.tsx +21 -42
  804. package/src/app/teams/[teamId]/page.tsx +27 -49
  805. package/src/app/teams/[teamId]/team-editor/TeamAgentsTab.tsx +145 -0
  806. package/src/app/teams/[teamId]/team-editor/TeamCronTab.tsx +72 -0
  807. package/src/app/teams/[teamId]/team-editor/TeamFilesTab.tsx +74 -0
  808. package/src/app/teams/[teamId]/team-editor/TeamMemoryTab.tsx +349 -0
  809. package/src/app/teams/[teamId]/team-editor/TeamRecipeTab.tsx +151 -0
  810. package/src/app/teams/[teamId]/team-editor/TeamSkillsTab.tsx +68 -0
  811. package/src/app/teams/[teamId]/team-editor/index.tsx +558 -0
  812. package/src/app/teams/[teamId]/team-editor/team-editor-data.ts +255 -0
  813. package/src/app/teams/[teamId]/team-editor/team-editor-utils.ts +78 -0
  814. package/src/app/teams/[teamId]/team-editor/types.ts +34 -0
  815. package/src/app/teams/[teamId]/tickets/[ticket]/page.tsx +35 -0
  816. package/src/app/teams/[teamId]/tickets/page.tsx +15 -0
  817. package/src/app/teams/[teamId]/workflows/[workflowId]/WorkflowCanvas.tsx +111 -0
  818. package/src/app/teams/[teamId]/workflows/[workflowId]/page.tsx +27 -0
  819. package/src/app/teams/[teamId]/workflows/[workflowId]/workflows-editor-client.tsx +1608 -0
  820. package/src/app/teams/[teamId]/workflows/page.tsx +40 -0
  821. package/src/app/teams/[teamId]/workflows/workflows-client.tsx +494 -0
  822. package/src/app/tickets/TicketDetailClient.tsx +147 -0
  823. package/src/app/tickets/TicketsBoardClient.tsx +11 -57
  824. package/src/app/tickets/[ticket]/TicketAssignControl.tsx +112 -0
  825. package/src/app/tickets/[ticket]/page.tsx +13 -21
  826. package/src/app/tickets/page.tsx +5 -2
  827. package/src/components/AppShell.tsx +252 -31
  828. package/src/{app/cron-jobs/DeleteCronJobModal.tsx → components/ConfirmationModal.tsx} +35 -17
  829. package/src/components/DeleteEntityModal.tsx +41 -0
  830. package/src/components/ErrorBoundary.tsx +70 -0
  831. package/src/components/FileListWithOptionalToggle.tsx +86 -0
  832. package/src/components/GoalFormFields.tsx +163 -0
  833. package/src/components/ScaffoldOverlay.tsx +7 -10
  834. package/src/components/ToastProvider.tsx +22 -18
  835. package/src/components/__tests__/ConfirmationModal.test.tsx +109 -0
  836. package/src/components/__tests__/ErrorBoundary.test.tsx +39 -0
  837. package/src/components/__tests__/FileListWithOptionalToggle.test.tsx +109 -0
  838. package/src/components/__tests__/GoalFormFields.test.tsx +117 -0
  839. package/src/components/delete-modals.tsx +59 -0
  840. package/src/components/icons.tsx +12 -10
  841. package/src/lib/__tests__/agent-workspace.test.ts +44 -0
  842. package/src/lib/__tests__/agents.test.ts +36 -0
  843. package/src/lib/__tests__/api-route-helpers.test.ts +188 -0
  844. package/src/lib/__tests__/cron.test.ts +45 -0
  845. package/src/lib/__tests__/editor-utils.test.ts +38 -0
  846. package/src/lib/__tests__/errors.test.ts +15 -0
  847. package/src/lib/__tests__/exec.test.ts +13 -0
  848. package/src/lib/__tests__/fetch-json.test.ts +118 -0
  849. package/src/lib/__tests__/gateway.test.ts +234 -0
  850. package/src/lib/__tests__/goal-promote.test.ts +39 -0
  851. package/src/lib/__tests__/goals-client.test.ts +26 -0
  852. package/src/lib/__tests__/goals.test.ts +275 -0
  853. package/src/lib/__tests__/json.test.ts +15 -0
  854. package/src/lib/__tests__/kitchen-api.test.ts +32 -0
  855. package/src/lib/__tests__/marketplace.test.ts +116 -0
  856. package/src/lib/__tests__/openclaw.test.ts +129 -0
  857. package/src/lib/__tests__/paths.test.ts +136 -0
  858. package/src/lib/__tests__/poll.test.ts +26 -0
  859. package/src/lib/__tests__/recipe-clone.test.ts +85 -0
  860. package/src/lib/__tests__/recipe-team-agents.test.ts +70 -0
  861. package/src/lib/__tests__/recipes.test.ts +199 -0
  862. package/src/lib/__tests__/scaffold-client.test.ts +106 -0
  863. package/src/lib/__tests__/scaffold.test.ts +64 -0
  864. package/src/lib/__tests__/slugify.test.ts +23 -0
  865. package/src/lib/__tests__/tickets.test.ts +158 -0
  866. package/src/lib/__tests__/type-guards.test.ts +18 -0
  867. package/src/lib/__tests__/use-slugified-id.test.tsx +120 -0
  868. package/src/lib/agents.ts +17 -0
  869. package/src/lib/api-route-helpers.ts +157 -0
  870. package/src/lib/cron.ts +40 -0
  871. package/src/lib/editor-utils.ts +18 -0
  872. package/src/lib/errors.ts +7 -0
  873. package/src/lib/exec.ts +4 -0
  874. package/src/lib/fetch-json.ts +29 -0
  875. package/src/lib/gateway.ts +5 -1
  876. package/src/lib/goal-promote.ts +27 -0
  877. package/src/lib/goals-client.ts +69 -0
  878. package/src/lib/goals.ts +22 -3
  879. package/src/lib/json.ts +10 -0
  880. package/src/lib/openclaw.ts +28 -13
  881. package/src/lib/paths.ts +12 -0
  882. package/src/lib/poll.ts +18 -0
  883. package/src/lib/recipe-clone.ts +42 -0
  884. package/src/lib/recipe-team-agents.ts +30 -0
  885. package/src/lib/recipes.ts +47 -0
  886. package/src/lib/scaffold-client.ts +31 -0
  887. package/src/lib/scaffold.ts +37 -0
  888. package/src/lib/slugify.ts +25 -0
  889. package/src/lib/swarms.ts +25 -0
  890. package/src/lib/tickets.ts +81 -25
  891. package/src/lib/type-guards.ts +3 -0
  892. package/src/lib/use-slugified-id.ts +35 -0
  893. package/src/lib/workflows/README.md +11 -0
  894. package/src/lib/workflows/__tests__/storage.test.ts +129 -0
  895. package/src/lib/workflows/__tests__/validate.test.ts +92 -0
  896. package/src/lib/workflows/api-handlers.ts +35 -0
  897. package/src/lib/workflows/readdir.ts +23 -0
  898. package/src/lib/workflows/runs-storage.ts +59 -0
  899. package/src/lib/workflows/runs-types.ts +42 -0
  900. package/src/lib/workflows/storage.ts +70 -0
  901. package/src/lib/workflows/templates/index.ts +1 -0
  902. package/src/lib/workflows/templates/marketing-cadence-v1.ts +142 -0
  903. package/src/lib/workflows/types.ts +48 -0
  904. package/src/lib/workflows/validate.ts +92 -0
  905. package/.next/server/app/tickets.html +0 -1
  906. package/.next/server/app/tickets.meta +0 -15
  907. package/.next/server/app/tickets.rsc +0 -19
  908. package/.next/server/app/tickets.segments/_full.segment.rsc +0 -19
  909. package/.next/server/app/tickets.segments/_head.segment.rsc +0 -6
  910. package/.next/server/app/tickets.segments/_index.segment.rsc +0 -6
  911. package/.next/server/app/tickets.segments/_tree.segment.rsc +0 -4
  912. package/.next/server/app/tickets.segments/tickets/__PAGE__.segment.rsc +0 -8
  913. package/.next/server/app/tickets.segments/tickets.segment.rsc +0 -4
  914. package/.next/server/chunks/[root-of-the-server]__055885ce._.js +0 -3
  915. package/.next/server/chunks/[root-of-the-server]__055885ce._.js.map +0 -1
  916. package/.next/server/chunks/[root-of-the-server]__0c01c5c7._.js +0 -10
  917. package/.next/server/chunks/[root-of-the-server]__0c01c5c7._.js.map +0 -1
  918. package/.next/server/chunks/[root-of-the-server]__1398a33a._.js +0 -3
  919. package/.next/server/chunks/[root-of-the-server]__1398a33a._.js.map +0 -1
  920. package/.next/server/chunks/[root-of-the-server]__159c002b._.js +0 -8
  921. package/.next/server/chunks/[root-of-the-server]__159c002b._.js.map +0 -1
  922. package/.next/server/chunks/[root-of-the-server]__20c60fb7._.js +0 -3
  923. package/.next/server/chunks/[root-of-the-server]__20c60fb7._.js.map +0 -1
  924. package/.next/server/chunks/[root-of-the-server]__2588560d._.js +0 -6
  925. package/.next/server/chunks/[root-of-the-server]__2588560d._.js.map +0 -1
  926. package/.next/server/chunks/[root-of-the-server]__27293e91._.js +0 -3
  927. package/.next/server/chunks/[root-of-the-server]__27293e91._.js.map +0 -1
  928. package/.next/server/chunks/[root-of-the-server]__29c85a51._.js +0 -3
  929. package/.next/server/chunks/[root-of-the-server]__29c85a51._.js.map +0 -1
  930. package/.next/server/chunks/[root-of-the-server]__29fa8108._.js +0 -3
  931. package/.next/server/chunks/[root-of-the-server]__29fa8108._.js.map +0 -1
  932. package/.next/server/chunks/[root-of-the-server]__2bd44067._.js +0 -3
  933. package/.next/server/chunks/[root-of-the-server]__2bd44067._.js.map +0 -1
  934. package/.next/server/chunks/[root-of-the-server]__2dd1afff._.js +0 -3
  935. package/.next/server/chunks/[root-of-the-server]__2dd1afff._.js.map +0 -1
  936. package/.next/server/chunks/[root-of-the-server]__401ab759._.js +0 -3
  937. package/.next/server/chunks/[root-of-the-server]__401ab759._.js.map +0 -1
  938. package/.next/server/chunks/[root-of-the-server]__422c7160._.js +0 -3
  939. package/.next/server/chunks/[root-of-the-server]__422c7160._.js.map +0 -1
  940. package/.next/server/chunks/[root-of-the-server]__4670294e._.js +0 -3
  941. package/.next/server/chunks/[root-of-the-server]__4670294e._.js.map +0 -1
  942. package/.next/server/chunks/[root-of-the-server]__4eda99a9._.js +0 -3
  943. package/.next/server/chunks/[root-of-the-server]__4eda99a9._.js.map +0 -1
  944. package/.next/server/chunks/[root-of-the-server]__54478298._.js +0 -8
  945. package/.next/server/chunks/[root-of-the-server]__54478298._.js.map +0 -1
  946. package/.next/server/chunks/[root-of-the-server]__6dbdb384._.js +0 -3
  947. package/.next/server/chunks/[root-of-the-server]__6dbdb384._.js.map +0 -1
  948. package/.next/server/chunks/[root-of-the-server]__94d68aa3._.js +0 -3
  949. package/.next/server/chunks/[root-of-the-server]__94d68aa3._.js.map +0 -1
  950. package/.next/server/chunks/[root-of-the-server]__9ecbb339._.js +0 -3
  951. package/.next/server/chunks/[root-of-the-server]__9ecbb339._.js.map +0 -1
  952. package/.next/server/chunks/[root-of-the-server]__a27f8405._.js +0 -3
  953. package/.next/server/chunks/[root-of-the-server]__a27f8405._.js.map +0 -1
  954. package/.next/server/chunks/[root-of-the-server]__a6ac3ddf._.js +0 -3
  955. package/.next/server/chunks/[root-of-the-server]__b11231a9._.js +0 -3
  956. package/.next/server/chunks/[root-of-the-server]__b11231a9._.js.map +0 -1
  957. package/.next/server/chunks/[root-of-the-server]__b59b3cdd._.js +0 -3
  958. package/.next/server/chunks/[root-of-the-server]__b59b3cdd._.js.map +0 -1
  959. package/.next/server/chunks/[root-of-the-server]__b5c2b370._.js +0 -3
  960. package/.next/server/chunks/[root-of-the-server]__b5c2b370._.js.map +0 -1
  961. package/.next/server/chunks/[root-of-the-server]__b955e35a._.js +0 -3
  962. package/.next/server/chunks/[root-of-the-server]__b955e35a._.js.map +0 -1
  963. package/.next/server/chunks/[root-of-the-server]__be5f57b2._.js +0 -3
  964. package/.next/server/chunks/[root-of-the-server]__c4ff0427._.js +0 -3
  965. package/.next/server/chunks/[root-of-the-server]__c4ff0427._.js.map +0 -1
  966. package/.next/server/chunks/[root-of-the-server]__c4ffbb03._.js +0 -3
  967. package/.next/server/chunks/[root-of-the-server]__c4ffbb03._.js.map +0 -1
  968. package/.next/server/chunks/[root-of-the-server]__d737ca42._.js +0 -3
  969. package/.next/server/chunks/[root-of-the-server]__d737ca42._.js.map +0 -1
  970. package/.next/server/chunks/[root-of-the-server]__df7df3ac._.js +0 -3
  971. package/.next/server/chunks/[root-of-the-server]__df7df3ac._.js.map +0 -1
  972. package/.next/server/chunks/[root-of-the-server]__dfca6557._.js +0 -3
  973. package/.next/server/chunks/[root-of-the-server]__dfca6557._.js.map +0 -1
  974. package/.next/server/chunks/[root-of-the-server]__e6184ba3._.js +0 -3
  975. package/.next/server/chunks/[root-of-the-server]__e6184ba3._.js.map +0 -1
  976. package/.next/server/chunks/[root-of-the-server]__ed0323e9._.js +0 -8
  977. package/.next/server/chunks/[root-of-the-server]__ed0323e9._.js.map +0 -1
  978. package/.next/server/chunks/[root-of-the-server]__f585823b._.js +0 -6
  979. package/.next/server/chunks/[root-of-the-server]__f585823b._.js.map +0 -1
  980. package/.next/server/chunks/[root-of-the-server]__ff940674._.js +0 -3
  981. package/.next/server/chunks/[root-of-the-server]__ff940674._.js.map +0 -1
  982. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_5a9305ea.js +0 -6
  983. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_5a9305ea.js.map +0 -1
  984. package/.next/server/chunks/src_lib_d2210cbf._.js +0 -3
  985. package/.next/server/chunks/src_lib_d2210cbf._.js.map +0 -1
  986. package/.next/server/chunks/ssr/[externals]__c37e9f91._.js +0 -3
  987. package/.next/server/chunks/ssr/[root-of-the-server]__15600e29._.js +0 -3
  988. package/.next/server/chunks/ssr/[root-of-the-server]__247198dc._.js +0 -3
  989. package/.next/server/chunks/ssr/[root-of-the-server]__2a6f1e3e._.js +0 -3
  990. package/.next/server/chunks/ssr/[root-of-the-server]__346f79e5._.js +0 -3
  991. package/.next/server/chunks/ssr/[root-of-the-server]__346f79e5._.js.map +0 -1
  992. package/.next/server/chunks/ssr/[root-of-the-server]__3575e6da._.js +0 -3
  993. package/.next/server/chunks/ssr/[root-of-the-server]__3ad3e5b1._.js +0 -3
  994. package/.next/server/chunks/ssr/[root-of-the-server]__3bc7ad0a._.js +0 -3
  995. package/.next/server/chunks/ssr/[root-of-the-server]__4393e897._.js +0 -3
  996. package/.next/server/chunks/ssr/[root-of-the-server]__4393e897._.js.map +0 -1
  997. package/.next/server/chunks/ssr/[root-of-the-server]__46e08d44._.js +0 -3
  998. package/.next/server/chunks/ssr/[root-of-the-server]__491e06fa._.js +0 -3
  999. package/.next/server/chunks/ssr/[root-of-the-server]__491e06fa._.js.map +0 -1
  1000. package/.next/server/chunks/ssr/[root-of-the-server]__507d2fc9._.js +0 -3
  1001. package/.next/server/chunks/ssr/[root-of-the-server]__507d2fc9._.js.map +0 -1
  1002. package/.next/server/chunks/ssr/[root-of-the-server]__5d24d429._.js +0 -3
  1003. package/.next/server/chunks/ssr/[root-of-the-server]__5d24d429._.js.map +0 -1
  1004. package/.next/server/chunks/ssr/[root-of-the-server]__7180d770._.js.map +0 -1
  1005. package/.next/server/chunks/ssr/[root-of-the-server]__82ce3aee._.js +0 -3
  1006. package/.next/server/chunks/ssr/[root-of-the-server]__82ce3aee._.js.map +0 -1
  1007. package/.next/server/chunks/ssr/[root-of-the-server]__8d24c9c3._.js +0 -3
  1008. package/.next/server/chunks/ssr/[root-of-the-server]__8d24c9c3._.js.map +0 -1
  1009. package/.next/server/chunks/ssr/[root-of-the-server]__a457c799._.js +0 -3
  1010. package/.next/server/chunks/ssr/[root-of-the-server]__a457c799._.js.map +0 -1
  1011. package/.next/server/chunks/ssr/[root-of-the-server]__bc3b27b0._.js +0 -3
  1012. package/.next/server/chunks/ssr/[root-of-the-server]__bc3b27b0._.js.map +0 -1
  1013. package/.next/server/chunks/ssr/[root-of-the-server]__f75a61bf._.js +0 -3
  1014. package/.next/server/chunks/ssr/[root-of-the-server]__f75a61bf._.js.map +0 -1
  1015. package/.next/server/chunks/ssr/[root-of-the-server]__fd669584._.js +0 -3
  1016. package/.next/server/chunks/ssr/_0808c2b9._.js.map +0 -1
  1017. package/.next/server/chunks/ssr/_1aad1d9b._.js +0 -24
  1018. package/.next/server/chunks/ssr/_1aad1d9b._.js.map +0 -1
  1019. package/.next/server/chunks/ssr/_3158c108._.js.map +0 -1
  1020. package/.next/server/chunks/ssr/_39e6e769._.js.map +0 -1
  1021. package/.next/server/chunks/ssr/_3c8b2df6._.js.map +0 -1
  1022. package/.next/server/chunks/ssr/_5070929e._.js +0 -3
  1023. package/.next/server/chunks/ssr/_5070929e._.js.map +0 -1
  1024. package/.next/server/chunks/ssr/_68793c1f._.js.map +0 -1
  1025. package/.next/server/chunks/ssr/_6e70b5a4._.js.map +0 -1
  1026. package/.next/server/chunks/ssr/_8c45edba._.js.map +0 -1
  1027. package/.next/server/chunks/ssr/_8c8207c1._.js.map +0 -1
  1028. package/.next/server/chunks/ssr/_92140ca3._.js.map +0 -1
  1029. package/.next/server/chunks/ssr/_b5e9afcc._.js.map +0 -1
  1030. package/.next/server/chunks/ssr/_cd23c5af._.js.map +0 -1
  1031. package/.next/server/chunks/ssr/_d27483a1._.js.map +0 -1
  1032. package/.next/server/chunks/ssr/_da6f800e._.js.map +0 -1
  1033. package/.next/server/chunks/ssr/d4b1c_modules_next_dist_server_route-modules_app-page_vendored_ssr_react-dom_6ef9314a.js +0 -3
  1034. package/.next/server/chunks/ssr/d4b1c_modules_next_dist_server_route-modules_app-page_vendored_ssr_react-dom_6ef9314a.js.map +0 -1
  1035. package/.next/server/chunks/ssr/node_modules_next_dist_12287b3d._.js.map +0 -1
  1036. package/.next/server/chunks/ssr/node_modules_next_dist_852965c2._.js +0 -3
  1037. package/.next/server/chunks/ssr/node_modules_next_dist_852965c2._.js.map +0 -1
  1038. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_45780354.js +0 -3
  1039. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_forbidden_45780354.js.map +0 -1
  1040. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_ece394eb.js +0 -3
  1041. package/.next/server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_ece394eb.js.map +0 -1
  1042. package/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_68c68167.js.map +0 -1
  1043. package/.next/server/chunks/ssr/src_app_channels_channels-client_tsx_8c8be116._.js +0 -3
  1044. package/.next/server/chunks/ssr/src_app_channels_channels-client_tsx_8c8be116._.js.map +0 -1
  1045. package/.next/server/chunks/ssr/src_app_goals_[id]_goal-editor_tsx_7df8193f._.js +0 -3
  1046. package/.next/server/chunks/ssr/src_app_goals_[id]_goal-editor_tsx_7df8193f._.js.map +0 -1
  1047. package/.next/server/chunks/ssr/src_app_goals_goals-client_tsx_a45eeff4._.js +0 -3
  1048. package/.next/server/chunks/ssr/src_app_goals_goals-client_tsx_a45eeff4._.js.map +0 -1
  1049. package/.next/server/chunks/ssr/src_app_goals_new_page_tsx_8f749229._.js +0 -3
  1050. package/.next/server/chunks/ssr/src_app_goals_new_page_tsx_8f749229._.js.map +0 -1
  1051. package/.next/server/chunks/ssr/src_app_recipes_[id]_RecipeEditor_tsx_c6d38350._.js +0 -3
  1052. package/.next/server/chunks/ssr/src_app_recipes_[id]_RecipeEditor_tsx_c6d38350._.js.map +0 -1
  1053. package/.next/server/chunks/ssr/src_app_settings_settings-client_tsx_279084f8._.js +0 -3
  1054. package/.next/server/chunks/ssr/src_app_settings_settings-client_tsx_279084f8._.js.map +0 -1
  1055. package/.next/server/chunks/ssr/src_app_teams_[teamId]_team-editor_tsx_2900b91d._.js +0 -12
  1056. package/.next/server/chunks/ssr/src_app_teams_[teamId]_team-editor_tsx_2900b91d._.js.map +0 -1
  1057. package/.next/static/chunks/10cbf02e6fc36465.js +0 -2
  1058. package/.next/static/chunks/1ce21af6dfb18ee3.js +0 -1
  1059. package/.next/static/chunks/40f7fde35327d214.js +0 -1
  1060. package/.next/static/chunks/54beb791bcc086ae.js +0 -1
  1061. package/.next/static/chunks/55866d57aa2c7a9c.js +0 -1
  1062. package/.next/static/chunks/6a7862e37c616cc3.js +0 -1
  1063. package/.next/static/chunks/817ae077ec8c6255.js +0 -1
  1064. package/.next/static/chunks/8484c54dc9a377e8.js +0 -10
  1065. package/.next/static/chunks/8662fcc3cdff66f3.js +0 -1
  1066. package/.next/static/chunks/99208ebf7e47471d.js +0 -1
  1067. package/.next/static/chunks/a4e69b85b74277a7.css +0 -3
  1068. package/.next/static/chunks/a9ed074e89b16a5e.js +0 -1
  1069. package/.next/static/chunks/c6dfa918cafb6c0c.js +0 -1
  1070. package/.next/static/chunks/d1c5f764e5fd615a.js +0 -1
  1071. package/.next/static/chunks/d4ce2f908d8c4dea.js +0 -1
  1072. package/.next/static/chunks/de9e30e86ef31e72.js +0 -1
  1073. package/src/app/recipes/DeleteRecipeModal.tsx +0 -62
  1074. package/src/app/recipes/[id]/RecipeEditor.tsx +0 -697
  1075. package/src/app/teams/[teamId]/DeleteTeamModal.tsx +0 -54
  1076. package/src/app/teams/[teamId]/team-editor.tsx +0 -1195
  1077. /package/.next/server/chunks/{[root-of-the-server]__74b80ca4._.js.map → [root-of-the-server]__c63a9f28._.js.map} +0 -0
  1078. /package/.next/server/chunks/{ssr/[externals]__c37e9f91._.js.map → _next-internal_server_app_api_recipes_custom-team_route_actions_861b1489.js.map} +0 -0
  1079. /package/.next/server/chunks/ssr/{[root-of-the-server]__3bc7ad0a._.js.map → [root-of-the-server]__0d4cb2ba._.js.map} +0 -0
  1080. /package/.next/server/chunks/ssr/{[root-of-the-server]__e2e52c6e._.js.map → [root-of-the-server]__78cdd31e._.js.map} +0 -0
  1081. /package/.next/static/{QOy0ilqTW1kHfmpls_oWp → z9yFlFZ5f_hw9mm0nfMJl}/_buildManifest.js +0 -0
  1082. /package/.next/static/{QOy0ilqTW1kHfmpls_oWp → z9yFlFZ5f_hw9mm0nfMJl}/_clientMiddlewareManifest.json +0 -0
  1083. /package/.next/static/{QOy0ilqTW1kHfmpls_oWp → z9yFlFZ5f_hw9mm0nfMJl}/_ssgManifest.js +0 -0
@@ -0,0 +1,1608 @@
1
+ "use client";
2
+
3
+ import { useEffect, useMemo, useRef, useState } from "react";
4
+ import type { WorkflowFileV1 } from "@/lib/workflows/types";
5
+ import { validateWorkflowFileV1 } from "@/lib/workflows/validate";
6
+
7
+ type LoadState =
8
+ | { kind: "loading" }
9
+ | { kind: "error"; error: string }
10
+ | { kind: "ready"; jsonText: string };
11
+
12
+ function draftKey(teamId: string, workflowId: string) {
13
+ return `ck-wf-draft:${teamId}:${workflowId}`;
14
+ }
15
+
16
+ export default function WorkflowsEditorClient({
17
+ teamId,
18
+ workflowId,
19
+ draft,
20
+ }: {
21
+ teamId: string;
22
+ workflowId: string;
23
+ draft: boolean;
24
+ }) {
25
+ const [view, setView] = useState<"canvas" | "json">("canvas");
26
+ const [saving, setSaving] = useState(false);
27
+ const [status, setStatus] = useState<LoadState>({ kind: "loading" });
28
+ const [actionError, setActionError] = useState<string>("");
29
+ const importInputRef = useRef<HTMLInputElement | null>(null);
30
+
31
+ const [toolsCollapsed, setToolsCollapsed] = useState(false);
32
+
33
+ // Canvas: selection, drag, node/edge creation.
34
+ const canvasRef = useRef<HTMLDivElement | null>(null);
35
+ const [selectedNodeId, setSelectedNodeId] = useState<string>("");
36
+ const [dragging, setDragging] = useState<null | { nodeId: string; dx: number; dy: number; left: number; top: number }>(null);
37
+
38
+ const [activeTool, setActiveTool] = useState<
39
+ | { kind: "select" }
40
+ | { kind: "add-node"; nodeType: WorkflowFileV1["nodes"][number]["type"] }
41
+ | { kind: "connect" }
42
+ >({ kind: "select" });
43
+ const [connectFromNodeId, setConnectFromNodeId] = useState<string>("");
44
+
45
+ const [agents, setAgents] = useState<Array<{ id: string; identityName?: string }>>([]);
46
+ const [agentsError, setAgentsError] = useState<string>("");
47
+
48
+ // Inspector state (parity with modal)
49
+ const [workflowRuns, setWorkflowRuns] = useState<string[]>([]);
50
+ const [workflowRunsLoading, setWorkflowRunsLoading] = useState(false);
51
+ const [workflowRunsError, setWorkflowRunsError] = useState("");
52
+ const [selectedWorkflowRunId, setSelectedWorkflowRunId] = useState<string>("");
53
+
54
+ const [newNodeId, setNewNodeId] = useState("");
55
+ const [newNodeName, setNewNodeName] = useState("");
56
+ const [newNodeType, setNewNodeType] = useState<WorkflowFileV1["nodes"][number]["type"]>("llm");
57
+
58
+ const [newEdgeFrom, setNewEdgeFrom] = useState("");
59
+ const [newEdgeTo, setNewEdgeTo] = useState("");
60
+ const [newEdgeLabel, setNewEdgeLabel] = useState("");
61
+
62
+ useEffect(() => {
63
+ (async () => {
64
+ try {
65
+ if (draft) {
66
+ const stored = sessionStorage.getItem(draftKey(teamId, workflowId));
67
+ if (stored) {
68
+ setStatus({ kind: "ready", jsonText: stored });
69
+ return;
70
+ }
71
+
72
+ // New draft: initialize a clean workflow instead of trying to fetch an existing file.
73
+ const initial: WorkflowFileV1 = {
74
+ schema: "clawkitchen.workflow.v1",
75
+ id: workflowId,
76
+ name: "New workflow",
77
+ timezone: "UTC",
78
+ nodes: [
79
+ { id: "start", type: "start", name: "start", x: 80, y: 80, config: {} },
80
+ { id: "end", type: "end", name: "end", x: 520, y: 80, config: {} },
81
+ ],
82
+ edges: [{ id: "e1", from: "start", to: "end" }],
83
+ };
84
+ const text = JSON.stringify(initial, null, 2) + "\n";
85
+ setStatus({ kind: "ready", jsonText: text });
86
+ try {
87
+ sessionStorage.setItem(draftKey(teamId, workflowId), text);
88
+ } catch {
89
+ // ignore
90
+ }
91
+ return;
92
+ }
93
+
94
+ const res = await fetch(
95
+ `/api/teams/workflows?teamId=${encodeURIComponent(teamId)}&id=${encodeURIComponent(workflowId)}`,
96
+ { cache: "no-store" }
97
+ );
98
+ const json = (await res.json()) as { ok?: boolean; error?: string; workflow?: unknown };
99
+ if (!res.ok || !json.ok) throw new Error(json.error || "Failed to load workflow");
100
+ setStatus({ kind: "ready", jsonText: JSON.stringify(json.workflow, null, 2) + "\n" });
101
+ } catch (e: unknown) {
102
+ setStatus({ kind: "error", error: e instanceof Error ? e.message : String(e) });
103
+ }
104
+ })();
105
+ }, [teamId, workflowId, draft]);
106
+
107
+ useEffect(() => {
108
+ (async () => {
109
+ setAgentsError("");
110
+ try {
111
+ const res = await fetch("/api/agents", { cache: "no-store" });
112
+ const json = (await res.json()) as { agents?: Array<{ id?: unknown; identityName?: unknown }>; error?: string; message?: string };
113
+ if (!res.ok) throw new Error(json.error || json.message || "Failed to load agents");
114
+ const list = Array.isArray(json.agents) ? json.agents : [];
115
+ const filtered = list
116
+ .map((a) => ({ id: String(a.id ?? "").trim(), identityName: typeof a.identityName === "string" ? a.identityName : undefined }))
117
+ .filter((a) => a.id && a.id.startsWith(`${teamId}-`));
118
+ setAgents(filtered);
119
+ } catch (e: unknown) {
120
+ setAgentsError(e instanceof Error ? e.message : String(e));
121
+ setAgents([]);
122
+ }
123
+ })();
124
+ }, [teamId]);
125
+
126
+ const parsed = useMemo(() => {
127
+ if (status.kind !== "ready") return { wf: null as WorkflowFileV1 | null, err: "" };
128
+ try {
129
+ const wf = JSON.parse(status.jsonText) as WorkflowFileV1;
130
+ return { wf, err: "" };
131
+ } catch (e: unknown) {
132
+ return { wf: null, err: e instanceof Error ? e.message : String(e) };
133
+ }
134
+ }, [status]);
135
+
136
+ const validation = useMemo(() => {
137
+ if (!parsed.wf) return { errors: [], warnings: [] as string[] };
138
+ return validateWorkflowFileV1(parsed.wf);
139
+ }, [parsed.wf]);
140
+
141
+ function setWorkflow(next: WorkflowFileV1) {
142
+ const text = JSON.stringify(next, null, 2) + "\n";
143
+ setStatus({ kind: "ready", jsonText: text });
144
+ if (draft) {
145
+ try {
146
+ sessionStorage.setItem(draftKey(teamId, workflowId), text);
147
+ } catch {
148
+ // ignore
149
+ }
150
+ }
151
+ }
152
+
153
+ async function onSave() {
154
+ if (status.kind !== "ready") return;
155
+ if (!parsed.wf) return;
156
+ if (parsed.err) return;
157
+ if (validation.errors.length) return;
158
+
159
+ setSaving(true);
160
+ setActionError("");
161
+ try {
162
+ const res = await fetch("/api/teams/workflows", {
163
+ method: "POST",
164
+ headers: { "content-type": "application/json" },
165
+ body: JSON.stringify({ teamId, workflow: parsed.wf }),
166
+ });
167
+ const json = (await res.json()) as { ok?: boolean; error?: string };
168
+ if (!res.ok || !json.ok) throw new Error(json.error || "Failed to save workflow");
169
+
170
+ // Clear draft cache once persisted.
171
+ try {
172
+ sessionStorage.removeItem(draftKey(teamId, workflowId));
173
+ } catch {
174
+ // ignore
175
+ }
176
+ } catch (e: unknown) {
177
+ setActionError(e instanceof Error ? e.message : String(e));
178
+ } finally {
179
+ setSaving(false);
180
+ }
181
+ }
182
+
183
+ function onExport() {
184
+ if (!parsed.wf) return;
185
+ if (parsed.err) return;
186
+ if (validation.errors.length) return;
187
+
188
+ const filename = `${parsed.wf.id || workflowId}.workflow.json`;
189
+ const blob = new Blob([JSON.stringify(parsed.wf, null, 2) + "\n"], { type: "application/json" });
190
+ const url = URL.createObjectURL(blob);
191
+ const a = document.createElement("a");
192
+ a.href = url;
193
+ a.download = filename;
194
+ document.body.appendChild(a);
195
+ a.click();
196
+ a.remove();
197
+ URL.revokeObjectURL(url);
198
+ }
199
+
200
+ if (status.kind === "loading") return <div className="ck-glass w-full p-6">Loading…</div>;
201
+ if (status.kind === "error") return <div className="ck-glass w-full p-6">{status.error}</div>;
202
+
203
+ // (section collapse uses native <details> to keep this file simple)
204
+
205
+ return (
206
+ <div className="flex h-full min-h-0 w-full flex-1 flex-col">
207
+ <div className="flex flex-wrap items-center justify-between gap-3 px-3 py-3">
208
+ <div className="flex min-w-0 items-center gap-2">
209
+ <a
210
+ href={`/teams/${encodeURIComponent(teamId)}?tab=workflows`}
211
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)] hover:bg-white/10"
212
+ >
213
+ Back
214
+ </a>
215
+ <div className="min-w-0">
216
+ <div className="truncate text-base font-medium text-[color:var(--ck-text-primary)]">
217
+ {workflowId}.workflow.json
218
+ </div>
219
+ <div className="mt-0.5 text-sm text-[color:var(--ck-text-tertiary)]">Team: {teamId}</div>
220
+ </div>
221
+ </div>
222
+
223
+ <div className="flex flex-wrap items-center gap-2">
224
+ <div className="flex overflow-hidden rounded-[var(--ck-radius-sm)] border border-white/10">
225
+ <button
226
+ type="button"
227
+ onClick={() => setView("canvas")}
228
+ className={
229
+ view === "canvas"
230
+ ? "bg-white/10 px-3 py-2 text-xs font-medium text-[color:var(--ck-text-primary)]"
231
+ : "bg-transparent px-3 py-2 text-xs font-medium text-[color:var(--ck-text-secondary)] hover:bg-white/5"
232
+ }
233
+ >
234
+ Canvas
235
+ </button>
236
+ <button
237
+ type="button"
238
+ onClick={() => setView("json")}
239
+ className={
240
+ view === "json"
241
+ ? "bg-white/10 px-3 py-2 text-xs font-medium text-[color:var(--ck-text-primary)]"
242
+ : "bg-transparent px-3 py-2 text-xs font-medium text-[color:var(--ck-text-secondary)] hover:bg-white/5"
243
+ }
244
+ >
245
+ JSON
246
+ </button>
247
+ </div>
248
+
249
+ <input
250
+ ref={importInputRef}
251
+ type="file"
252
+ accept="application/json,.json"
253
+ className="hidden"
254
+ onChange={async (e) => {
255
+ const file = e.target.files?.[0];
256
+ // Reset the input so re-importing the same file still triggers onChange.
257
+ e.target.value = "";
258
+ if (!file) return;
259
+
260
+ setActionError("");
261
+ try {
262
+ const text = await file.text();
263
+ const next = JSON.parse(text) as WorkflowFileV1;
264
+ setStatus({ kind: "ready", jsonText: JSON.stringify(next, null, 2) + "\n" });
265
+ if (draft) {
266
+ try {
267
+ sessionStorage.setItem(draftKey(teamId, workflowId), JSON.stringify(next, null, 2) + "\n");
268
+ } catch {
269
+ // ignore
270
+ }
271
+ }
272
+ } catch (err: unknown) {
273
+ setActionError(err instanceof Error ? err.message : String(err));
274
+ }
275
+ }}
276
+ />
277
+
278
+ <button
279
+ type="button"
280
+ disabled={saving}
281
+ onClick={() => importInputRef.current?.click()}
282
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)] shadow-[var(--ck-shadow-1)] hover:bg-white/10 disabled:opacity-50"
283
+ >
284
+ Import
285
+ </button>
286
+
287
+ <button
288
+ type="button"
289
+ disabled={!parsed.wf || Boolean(parsed.err) || validation.errors.length > 0}
290
+ onClick={onExport}
291
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)] shadow-[var(--ck-shadow-1)] hover:bg-white/10 disabled:opacity-50"
292
+ >
293
+ Export
294
+ </button>
295
+
296
+ <button
297
+ type="button"
298
+ disabled={saving || !parsed.wf || Boolean(parsed.err) || validation.errors.length > 0}
299
+ onClick={onSave}
300
+ className="rounded-[var(--ck-radius-sm)] bg-[var(--ck-accent-red)] px-3 py-2 text-sm font-medium text-white shadow-[var(--ck-shadow-1)] disabled:opacity-50"
301
+ >
302
+ {saving ? "Saving…" : "Save"}
303
+ </button>
304
+
305
+ {/* Back button lives in the left header. */}
306
+ </div>
307
+ </div>
308
+
309
+ {parsed.err ? (
310
+ <div className="mt-3 rounded-[var(--ck-radius-sm)] border border-yellow-400/30 bg-yellow-500/10 p-3 text-sm text-yellow-100">
311
+ JSON parse error: {parsed.err}
312
+ </div>
313
+ ) : null}
314
+ {!parsed.err && validation.errors.length ? (
315
+ <div className="mt-3 rounded-[var(--ck-radius-sm)] border border-red-400/30 bg-red-500/10 p-3 text-sm text-red-100">
316
+ <div className="font-medium">Workflow validation errors</div>
317
+ <ul className="mt-2 list-disc space-y-1 pl-5">
318
+ {validation.errors.map((e) => (
319
+ <li key={e}>{e}</li>
320
+ ))}
321
+ </ul>
322
+ </div>
323
+ ) : null}
324
+
325
+ {!parsed.err && !validation.errors.length && validation.warnings.length ? (
326
+ <div className="mt-3 rounded-[var(--ck-radius-sm)] border border-yellow-400/30 bg-yellow-500/10 p-3 text-sm text-yellow-100">
327
+ <div className="font-medium">Workflow validation warnings</div>
328
+ <ul className="mt-2 list-disc space-y-1 pl-5">
329
+ {validation.warnings.map((w) => (
330
+ <li key={w}>{w}</li>
331
+ ))}
332
+ </ul>
333
+ </div>
334
+ ) : null}
335
+
336
+ {actionError ? (
337
+ <div className="mt-3 rounded-[var(--ck-radius-sm)] border border-red-400/30 bg-red-500/10 p-3 text-sm text-red-100">
338
+ {actionError}
339
+ </div>
340
+ ) : null}
341
+
342
+ <div className="flex min-h-0 flex-1 gap-0">
343
+ {view === "json" ? (
344
+ <textarea
345
+ value={status.jsonText}
346
+ onChange={(e) => {
347
+ const t = e.target.value;
348
+ setStatus({ kind: "ready", jsonText: t });
349
+ if (draft) {
350
+ try {
351
+ sessionStorage.setItem(draftKey(teamId, workflowId), t);
352
+ } catch {
353
+ // ignore
354
+ }
355
+ }
356
+ }}
357
+ className="h-full min-h-0 w-full flex-1 resize-none rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/20 p-3 font-mono text-xs text-[color:var(--ck-text-primary)]"
358
+ />
359
+ ) : (
360
+ <div
361
+ ref={canvasRef}
362
+ className="relative h-full min-h-0 w-full flex-1 overflow-auto bg-black/20"
363
+ onClick={(e) => {
364
+ if (activeTool.kind !== "add-node") return;
365
+ const wf = parsed.wf;
366
+ if (!wf) return;
367
+ const el = canvasRef.current;
368
+ if (!el) return;
369
+
370
+ // Only create when clicking on the canvas background (not a node).
371
+ const target = e.target as HTMLElement | null;
372
+ if (target && target.closest("[data-wf-node='1']")) return;
373
+
374
+ const rect = el.getBoundingClientRect();
375
+ const clickX = e.clientX - rect.left + el.scrollLeft;
376
+ const clickY = e.clientY - rect.top + el.scrollTop;
377
+
378
+ const base = activeTool.nodeType.replace(/[^a-z0-9_\-]/gi, "_");
379
+ const used = new Set(wf.nodes.map((n) => n.id));
380
+ let i = 1;
381
+ let id = `${base}_${i}`;
382
+ while (used.has(id)) {
383
+ i++;
384
+ id = `${base}_${i}`;
385
+ }
386
+
387
+ const x = Math.max(0, clickX - 90);
388
+ const y = Math.max(0, clickY - 24);
389
+
390
+ const nextNode: WorkflowFileV1["nodes"][number] = {
391
+ id,
392
+ type: activeTool.nodeType,
393
+ name: id,
394
+ x,
395
+ y,
396
+ config: {},
397
+ };
398
+
399
+ setWorkflow({ ...wf, nodes: [...wf.nodes, nextNode] });
400
+ setSelectedNodeId(id);
401
+ setActiveTool({ kind: "select" });
402
+ }}
403
+ >
404
+ <div className="relative h-[1200px] w-[2200px]">
405
+ {/* Tool palette / agent palette */}
406
+ <div
407
+ className={
408
+ toolsCollapsed
409
+ ? "sticky left-3 top-3 z-20 w-[44px] overflow-hidden rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/40 p-2 backdrop-blur"
410
+ : "sticky left-3 top-3 z-20 w-[260px] rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/40 p-2 backdrop-blur"
411
+ }
412
+ >
413
+ <div className="flex items-center justify-between gap-2">
414
+ <div className={toolsCollapsed ? "hidden" : "text-[10px] font-medium uppercase tracking-wide text-[color:var(--ck-text-tertiary)]"}>Tools</div>
415
+ <button
416
+ type="button"
417
+ onClick={() => setToolsCollapsed((v) => !v)}
418
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-[10px] text-[color:var(--ck-text-secondary)] hover:bg-white/10"
419
+ title={toolsCollapsed ? "Expand" : "Collapse"}
420
+ >
421
+ {toolsCollapsed ? ">" : "<"}
422
+ </button>
423
+ </div>
424
+ {toolsCollapsed ? (
425
+ <div className="mt-2 flex flex-col items-center gap-2">
426
+ {(
427
+ [
428
+ {
429
+ key: "select",
430
+ label: "Select",
431
+ active: activeTool.kind === "select",
432
+ onClick: () => {
433
+ setActiveTool({ kind: "select" });
434
+ setConnectFromNodeId("");
435
+ },
436
+ icon: (
437
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
438
+ <path d="M5 4l7 16 2-7 7-2L5 4Z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" />
439
+ </svg>
440
+ ),
441
+ },
442
+ {
443
+ key: "connect",
444
+ label: "Connect",
445
+ active: activeTool.kind === "connect",
446
+ onClick: () => {
447
+ setActiveTool({ kind: "connect" });
448
+ setConnectFromNodeId("");
449
+ },
450
+ icon: (
451
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
452
+ <path d="M10 13a5 5 0 0 1 0-7l1.2-1.2a5 5 0 0 1 7 7L17 12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
453
+ <path d="M14 11a5 5 0 0 1 0 7L12.8 19.2a5 5 0 1 1-7-7L7 12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
454
+ </svg>
455
+ ),
456
+ },
457
+ {
458
+ key: "llm",
459
+ label: "LLM",
460
+ active: activeTool.kind === "add-node" && activeTool.nodeType === "llm",
461
+ onClick: () => {
462
+ setActiveTool({ kind: "add-node", nodeType: "llm" });
463
+ setConnectFromNodeId("");
464
+ },
465
+ icon: (
466
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
467
+ <path d="M12 2l1.5 6.5L20 10l-6.5 1.5L12 18l-1.5-6.5L4 10l6.5-1.5L12 2Z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" />
468
+ </svg>
469
+ ),
470
+ },
471
+ {
472
+ key: "tool",
473
+ label: "Tool",
474
+ active: activeTool.kind === "add-node" && activeTool.nodeType === "tool",
475
+ onClick: () => {
476
+ setActiveTool({ kind: "add-node", nodeType: "tool" });
477
+ setConnectFromNodeId("");
478
+ },
479
+ icon: (
480
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
481
+ <path d="M14.5 7.5l2 2-8.5 8.5H6v-2l8.5-8.5Z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" />
482
+ <path d="M12 6a4 4 0 0 0-5 5l3-3 2 2 3-3A4 4 0 0 0 12 6Z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" />
483
+ </svg>
484
+ ),
485
+ },
486
+ {
487
+ key: "condition",
488
+ label: "If",
489
+ active: activeTool.kind === "add-node" && activeTool.nodeType === "condition",
490
+ onClick: () => {
491
+ setActiveTool({ kind: "add-node", nodeType: "condition" });
492
+ setConnectFromNodeId("");
493
+ },
494
+ icon: (
495
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
496
+ <path d="M7 4v7a3 3 0 0 0 3 3h7" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
497
+ <path d="M17 10l3 3-3 3" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
498
+ </svg>
499
+ ),
500
+ },
501
+ {
502
+ key: "delay",
503
+ label: "Delay",
504
+ active: activeTool.kind === "add-node" && activeTool.nodeType === "delay",
505
+ onClick: () => {
506
+ setActiveTool({ kind: "add-node", nodeType: "delay" });
507
+ setConnectFromNodeId("");
508
+ },
509
+ icon: (
510
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
511
+ <path d="M12 7v5l3 2" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
512
+ <path d="M21 12a9 9 0 1 1-9-9" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
513
+ </svg>
514
+ ),
515
+ },
516
+ {
517
+ key: "approval",
518
+ label: "Approval",
519
+ active: activeTool.kind === "add-node" && activeTool.nodeType === "human_approval",
520
+ onClick: () => {
521
+ setActiveTool({ kind: "add-node", nodeType: "human_approval" });
522
+ setConnectFromNodeId("");
523
+ },
524
+ icon: (
525
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
526
+ <path d="M20 6 9 17l-5-5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
527
+ </svg>
528
+ ),
529
+ },
530
+ {
531
+ key: "end",
532
+ label: "End",
533
+ active: activeTool.kind === "add-node" && activeTool.nodeType === "end",
534
+ onClick: () => {
535
+ setActiveTool({ kind: "add-node", nodeType: "end" });
536
+ setConnectFromNodeId("");
537
+ },
538
+ icon: (
539
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
540
+ <path d="M7 7h10v10H7V7Z" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" />
541
+ </svg>
542
+ ),
543
+ },
544
+ ] as const
545
+ ).map((b) => (
546
+ <button
547
+ key={b.key}
548
+ type="button"
549
+ onClick={b.onClick}
550
+ className={
551
+ b.active
552
+ ? "flex h-8 w-8 items-center justify-center rounded-[var(--ck-radius-sm)] bg-white/10 text-[color:var(--ck-text-primary)]"
553
+ : "flex h-8 w-8 items-center justify-center rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 text-[color:var(--ck-text-secondary)] hover:bg-white/10"
554
+ }
555
+ title={b.label}
556
+ aria-label={b.label}
557
+ >
558
+ {b.icon}
559
+ </button>
560
+ ))}
561
+ </div>
562
+ ) : (
563
+ <div className="mt-2 grid grid-cols-2 gap-2">
564
+ <button
565
+ type="button"
566
+ onClick={() => {
567
+ setActiveTool({ kind: "select" });
568
+ setConnectFromNodeId("");
569
+ }}
570
+ className={
571
+ activeTool.kind === "select"
572
+ ? "rounded-[var(--ck-radius-sm)] bg-white/10 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
573
+ : "rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-xs text-[color:var(--ck-text-secondary)] hover:bg-white/10"
574
+ }
575
+ >
576
+ Select
577
+ </button>
578
+ <button
579
+ type="button"
580
+ onClick={() => {
581
+ setActiveTool({ kind: "connect" });
582
+ setConnectFromNodeId("");
583
+ }}
584
+ className={
585
+ activeTool.kind === "connect"
586
+ ? "rounded-[var(--ck-radius-sm)] bg-white/10 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
587
+ : "rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-xs text-[color:var(--ck-text-secondary)] hover:bg-white/10"
588
+ }
589
+ title="Click a node, then click another node to create an edge"
590
+ >
591
+ Connect
592
+ </button>
593
+
594
+ {([
595
+ { t: "llm", label: "LLM" },
596
+ { t: "tool", label: "Tool" },
597
+ { t: "condition", label: "If" },
598
+ { t: "delay", label: "Delay" },
599
+ { t: "human_approval", label: "Approve" },
600
+ { t: "end", label: "End" },
601
+ ] as Array<{ t: WorkflowFileV1["nodes"][number]["type"]; label: string }>).map((x) => (
602
+ <button
603
+ key={x.t}
604
+ type="button"
605
+ onClick={() => {
606
+ setActiveTool({ kind: "add-node", nodeType: x.t });
607
+ setConnectFromNodeId("");
608
+ }}
609
+ className={
610
+ activeTool.kind === "add-node" && activeTool.nodeType === x.t
611
+ ? "rounded-[var(--ck-radius-sm)] bg-white/10 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
612
+ : "rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-xs text-[color:var(--ck-text-secondary)] hover:bg-white/10"
613
+ }
614
+ title="Select tool, then click on the canvas to place"
615
+ >
616
+ + {x.label}
617
+ </button>
618
+ ))}
619
+ </div>
620
+ )}
621
+
622
+ {!toolsCollapsed && activeTool.kind === "connect" && connectFromNodeId ? (
623
+ <div className="mt-2 text-xs text-[color:var(--ck-text-secondary)]">Connecting from: <span className="font-mono">{connectFromNodeId}</span></div>
624
+ ) : null}
625
+ {!toolsCollapsed && activeTool.kind === "add-node" ? (
626
+ <div className="mt-2 text-xs text-[color:var(--ck-text-secondary)]">Click on the canvas to place a <span className="font-mono">{activeTool.nodeType}</span> node.</div>
627
+ ) : null}
628
+
629
+ <div className="mt-3 border-t border-white/10 pt-3">
630
+ <div className={toolsCollapsed ? "hidden" : "flex items-center justify-between gap-2"}>
631
+ <div className="text-[10px] font-medium uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">Agents</div>
632
+ <div className="text-[10px] text-[color:var(--ck-text-tertiary)]">drag → node</div>
633
+ </div>
634
+
635
+ {toolsCollapsed ? (
636
+ <button
637
+ type="button"
638
+ onClick={() => setToolsCollapsed(false)}
639
+ className="mt-2 flex h-8 w-8 items-center justify-center rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 text-[color:var(--ck-text-secondary)] hover:bg-white/10"
640
+ title="Expand to see agents"
641
+ aria-label="Expand to see agents"
642
+ >
643
+ <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" aria-hidden="true">
644
+ <path d="M16 11a4 4 0 1 0-8 0" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
645
+ <path d="M4 20a8 8 0 0 1 16 0" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
646
+ </svg>
647
+ </button>
648
+ ) : (
649
+ <>
650
+ {agentsError ? <div className="mt-1 text-[11px] text-red-200">{agentsError}</div> : null}
651
+ <div className="mt-2 max-h-[140px] space-y-1 overflow-auto">
652
+ {agents.length ? (
653
+ agents.map((a) => (
654
+ <div
655
+ key={a.id}
656
+ draggable
657
+ onDragStart={(e) => {
658
+ e.dataTransfer.setData("text/plain", a.id);
659
+ e.dataTransfer.effectAllowed = "copy";
660
+ }}
661
+ className="cursor-grab rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-xs text-[color:var(--ck-text-secondary)] hover:bg-white/10"
662
+ title={a.id}
663
+ >
664
+ {a.identityName ? a.identityName : a.id.replace(`${teamId}-`, "")}
665
+ </div>
666
+ ))
667
+ ) : (
668
+ <div className="text-xs text-[color:var(--ck-text-tertiary)]">No team agents found.</div>
669
+ )}
670
+ </div>
671
+ </>
672
+ )}
673
+ </div>
674
+ </div>
675
+
676
+ <svg className="absolute inset-0" width={2200} height={1200}>
677
+ {(parsed.wf?.edges ?? []).map((e) => {
678
+ const wf = parsed.wf;
679
+ if (!wf) return null;
680
+ const a = wf.nodes.find((n) => n.id === e.from);
681
+ const b = wf.nodes.find((n) => n.id === e.to);
682
+ if (!a || !b) return null;
683
+ const ax = (typeof a.x === "number" ? a.x : 80) + 90;
684
+ const ay = (typeof a.y === "number" ? a.y : 80) + 24;
685
+ const bx = (typeof b.x === "number" ? b.x : 80) + 90;
686
+ const by = (typeof b.y === "number" ? b.y : 80) + 24;
687
+ return <line key={e.id} x1={ax} y1={ay} x2={bx} y2={by} stroke="rgba(255,255,255,0.18)" strokeWidth={2} />;
688
+ })}
689
+ </svg>
690
+
691
+ {(parsed.wf?.nodes ?? []).map((n, idx) => {
692
+ const x = typeof n.x === "number" ? n.x : 80 + idx * 220;
693
+ const y = typeof n.y === "number" ? n.y : 80;
694
+ const selected = selectedNodeId === n.id;
695
+ return (
696
+ <div
697
+ key={n.id}
698
+ role="button"
699
+ tabIndex={0}
700
+ data-wf-node="1"
701
+ draggable={activeTool.kind === "select"}
702
+ onDragStart={(e) => {
703
+ // allow agent pills to be dropped; do not start a browser drag ghost for nodes.
704
+ if (activeTool.kind !== "select") return;
705
+ e.dataTransfer.setData("text/plain", "");
706
+ }}
707
+ onDragOver={(e) => {
708
+ // Allow dropping agents.
709
+ if (e.dataTransfer.types.includes("text/plain")) e.preventDefault();
710
+ }}
711
+ onDrop={(e) => {
712
+ const wf = parsed.wf;
713
+ if (!wf) return;
714
+ e.preventDefault();
715
+ e.stopPropagation();
716
+ const agentId = String(e.dataTransfer.getData("text/plain") || "").trim();
717
+ if (!agentId) return;
718
+
719
+ const nextNodes = wf.nodes.map((node) => {
720
+ if (node.id !== n.id) return node;
721
+ const cfg = node.config && typeof node.config === "object" && !Array.isArray(node.config) ? node.config : {};
722
+ return { ...node, config: { ...cfg, agentId } };
723
+ });
724
+ setWorkflow({ ...wf, nodes: nextNodes });
725
+ setSelectedNodeId(n.id);
726
+ }}
727
+ onClick={(e) => {
728
+ e.stopPropagation();
729
+ const wf = parsed.wf;
730
+ if (activeTool.kind === "connect") {
731
+ if (!wf) return;
732
+ if (!connectFromNodeId) {
733
+ setConnectFromNodeId(n.id);
734
+ setSelectedNodeId(n.id);
735
+ return;
736
+ }
737
+ const from = connectFromNodeId;
738
+ const to = n.id;
739
+ setConnectFromNodeId("");
740
+ if (!from || !to || from === to) return;
741
+ const exists = (wf.edges ?? []).some((e) => e.from === from && e.to === to);
742
+ if (exists) return;
743
+ const id = `e${Date.now()}`;
744
+ const nextEdge: WorkflowFileV1["edges"][number] = { id, from, to };
745
+ setWorkflow({ ...wf, edges: [...(wf.edges ?? []), nextEdge] });
746
+ return;
747
+ }
748
+
749
+ setSelectedNodeId(n.id);
750
+ }}
751
+ onPointerDown={(e) => {
752
+ if (activeTool.kind !== "select") return;
753
+ if (e.button !== 0) return;
754
+ const el = canvasRef.current;
755
+ if (!el) return;
756
+ const rect = el.getBoundingClientRect();
757
+ setSelectedNodeId(n.id);
758
+ try {
759
+ e.currentTarget.setPointerCapture(e.pointerId);
760
+ } catch {
761
+ // ignore
762
+ }
763
+ e.preventDefault();
764
+ setDragging({ nodeId: n.id, dx: e.clientX - rect.left - x, dy: e.clientY - rect.top - y, left: rect.left, top: rect.top });
765
+ }}
766
+ onPointerUp={(e) => {
767
+ try {
768
+ e.currentTarget.releasePointerCapture(e.pointerId);
769
+ } catch {
770
+ // ignore
771
+ }
772
+ setDragging(null);
773
+ }}
774
+ onPointerMove={(e) => {
775
+ if (!dragging) return;
776
+ if (dragging.nodeId !== n.id) return;
777
+ const wf = parsed.wf;
778
+ if (!wf) return;
779
+ const el = canvasRef.current;
780
+ if (!el) return;
781
+ const nextX = e.clientX - dragging.left - dragging.dx;
782
+ const nextY = e.clientY - dragging.top - dragging.dy;
783
+ const nextNodes = wf.nodes.map((node) => (node.id === n.id ? { ...node, x: nextX, y: nextY } : node));
784
+ const next: WorkflowFileV1 = { ...wf, nodes: nextNodes };
785
+ setStatus({ kind: "ready", jsonText: JSON.stringify(next, null, 2) + "\n" });
786
+ }}
787
+ className={
788
+ selected
789
+ ? "absolute cursor-grab rounded-[var(--ck-radius-sm)] border border-white/25 bg-white/10 px-3 py-2 text-xs text-[color:var(--ck-text-primary)] shadow-[var(--ck-shadow-1)]"
790
+ : "absolute cursor-grab rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-3 py-2 text-xs text-[color:var(--ck-text-secondary)] hover:bg-white/10"
791
+ }
792
+ style={{ left: x, top: y, width: 180 }}
793
+ >
794
+ <div className="font-medium text-[color:var(--ck-text-primary)]">{n.name || n.id}</div>
795
+ <div className="mt-0.5 text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">{n.type}</div>
796
+ {(() => {
797
+ const cfg = n.config && typeof n.config === "object" && !Array.isArray(n.config) ? (n.config as Record<string, unknown>) : null;
798
+ const agentId = cfg ? String(cfg.agentId ?? "").trim() : "";
799
+ if (!agentId) return null;
800
+ const short = agentId.replace(`${teamId}-`, "");
801
+ return <div className="mt-1 text-[10px] text-[color:var(--ck-text-secondary)]">Agent: {short}</div>;
802
+ })()}
803
+ </div>
804
+ );
805
+ })}
806
+
807
+ {/* Inline in-canvas node inspector (requirement #6) */}
808
+ {(() => {
809
+ const wf = parsed.wf;
810
+ if (!wf) return null;
811
+ if (!selectedNodeId) return null;
812
+ const node = wf.nodes.find((n) => n.id === selectedNodeId);
813
+ if (!node) return null;
814
+
815
+ const x = typeof node.x === "number" ? node.x : 80;
816
+ const y = typeof node.y === "number" ? node.y : 80;
817
+ const cfg = node.config && typeof node.config === "object" && !Array.isArray(node.config) ? (node.config as Record<string, unknown>) : {};
818
+ const agentId = String(cfg.agentId ?? "").trim();
819
+
820
+ return (
821
+ <div
822
+ className="absolute z-10 w-[320px] rounded-[var(--ck-radius-sm)] border border-white/15 bg-black/60 p-3 shadow-[var(--ck-shadow-1)] backdrop-blur"
823
+ style={{ left: x + 200, top: y }}
824
+ >
825
+ <div className="flex items-center justify-between gap-2">
826
+ <div className="text-xs font-medium text-[color:var(--ck-text-primary)]">{node.name || node.id}</div>
827
+ <button
828
+ type="button"
829
+ onClick={() => setSelectedNodeId("")}
830
+ className="text-[10px] text-[color:var(--ck-text-tertiary)] hover:text-[color:var(--ck-text-primary)]"
831
+ >
832
+ Close
833
+ </button>
834
+ </div>
835
+
836
+ <div className="mt-2 space-y-2">
837
+ <label className="block">
838
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">name</div>
839
+ <input
840
+ value={String(node.name ?? "")}
841
+ onChange={(e) => {
842
+ const nextName = e.target.value;
843
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, name: nextName } : n)) });
844
+ }}
845
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/30 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
846
+ placeholder="Optional"
847
+ />
848
+ </label>
849
+
850
+ <label className="block">
851
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">type</div>
852
+ <select
853
+ value={node.type}
854
+ onChange={(e) => {
855
+ const nextType = e.target.value as WorkflowFileV1["nodes"][number]["type"];
856
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, type: nextType } : n)) });
857
+ }}
858
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/30 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
859
+ >
860
+ <option value="start">start</option>
861
+ <option value="end">end</option>
862
+ <option value="llm">llm</option>
863
+ <option value="tool">tool</option>
864
+ <option value="condition">condition</option>
865
+ <option value="delay">delay</option>
866
+ <option value="human_approval">human_approval</option>
867
+ </select>
868
+ </label>
869
+
870
+ <label className="block">
871
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">agentId</div>
872
+ <input
873
+ value={agentId}
874
+ onChange={(e) => {
875
+ const nextAgentId = String(e.target.value || "").trim();
876
+ const nextCfg = { ...cfg, ...(nextAgentId ? { agentId: nextAgentId } : {}) };
877
+ if (!nextAgentId) delete (nextCfg as Record<string, unknown>).agentId;
878
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, config: nextCfg } : n)) });
879
+ }}
880
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/30 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
881
+ placeholder="(drag an agent onto the node or type)"
882
+ />
883
+ </label>
884
+
885
+ {node.type === "human_approval" ? (
886
+ <div className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/20 p-2">
887
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">approval config</div>
888
+
889
+ <div className="mt-2 space-y-2">
890
+ <label className="block">
891
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">provider</div>
892
+ <input
893
+ value={String((cfg as Record<string, unknown>).provider ?? "")}
894
+ onChange={(e) => {
895
+ const v = String(e.target.value || "").trim();
896
+ const nextCfg = { ...cfg, ...(v ? { provider: v } : {}) };
897
+ if (!v) delete (nextCfg as Record<string, unknown>).provider;
898
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, config: nextCfg } : n)) });
899
+ }}
900
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
901
+ placeholder="telegram"
902
+ />
903
+ </label>
904
+
905
+ <label className="block">
906
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">target</div>
907
+ <input
908
+ value={String((cfg as Record<string, unknown>).target ?? "")}
909
+ onChange={(e) => {
910
+ const v = String(e.target.value || "").trim();
911
+ const nextCfg = { ...cfg, ...(v ? { target: v } : {}) };
912
+ if (!v) delete (nextCfg as Record<string, unknown>).target;
913
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, config: nextCfg } : n)) });
914
+ }}
915
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
916
+ placeholder="(e.g. Telegram chat id)"
917
+ />
918
+ <div className="mt-1 text-[10px] text-[color:var(--ck-text-tertiary)]">Overrides workflow-level default when set.</div>
919
+ </label>
920
+
921
+ <label className="block">
922
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">messageTemplate (optional)</div>
923
+ <textarea
924
+ value={String((cfg as Record<string, unknown>).messageTemplate ?? "")}
925
+ onChange={(e) => {
926
+ const v = String(e.target.value || "");
927
+ const nextCfg = { ...cfg, ...(v.trim() ? { messageTemplate: v } : {}) };
928
+ if (!v.trim()) delete (nextCfg as Record<string, unknown>).messageTemplate;
929
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, config: nextCfg } : n)) });
930
+ }}
931
+ className="mt-1 h-[70px] w-full resize-none rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-2 font-mono text-[10px] text-[color:var(--ck-text-primary)]"
932
+ placeholder="Approval needed for {{workflowName}} (run {{runId}})"
933
+ spellCheck={false}
934
+ />
935
+ <div className="mt-1 text-[10px] text-[color:var(--ck-text-tertiary)]">
936
+ Vars: {"{{workflowName}}"}, {"{{workflowId}}"}, {"{{runId}}"}, {"{{nodeId}}"}
937
+ </div>
938
+ </label>
939
+ </div>
940
+ </div>
941
+ ) : null}
942
+
943
+ <label className="block">
944
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">config (json)</div>
945
+ <textarea
946
+ value={JSON.stringify(cfg, null, 2)}
947
+ onChange={(e) => {
948
+ try {
949
+ const nextCfg = JSON.parse(e.target.value) as Record<string, unknown>;
950
+ if (!nextCfg || typeof nextCfg !== "object" || Array.isArray(nextCfg)) return;
951
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, config: nextCfg } : n)) });
952
+ } catch {
953
+ // ignore invalid JSON while typing
954
+ }
955
+ }}
956
+ className="mt-1 h-[140px] w-full resize-none rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/30 p-2 font-mono text-[10px] text-[color:var(--ck-text-primary)]"
957
+ spellCheck={false}
958
+ />
959
+ <div className="mt-1 text-[10px] text-[color:var(--ck-text-tertiary)]">(Edits apply when JSON is valid.)</div>
960
+ </label>
961
+ </div>
962
+ </div>
963
+ );
964
+ })()}
965
+ </div>
966
+ </div>
967
+ )}
968
+
969
+ <div className="w-[380px] shrink-0 overflow-auto p-3 text-sm">
970
+ <div className="space-y-3">
971
+ {parsed.wf ? (
972
+ (() => {
973
+ const wf = parsed.wf;
974
+ const tz = String(wf.timezone ?? "").trim() || "UTC";
975
+ const triggers = wf.triggers ?? [];
976
+
977
+ const meta = wf.meta && typeof wf.meta === "object" && !Array.isArray(wf.meta) ? (wf.meta as Record<string, unknown>) : {};
978
+ const approvalProvider = String(meta.approvalProvider ?? "telegram").trim() || "telegram";
979
+ const approvalTarget = String(meta.approvalTarget ?? "").trim();
980
+
981
+ // Cron schedule suggestions.
982
+ // Note: dev-team automation defaults should avoid the 02:00–07:00 America/New_York blackout window.
983
+ // We keep presets in "safe" hours by default.
984
+ const presets = [
985
+ { label: "(no preset)", expr: "" },
986
+ { label: "Weekdays 09:00 local", expr: "0 9 * * 1-5" },
987
+ { label: "Mon/Wed/Fri 09:00 local", expr: "0 9 * * 1,3,5" },
988
+ { label: "Daily 08:00 local", expr: "0 8 * * *" },
989
+ { label: "Daily 12:00 local", expr: "0 12 * * *" },
990
+ { label: "Mon 09:30 local", expr: "30 9 * * 1" },
991
+ ];
992
+
993
+ return (
994
+ <div className="space-y-3">
995
+ <details open className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/15">
996
+ <summary className="cursor-pointer list-none px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)]">Workflow</summary>
997
+ <div className="px-3 pb-3">
998
+ <label className="block">
999
+ <div className="text-[11px] font-medium text-[color:var(--ck-text-tertiary)]">Timezone</div>
1000
+ <input
1001
+ value={tz}
1002
+ onChange={(e) => {
1003
+ const nextTz = String(e.target.value || "").trim() || "UTC";
1004
+ setWorkflow({ ...wf, timezone: nextTz });
1005
+ }}
1006
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-sm text-[color:var(--ck-text-primary)]"
1007
+ placeholder="America/New_York"
1008
+ />
1009
+ </label>
1010
+ </div>
1011
+ </details>
1012
+
1013
+ <details open className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/15">
1014
+ <summary className="cursor-pointer list-none px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)]">Approval Channel</summary>
1015
+ <div className="px-3 pb-3 space-y-2">
1016
+ <label className="block">
1017
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">provider</div>
1018
+ <input
1019
+ value={approvalProvider}
1020
+ onChange={(e) => {
1021
+ const nextProvider = String(e.target.value || "").trim() || "telegram";
1022
+ setWorkflow({ ...wf, meta: { ...meta, approvalProvider: nextProvider } });
1023
+ }}
1024
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1025
+ placeholder="telegram"
1026
+ />
1027
+ </label>
1028
+
1029
+ <label className="block">
1030
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">target</div>
1031
+ <input
1032
+ value={approvalTarget}
1033
+ onChange={(e) => {
1034
+ const nextTarget = String(e.target.value || "").trim();
1035
+ setWorkflow({ ...wf, meta: { ...meta, approvalTarget: nextTarget } });
1036
+ }}
1037
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1038
+ placeholder="(e.g. Telegram chat id)"
1039
+ />
1040
+ <div className="mt-1 text-[10px] text-[color:var(--ck-text-tertiary)]">
1041
+ If set, runs that reach a human-approval node can send an approval packet via the gateway message tool.
1042
+ </div>
1043
+ </label>
1044
+ </div>
1045
+ </details>
1046
+
1047
+ <details open className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/15">
1048
+ <summary className="cursor-pointer list-none px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)]">Triggers</summary>
1049
+ <div className="px-3 pb-3">
1050
+ <div className="flex items-center justify-between gap-2">
1051
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">triggers</div>
1052
+ <button
1053
+ type="button"
1054
+ onClick={() => {
1055
+ const id = `t${Date.now()}`;
1056
+ setWorkflow({
1057
+ ...wf,
1058
+ triggers: [
1059
+ ...triggers,
1060
+ { kind: "cron", id, name: "New trigger", enabled: true, expr: "0 9 * * 1-5", tz },
1061
+ ],
1062
+ });
1063
+ }}
1064
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-[10px] font-medium text-[color:var(--ck-text-primary)] hover:bg-white/10"
1065
+ >
1066
+ + Add
1067
+ </button>
1068
+ </div>
1069
+
1070
+ <div className="mt-2 space-y-2">
1071
+ {triggers.length ? (
1072
+ triggers.map((t, i) => {
1073
+ const kind = (t as { kind?: unknown }).kind;
1074
+ const isCron = kind === "cron";
1075
+ const id = String((t as { id?: unknown }).id ?? "");
1076
+ const name = String((t as { name?: unknown }).name ?? "");
1077
+ const enabled = Boolean((t as { enabled?: unknown }).enabled);
1078
+ const expr = String((t as { expr?: unknown }).expr ?? "");
1079
+ const trigTz = String((t as { tz?: unknown }).tz ?? tz);
1080
+ const cronFields = expr.trim().split(/\s+/).filter(Boolean);
1081
+ const cronLooksValid = !expr.trim() || cronFields.length === 5;
1082
+
1083
+ return (
1084
+ <div key={`${id}-${i}`} className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-2">
1085
+ <div className="flex items-center justify-between gap-2">
1086
+ <div className="text-xs text-[color:var(--ck-text-primary)]">{name || id || `trigger-${i + 1}`}</div>
1087
+ <button
1088
+ type="button"
1089
+ onClick={() => setWorkflow({ ...wf, triggers: triggers.filter((_, idx) => idx !== i) })}
1090
+ className="text-[10px] text-[color:var(--ck-text-tertiary)] hover:text-[color:var(--ck-text-primary)]"
1091
+ >
1092
+ Remove
1093
+ </button>
1094
+ </div>
1095
+
1096
+ {!isCron ? (
1097
+ <div className="mt-1 text-xs text-[color:var(--ck-text-secondary)]">Unsupported trigger kind: {String(kind)}</div>
1098
+ ) : null}
1099
+
1100
+ <div className="mt-2 grid grid-cols-1 gap-2">
1101
+ <label className="flex items-center gap-2 text-xs text-[color:var(--ck-text-secondary)]">
1102
+ <input
1103
+ type="checkbox"
1104
+ checked={enabled}
1105
+ onChange={(e) => {
1106
+ const nextEnabled = e.target.checked;
1107
+ setWorkflow({
1108
+ ...wf,
1109
+ triggers: triggers.map((x, idx) => (idx === i && x.kind === "cron" ? { ...x, enabled: nextEnabled } : x)),
1110
+ });
1111
+ }}
1112
+ />
1113
+ Enabled
1114
+ </label>
1115
+
1116
+ <label className="block">
1117
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">name</div>
1118
+ <input
1119
+ value={name}
1120
+ onChange={(e) => {
1121
+ const nextName = e.target.value;
1122
+ setWorkflow({
1123
+ ...wf,
1124
+ triggers: triggers.map((x, idx) => (idx === i && x.kind === "cron" ? { ...x, name: nextName } : x)),
1125
+ });
1126
+ }}
1127
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1128
+ placeholder="Content cadence"
1129
+ />
1130
+ </label>
1131
+
1132
+ <label className="block">
1133
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">schedule (cron)</div>
1134
+ <input
1135
+ value={expr}
1136
+ onChange={(e) => {
1137
+ const nextExpr = e.target.value;
1138
+ setWorkflow({
1139
+ ...wf,
1140
+ triggers: triggers.map((x, idx) => (idx === i && x.kind === "cron" ? { ...x, expr: nextExpr } : x)),
1141
+ });
1142
+ }}
1143
+ className={
1144
+ cronLooksValid
1145
+ ? "mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 font-mono text-[11px] text-[color:var(--ck-text-primary)]"
1146
+ : "mt-1 w-full rounded-[var(--ck-radius-sm)] border border-red-400/50 bg-black/25 px-2 py-1 font-mono text-[11px] text-[color:var(--ck-text-primary)]"
1147
+ }
1148
+ placeholder="0 9 * * 1,3,5"
1149
+ />
1150
+ {!cronLooksValid ? (
1151
+ <div className="mt-1 text-[10px] text-red-200">
1152
+ Cron should be 5 fields (min hour dom month dow). You entered {cronFields.length}.
1153
+ </div>
1154
+ ) : null}
1155
+ <div className="mt-1 grid grid-cols-1 gap-1">
1156
+ <select
1157
+ value={presets.some((p) => p.expr === expr) ? expr : ""}
1158
+ onChange={(e) => {
1159
+ const nextExpr = e.target.value;
1160
+ setWorkflow({
1161
+ ...wf,
1162
+ triggers: triggers.map((x, idx) => (idx === i && x.kind === "cron" ? { ...x, expr: nextExpr } : x)),
1163
+ });
1164
+ }}
1165
+ className="w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-[11px] text-[color:var(--ck-text-secondary)]"
1166
+ >
1167
+ {presets.map((p) => (
1168
+ <option key={p.label} value={p.expr}>
1169
+ {p.label}
1170
+ </option>
1171
+ ))}
1172
+ </select>
1173
+ <div className="text-[10px] text-[color:var(--ck-text-tertiary)]">Presets set the cron; edit freely for advanced schedules.</div>
1174
+ </div>
1175
+ </label>
1176
+
1177
+ <label className="block">
1178
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">timezone override</div>
1179
+ <input
1180
+ value={trigTz}
1181
+ onChange={(e) => {
1182
+ const nextTz = String(e.target.value || "").trim() || tz;
1183
+ setWorkflow({
1184
+ ...wf,
1185
+ triggers: triggers.map((x, idx) => (idx === i && x.kind === "cron" ? { ...x, tz: nextTz } : x)),
1186
+ });
1187
+ }}
1188
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1189
+ placeholder={tz}
1190
+ />
1191
+ </label>
1192
+ </div>
1193
+ </div>
1194
+ );
1195
+ })
1196
+ ) : (
1197
+ <div className="text-xs text-[color:var(--ck-text-secondary)]">No triggers yet.</div>
1198
+ )}
1199
+ </div>
1200
+ </div>
1201
+ </details>
1202
+
1203
+ <details open className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/15">
1204
+ <summary className="cursor-pointer list-none px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)]">Runs</summary>
1205
+ <div className="px-3 pb-3">
1206
+ <div className="flex items-center justify-between gap-2">
1207
+ <div className="text-xs font-medium text-[color:var(--ck-text-secondary)]">Runs (history)</div>
1208
+ <button
1209
+ type="button"
1210
+ disabled={saving}
1211
+ onClick={async () => {
1212
+ const wfId = String(wf.id ?? "").trim();
1213
+ if (!wfId) return;
1214
+ setWorkflowRunsError("");
1215
+ setWorkflowRunsLoading(true);
1216
+ try {
1217
+ const res = await fetch("/api/teams/workflow-runs", {
1218
+ method: "POST",
1219
+ headers: { "content-type": "application/json" },
1220
+ body: JSON.stringify({ teamId, workflowId: wfId, mode: "sample" }),
1221
+ });
1222
+ const json = await res.json();
1223
+ if (!res.ok || !json.ok) throw new Error(json.error || "Failed to create sample run");
1224
+
1225
+ const listRes = await fetch(
1226
+ `/api/teams/workflow-runs?teamId=${encodeURIComponent(teamId)}&workflowId=${encodeURIComponent(wfId)}`,
1227
+ { cache: "no-store" }
1228
+ );
1229
+ const listJson = await listRes.json();
1230
+ if (!listRes.ok || !listJson.ok) throw new Error(listJson.error || "Failed to refresh runs");
1231
+ const files = Array.isArray(listJson.files) ? listJson.files : [];
1232
+ const list = files.map((f: unknown) => String(f ?? "").trim()).filter((f: string) => Boolean(f));
1233
+ setWorkflowRuns(list);
1234
+ } catch (e: unknown) {
1235
+ setWorkflowRunsError(e instanceof Error ? e.message : String(e));
1236
+ } finally {
1237
+ setWorkflowRunsLoading(false);
1238
+ }
1239
+ }}
1240
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-[10px] font-medium text-[color:var(--ck-text-primary)] hover:bg-white/10 disabled:opacity-50"
1241
+ >
1242
+ + Sample run
1243
+ </button>
1244
+ </div>
1245
+
1246
+ {workflowRunsError ? (
1247
+ <div className="mt-2 rounded-[var(--ck-radius-sm)] border border-red-400/30 bg-red-500/10 p-2 text-xs text-red-100">
1248
+ {workflowRunsError}
1249
+ </div>
1250
+ ) : null}
1251
+
1252
+ <div className="mt-2 space-y-1">
1253
+ {workflowRunsLoading ? (
1254
+ <div className="text-xs text-[color:var(--ck-text-secondary)]">Loading runs…</div>
1255
+ ) : workflowRuns.length ? (
1256
+ workflowRuns.slice(0, 8).map((f) => {
1257
+ const runId = String(f).replace(/\.run\.json$/i, "");
1258
+ const selected = selectedWorkflowRunId === runId;
1259
+ return (
1260
+ <button
1261
+ key={f}
1262
+ type="button"
1263
+ onClick={async () => {
1264
+ const wfId = String(wf.id ?? "").trim();
1265
+ if (!wfId) return;
1266
+ setSelectedWorkflowRunId(runId);
1267
+ setWorkflowRunsError("");
1268
+ try {
1269
+ const res = await fetch(
1270
+ `/api/teams/workflow-runs?teamId=${encodeURIComponent(teamId)}&workflowId=${encodeURIComponent(wfId)}&runId=${encodeURIComponent(runId)}`,
1271
+ { cache: "no-store" }
1272
+ );
1273
+ const json = await res.json();
1274
+ if (!res.ok || !json.ok) throw new Error(json.error || "Failed to load run");
1275
+ // (run detail rendering not implemented yet; selecting stores runId only)
1276
+ } catch (e: unknown) {
1277
+ setWorkflowRunsError(e instanceof Error ? e.message : String(e));
1278
+ }
1279
+ }}
1280
+ className={
1281
+ selected
1282
+ ? "w-full rounded-[var(--ck-radius-sm)] bg-white/10 px-2 py-1 text-left text-[11px] text-[color:var(--ck-text-primary)]"
1283
+ : "w-full rounded-[var(--ck-radius-sm)] px-2 py-1 text-left text-[11px] text-[color:var(--ck-text-secondary)] hover:bg-white/5"
1284
+ }
1285
+ >
1286
+ {runId}
1287
+ </button>
1288
+ );
1289
+ })
1290
+ ) : (
1291
+ <div className="text-xs text-[color:var(--ck-text-secondary)]">No runs yet.</div>
1292
+ )}
1293
+ </div>
1294
+
1295
+ <details open className="mt-3 rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/10">
1296
+ <summary className="cursor-pointer list-none px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)]">Nodes</summary>
1297
+ <div className="px-3 pb-3">
1298
+
1299
+ <div className="mt-2 rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-2">
1300
+ <div className="grid grid-cols-1 gap-2">
1301
+ <label className="block">
1302
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">id</div>
1303
+ <input
1304
+ value={newNodeId}
1305
+ onChange={(e) => setNewNodeId(e.target.value)}
1306
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1307
+ placeholder="e.g. draft_assets"
1308
+ />
1309
+ </label>
1310
+
1311
+ <label className="block">
1312
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">name (optional)</div>
1313
+ <input
1314
+ value={newNodeName}
1315
+ onChange={(e) => setNewNodeName(e.target.value)}
1316
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1317
+ placeholder="Human-friendly label"
1318
+ />
1319
+ </label>
1320
+
1321
+ <label className="block">
1322
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">type</div>
1323
+ <select
1324
+ value={newNodeType}
1325
+ onChange={(e) => setNewNodeType(e.target.value as WorkflowFileV1["nodes"][number]["type"])}
1326
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1327
+ >
1328
+ <option value="start">start</option>
1329
+ <option value="end">end</option>
1330
+ <option value="llm">llm</option>
1331
+ <option value="tool">tool</option>
1332
+ <option value="condition">condition</option>
1333
+ <option value="delay">delay</option>
1334
+ <option value="human_approval">human_approval</option>
1335
+ </select>
1336
+ </label>
1337
+
1338
+ <button
1339
+ type="button"
1340
+ onClick={() => {
1341
+ const rawId = String(newNodeId || "").trim();
1342
+ const id = rawId.replace(/[^a-z0-9_\-]/gi, "_");
1343
+ if (!id) return;
1344
+ if (wf.nodes.some((n) => n.id === id)) return;
1345
+
1346
+ const maxX = wf.nodes.reduce((acc, n) => (typeof n.x === "number" ? Math.max(acc, n.x) : acc), 80);
1347
+ const nextNode = {
1348
+ id,
1349
+ type: newNodeType,
1350
+ name: String(newNodeName || "").trim() || id,
1351
+ x: maxX + 220,
1352
+ y: 80,
1353
+ } as WorkflowFileV1["nodes"][number];
1354
+
1355
+ setWorkflow({ ...wf, nodes: [...wf.nodes, nextNode] });
1356
+ setSelectedNodeId(id);
1357
+ setNewNodeId("");
1358
+ setNewNodeName("");
1359
+ }}
1360
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-[11px] font-medium text-[color:var(--ck-text-primary)] hover:bg-white/10"
1361
+ >
1362
+ + Add node
1363
+ </button>
1364
+ </div>
1365
+ </div>
1366
+
1367
+ <div className="mt-2 space-y-1">
1368
+ {wf.nodes.map((n) => {
1369
+ const selected = selectedNodeId === n.id;
1370
+ return (
1371
+ <button
1372
+ key={n.id}
1373
+ type="button"
1374
+ onClick={() => setSelectedNodeId(n.id)}
1375
+ className={
1376
+ selected
1377
+ ? "w-full rounded-[var(--ck-radius-sm)] bg-white/10 px-2 py-1 text-left text-[11px] text-[color:var(--ck-text-primary)]"
1378
+ : "w-full rounded-[var(--ck-radius-sm)] px-2 py-1 text-left text-[11px] text-[color:var(--ck-text-secondary)] hover:bg-white/5"
1379
+ }
1380
+ >
1381
+ <span className="font-mono">{n.id}</span>
1382
+ <span className="ml-2 text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">{n.type}</span>
1383
+ </button>
1384
+ );
1385
+ })}
1386
+ </div>
1387
+ </div>
1388
+ </details>
1389
+
1390
+ <details open className="mt-3 rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/10">
1391
+ <summary className="cursor-pointer list-none px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)]">Edges</summary>
1392
+ <div className="px-3 pb-3">
1393
+
1394
+ <div className="mt-2 rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-2">
1395
+ <div className="grid grid-cols-1 gap-2">
1396
+ <label className="block">
1397
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">from</div>
1398
+ <select
1399
+ value={newEdgeFrom}
1400
+ onChange={(e) => setNewEdgeFrom(e.target.value)}
1401
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1402
+ >
1403
+ <option value="">(select)</option>
1404
+ {wf.nodes.map((n) => (
1405
+ <option key={n.id} value={n.id}>
1406
+ {n.id}
1407
+ </option>
1408
+ ))}
1409
+ </select>
1410
+ </label>
1411
+
1412
+ <label className="block">
1413
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">to</div>
1414
+ <select
1415
+ value={newEdgeTo}
1416
+ onChange={(e) => setNewEdgeTo(e.target.value)}
1417
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1418
+ >
1419
+ <option value="">(select)</option>
1420
+ {wf.nodes.map((n) => (
1421
+ <option key={n.id} value={n.id}>
1422
+ {n.id}
1423
+ </option>
1424
+ ))}
1425
+ </select>
1426
+ </label>
1427
+
1428
+ <label className="block">
1429
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">label (optional)</div>
1430
+ <input
1431
+ value={newEdgeLabel}
1432
+ onChange={(e) => setNewEdgeLabel(e.target.value)}
1433
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1434
+ placeholder="e.g. approve"
1435
+ />
1436
+ </label>
1437
+
1438
+ <button
1439
+ type="button"
1440
+ onClick={() => {
1441
+ const from = String(newEdgeFrom || "").trim();
1442
+ const to = String(newEdgeTo || "").trim();
1443
+ if (!from || !to) return;
1444
+ if (from === to) return;
1445
+ const id = `e${Date.now()}`;
1446
+ const nextEdge: WorkflowFileV1["edges"][number] = {
1447
+ id,
1448
+ from,
1449
+ to,
1450
+ ...(String(newEdgeLabel || "").trim() ? { label: String(newEdgeLabel).trim() } : {}),
1451
+ };
1452
+ setWorkflow({ ...wf, edges: [...(wf.edges ?? []), nextEdge] });
1453
+ setNewEdgeLabel("");
1454
+ }}
1455
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-[11px] font-medium text-[color:var(--ck-text-primary)] hover:bg-white/10"
1456
+ >
1457
+ + Add edge
1458
+ </button>
1459
+ </div>
1460
+ </div>
1461
+
1462
+ <div className="mt-2 space-y-2">
1463
+ {(wf.edges ?? []).length ? (
1464
+ (wf.edges ?? []).map((e) => (
1465
+ <div key={e.id} className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-2">
1466
+ <div className="flex items-center justify-between gap-2">
1467
+ <div className="text-[11px] text-[color:var(--ck-text-secondary)]">
1468
+ <span className="font-mono">{e.from}</span> → <span className="font-mono">{e.to}</span>
1469
+ {e.label ? <span className="ml-2 text-[10px] text-[color:var(--ck-text-tertiary)]">({e.label})</span> : null}
1470
+ </div>
1471
+ <button
1472
+ type="button"
1473
+ onClick={() => setWorkflow({ ...wf, edges: (wf.edges ?? []).filter((x) => x.id !== e.id) })}
1474
+ className="text-[10px] text-[color:var(--ck-text-tertiary)] hover:text-[color:var(--ck-text-primary)]"
1475
+ >
1476
+ Remove
1477
+ </button>
1478
+ </div>
1479
+ </div>
1480
+ ))
1481
+ ) : (
1482
+ <div className="text-xs text-[color:var(--ck-text-secondary)]">No edges yet.</div>
1483
+ )}
1484
+ </div>
1485
+ </div>
1486
+ </details>
1487
+
1488
+ <details open className="mt-3 rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/10">
1489
+ <summary className="cursor-pointer list-none px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)]">Node inspector</summary>
1490
+ <div className="px-3 pb-3">
1491
+ <div className="flex items-center justify-between gap-2">
1492
+ {selectedNodeId ? (
1493
+ <button
1494
+ type="button"
1495
+ onClick={() => {
1496
+ const nodeId = selectedNodeId;
1497
+ const nextNodes = wf.nodes.filter((n) => n.id !== nodeId);
1498
+ const nextEdges = (wf.edges ?? []).filter((e) => e.from !== nodeId && e.to !== nodeId);
1499
+ setWorkflow({ ...wf, nodes: nextNodes, edges: nextEdges });
1500
+ setSelectedNodeId("");
1501
+ }}
1502
+ className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-[10px] font-medium text-red-100 hover:bg-white/10"
1503
+ >
1504
+ Delete node
1505
+ </button>
1506
+ ) : null}
1507
+ </div>
1508
+
1509
+ {selectedNodeId ? (
1510
+ (() => {
1511
+ const node = wf.nodes.find((n) => n.id === selectedNodeId);
1512
+ if (!node) return <div className="mt-2 text-sm text-[color:var(--ck-text-secondary)]">No node selected.</div>;
1513
+
1514
+ return (
1515
+ <div className="mt-3 space-y-3">
1516
+ <div>
1517
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">id</div>
1518
+ <div className="mt-1 rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]">
1519
+ {node.id}
1520
+ </div>
1521
+ </div>
1522
+
1523
+ <label className="block">
1524
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">name</div>
1525
+ <input
1526
+ value={String(node.name ?? "")}
1527
+ onChange={(e) => {
1528
+ const nextName = e.target.value;
1529
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, name: nextName } : n)) });
1530
+ }}
1531
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1532
+ placeholder="Optional"
1533
+ />
1534
+ </label>
1535
+
1536
+ <label className="block">
1537
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">type</div>
1538
+ <select
1539
+ value={node.type}
1540
+ onChange={(e) => {
1541
+ const nextType = e.target.value as WorkflowFileV1["nodes"][number]["type"];
1542
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, type: nextType } : n)) });
1543
+ }}
1544
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1545
+ >
1546
+ <option value="start">start</option>
1547
+ <option value="end">end</option>
1548
+ <option value="llm">llm</option>
1549
+ <option value="tool">tool</option>
1550
+ <option value="condition">condition</option>
1551
+ <option value="delay">delay</option>
1552
+ <option value="human_approval">human_approval</option>
1553
+ </select>
1554
+ </label>
1555
+
1556
+ <div className="grid grid-cols-2 gap-2">
1557
+ <label className="block">
1558
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">x</div>
1559
+ <input
1560
+ type="number"
1561
+ value={typeof node.x === "number" ? node.x : 0}
1562
+ onChange={(e) => {
1563
+ const nextX = Number(e.target.value);
1564
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, x: nextX } : n)) });
1565
+ }}
1566
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1567
+ />
1568
+ </label>
1569
+ <label className="block">
1570
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">y</div>
1571
+ <input
1572
+ type="number"
1573
+ value={typeof node.y === "number" ? node.y : 0}
1574
+ onChange={(e) => {
1575
+ const nextY = Number(e.target.value);
1576
+ setWorkflow({ ...wf, nodes: wf.nodes.map((n) => (n.id === node.id ? { ...n, y: nextY } : n)) });
1577
+ }}
1578
+ className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-1 text-xs text-[color:var(--ck-text-primary)]"
1579
+ />
1580
+ </label>
1581
+ </div>
1582
+
1583
+ <div>
1584
+ <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">config</div>
1585
+ <pre className="mt-1 max-h-[200px] overflow-auto rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-2 text-[10px] text-[color:var(--ck-text-secondary)]">
1586
+ {JSON.stringify(node.config ?? {}, null, 2)}
1587
+ </pre>
1588
+ </div>
1589
+ </div>
1590
+ );
1591
+ })()
1592
+ ) : (
1593
+ <div className="mt-2 text-sm text-[color:var(--ck-text-secondary)]">Select a node.</div>
1594
+ )}
1595
+ </div>
1596
+ </details>
1597
+ </div>
1598
+ </details>
1599
+ </div>
1600
+ );
1601
+ })()
1602
+ ) : null}
1603
+ </div>
1604
+ </div>
1605
+ </div>
1606
+ </div>
1607
+ );
1608
+ }