@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,95 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from "vitest";
2
- import { POST } from "../agents/update/route";
3
-
4
- vi.mock("@/lib/gateway", () => ({
5
- gatewayConfigGet: vi.fn(),
6
- gatewayConfigPatch: vi.fn(),
7
- }));
8
-
9
- import { gatewayConfigGet, gatewayConfigPatch } from "@/lib/gateway";
10
-
11
- describe("api agents update route", () => {
12
- const cfgWithAgent = {
13
- agents: {
14
- list: [
15
- { id: "agent-1", workspace: "/ws", model: "gpt-4", identity: { name: "Old", emoji: "🧑" } },
16
- ],
17
- },
18
- };
19
-
20
- beforeEach(() => {
21
- vi.mocked(gatewayConfigGet).mockReset();
22
- vi.mocked(gatewayConfigPatch).mockReset();
23
-
24
- vi.mocked(gatewayConfigGet).mockResolvedValue({
25
- raw: JSON.stringify(cfgWithAgent),
26
- hash: "abc",
27
- });
28
- vi.mocked(gatewayConfigPatch).mockResolvedValue(undefined);
29
- });
30
-
31
- it("throws when agentId missing", async () => {
32
- await expect(
33
- POST(
34
- new Request("https://test", {
35
- method: "POST",
36
- body: JSON.stringify({ agentId: " " }),
37
- })
38
- )
39
- ).rejects.toThrow("agentId is required");
40
- });
41
-
42
- it("returns 404 when agent not in config", async () => {
43
- const res = await POST(
44
- new Request("https://test", {
45
- method: "POST",
46
- body: JSON.stringify({ agentId: "missing" }),
47
- })
48
- );
49
- expect(res.status).toBe(404);
50
- const json = await res.json();
51
- expect(json.error).toContain("Agent not found");
52
- });
53
-
54
- it("returns ok and patches config on success", async () => {
55
- const res = await POST(
56
- new Request("https://test", {
57
- method: "POST",
58
- body: JSON.stringify({
59
- agentId: "agent-1",
60
- patch: {
61
- workspace: " /new/ws ",
62
- model: "gpt-4o",
63
- identity: { name: "New Name", theme: "dark", emoji: "🤖", avatar: "x" },
64
- },
65
- }),
66
- })
67
- );
68
- expect(res.status).toBe(200);
69
- const json = await res.json();
70
- expect(json.ok).toBe(true);
71
- expect(json.agentId).toBe("agent-1");
72
-
73
- expect(gatewayConfigPatch).toHaveBeenCalled();
74
- const [patch] = vi.mocked(gatewayConfigPatch).mock.calls[0];
75
- expect(patch.agents.list[0].workspace).toBe("/new/ws");
76
- expect(patch.agents.list[0].model).toBe("gpt-4o");
77
- expect(patch.agents.list[0].identity).toMatchObject({
78
- name: "New Name",
79
- theme: "dark",
80
- emoji: "🤖",
81
- avatar: "x",
82
- });
83
- });
84
-
85
- it("finds agent case-insensitively", async () => {
86
- const res = await POST(
87
- new Request("https://test", {
88
- method: "POST",
89
- body: JSON.stringify({ agentId: "AGENT-1", patch: {} }),
90
- })
91
- );
92
- expect(res.status).toBe(200);
93
- expect(gatewayConfigPatch).toHaveBeenCalled();
94
- });
95
- });
@@ -1,143 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from "vitest";
2
- import { GET, PUT, DELETE } from "../channels/bindings/route";
3
-
4
- vi.mock("@/lib/gateway", () => ({
5
- gatewayConfigGet: vi.fn(),
6
- gatewayConfigPatch: vi.fn(),
7
- }));
8
-
9
- import { gatewayConfigGet, gatewayConfigPatch } from "@/lib/gateway";
10
-
11
- describe("api channels bindings route", () => {
12
- beforeEach(() => {
13
- vi.mocked(gatewayConfigGet).mockReset();
14
- vi.mocked(gatewayConfigPatch).mockReset();
15
-
16
- vi.mocked(gatewayConfigGet).mockResolvedValue({
17
- raw: JSON.stringify({ channels: { telegram: { botToken: "x" } } }),
18
- hash: "abc",
19
- });
20
- vi.mocked(gatewayConfigPatch).mockResolvedValue(undefined);
21
- });
22
-
23
- describe("GET", () => {
24
- it("returns channels and hash", async () => {
25
- const res = await GET();
26
- expect(res.status).toBe(200);
27
- const json = await res.json();
28
- expect(json.ok).toBe(true);
29
- expect(json.channels).toEqual({ telegram: { botToken: "x" } });
30
- expect(json.hash).toBe("abc");
31
- });
32
-
33
- it("returns empty channels when invalid JSON", async () => {
34
- vi.mocked(gatewayConfigGet).mockResolvedValue({
35
- raw: "not json",
36
- hash: "x",
37
- });
38
- const res = await GET();
39
- expect(res.status).toBe(200);
40
- const json = await res.json();
41
- expect(json.channels).toEqual({});
42
- });
43
-
44
- it("returns 500 when gateway throws", async () => {
45
- vi.mocked(gatewayConfigGet).mockRejectedValue(new Error("Gateway error"));
46
- const res = await GET();
47
- expect(res.status).toBe(500);
48
- });
49
- });
50
-
51
- describe("PUT", () => {
52
- it("returns 400 when provider or config missing", async () => {
53
- const r1 = await PUT(
54
- new Request("https://test", { method: "PUT", body: JSON.stringify({}) })
55
- );
56
- expect(r1.status).toBe(400);
57
- expect((await r1.json()).error).toBe("provider is required");
58
-
59
- const r2 = await PUT(
60
- new Request("https://test", {
61
- method: "PUT",
62
- body: JSON.stringify({ provider: "tg", config: "not-object" }),
63
- })
64
- );
65
- expect(r2.status).toBe(400);
66
- expect((await r2.json()).error).toBe("config must be an object");
67
- });
68
-
69
- it("returns 400 when telegram config lacks botToken", async () => {
70
- const res = await PUT(
71
- new Request("https://test", {
72
- method: "PUT",
73
- body: JSON.stringify({ provider: "telegram", config: {} }),
74
- })
75
- );
76
- expect(res.status).toBe(400);
77
- expect((await res.json()).error).toBe("telegram.botToken is required");
78
- });
79
-
80
- it("returns ok and patches on success", async () => {
81
- const res = await PUT(
82
- new Request("https://test", {
83
- method: "PUT",
84
- body: JSON.stringify({
85
- provider: "telegram",
86
- config: { botToken: "secret" },
87
- }),
88
- })
89
- );
90
- expect(res.status).toBe(200);
91
- expect(gatewayConfigPatch).toHaveBeenCalledWith(
92
- { channels: { telegram: { botToken: "secret" } } },
93
- expect.stringContaining("telegram")
94
- );
95
- });
96
-
97
- it("returns 500 when gatewayConfigPatch throws", async () => {
98
- vi.mocked(gatewayConfigPatch).mockRejectedValue(new Error("Gateway error"));
99
- const res = await PUT(
100
- new Request("https://test", {
101
- method: "PUT",
102
- body: JSON.stringify({ provider: "slack", config: {} }),
103
- })
104
- );
105
- expect(res.status).toBe(500);
106
- expect((await res.json()).error).toBe("Gateway error");
107
- });
108
- });
109
-
110
- describe("DELETE", () => {
111
- it("returns 400 when provider missing", async () => {
112
- const res = await DELETE(
113
- new Request("https://test", { method: "DELETE", body: JSON.stringify({}) })
114
- );
115
- expect(res.status).toBe(400);
116
- });
117
-
118
- it("returns ok and patches provider to null", async () => {
119
- const res = await DELETE(
120
- new Request("https://test", {
121
- method: "DELETE",
122
- body: JSON.stringify({ provider: "telegram" }),
123
- })
124
- );
125
- expect(res.status).toBe(200);
126
- expect(gatewayConfigPatch).toHaveBeenCalledWith(
127
- { channels: { telegram: null } },
128
- expect.stringContaining("telegram")
129
- );
130
- });
131
-
132
- it("returns 500 when gatewayConfigPatch throws", async () => {
133
- vi.mocked(gatewayConfigPatch).mockRejectedValue(new Error("Gateway error"));
134
- const res = await DELETE(
135
- new Request("https://test", {
136
- method: "DELETE",
137
- body: JSON.stringify({ provider: "telegram" }),
138
- })
139
- );
140
- expect(res.status).toBe(500);
141
- });
142
- });
143
- });
@@ -1,93 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from "vitest";
2
- import { POST } from "../cron/delete/route";
3
-
4
- vi.mock("@/lib/gateway", () => ({ toolsInvoke: vi.fn() }));
5
- vi.mock("node:fs/promises", () => ({
6
- default: {
7
- readdir: vi.fn(),
8
- stat: vi.fn(),
9
- readFile: vi.fn(),
10
- writeFile: vi.fn(),
11
- },
12
- }));
13
-
14
- import { toolsInvoke } from "@/lib/gateway";
15
- import fs from "node:fs/promises";
16
-
17
- describe("api cron delete route", () => {
18
- beforeEach(() => {
19
- vi.mocked(toolsInvoke).mockReset();
20
- vi.mocked(fs.readdir).mockReset();
21
- vi.mocked(fs.stat).mockReset();
22
- vi.mocked(fs.readFile).mockReset();
23
- vi.mocked(fs.writeFile).mockReset();
24
- });
25
-
26
- it("returns 400 when id missing", async () => {
27
- const res = await POST(
28
- new Request("https://test", { method: "POST", body: JSON.stringify({}) })
29
- );
30
- expect(res.status).toBe(400);
31
- const json = await res.json();
32
- expect(json.error).toBe("id is required");
33
- });
34
-
35
- it("returns 200 and invokes cron remove", async () => {
36
- vi.mocked(toolsInvoke).mockResolvedValue({ ok: true });
37
-
38
- const res = await POST(
39
- new Request("https://test", { method: "POST", body: JSON.stringify({ id: "job-1" }) })
40
- );
41
- expect(res.status).toBe(200);
42
- const json = await res.json();
43
- expect(json.ok).toBe(true);
44
- expect(json.id).toBe("job-1");
45
- expect(toolsInvoke).toHaveBeenCalledWith({ tool: "cron", args: { action: "remove", jobId: "job-1" } });
46
- });
47
-
48
- it("marks orphaned entries in cron-jobs.json when mapping references job", async () => {
49
- const baseHome = "/mock/base";
50
- vi.mocked(toolsInvoke)
51
- .mockResolvedValueOnce({ ok: true })
52
- .mockResolvedValueOnce({
53
- content: [
54
- {
55
- type: "text",
56
- text: JSON.stringify({
57
- result: {
58
- raw: JSON.stringify({
59
- agents: { defaults: { workspace: baseHome + "/agents" } },
60
- }),
61
- },
62
- }),
63
- },
64
- ],
65
- });
66
- vi.mocked(fs.readdir).mockResolvedValue([
67
- { name: "workspace-team1", isDirectory: () => true } as never,
68
- ]);
69
- vi.mocked(fs.stat).mockResolvedValue({} as never);
70
- vi.mocked(fs.readFile).mockResolvedValue(
71
- JSON.stringify({
72
- version: 1,
73
- entries: {
74
- "recipe-1": { installedCronId: "job-1", orphaned: false },
75
- "recipe-2": { installedCronId: "other", orphaned: false },
76
- },
77
- })
78
- );
79
- vi.mocked(fs.writeFile).mockResolvedValue(undefined);
80
-
81
- const res = await POST(
82
- new Request("https://test", { method: "POST", body: JSON.stringify({ id: "job-1" }) })
83
- );
84
- expect(res.status).toBe(200);
85
- const json = await res.json();
86
- expect(json.orphanedIn).toHaveLength(1);
87
- expect(json.orphanedIn[0].teamId).toBe("team1");
88
- expect(json.orphanedIn[0].keys).toContain("recipe-1");
89
- expect(fs.writeFile).toHaveBeenCalled();
90
- const written = JSON.parse(vi.mocked(fs.writeFile).mock.calls[0][1] as string);
91
- expect(written.entries["recipe-1"].orphaned).toBe(true);
92
- });
93
- });
@@ -1,78 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from "vitest";
2
- import { POST } from "../cron/job/route";
3
-
4
- vi.mock("@/lib/gateway", () => ({ toolsInvoke: vi.fn() }));
5
-
6
- import { toolsInvoke } from "@/lib/gateway";
7
-
8
- describe("api cron job route", () => {
9
- beforeEach(() => {
10
- vi.mocked(toolsInvoke).mockReset();
11
- vi.mocked(toolsInvoke).mockResolvedValue({ ok: true });
12
- });
13
-
14
- it("returns 400 when id or action missing", async () => {
15
- const r1 = await POST(
16
- new Request("https://test", {
17
- method: "POST",
18
- body: JSON.stringify({ action: "enable" }),
19
- })
20
- );
21
- expect(r1.status).toBe(400);
22
- expect((await r1.json()).error).toBe("id is required");
23
-
24
- const r2 = await POST(
25
- new Request("https://test", {
26
- method: "POST",
27
- body: JSON.stringify({ id: "job-1", action: "invalid" }),
28
- })
29
- );
30
- expect(r2.status).toBe(400);
31
- expect((await r2.json()).error).toBe("action must be enable|disable|run");
32
- });
33
-
34
- it("calls toolsInvoke for enable", async () => {
35
- const res = await POST(
36
- new Request("https://test", {
37
- method: "POST",
38
- body: JSON.stringify({ id: "job-1", action: "enable" }),
39
- })
40
- );
41
- expect(res.status).toBe(200);
42
- expect(toolsInvoke).toHaveBeenCalledWith({
43
- tool: "cron",
44
- args: { action: "update", jobId: "job-1", patch: { enabled: true } },
45
- });
46
- });
47
-
48
- it("calls toolsInvoke for disable", async () => {
49
- const res = await POST(
50
- new Request("https://test", {
51
- method: "POST",
52
- body: JSON.stringify({ id: "job-1", action: "disable" }),
53
- })
54
- );
55
- expect(res.status).toBe(200);
56
- expect(toolsInvoke).toHaveBeenCalledWith({
57
- tool: "cron",
58
- args: { action: "update", jobId: "job-1", patch: { enabled: false } },
59
- });
60
- });
61
-
62
- it("calls toolsInvoke for run", async () => {
63
- vi.mocked(toolsInvoke).mockResolvedValue({ ok: true, result: { ran: true } });
64
- const res = await POST(
65
- new Request("https://test", {
66
- method: "POST",
67
- body: JSON.stringify({ id: "job-1", action: "run" }),
68
- })
69
- );
70
- expect(res.status).toBe(200);
71
- expect(toolsInvoke).toHaveBeenCalledWith({
72
- tool: "cron",
73
- args: { action: "run", jobId: "job-1" },
74
- });
75
- const json = await res.json();
76
- expect(json.result).toEqual({ ok: true, result: { ran: true } });
77
- });
78
- });
@@ -1,116 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from "vitest";
2
- import { GET } from "../cron/jobs/route";
3
-
4
- vi.mock("@/lib/gateway", async (importOriginal) => {
5
- const actual = await importOriginal<typeof import("@/lib/gateway")>();
6
- return { ...actual, toolsInvoke: vi.fn() };
7
- });
8
- vi.mock("@/lib/paths", async (importOriginal) => {
9
- const actual = await importOriginal<typeof import("@/lib/paths")>();
10
- return {
11
- ...actual,
12
- getTeamWorkspaceDir: vi.fn(),
13
- readOpenClawConfig: vi.fn().mockResolvedValue({ agents: { defaults: { workspace: "/home/test/.openclaw/agents" } } }),
14
- };
15
- });
16
- vi.mock("@/lib/openclaw", () => ({ runOpenClaw: vi.fn().mockResolvedValue({ ok: true, stdout: "[]" }) }));
17
- vi.mock("node:fs/promises", () => ({
18
- default: {
19
- readFile: vi.fn(),
20
- readdir: vi.fn().mockResolvedValue([]),
21
- stat: vi.fn(),
22
- },
23
- }));
24
-
25
- import { toolsInvoke } from "@/lib/gateway";
26
- import { getTeamWorkspaceDir } from "@/lib/paths";
27
- import fs from "node:fs/promises";
28
-
29
- describe("api cron jobs route", () => {
30
- beforeEach(() => {
31
- vi.mocked(toolsInvoke).mockReset();
32
- vi.mocked(getTeamWorkspaceDir).mockReset();
33
- vi.mocked(fs.readFile).mockReset();
34
- vi.mocked(fs.readdir).mockReset();
35
- vi.mocked(fs.readdir).mockResolvedValue([]);
36
- });
37
-
38
- it("returns empty jobs when toolsInvoke has no text", async () => {
39
- vi.mocked(toolsInvoke).mockResolvedValue({ content: [] });
40
-
41
- const res = await GET(new Request("https://test"));
42
- expect(res.status).toBe(200);
43
- const json = await res.json();
44
- expect(json.ok).toBe(true);
45
- expect(json.jobs).toEqual([]);
46
- });
47
-
48
- it("returns jobs when no teamId", async () => {
49
- const jobs = [{ id: "j1", name: "Job 1" }];
50
- vi.mocked(toolsInvoke).mockResolvedValue({
51
- content: [{ type: "text", text: JSON.stringify({ jobs }) }],
52
- });
53
-
54
- const res = await GET(new Request("https://test"));
55
- expect(res.status).toBe(200);
56
- const json = await res.json();
57
- expect(json.ok).toBe(true);
58
- expect(json.jobs).toEqual(jobs);
59
- });
60
-
61
- it("filters by team when teamId provided", async () => {
62
- const allJobs = [
63
- { id: "j1" },
64
- { id: "j2" },
65
- { id: "j3" },
66
- ];
67
- vi.mocked(toolsInvoke).mockResolvedValue({
68
- content: [{ type: "text", text: JSON.stringify({ jobs: allJobs }) }],
69
- });
70
- vi.mocked(getTeamWorkspaceDir).mockResolvedValue("/home/x/.openclaw/workspace-my-team");
71
- vi.mocked(fs.readFile).mockResolvedValue(
72
- JSON.stringify({
73
- entries: {
74
- a: { installedCronId: "j1", orphaned: false },
75
- b: { installedCronId: "j3", orphaned: false },
76
- c: { installedCronId: "j99", orphaned: true },
77
- },
78
- })
79
- );
80
-
81
- const res = await GET(
82
- new Request("https://test?teamId=my-team")
83
- );
84
- expect(res.status).toBe(200);
85
- const json = await res.json();
86
- expect(json.ok).toBe(true);
87
- expect(json.jobs).toHaveLength(2);
88
- expect(json.jobs.map((j: { id: string }) => j.id)).toEqual(["j1", "j3"]);
89
- expect(json.installedIds).toEqual(["j1", "j3"]);
90
- });
91
-
92
- it("returns empty filtered jobs when provenance file missing", async () => {
93
- vi.mocked(toolsInvoke).mockResolvedValue({
94
- content: [{ type: "text", text: JSON.stringify({ jobs: [{ id: "j1" }] }) }],
95
- });
96
- vi.mocked(getTeamWorkspaceDir).mockResolvedValue("/home/x/.openclaw/workspace-t");
97
- vi.mocked(fs.readFile).mockRejectedValue(new Error("ENOENT"));
98
-
99
- const res = await GET(
100
- new Request("https://test?teamId=my-team")
101
- );
102
- expect(res.status).toBe(200);
103
- const json = await res.json();
104
- expect(json.jobs).toEqual([]);
105
- expect(json.installedIds).toEqual([]);
106
- });
107
-
108
- it("returns 500 when toolsInvoke throws", async () => {
109
- vi.mocked(toolsInvoke).mockRejectedValue(new Error("Gateway unavailable"));
110
-
111
- const res = await GET(new Request("https://test"));
112
- expect(res.status).toBe(500);
113
- const json = await res.json();
114
- expect(json.error).toBe("Gateway unavailable");
115
- });
116
- });
@@ -1,114 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach } from "vitest";
2
- import { GET } from "../cron/recipe-installed/route";
3
-
4
- vi.mock("@/lib/gateway", async (importOriginal) => {
5
- const actual = await importOriginal<typeof import("@/lib/gateway")>();
6
- return { ...actual, toolsInvoke: vi.fn() };
7
- });
8
- vi.mock("node:fs/promises", () => ({ default: { readFile: vi.fn() } }));
9
-
10
- import { toolsInvoke } from "@/lib/gateway";
11
- import fs from "node:fs/promises";
12
-
13
- describe("api cron recipe-installed route", () => {
14
- const baseWorkspace = "/home/x/.openclaw/agents";
15
- const gatewayConfigResponse = {
16
- content: [
17
- {
18
- type: "text",
19
- text: JSON.stringify({
20
- result: {
21
- raw: JSON.stringify({
22
- agents: { defaults: { workspace: baseWorkspace } },
23
- }),
24
- },
25
- }),
26
- },
27
- ],
28
- };
29
-
30
- beforeEach(() => {
31
- vi.mocked(toolsInvoke).mockReset();
32
- vi.mocked(fs.readFile).mockReset();
33
-
34
- vi.mocked(toolsInvoke)
35
- .mockResolvedValueOnce(gatewayConfigResponse as never)
36
- .mockResolvedValueOnce({ jobs: [] } as never);
37
- });
38
-
39
- it("returns 400 when teamId missing", async () => {
40
- const res = await GET(new Request("https://test"));
41
- expect(res.status).toBe(400);
42
- const json = await res.json();
43
- expect(json.error).toBe("teamId is required");
44
- });
45
-
46
- it("returns 500 when gateway config has no text", async () => {
47
- vi.mocked(toolsInvoke).mockReset();
48
- vi.mocked(toolsInvoke).mockResolvedValue({ content: [] } as never);
49
-
50
- const res = await GET(
51
- new Request("https://test?teamId=my-team")
52
- );
53
- expect(res.status).toBe(500);
54
- expect((await res.json()).error).toBe("Failed to fetch config via gateway");
55
- });
56
-
57
- it("returns 500 when workspace not set", async () => {
58
- vi.mocked(toolsInvoke).mockReset();
59
- vi.mocked(toolsInvoke).mockResolvedValue({
60
- content: [{ type: "text", text: JSON.stringify({ result: { raw: "{}" } }) }],
61
- } as never);
62
-
63
- const res = await GET(
64
- new Request("https://test?teamId=my-team")
65
- );
66
- expect(res.status).toBe(500);
67
- expect((await res.json()).error).toBe("agents.defaults.workspace not set");
68
- });
69
-
70
- it("returns jobs filtered by mapping", async () => {
71
- vi.mocked(fs.readFile).mockResolvedValue(
72
- JSON.stringify({
73
- version: 1,
74
- entries: {
75
- r1: { installedCronId: "cron-1", orphaned: false },
76
- r2: { installedCronId: "cron-2", orphaned: false },
77
- },
78
- })
79
- );
80
- vi.mocked(toolsInvoke)
81
- .mockReset()
82
- .mockResolvedValueOnce(gatewayConfigResponse as never)
83
- .mockResolvedValueOnce({
84
- jobs: [
85
- { id: "cron-1", name: "J1" },
86
- { id: "cron-2", name: "J2" },
87
- { id: "cron-3", name: "J3" },
88
- ],
89
- } as never);
90
-
91
- const res = await GET(
92
- new Request("https://test?teamId=my-team")
93
- );
94
- expect(res.status).toBe(200);
95
- const json = await res.json();
96
- expect(json.ok).toBe(true);
97
- expect(json.jobCount).toBe(2);
98
- expect(json.jobs).toHaveLength(2);
99
- expect(json.jobs.map((j: { id: string }) => j.id)).toEqual(["cron-1", "cron-2"]);
100
- });
101
-
102
- it("returns empty jobs when mapping file missing", async () => {
103
- vi.mocked(fs.readFile).mockRejectedValue(new Error("ENOENT"));
104
-
105
- const res = await GET(
106
- new Request("https://test?teamId=my-team")
107
- );
108
- expect(res.status).toBe(200);
109
- const json = await res.json();
110
- expect(json.ok).toBe(true);
111
- expect(json.jobs).toEqual([]);
112
- expect(json.jobCount).toBe(0);
113
- });
114
- });
@@ -1,36 +0,0 @@
1
- import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
2
- import { POST } from "../gateway/restart/route";
3
-
4
- vi.mock("@/lib/openclaw", () => ({ runOpenClaw: vi.fn() }));
5
- import { runOpenClaw } from "@/lib/openclaw";
6
-
7
- describe("api gateway restart route", () => {
8
- beforeEach(() => {
9
- vi.useFakeTimers();
10
- vi.mocked(runOpenClaw).mockReset();
11
- });
12
-
13
- afterEach(() => {
14
- vi.useRealTimers();
15
- });
16
-
17
- it("returns 200 and schedules restart", async () => {
18
- vi.mocked(runOpenClaw).mockResolvedValue({ ok: true, exitCode: 0, stdout: "", stderr: "" });
19
-
20
- const res = await POST();
21
- expect(res.status).toBe(200);
22
- const json = await res.json();
23
- expect(json.ok).toBe(true);
24
- expect(json.scheduled).toBe(true);
25
-
26
- expect(runOpenClaw).not.toHaveBeenCalled();
27
- vi.advanceTimersByTime(50);
28
- expect(runOpenClaw).toHaveBeenCalledWith(["gateway", "restart"]);
29
- });
30
-
31
- it("responds immediately before restart runs", async () => {
32
- const res = await POST();
33
- expect(res.status).toBe(200);
34
- expect(runOpenClaw).not.toHaveBeenCalled();
35
- });
36
- });