@jiggai/kitchen 0.3.1 → 0.3.3

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 (307) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +2 -2
  3. package/.next/server/app/_global-error.html +2 -2
  4. package/.next/server/app/_global-error.rsc +1 -1
  5. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  6. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  7. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/.next/server/app/_not-found.html +1 -1
  11. package/.next/server/app/_not-found.rsc +1 -1
  12. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  13. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  14. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  15. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  16. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  18. package/.next/server/app/channels.html +2 -2
  19. package/.next/server/app/channels.rsc +1 -1
  20. package/.next/server/app/channels.segments/_full.segment.rsc +1 -1
  21. package/.next/server/app/channels.segments/_head.segment.rsc +1 -1
  22. package/.next/server/app/channels.segments/_index.segment.rsc +1 -1
  23. package/.next/server/app/channels.segments/_tree.segment.rsc +1 -1
  24. package/.next/server/app/channels.segments/channels/__PAGE__.segment.rsc +1 -1
  25. package/.next/server/app/channels.segments/channels.segment.rsc +1 -1
  26. package/.next/server/app/cron-jobs.html +1 -1
  27. package/.next/server/app/cron-jobs.rsc +1 -1
  28. package/.next/server/app/cron-jobs.segments/_full.segment.rsc +1 -1
  29. package/.next/server/app/cron-jobs.segments/_head.segment.rsc +1 -1
  30. package/.next/server/app/cron-jobs.segments/_index.segment.rsc +1 -1
  31. package/.next/server/app/cron-jobs.segments/_tree.segment.rsc +1 -1
  32. package/.next/server/app/cron-jobs.segments/cron-jobs/__PAGE__.segment.rsc +1 -1
  33. package/.next/server/app/cron-jobs.segments/cron-jobs.segment.rsc +1 -1
  34. package/.next/server/app/goals/new.html +2 -2
  35. package/.next/server/app/goals/new.rsc +1 -1
  36. package/.next/server/app/goals/new.segments/_full.segment.rsc +1 -1
  37. package/.next/server/app/goals/new.segments/_head.segment.rsc +1 -1
  38. package/.next/server/app/goals/new.segments/_index.segment.rsc +1 -1
  39. package/.next/server/app/goals/new.segments/_tree.segment.rsc +1 -1
  40. package/.next/server/app/goals/new.segments/goals/new/__PAGE__.segment.rsc +1 -1
  41. package/.next/server/app/goals/new.segments/goals/new.segment.rsc +1 -1
  42. package/.next/server/app/goals/new.segments/goals.segment.rsc +1 -1
  43. package/.next/server/app/goals.html +1 -1
  44. package/.next/server/app/goals.rsc +1 -1
  45. package/.next/server/app/goals.segments/_full.segment.rsc +1 -1
  46. package/.next/server/app/goals.segments/_head.segment.rsc +1 -1
  47. package/.next/server/app/goals.segments/_index.segment.rsc +1 -1
  48. package/.next/server/app/goals.segments/_tree.segment.rsc +1 -1
  49. package/.next/server/app/goals.segments/goals/__PAGE__.segment.rsc +1 -1
  50. package/.next/server/app/goals.segments/goals.segment.rsc +1 -1
  51. package/.next/server/app/settings.html +1 -1
  52. package/.next/server/app/settings.rsc +1 -1
  53. package/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  54. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  55. package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  56. package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  57. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  58. package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  59. package/.next/server/pages/404.html +1 -1
  60. package/.next/server/pages/500.html +2 -2
  61. package/package.json +1 -2
  62. package/src/app/HomeClient.tsx +0 -207
  63. package/src/app/agents/[agentId]/agent-editor-tabs.tsx +0 -298
  64. package/src/app/agents/[agentId]/agent-editor.tsx +0 -468
  65. package/src/app/agents/[agentId]/page.tsx +0 -32
  66. package/src/app/api/__tests__/agents-add-route.test.ts +0 -143
  67. package/src/app/api/__tests__/agents-file-route.test.ts +0 -117
  68. package/src/app/api/__tests__/agents-files-route.test.ts +0 -61
  69. package/src/app/api/__tests__/agents-id-route.test.ts +0 -104
  70. package/src/app/api/__tests__/agents-identity-route.test.ts +0 -92
  71. package/src/app/api/__tests__/agents-route.test.ts +0 -54
  72. package/src/app/api/__tests__/agents-skills-install-route.test.ts +0 -131
  73. package/src/app/api/__tests__/agents-skills-route.test.ts +0 -64
  74. package/src/app/api/__tests__/agents-update-route.test.ts +0 -95
  75. package/src/app/api/__tests__/channels-bindings-route.test.ts +0 -143
  76. package/src/app/api/__tests__/cron-delete-route.test.ts +0 -93
  77. package/src/app/api/__tests__/cron-job-route.test.ts +0 -78
  78. package/src/app/api/__tests__/cron-jobs-route.test.ts +0 -116
  79. package/src/app/api/__tests__/cron-recipe-installed-route.test.ts +0 -114
  80. package/src/app/api/__tests__/gateway-restart-route.test.ts +0 -36
  81. package/src/app/api/__tests__/goals-promote-route.test.ts +0 -200
  82. package/src/app/api/__tests__/goals-route.test.ts +0 -184
  83. package/src/app/api/__tests__/ids-check-route.test.ts +0 -188
  84. package/src/app/api/__tests__/marketplace-recipes-route.test.ts +0 -123
  85. package/src/app/api/__tests__/recipes-clone-route.test.ts +0 -221
  86. package/src/app/api/__tests__/recipes-delete-route.test.ts +0 -248
  87. package/src/app/api/__tests__/recipes-id-route.test.ts +0 -166
  88. package/src/app/api/__tests__/recipes-route.test.ts +0 -57
  89. package/src/app/api/__tests__/recipes-team-agents-route.test.ts +0 -135
  90. package/src/app/api/__tests__/scaffold-route.test.ts +0 -173
  91. package/src/app/api/__tests__/settings-cron-installation-route.test.ts +0 -82
  92. package/src/app/api/__tests__/skills-available-route.test.ts +0 -47
  93. package/src/app/api/__tests__/swarms-start-route.test.ts +0 -79
  94. package/src/app/api/__tests__/swarms-status-route.test.ts +0 -42
  95. package/src/app/api/__tests__/teams-file-route.test.ts +0 -129
  96. package/src/app/api/__tests__/teams-files-route.test.ts +0 -57
  97. package/src/app/api/__tests__/teams-meta-route.test.ts +0 -113
  98. package/src/app/api/__tests__/teams-orchestrator-install-route.test.ts +0 -66
  99. package/src/app/api/__tests__/teams-orchestrator-route.test.ts +0 -59
  100. package/src/app/api/__tests__/teams-remove-team-route.test.ts +0 -122
  101. package/src/app/api/__tests__/teams-skills-install-route.test.ts +0 -78
  102. package/src/app/api/__tests__/teams-skills-route.test.ts +0 -73
  103. package/src/app/api/__tests__/teams-workflow-runs-route.test.ts +0 -85
  104. package/src/app/api/__tests__/teams-workflows-route.test.ts +0 -110
  105. package/src/app/api/__tests__/tickets-move-route.test.ts +0 -60
  106. package/src/app/api/agents/[id]/route.ts +0 -83
  107. package/src/app/api/agents/add/route.ts +0 -114
  108. package/src/app/api/agents/file/route.ts +0 -45
  109. package/src/app/api/agents/files/route.ts +0 -23
  110. package/src/app/api/agents/identity/route.ts +0 -41
  111. package/src/app/api/agents/route.ts +0 -22
  112. package/src/app/api/agents/skills/install/route.ts +0 -34
  113. package/src/app/api/agents/skills/route.ts +0 -39
  114. package/src/app/api/agents/update/route.ts +0 -52
  115. package/src/app/api/channels/bindings/route.ts +0 -63
  116. package/src/app/api/cron/__tests__/helpers.test.ts +0 -164
  117. package/src/app/api/cron/delete/route.ts +0 -23
  118. package/src/app/api/cron/helpers.ts +0 -172
  119. package/src/app/api/cron/job/route.ts +0 -22
  120. package/src/app/api/cron/jobs/route.ts +0 -52
  121. package/src/app/api/cron/recipe-installed/route.ts +0 -65
  122. package/src/app/api/gateway/restart/route.ts +0 -20
  123. package/src/app/api/goals/[id]/promote/route.ts +0 -119
  124. package/src/app/api/goals/[id]/route.ts +0 -54
  125. package/src/app/api/goals/route.ts +0 -44
  126. package/src/app/api/ids/check/route.ts +0 -113
  127. package/src/app/api/marketplace/recipes/[slug]/route.ts +0 -16
  128. package/src/app/api/marketplace/recipes/route.ts +0 -22
  129. package/src/app/api/recipes/[id]/route.ts +0 -62
  130. package/src/app/api/recipes/clone/route.ts +0 -106
  131. package/src/app/api/recipes/custom-team/route.ts +0 -193
  132. package/src/app/api/recipes/delete/helpers.ts +0 -65
  133. package/src/app/api/recipes/delete/route.ts +0 -73
  134. package/src/app/api/recipes/route.ts +0 -21
  135. package/src/app/api/recipes/team-agents/__tests__/helpers.test.ts +0 -156
  136. package/src/app/api/recipes/team-agents/helpers.ts +0 -151
  137. package/src/app/api/recipes/team-agents/route.ts +0 -80
  138. package/src/app/api/scaffold/__tests__/helpers.test.ts +0 -186
  139. package/src/app/api/scaffold/helpers.ts +0 -214
  140. package/src/app/api/scaffold/route.ts +0 -95
  141. package/src/app/api/settings/cron-installation/route.ts +0 -58
  142. package/src/app/api/skills/available/route.ts +0 -23
  143. package/src/app/api/swarms/start/route.ts +0 -100
  144. package/src/app/api/swarms/status/route.ts +0 -31
  145. package/src/app/api/teams/[teamId]/tickets/assign/route.ts +0 -105
  146. package/src/app/api/teams/[teamId]/tickets/assignees/route.ts +0 -27
  147. package/src/app/api/teams/[teamId]/tickets/delete/route.ts +0 -55
  148. package/src/app/api/teams/[teamId]/tickets/move/route.ts +0 -70
  149. package/src/app/api/teams/[teamId]/tickets/move-to-goals/route.ts +0 -56
  150. package/src/app/api/teams/file/route.ts +0 -46
  151. package/src/app/api/teams/files/route.ts +0 -63
  152. package/src/app/api/teams/memory/route.ts +0 -250
  153. package/src/app/api/teams/meta/route.ts +0 -43
  154. package/src/app/api/teams/orchestrator/install/route.ts +0 -129
  155. package/src/app/api/teams/orchestrator/route.ts +0 -216
  156. package/src/app/api/teams/remove-team/route.ts +0 -37
  157. package/src/app/api/teams/skills/install/route.ts +0 -18
  158. package/src/app/api/teams/skills/route.ts +0 -25
  159. package/src/app/api/teams/workflow-runs/route.ts +0 -534
  160. package/src/app/api/teams/workflow-templates/route.ts +0 -71
  161. package/src/app/api/teams/workflows/route.ts +0 -55
  162. package/src/app/api/tickets/assign/route.ts +0 -94
  163. package/src/app/api/tickets/assignees/route.ts +0 -24
  164. package/src/app/api/tickets/move/route.ts +0 -69
  165. package/src/app/channels/channels-client.tsx +0 -271
  166. package/src/app/channels/page.tsx +0 -5
  167. package/src/app/cron-jobs/cron-jobs-client.tsx +0 -243
  168. package/src/app/cron-jobs/page.tsx +0 -34
  169. package/src/app/favicon.ico +0 -0
  170. package/src/app/global-error.tsx +0 -50
  171. package/src/app/globals.css +0 -153
  172. package/src/app/goals/[id]/goal-editor.tsx +0 -162
  173. package/src/app/goals/[id]/page.tsx +0 -6
  174. package/src/app/goals/goals-client.tsx +0 -201
  175. package/src/app/goals/new/page.tsx +0 -81
  176. package/src/app/goals/page.tsx +0 -10
  177. package/src/app/layout.tsx +0 -53
  178. package/src/app/manifest.ts +0 -15
  179. package/src/app/not-found.tsx +0 -8
  180. package/src/app/page.tsx +0 -33
  181. package/src/app/recipes/CreateAgentModal.tsx +0 -156
  182. package/src/app/recipes/CreateCustomTeamModal.tsx +0 -375
  183. package/src/app/recipes/CreateModalShell.tsx +0 -55
  184. package/src/app/recipes/CreateTeamModal.tsx +0 -91
  185. package/src/app/recipes/[id]/RecipeEditor/RecipeEditorCreateModal.tsx +0 -72
  186. package/src/app/recipes/[id]/RecipeEditor/RecipeEditorPanel.tsx +0 -216
  187. package/src/app/recipes/[id]/RecipeEditor/index.tsx +0 -271
  188. package/src/app/recipes/[id]/RecipeEditor/recipe-editor-utils.ts +0 -46
  189. package/src/app/recipes/[id]/RecipeEditor/types.ts +0 -52
  190. package/src/app/recipes/[id]/page.tsx +0 -37
  191. package/src/app/recipes/page.tsx +0 -101
  192. package/src/app/recipes/recipes-client.tsx +0 -620
  193. package/src/app/settings/page.tsx +0 -26
  194. package/src/app/settings/settings-client.tsx +0 -91
  195. package/src/app/teams/[teamId]/CloneTeamModal.tsx +0 -116
  196. package/src/app/teams/[teamId]/OrchestratorPanel.tsx +0 -255
  197. package/src/app/teams/[teamId]/OrchestratorSetupModal.tsx +0 -184
  198. package/src/app/teams/[teamId]/PublishChangesModal.tsx +0 -43
  199. package/src/app/teams/[teamId]/page.tsx +0 -49
  200. package/src/app/teams/[teamId]/team-editor/TeamAgentsTab.tsx +0 -145
  201. package/src/app/teams/[teamId]/team-editor/TeamCronTab.tsx +0 -72
  202. package/src/app/teams/[teamId]/team-editor/TeamFilesTab.tsx +0 -74
  203. package/src/app/teams/[teamId]/team-editor/TeamMemoryTab.tsx +0 -349
  204. package/src/app/teams/[teamId]/team-editor/TeamRecipeTab.tsx +0 -151
  205. package/src/app/teams/[teamId]/team-editor/TeamSkillsTab.tsx +0 -68
  206. package/src/app/teams/[teamId]/team-editor/index.tsx +0 -558
  207. package/src/app/teams/[teamId]/team-editor/team-editor-data.ts +0 -255
  208. package/src/app/teams/[teamId]/team-editor/team-editor-utils.ts +0 -78
  209. package/src/app/teams/[teamId]/team-editor/types.ts +0 -34
  210. package/src/app/teams/[teamId]/tickets/[ticket]/page.tsx +0 -35
  211. package/src/app/teams/[teamId]/tickets/page.tsx +0 -15
  212. package/src/app/teams/[teamId]/workflows/[workflowId]/WorkflowCanvas.tsx +0 -111
  213. package/src/app/teams/[teamId]/workflows/[workflowId]/page.tsx +0 -27
  214. package/src/app/teams/[teamId]/workflows/[workflowId]/workflows-editor-client.tsx +0 -1608
  215. package/src/app/teams/[teamId]/workflows/page.tsx +0 -40
  216. package/src/app/teams/[teamId]/workflows/workflows-client.tsx +0 -494
  217. package/src/app/tickets/TicketDetailClient.tsx +0 -147
  218. package/src/app/tickets/TicketsBoardClient.tsx +0 -200
  219. package/src/app/tickets/[ticket]/TicketAssignControl.tsx +0 -112
  220. package/src/app/tickets/[ticket]/page.tsx +0 -36
  221. package/src/app/tickets/page.tsx +0 -10
  222. package/src/components/AppShell.tsx +0 -286
  223. package/src/components/ConfirmationModal.tsx +0 -81
  224. package/src/components/DeleteEntityModal.tsx +0 -41
  225. package/src/components/ErrorBoundary.tsx +0 -70
  226. package/src/components/FileListWithOptionalToggle.tsx +0 -86
  227. package/src/components/GoalFormFields.tsx +0 -163
  228. package/src/components/ScaffoldOverlay.tsx +0 -78
  229. package/src/components/ThemeToggle.tsx +0 -53
  230. package/src/components/ToastProvider.tsx +0 -163
  231. package/src/components/__tests__/ConfirmationModal.test.tsx +0 -109
  232. package/src/components/__tests__/ErrorBoundary.test.tsx +0 -39
  233. package/src/components/__tests__/FileListWithOptionalToggle.test.tsx +0 -109
  234. package/src/components/__tests__/GoalFormFields.test.tsx +0 -117
  235. package/src/components/delete-modals.tsx +0 -59
  236. package/src/components/icons.tsx +0 -48
  237. package/src/lib/__tests__/agent-workspace.test.ts +0 -44
  238. package/src/lib/__tests__/agents.test.ts +0 -36
  239. package/src/lib/__tests__/api-route-helpers.test.ts +0 -188
  240. package/src/lib/__tests__/cron.test.ts +0 -45
  241. package/src/lib/__tests__/editor-utils.test.ts +0 -38
  242. package/src/lib/__tests__/errors.test.ts +0 -15
  243. package/src/lib/__tests__/exec.test.ts +0 -13
  244. package/src/lib/__tests__/fetch-json.test.ts +0 -118
  245. package/src/lib/__tests__/gateway.test.ts +0 -234
  246. package/src/lib/__tests__/goal-promote.test.ts +0 -39
  247. package/src/lib/__tests__/goals-client.test.ts +0 -26
  248. package/src/lib/__tests__/goals.test.ts +0 -275
  249. package/src/lib/__tests__/json.test.ts +0 -15
  250. package/src/lib/__tests__/kitchen-api.test.ts +0 -32
  251. package/src/lib/__tests__/marketplace.test.ts +0 -116
  252. package/src/lib/__tests__/openclaw.test.ts +0 -129
  253. package/src/lib/__tests__/paths.test.ts +0 -136
  254. package/src/lib/__tests__/poll.test.ts +0 -26
  255. package/src/lib/__tests__/recipe-clone.test.ts +0 -85
  256. package/src/lib/__tests__/recipe-team-agents.test.ts +0 -70
  257. package/src/lib/__tests__/recipes.test.ts +0 -199
  258. package/src/lib/__tests__/scaffold-client.test.ts +0 -106
  259. package/src/lib/__tests__/scaffold.test.ts +0 -64
  260. package/src/lib/__tests__/slugify.test.ts +0 -23
  261. package/src/lib/__tests__/tickets.test.ts +0 -158
  262. package/src/lib/__tests__/type-guards.test.ts +0 -18
  263. package/src/lib/__tests__/use-slugified-id.test.tsx +0 -120
  264. package/src/lib/agent-workspace.ts +0 -14
  265. package/src/lib/agents.ts +0 -17
  266. package/src/lib/api-route-helpers.ts +0 -157
  267. package/src/lib/cron.ts +0 -40
  268. package/src/lib/editor-utils.ts +0 -18
  269. package/src/lib/errors.ts +0 -7
  270. package/src/lib/exec.ts +0 -4
  271. package/src/lib/fetch-json.ts +0 -29
  272. package/src/lib/gateway.ts +0 -100
  273. package/src/lib/goal-promote.ts +0 -27
  274. package/src/lib/goals-client.ts +0 -69
  275. package/src/lib/goals.ts +0 -171
  276. package/src/lib/json.ts +0 -10
  277. package/src/lib/kitchen-api.ts +0 -19
  278. package/src/lib/marketplace.ts +0 -46
  279. package/src/lib/openclaw.ts +0 -59
  280. package/src/lib/paths.ts +0 -69
  281. package/src/lib/poll.ts +0 -18
  282. package/src/lib/recipe-clone.ts +0 -42
  283. package/src/lib/recipe-team-agents.ts +0 -30
  284. package/src/lib/recipes.ts +0 -95
  285. package/src/lib/scaffold-client.ts +0 -31
  286. package/src/lib/scaffold.ts +0 -37
  287. package/src/lib/slugify.ts +0 -25
  288. package/src/lib/swarms.ts +0 -25
  289. package/src/lib/tickets.ts +0 -192
  290. package/src/lib/type-guards.ts +0 -3
  291. package/src/lib/use-slugified-id.ts +0 -35
  292. package/src/lib/workflows/README.md +0 -11
  293. package/src/lib/workflows/__tests__/storage.test.ts +0 -129
  294. package/src/lib/workflows/__tests__/validate.test.ts +0 -92
  295. package/src/lib/workflows/api-handlers.ts +0 -35
  296. package/src/lib/workflows/readdir.ts +0 -23
  297. package/src/lib/workflows/runs-storage.ts +0 -59
  298. package/src/lib/workflows/runs-types.ts +0 -42
  299. package/src/lib/workflows/storage.ts +0 -70
  300. package/src/lib/workflows/templates/index.ts +0 -1
  301. package/src/lib/workflows/templates/marketing-cadence-v1.ts +0 -142
  302. package/src/lib/workflows/types.ts +0 -48
  303. package/src/lib/workflows/validate.ts +0 -92
  304. package/src/proxy.ts +0 -28
  305. /package/.next/static/{z86RoqzzXXrWnpi229zP6 → Jrrrm9HH5bKkSrQhe1j93}/_buildManifest.js +0 -0
  306. /package/.next/static/{z86RoqzzXXrWnpi229zP6 → Jrrrm9HH5bKkSrQhe1j93}/_clientMiddlewareManifest.json +0 -0
  307. /package/.next/static/{z86RoqzzXXrWnpi229zP6 → Jrrrm9HH5bKkSrQhe1j93}/_ssgManifest.js +0 -0
@@ -1,558 +0,0 @@
1
- "use client";
2
-
3
- import { useEffect, useMemo, useState } from "react";
4
- import { parse as parseYaml } from "yaml";
5
- import { useRouter } from "next/navigation";
6
- import { DeleteTeamModal } from "@/components/delete-modals";
7
- import { PublishChangesModal } from "../PublishChangesModal";
8
- import { useToast } from "@/components/ToastProvider";
9
- import { errorMessage } from "@/lib/errors";
10
- import { fetchJson } from "@/lib/fetch-json";
11
- import {
12
- loadTeamEditorInitial,
13
- handleAddAgentToTeam,
14
- } from "./team-editor-data";
15
- import { forceFrontmatterId, forceFrontmatterTeamTeamId } from "./team-editor-utils";
16
- import type { RecipeDetail, RecipeListItem, TeamAgentEntry } from "./types";
17
- import { TeamRecipeTab } from "./TeamRecipeTab";
18
- import { TeamAgentsTab } from "./TeamAgentsTab";
19
- import { TeamSkillsTab } from "./TeamSkillsTab";
20
- import { TeamCronTab } from "./TeamCronTab";
21
- import { TeamFilesTab } from "./TeamFilesTab";
22
- import { TeamMemoryTab } from "./TeamMemoryTab";
23
- import { OrchestratorPanel } from "../OrchestratorPanel";
24
- import WorkflowsClient from "../workflows/workflows-client";
25
-
26
- const TABS = [
27
- { id: "recipe" as const, label: "Recipe" },
28
- { id: "agents" as const, label: "Agents" },
29
- { id: "skills" as const, label: "Skills" },
30
- { id: "cron" as const, label: "Cron" },
31
- { id: "files" as const, label: "Files" },
32
- { id: "memory" as const, label: "Memory" },
33
- { id: "orchestrator" as const, label: "Orchestrator" },
34
- { id: "workflows" as const, label: "Workflows" },
35
- ];
36
-
37
- type TabId = (typeof TABS)[number]["id"];
38
-
39
- export default function TeamEditor({ teamId, initialTab }: { teamId: string; initialTab?: string }) {
40
- const router = useRouter();
41
- const [recipes, setRecipes] = useState<RecipeListItem[]>([]);
42
- const [fromId, setFromId] = useState<string>("");
43
- const [lockedFromId, setLockedFromId] = useState<string | null>(null);
44
- const [lockedFromName, setLockedFromName] = useState<string | null>(null);
45
- const [provenanceMissing, setProvenanceMissing] = useState(false);
46
- const [toId, setToId] = useState<string>(teamId);
47
- const [toName, setToName] = useState<string>(teamId);
48
- const [content, setContent] = useState<string>("");
49
- const [loadedRecipeHash, setLoadedRecipeHash] = useState<string | null>(null);
50
- const [activeTab, setActiveTab] = useState<TabId>(() => {
51
- const valid: TabId[] = ["recipe", "agents", "skills", "cron", "files", "memory", "orchestrator", "workflows"];
52
- return valid.includes(initialTab as TabId) ? (initialTab as TabId) : "recipe";
53
- });
54
- const [loading, setLoading] = useState(true);
55
- const [saving, setSaving] = useState(false);
56
- const [publishing, setPublishing] = useState(false);
57
- const [deleting, setDeleting] = useState(false);
58
- const [loadingSource, setLoadingSource] = useState(false);
59
- const [recipeLoadError, setRecipeLoadError] = useState<string>("");
60
- const toast = useToast();
61
-
62
- const [deleteOpen, setDeleteOpen] = useState(false);
63
- const [publishOpen, setPublishOpen] = useState(false);
64
- const [teamMetaRecipeHash, setTeamMetaRecipeHash] = useState<string | null>(null);
65
-
66
- function flashMessage(next: string, kind: "success" | "error" | "info" = "info") {
67
- const msg = String(next ?? "").trim();
68
- if (!msg) return;
69
- toast.push({ kind, message: msg });
70
- }
71
-
72
- const [teamFiles, setTeamFiles] = useState<{ name: string; missing: boolean; required?: boolean; rationale?: string }[]>([]);
73
- const [teamFilesLoading, setTeamFilesLoading] = useState(false);
74
- const [teamFileError, setTeamFileError] = useState<string>("");
75
- const [showOptionalFiles, setShowOptionalFiles] = useState(false);
76
- const [fileName, setFileName] = useState<string>("SOUL.md");
77
- const [fileContent, setFileContent] = useState<string>("");
78
-
79
- const [cronJobs, setCronJobs] = useState<unknown[]>([]);
80
- const [cronLoading, setCronLoading] = useState(false);
81
-
82
- const [teamAgents, setTeamAgents] = useState<TeamAgentEntry[]>([]);
83
- const [teamAgentsLoading, setTeamAgentsLoading] = useState(false);
84
-
85
- const recipeAgents = useMemo(() => {
86
- const md = String(content ?? "");
87
- if (!md.startsWith("---\n")) return [] as Array<{ role: string; name?: string }>;
88
- const end = md.indexOf("\n---\n", 4);
89
- if (end === -1) return [] as Array<{ role: string; name?: string }>;
90
- const fmText = md.slice(4, end + 1);
91
- try {
92
- const fm = (parseYaml(fmText) ?? {}) as { agents?: unknown };
93
- const agents = Array.isArray(fm.agents) ? fm.agents : [];
94
- return agents
95
- .map((a) => a as { role?: unknown; name?: unknown })
96
- .map((a) => ({ role: String(a.role ?? "").trim(), name: typeof a.name === "string" ? a.name : undefined }))
97
- .filter((a) => Boolean(a.role));
98
- } catch {
99
- return [] as Array<{ role: string; name?: string }>;
100
- }
101
- }, [content]);
102
-
103
- const [newRole, setNewRole] = useState<string>("");
104
- const [customRole, setCustomRole] = useState<string>("");
105
- const [newRoleName, setNewRoleName] = useState<string>("");
106
-
107
- const derivedRole = useMemo(() => {
108
- const v = (newRole === "__custom__" ? customRole : newRole).trim();
109
- return v || "";
110
- }, [newRole, customRole]);
111
-
112
- const [skillsList, setSkillsList] = useState<string[]>([]);
113
- const [availableSkills, setAvailableSkills] = useState<string[]>([]);
114
- const [skillsLoading, setSkillsLoading] = useState(false);
115
- const [selectedSkill, setSelectedSkill] = useState<string>("");
116
- const [installingSkill, setInstallingSkill] = useState(false);
117
- const [teamSkillMsg, setTeamSkillMsg] = useState<string>("");
118
- const [teamSkillError, setTeamSkillError] = useState<string>("");
119
-
120
- const teamRecipes = useMemo(() => recipes.filter((r) => r.kind === "team"), [recipes]);
121
-
122
- const toRecipe = useMemo(() => {
123
- const ws = recipes.find((r) => r.id === toId && r.source === "workspace");
124
- return ws ?? recipes.find((r) => r.id === toId) ?? null;
125
- }, [recipes, toId]);
126
-
127
- const teamIdValid = Boolean(teamId.trim());
128
- const targetIdValid = Boolean(toId.trim());
129
- const hasWorkspaceOverride = recipes.some((r) => r.id === toId && r.source === "workspace");
130
- const targetIsBuiltin = Boolean(toRecipe?.source === "builtin" && !hasWorkspaceOverride);
131
- const canEditTargetId = true;
132
-
133
- useEffect(() => {
134
- setToId(teamId);
135
- setToName(teamId);
136
- setContent("");
137
- setLoadedRecipeHash(null);
138
- setTeamMetaRecipeHash(null);
139
- setPublishOpen(false);
140
- setDeleteOpen(false);
141
- const valid: TabId[] = ["recipe", "agents", "skills", "cron", "files", "memory", "orchestrator", "workflows"];
142
- if (initialTab && valid.includes(initialTab as TabId)) {
143
- setActiveTab(initialTab as TabId);
144
- }
145
- }, [teamId, initialTab]);
146
-
147
- useEffect(() => {
148
- let cancelled = false;
149
- setLoading(true);
150
- loadTeamEditorInitial(teamId, {
151
- setRecipes,
152
- setLockedFromId,
153
- setLockedFromName,
154
- setProvenanceMissing,
155
- setFromId,
156
- setTeamMetaRecipeHash,
157
- setTeamFiles,
158
- setCronJobs,
159
- setTeamAgents,
160
- setSkillsList,
161
- setAvailableSkills,
162
- setSelectedSkill,
163
- setTeamFilesLoading,
164
- setCronLoading,
165
- setTeamAgentsLoading,
166
- setSkillsLoading,
167
- })
168
- .then(() => {
169
- if (!cancelled) setLoading(false);
170
- })
171
- .catch((e: unknown) => {
172
- flashMessage(errorMessage(e), "error");
173
- if (!cancelled) setLoading(false);
174
- });
175
- return () => {
176
- cancelled = true;
177
- };
178
- // eslint-disable-next-line react-hooks/exhaustive-deps -- Initial load only; flashMessage and setters are stable.
179
- }, [teamId]);
180
-
181
- async function onLoadTeamRecipeMarkdown() {
182
- const id = toId.trim();
183
- if (!id) return;
184
- setLoadingSource(true);
185
- setRecipeLoadError("");
186
- try {
187
- const json = await fetchJson<{ recipe?: RecipeDetail; recipeHash?: string }>(`/api/recipes/${encodeURIComponent(id)}`, {
188
- cache: "no-store",
189
- });
190
- const r = json.recipe as RecipeDetail;
191
- setContent(r.content);
192
- setLoadedRecipeHash(typeof json.recipeHash === "string" ? json.recipeHash : null);
193
- } catch (e: unknown) {
194
- setRecipeLoadError(errorMessage(e));
195
- } finally {
196
- setLoadingSource(false);
197
- }
198
- }
199
-
200
- useEffect(() => {
201
- const id = toId.trim();
202
- if (!id) return;
203
- if (content.trim()) return;
204
- if (loadingSource) return;
205
- void onLoadTeamRecipeMarkdown();
206
- // eslint-disable-next-line react-hooks/exhaustive-deps -- Sync toId to load; onLoadTeamRecipeMarkdown and content are intentionally omitted.
207
- }, [toId]);
208
-
209
- async function ensureCustomRecipeExists(args: { overwrite: boolean; toId?: string; toName?: string; scaffold?: boolean }) {
210
- const f = fromId.trim();
211
- const id = String(args.toId ?? toId).trim();
212
- const name = String(args.toName ?? toName).trim();
213
- const overwrite = Boolean(args.overwrite);
214
- const scaffold = Boolean(args.scaffold);
215
- if (!f) throw new Error("Source recipe id is required");
216
- if (!id) throw new Error("Custom recipe id is required");
217
- const json = await fetchJson<{ filePath: string; content: string; scaffold?: { ok: boolean; error?: string } | null }>(
218
- "/api/recipes/clone",
219
- {
220
- method: "POST",
221
- headers: { "content-type": "application/json" },
222
- body: JSON.stringify({ fromId: f, toId: id, toName: name || undefined, overwrite, scaffold }),
223
- }
224
- );
225
- return json;
226
- }
227
-
228
- async function onSaveCustom(overwrite: boolean, overrides?: { toId?: string; toName?: string; scaffold?: boolean }) {
229
- setSaving(true);
230
- flashMessage("");
231
- try {
232
- const json = await ensureCustomRecipeExists({ overwrite, ...overrides });
233
- if (json.scaffold && !json.scaffold.ok) {
234
- flashMessage(`Scaffold failed (recipe was still cloned): ${json.scaffold.error || "Unknown error"}`, "error");
235
- }
236
- const hasEdits = Boolean(content.trim()) && content.trim() !== json.content.trim();
237
- if (hasEdits) {
238
- const nextContent = forceFrontmatterTeamTeamId(forceFrontmatterId(content, toId.trim()), toId.trim());
239
- await fetchJson(`/api/recipes/${encodeURIComponent(toId.trim())}`, {
240
- method: "PUT",
241
- headers: { "content-type": "application/json" },
242
- body: JSON.stringify({ content: nextContent }),
243
- });
244
- setContent(nextContent);
245
- } else {
246
- setContent(json.content);
247
- }
248
- try {
249
- const next = await fetchJson<{ recipeHash?: string }>(`/api/recipes/${encodeURIComponent(toId.trim())}`, {
250
- cache: "no-store",
251
- });
252
- if (typeof next.recipeHash === "string") setLoadedRecipeHash(next.recipeHash);
253
- } catch {
254
- setLoadedRecipeHash(null);
255
- }
256
- flashMessage(`Saved team recipe: ${json.filePath}`, "success");
257
- } catch (e: unknown) {
258
- flashMessage(errorMessage(e), "error");
259
- } finally {
260
- setSaving(false);
261
- }
262
- }
263
-
264
- async function onLoadTeamFile(name: string) {
265
- setSaving(true);
266
- setTeamFileError("");
267
- try {
268
- const json = await fetchJson<{ ok?: boolean; content?: string }>(
269
- `/api/teams/file?teamId=${encodeURIComponent(teamId)}&name=${encodeURIComponent(name)}`,
270
- { cache: "no-store" }
271
- );
272
- if (!json.ok) throw new Error("Failed to load file");
273
- setFileName(name);
274
- setFileContent(String(json.content ?? ""));
275
- } catch (e: unknown) {
276
- setTeamFileError(errorMessage(e));
277
- } finally {
278
- setSaving(false);
279
- }
280
- }
281
-
282
- async function onSaveTeamFile() {
283
- setSaving(true);
284
- setTeamFileError("");
285
- try {
286
- const json = await fetchJson<{ ok?: boolean }>("/api/teams/file", {
287
- method: "PUT",
288
- headers: { "content-type": "application/json" },
289
- body: JSON.stringify({ teamId, name: fileName, content: fileContent }),
290
- });
291
- if (!json.ok) throw new Error("Failed to save file");
292
- } catch (e: unknown) {
293
- setTeamFileError(errorMessage(e));
294
- } finally {
295
- setSaving(false);
296
- }
297
- }
298
-
299
- async function onAddAgent() {
300
- setSaving(true);
301
- try {
302
- await handleAddAgentToTeam({
303
- teamId,
304
- toId,
305
- newRole,
306
- derivedRole,
307
- newRoleName,
308
- content,
309
- setContent,
310
- setTeamAgents,
311
- flashMessage,
312
- ensureCustomRecipeExists,
313
- });
314
- } catch (e: unknown) {
315
- flashMessage(errorMessage(e), "error");
316
- } finally {
317
- setSaving(false);
318
- }
319
- }
320
-
321
- async function onCronAction(id: string, label: string, action: "enable" | "disable" | "run") {
322
- setSaving(true);
323
- try {
324
- await fetchJson("/api/cron/job", {
325
- method: "POST",
326
- headers: { "content-type": "application/json" },
327
- body: JSON.stringify({ id, action }),
328
- });
329
- flashMessage(`Cron ${action}: ${label}`, "success");
330
- } catch (e: unknown) {
331
- flashMessage(errorMessage(e), "error");
332
- } finally {
333
- setSaving(false);
334
- }
335
- }
336
-
337
- async function onInstallSkill() {
338
- setInstallingSkill(true);
339
- setTeamSkillMsg("");
340
- setTeamSkillError("");
341
- try {
342
- await fetchJson("/api/teams/skills/install", {
343
- method: "POST",
344
- headers: { "content-type": "application/json" },
345
- body: JSON.stringify({ teamId, skill: selectedSkill }),
346
- });
347
- setTeamSkillMsg(`Installed skill: ${selectedSkill}`);
348
- try {
349
- const j = await fetchJson<{ ok?: boolean; skills?: string[] }>(
350
- `/api/teams/skills?teamId=${encodeURIComponent(teamId)}`,
351
- { cache: "no-store" }
352
- );
353
- if (j.ok && Array.isArray(j.skills)) setSkillsList(j.skills);
354
- } catch {
355
- // ignore
356
- }
357
- } catch (e: unknown) {
358
- setTeamSkillError(errorMessage(e));
359
- } finally {
360
- setInstallingSkill(false);
361
- }
362
- }
363
-
364
- return (
365
- <div className="ck-glass w-full p-6 sm:p-8">
366
- <h1 className="text-2xl font-semibold tracking-tight">Team editor</h1>
367
- <p className="mt-2 text-sm text-[color:var(--ck-text-secondary)]">
368
- Bootstrap a <strong>custom team recipe</strong> for this installed team, without modifying builtin recipes.
369
- </p>
370
-
371
-
372
- <div className="mt-6 flex flex-wrap gap-2">
373
- {TABS.map((t) => (
374
- <button
375
- key={t.id}
376
- onClick={() => setActiveTab(t.id as TabId)}
377
- className={
378
- activeTab === t.id
379
- ? "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)]"
380
- : "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"
381
- }
382
- >
383
- {t.label}
384
- </button>
385
- ))}
386
- </div>
387
-
388
- {activeTab === "recipe" && (
389
- <TeamRecipeTab
390
- loading={loading}
391
- fromId={fromId}
392
- setFromId={setFromId}
393
- toId={toId}
394
- setToId={setToId}
395
- toName={toName}
396
- setToName={setToName}
397
- canEditTargetId={canEditTargetId}
398
- teamRecipes={teamRecipes}
399
- lockedFromId={lockedFromId}
400
- lockedFromName={lockedFromName}
401
- provenanceMissing={provenanceMissing}
402
- saving={saving}
403
- teamIdValid={teamIdValid}
404
- targetIdValid={targetIdValid}
405
- targetIsBuiltin={targetIsBuiltin}
406
- loadedRecipeHash={loadedRecipeHash}
407
- teamMetaRecipeHash={teamMetaRecipeHash}
408
- publishing={publishing}
409
- content={content}
410
- setContent={setContent}
411
- setLoadedRecipeHash={setLoadedRecipeHash}
412
- recipeLoadError={recipeLoadError}
413
- onSaveCustom={onSaveCustom}
414
- onPublishOpen={() => setPublishOpen(true)}
415
- onDeleteOpen={() => setDeleteOpen(true)}
416
- />
417
- )}
418
-
419
- {activeTab === "agents" && (
420
- <TeamAgentsTab
421
- teamId={teamId}
422
- toId={toId}
423
- recipeAgents={recipeAgents}
424
- newRole={newRole}
425
- setNewRole={setNewRole}
426
- customRole={customRole}
427
- setCustomRole={setCustomRole}
428
- newRoleName={newRoleName}
429
- setNewRoleName={setNewRoleName}
430
- derivedRole={derivedRole}
431
- saving={saving}
432
- teamAgents={teamAgents}
433
- teamAgentsLoading={teamAgentsLoading}
434
- onAddAgent={onAddAgent}
435
- />
436
- )}
437
-
438
- {activeTab === "skills" && (
439
- <TeamSkillsTab
440
- teamId={teamId}
441
- skillsList={skillsList}
442
- availableSkills={availableSkills}
443
- skillsLoading={skillsLoading}
444
- selectedSkill={selectedSkill}
445
- setSelectedSkill={setSelectedSkill}
446
- installingSkill={installingSkill}
447
- teamSkillMsg={teamSkillMsg}
448
- teamSkillError={teamSkillError}
449
- onInstallSkill={onInstallSkill}
450
- />
451
- )}
452
-
453
- {activeTab === "cron" && (
454
- <TeamCronTab
455
- cronJobs={cronJobs}
456
- cronLoading={cronLoading}
457
- saving={saving}
458
- onCronAction={onCronAction}
459
- />
460
- )}
461
-
462
- {activeTab === "workflows" && (
463
- <div className="mt-6">
464
- <WorkflowsClient teamId={teamId} />
465
- </div>
466
- )}
467
-
468
- {activeTab === "orchestrator" && <OrchestratorPanel teamId={teamId} />}
469
-
470
- {activeTab === "memory" && (
471
- <div className="mt-6">
472
- <TeamMemoryTab teamId={teamId} />
473
- </div>
474
- )}
475
-
476
- {activeTab === "files" && (
477
- <TeamFilesTab
478
- teamFiles={teamFiles}
479
- teamFilesLoading={teamFilesLoading}
480
- showOptionalFiles={showOptionalFiles}
481
- setShowOptionalFiles={setShowOptionalFiles}
482
- fileName={fileName}
483
- fileContent={fileContent}
484
- setFileContent={setFileContent}
485
- teamFileError={teamFileError}
486
- saving={saving}
487
- onLoadTeamFile={onLoadTeamFile}
488
- onSaveTeamFile={onSaveTeamFile}
489
- />
490
- )}
491
-
492
- <PublishChangesModal
493
- open={publishOpen}
494
- teamId={teamId}
495
- recipeId={toId}
496
- busy={publishing}
497
- onClose={() => setPublishOpen(false)}
498
- onConfirm={async () => {
499
- setPublishing(true);
500
- try {
501
- await fetchJson("/api/scaffold", {
502
- method: "POST",
503
- headers: { "content-type": "application/json" },
504
- body: JSON.stringify({
505
- kind: "team",
506
- recipeId: toId.trim(),
507
- teamId,
508
- overwrite: true,
509
- applyConfig: true,
510
- }),
511
- });
512
- try {
513
- const metaJson = await fetchJson<{ ok?: boolean; meta?: { recipeHash?: string } }>(
514
- `/api/teams/meta?teamId=${encodeURIComponent(teamId)}`,
515
- { cache: "no-store" }
516
- );
517
- if (metaJson.ok && metaJson.meta && typeof metaJson.meta.recipeHash === "string") {
518
- setTeamMetaRecipeHash(metaJson.meta.recipeHash);
519
- }
520
- } catch {
521
- // ignore
522
- }
523
- setPublishOpen(false);
524
- flashMessage("Published changes to active team", "success");
525
- } catch (e: unknown) {
526
- flashMessage(errorMessage(e), "error");
527
- } finally {
528
- setPublishing(false);
529
- }
530
- }}
531
- />
532
-
533
- <DeleteTeamModal
534
- open={deleteOpen}
535
- teamId={teamId}
536
- busy={deleting}
537
- onClose={() => setDeleteOpen(false)}
538
- onConfirm={async () => {
539
- setDeleting(true);
540
- try {
541
- await fetchJson("/api/teams/remove-team", {
542
- method: "POST",
543
- headers: { "content-type": "application/json" },
544
- body: JSON.stringify({ teamId }),
545
- });
546
- flashMessage("Deleted team successfully", "success");
547
- setDeleteOpen(false);
548
- setTimeout(() => router.push("/"), 250);
549
- } catch (e: unknown) {
550
- flashMessage(errorMessage(e), "error");
551
- } finally {
552
- setDeleting(false);
553
- }
554
- }}
555
- />
556
- </div>
557
- );
558
- }