@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,286 +0,0 @@
1
- "use client";
2
-
3
- import Link from "next/link";
4
- import { usePathname, useRouter } from "next/navigation";
5
- import { useEffect, useMemo, useState } from "react";
6
- import { ErrorBoundary } from "@/components/ErrorBoundary";
7
- import { fetchJson } from "@/lib/fetch-json";
8
- import { ThemeToggle } from "@/components/ThemeToggle";
9
- import { ToastProvider } from "@/components/ToastProvider";
10
-
11
- function Icon({ children }: { children: React.ReactNode }) {
12
- return (
13
- <span
14
- className="grid size-7 place-items-center text-[color:var(--ck-text-secondary)]"
15
- aria-hidden
16
- >
17
- {children}
18
- </span>
19
- );
20
- }
21
-
22
- function SideNavLink({
23
- href,
24
- label,
25
- icon,
26
- active,
27
- collapsed,
28
- }: {
29
- href: string;
30
- label: string;
31
- icon: React.ReactNode;
32
- active: boolean;
33
- collapsed: boolean;
34
- }) {
35
- return (
36
- <Link
37
- href={href}
38
- title={label}
39
- className={
40
- (
41
- active
42
- ? "flex items-center rounded-[var(--ck-radius-sm)] bg-white/10 text-sm font-medium text-[color:var(--ck-text-primary)]"
43
- : "flex items-center rounded-[var(--ck-radius-sm)] text-sm font-medium text-[color:var(--ck-text-secondary)] transition-colors hover:bg-white/5 hover:text-[color:var(--ck-text-primary)]"
44
- ) +
45
- (collapsed ? " justify-center px-0 py-3" : " gap-4 px-4 py-3")
46
- }
47
- >
48
- {icon}
49
- {collapsed ? null : <span>{label}</span>}
50
- </Link>
51
- );
52
- }
53
-
54
- export function AppShell({ children }: { children: React.ReactNode }) {
55
- const pathname = usePathname() || "/";
56
- const router = useRouter();
57
-
58
- const currentTeamId = useMemo(() => {
59
- const m = pathname.match(/^\/teams\/([^/]+)(?:\/|$)/);
60
- return m ? decodeURIComponent(m[1]) : null;
61
- }, [pathname]);
62
-
63
- const [collapsed, setCollapsed] = useState(false);
64
-
65
- // Avoid hydration mismatch: render un-collapsed on the server, then sync from localStorage after mount.
66
- useEffect(() => {
67
- try {
68
- const v = localStorage.getItem("ck-leftnav-collapsed");
69
- // eslint-disable-next-line react-hooks/set-state-in-effect
70
- setCollapsed(v === "1");
71
- } catch {
72
- // ignore
73
- }
74
- }, []);
75
-
76
- function toggleCollapsed() {
77
- setCollapsed((v) => {
78
- const next = !v;
79
- try {
80
- localStorage.setItem("ck-leftnav-collapsed", next ? "1" : "0");
81
- } catch {
82
- // ignore
83
- }
84
- return next;
85
- });
86
- }
87
-
88
- // Minimal team list (for switcher). We rely on existing /api/recipes.
89
- const [teamIds, setTeamIds] = useState<string[]>([]);
90
- useEffect(() => {
91
- (async () => {
92
- try {
93
- const json = await fetchJson<{ agents?: Array<{ workspace?: string }> }>("/api/agents", { cache: "no-store" });
94
- const agents = Array.isArray(json.agents)
95
- ? (json.agents as Array<{ workspace?: string }> )
96
- : [];
97
-
98
- const s = new Set<string>();
99
- for (const a of agents) {
100
- const ws = String(a.workspace ?? "");
101
- const parts = ws.split("/").filter(Boolean);
102
- const wsPart = parts.find((p) => p.startsWith("workspace-")) ?? "";
103
- if (!wsPart) continue;
104
- const teamId = wsPart.slice("workspace-".length);
105
- if (teamId && teamId !== "workspace") s.add(teamId);
106
- }
107
-
108
- setTeamIds(Array.from(s).sort());
109
- } catch {
110
- setTeamIds([]);
111
- }
112
- })();
113
- }, []);
114
-
115
- const globalNav = [
116
- {
117
- href: `/`,
118
- label: "Home",
119
- icon: (
120
- <Icon>
121
- <svg viewBox="0 0 24 24" className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth="2">
122
- <path d="M3 11l9-8 9 8" />
123
- <path d="M5 10v10h14V10" />
124
- </svg>
125
- </Icon>
126
- ),
127
- },
128
- {
129
- href: `/recipes`,
130
- label: "Recipes",
131
- icon: (
132
- <Icon>
133
- <svg viewBox="0 0 24 24" className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth="2">
134
- <path d="M6 4h12v16H6z" />
135
- <path d="M9 8h6" />
136
- <path d="M9 12h6" />
137
- </svg>
138
- </Icon>
139
- ),
140
- },
141
- {
142
- href: `/tickets`,
143
- label: "Tickets",
144
- icon: (
145
- <Icon>
146
- <svg viewBox="0 0 24 24" className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth="2">
147
- <path d="M4 7h16v4a2 2 0 0 1 0 4v4H4v-4a2 2 0 0 0 0-4z" />
148
- </svg>
149
- </Icon>
150
- ),
151
- },
152
- {
153
- href: `/goals`,
154
- label: "Goals",
155
- icon: (
156
- <Icon>
157
- <svg viewBox="0 0 24 24" className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth="2">
158
- <circle cx="12" cy="12" r="9" />
159
- <path d="M12 7v5l3 3" />
160
- </svg>
161
- </Icon>
162
- ),
163
- },
164
- {
165
- href: `/cron-jobs`,
166
- label: "Cron jobs",
167
- icon: (
168
- <Icon>
169
- <svg viewBox="0 0 24 24" className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth="2">
170
- <circle cx="12" cy="12" r="9" />
171
- <path d="M12 7v5" />
172
- </svg>
173
- </Icon>
174
- ),
175
- },
176
- {
177
- href: `/settings`,
178
- label: "Settings",
179
- icon: (
180
- <Icon>
181
- <svg viewBox="0 0 24 24" className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth="2">
182
- <path d="M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z" />
183
- <path d="M19.4 15a7.9 7.9 0 0 0 .1-1l2-1.5-2-3.5-2.4.5a7.8 7.8 0 0 0-1.7-1L13.5 3h-4L8.6 6.5a7.8 7.8 0 0 0-1.7 1L4.5 7l-2 3.5 2 1.5a7.9 7.9 0 0 0 .1 1l-2 1.5 2 3.5 2.4-.5a7.8 7.8 0 0 0 1.7 1L10.5 21h4l.9-3.5a7.8 7.8 0 0 0 1.7-1l2.4.5 2-3.5-2-1.5Z" />
184
- </svg>
185
- </Icon>
186
- ),
187
- },
188
- ];
189
-
190
- const sideWidth = collapsed ? "w-16" : "w-72";
191
-
192
- return (
193
- <ToastProvider>
194
- <div className="flex h-dvh w-dvw overflow-hidden">
195
- <aside className={`flex shrink-0 flex-col border-r border-[color:var(--ck-border-subtle)] bg-[color:var(--ck-bg-glass)] backdrop-blur-[var(--ck-glass-blur)] ${sideWidth}`}>
196
- <div className="flex h-14 items-center justify-between gap-2 border-b border-[color:var(--ck-border-subtle)] px-3">
197
- <Link href="/" className="text-sm font-semibold tracking-tight" title="Home">
198
- {collapsed ? "CK" : "Claw Kitchen"}
199
- </Link>
200
- <button
201
- onClick={toggleCollapsed}
202
- className="rounded-[var(--ck-radius-sm)] px-2 py-1 text-sm text-[color:var(--ck-text-secondary)] hover:bg-white/5 hover:text-[color:var(--ck-text-primary)]"
203
- title={collapsed ? "Expand" : "Collapse"}
204
- >
205
- {collapsed ? "»" : "«"}
206
- </button>
207
- </div>
208
-
209
- <div className="border-b border-[color:var(--ck-border-subtle)] p-2">
210
- {collapsed ? (
211
- <button
212
- className="w-full rounded-[var(--ck-radius-sm)] bg-white/5 px-2 py-2 text-xs font-medium text-[color:var(--ck-text-secondary)] hover:bg-white/10"
213
- title={currentTeamId ? `Team: ${currentTeamId}` : "Select team"}
214
- onClick={() => {
215
- if (teamIds[0]) router.push(`/teams/${encodeURIComponent(teamIds[0])}`);
216
- }}
217
- >
218
- 👥
219
- </button>
220
- ) : (
221
- <div className="flex flex-col gap-1">
222
- <div className="px-2 pt-1 text-xs font-semibold uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">
223
- Team
224
- </div>
225
- <select
226
- value={currentTeamId ?? ""}
227
- onChange={(e) => {
228
- const id = e.target.value;
229
- if (id) router.push(`/teams/${encodeURIComponent(id)}`);
230
- }}
231
- className="w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-2 py-2 text-sm text-[color:var(--ck-text-primary)]"
232
- >
233
- <option value="">(select)</option>
234
- {teamIds.map((id) => (
235
- <option key={id} value={id}>
236
- {id}
237
- </option>
238
- ))}
239
- </select>
240
- </div>
241
- )}
242
- </div>
243
-
244
- <nav className="min-h-0 flex-1 overflow-auto p-2">
245
- <div className="mt-2 px-2 pb-2 pt-2">
246
- {/* section label intentionally omitted */}
247
- </div>
248
- {globalNav.map((it) => (
249
- <SideNavLink
250
- key={it.href}
251
- href={it.href}
252
- label={it.label}
253
- icon={<span aria-hidden>{it.icon}</span>}
254
- collapsed={collapsed}
255
- active={pathname === it.href || pathname.startsWith(it.href + "/")}
256
- />
257
- ))}
258
- </nav>
259
-
260
- <div className="flex items-center justify-between gap-2 border-t border-[color:var(--ck-border-subtle)] p-2">
261
- <a
262
- href="https://github.com/JIGGAI/ClawRecipes/tree/main/docs"
263
- target="_blank"
264
- rel="noreferrer"
265
- className={
266
- collapsed
267
- ? "mx-auto rounded-[var(--ck-radius-sm)] px-2 py-2 text-sm text-[color:var(--ck-text-secondary)] hover:bg-white/5 hover:text-[color:var(--ck-text-primary)]"
268
- : "rounded-[var(--ck-radius-sm)] px-3 py-2 text-sm font-medium text-[color:var(--ck-text-secondary)] hover:bg-white/5 hover:text-[color:var(--ck-text-primary)]"
269
- }
270
- title="Docs"
271
- >
272
- {collapsed ? "📖" : "Docs"}
273
- </a>
274
- {collapsed ? null : <ThemeToggle />}
275
- </div>
276
- </aside>
277
-
278
- <div className="min-w-0 flex-1">
279
- <main className="h-full overflow-auto p-4 md:p-6">
280
- <ErrorBoundary>{children}</ErrorBoundary>
281
- </main>
282
- </div>
283
- </div>
284
- </ToastProvider>
285
- );
286
- }
@@ -1,81 +0,0 @@
1
- "use client";
2
-
3
- import { createPortal } from "react-dom";
4
-
5
- /** Shared confirmation modal shell: overlay, title, body, optional error, Cancel + Confirm buttons. */
6
- export function ConfirmationModal({
7
- open,
8
- onClose,
9
- title,
10
- children,
11
- error,
12
- confirmLabel,
13
- confirmBusyLabel,
14
- onConfirm,
15
- confirmDisabled,
16
- busy,
17
- confirmButtonClassName,
18
- }: {
19
- open: boolean;
20
- onClose: () => void;
21
- title: string;
22
- children: React.ReactNode;
23
- /** Optional error message to show above footer */
24
- error?: string | null;
25
- confirmLabel: string;
26
- confirmBusyLabel?: string;
27
- onConfirm: () => void;
28
- confirmDisabled?: boolean;
29
- busy?: boolean;
30
- /** Override confirm button styles (default: accent red) */
31
- confirmButtonClassName?: string;
32
- }) {
33
- if (!open) return null;
34
-
35
- const isDisabled = confirmDisabled ?? false;
36
- const isBusy = busy ?? false;
37
- const btnLabel = isBusy && confirmBusyLabel ? confirmBusyLabel : confirmLabel;
38
- const confirmClass =
39
- confirmButtonClassName ??
40
- "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)] transition-colors hover:bg-[var(--ck-accent-red-hover)] disabled:opacity-50";
41
-
42
- const titleId = "confirmation-modal-title";
43
- return createPortal(
44
- <div className="fixed inset-0 z-[200]">
45
- <div className="fixed inset-0 bg-black/60" onClick={onClose} aria-hidden="true" />
46
- <div className="fixed inset-0 overflow-y-auto" role="dialog" aria-modal="true" aria-labelledby={titleId}>
47
- <div className="flex min-h-full items-center justify-center p-4">
48
- <div className="w-full max-w-lg rounded-2xl border border-white/10 bg-[color:var(--ck-bg-glass-strong)] p-5 shadow-[var(--ck-shadow-2)]">
49
- <h2 id={titleId} className="text-lg font-semibold text-[color:var(--ck-text-primary)]">{title}</h2>
50
- {children}
51
-
52
- {error ? (
53
- <div className="mt-4 rounded-[var(--ck-radius-sm)] border border-red-400/30 bg-red-500/10 p-3 text-sm text-red-100">
54
- {error}
55
- </div>
56
- ) : null}
57
-
58
- <div className="mt-6 flex items-center justify-end gap-2">
59
- <button
60
- type="button"
61
- onClick={onClose}
62
- 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"
63
- >
64
- Cancel
65
- </button>
66
- <button
67
- type="button"
68
- disabled={isDisabled || isBusy}
69
- onClick={onConfirm}
70
- className={confirmClass}
71
- >
72
- {btnLabel}
73
- </button>
74
- </div>
75
- </div>
76
- </div>
77
- </div>
78
- </div>,
79
- document.body
80
- );
81
- }
@@ -1,41 +0,0 @@
1
- "use client";
2
-
3
- import { ConfirmationModal } from "./ConfirmationModal";
4
-
5
- /** Shared delete confirmation modal: title, entity label in code, body text. */
6
- export function DeleteEntityModal({
7
- open,
8
- onClose,
9
- title,
10
- entityLabel,
11
- bodyText,
12
- onConfirm,
13
- busy,
14
- error,
15
- }: {
16
- open: boolean;
17
- onClose: () => void;
18
- title: string;
19
- entityLabel: string;
20
- bodyText: string;
21
- onConfirm: () => void;
22
- busy?: boolean;
23
- error?: string | null;
24
- }) {
25
- return (
26
- <ConfirmationModal
27
- open={open}
28
- onClose={onClose}
29
- title={title}
30
- confirmLabel="Delete"
31
- confirmBusyLabel="Deleting…"
32
- onConfirm={onConfirm}
33
- busy={busy}
34
- error={error ?? undefined}
35
- >
36
- <p className="mt-2 text-sm text-[color:var(--ck-text-secondary)]">
37
- {title} <code className="font-mono">{entityLabel}</code>? {bodyText}
38
- </p>
39
- </ConfirmationModal>
40
- );
41
- }
@@ -1,70 +0,0 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import Link from "next/link";
5
-
6
- type Props = {
7
- children: React.ReactNode;
8
- fallback?: React.ReactNode;
9
- };
10
-
11
- type State = {
12
- hasError: boolean;
13
- error: Error | null;
14
- };
15
-
16
- /**
17
- * React Error Boundary for graceful crash handling.
18
- * Catches runtime errors in child components and shows a fallback UI.
19
- */
20
- export class ErrorBoundary extends React.Component<Props, State> {
21
- constructor(props: Props) {
22
- super(props);
23
- this.state = { hasError: false, error: null };
24
- }
25
-
26
- static getDerivedStateFromError(error: Error): State {
27
- return { hasError: true, error };
28
- }
29
-
30
- componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
31
- console.error("ErrorBoundary caught:", error, errorInfo);
32
- }
33
-
34
- render() {
35
- if (this.state.hasError && this.state.error) {
36
- if (this.props.fallback) {
37
- return this.props.fallback;
38
- }
39
- return (
40
- <div className="ck-glass mx-auto max-w-2xl p-6 sm:p-8">
41
- <h1 className="text-xl font-semibold tracking-tight text-[color:var(--ck-text-primary)]">
42
- Something went wrong
43
- </h1>
44
- <p className="mt-2 text-sm text-[color:var(--ck-text-secondary)]">
45
- An unexpected error occurred. You can try refreshing the page or go back home.
46
- </p>
47
- <pre className="mt-4 overflow-auto rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-3 font-mono text-xs text-[color:var(--ck-text-secondary)]">
48
- {this.state.error.message}
49
- </pre>
50
- <div className="mt-6 flex flex-wrap gap-3">
51
- <button
52
- type="button"
53
- onClick={() => window.location.reload()}
54
- className="rounded-[var(--ck-radius-sm)] bg-[var(--ck-accent-red)] px-4 py-2 text-sm font-medium text-white shadow-[var(--ck-shadow-1)] hover:bg-[var(--ck-accent-red)]/90"
55
- >
56
- Refresh page
57
- </button>
58
- <Link
59
- href="/"
60
- className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-4 py-2 text-sm font-medium text-[color:var(--ck-text-primary)] shadow-[var(--ck-shadow-1)] hover:bg-white/10"
61
- >
62
- Go home
63
- </Link>
64
- </div>
65
- </div>
66
- );
67
- }
68
- return this.props.children;
69
- }
70
- }
@@ -1,86 +0,0 @@
1
- "use client";
2
-
3
- export type FileListWithOptionalToggleEntry = {
4
- name: string;
5
- missing: boolean;
6
- required?: boolean;
7
- };
8
-
9
- function getFileButtonClass(selectedFileName: string, fName: string): string {
10
- const isSelected = selectedFileName === fName;
11
- const base = "w-full rounded-[var(--ck-radius-sm)] px-3 py-2 text-left text-sm";
12
- if (isSelected) {
13
- return `${base} bg-white/10 text-[color:var(--ck-text-primary)]`;
14
- }
15
- return `${base} text-[color:var(--ck-text-secondary)] hover:bg-white/5`;
16
- }
17
-
18
- export function FileListWithOptionalToggle({
19
- title,
20
- files,
21
- loading,
22
- showOptionalFiles,
23
- onShowOptionalChange,
24
- selectedFileName,
25
- onSelectFile,
26
- renderItemExtra,
27
- }: {
28
- title: string;
29
- files: FileListWithOptionalToggleEntry[];
30
- loading?: boolean;
31
- showOptionalFiles: boolean;
32
- onShowOptionalChange: (v: boolean) => void;
33
- selectedFileName: string;
34
- onSelectFile: (name: string) => void;
35
- renderItemExtra?: (f: FileListWithOptionalToggleEntry) => React.ReactNode;
36
- }) {
37
- const filtered = showOptionalFiles ? files : files.filter((f) => f.required || !f.missing);
38
-
39
- return (
40
- <div className="ck-glass-strong p-4">
41
- <div className="flex items-center justify-between gap-3">
42
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">{title}</div>
43
- <label className="flex items-center gap-2 text-xs text-[color:var(--ck-text-secondary)]">
44
- <input
45
- type="checkbox"
46
- checked={showOptionalFiles}
47
- onChange={(e) => onShowOptionalChange(e.target.checked)}
48
- />
49
- Show optional
50
- </label>
51
- </div>
52
- <div className="mt-2 text-xs text-[color:var(--ck-text-tertiary)]">
53
- Default view hides optional missing files to reduce noise.
54
- </div>
55
- <ul className="mt-3 space-y-1">
56
- {loading ? <li className="text-sm text-[color:var(--ck-text-secondary)]">Loading…</li> : null}
57
- {filtered.map((f) => (
58
- <li key={f.name}>
59
- <div className="flex items-center gap-2">
60
- <button
61
- type="button"
62
- onClick={() => onSelectFile(f.name)}
63
- className={getFileButtonClass(selectedFileName, f.name)}
64
- >
65
- <span
66
- className={
67
- f.required ? "text-[color:var(--ck-text-primary)]" : "text-[color:var(--ck-text-secondary)]"
68
- }
69
- >
70
- {f.name}
71
- </span>
72
- <span className="ml-2 text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">
73
- {f.required ? "required" : "optional"}
74
- </span>
75
- {f.missing ? (
76
- <span className="ml-2 text-xs text-[color:var(--ck-text-tertiary)]">missing</span>
77
- ) : null}
78
- </button>
79
- {renderItemExtra?.(f)}
80
- </div>
81
- </li>
82
- ))}
83
- </ul>
84
- </div>
85
- );
86
- }