@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,163 +0,0 @@
1
- "use client";
2
-
3
- import type { ReactNode } from "react";
4
- import { useId } from "react";
5
- import type { GoalFormState, GoalStatus } from "@/lib/goals-client";
6
-
7
- export type { GoalFormState };
8
-
9
- /** Wraps goal form content with error display and action buttons. */
10
- export function GoalFormCard({
11
- children,
12
- error,
13
- actions,
14
- }: {
15
- children: ReactNode;
16
- error: string | null;
17
- actions: ReactNode;
18
- }) {
19
- return (
20
- <div className="ck-glass p-6 space-y-4">
21
- {children}
22
- {error ? <div className="text-sm text-red-300">{error}</div> : null}
23
- {actions}
24
- </div>
25
- );
26
- }
27
-
28
- const inputClass =
29
- "mt-1 w-full rounded-[var(--ck-radius-sm)] border border-[color:var(--ck-border-subtle)] bg-transparent px-3 py-2 text-sm";
30
-
31
- type Props = {
32
- formState: GoalFormState;
33
- /** When provided, renders the ID field (for create flow). */
34
- idField?: { id: string; setId: (v: string) => void; suggestedId?: string };
35
- /** When provided, shows updated timestamp next to body label. */
36
- updatedAt?: string | null;
37
- /** Body textarea height override (e.g. 260 for new page). */
38
- bodyHeight?: string;
39
- };
40
-
41
- export function GoalFormFields({
42
- formState,
43
- idField,
44
- updatedAt,
45
- bodyHeight = "h-[320px]",
46
- }: Props) {
47
- const { title, setTitle, status, setStatus, tagsRaw, setTagsRaw, teamsRaw, setTeamsRaw, body, setBody } = formState;
48
- const baseId = useId();
49
- const idInputId = `${baseId}-id`;
50
- const titleInputId = `${baseId}-title`;
51
- const statusSelectId = `${baseId}-status`;
52
- const teamsInputId = `${baseId}-teams`;
53
- const tagsInputId = `${baseId}-tags`;
54
- const bodyTextareaId = `${baseId}-body`;
55
- return (
56
- <>
57
- {idField ? (
58
- <div>
59
- <label htmlFor={idInputId} className="text-xs text-[color:var(--ck-text-tertiary)]">
60
- ID
61
- </label>
62
- <input
63
- id={idInputId}
64
- className={`${inputClass} font-mono`}
65
- value={idField.id}
66
- onChange={(e) => idField.setId(e.target.value)}
67
- placeholder="increase-trial-activation"
68
- aria-describedby={`${baseId}-id-hint`}
69
- />
70
- <div id={`${baseId}-id-hint`} className="mt-1 text-xs text-[color:var(--ck-text-tertiary)]">
71
- Lowercase letters, numbers, hyphens. Stored as <code className="font-mono">{idField.id || "<id>"}.md</code>
72
- .
73
- {idField.suggestedId && !idField.id.trim() ? (
74
- <>
75
- {" "}
76
- Suggested:{" "}
77
- <button type="button" className="underline" onClick={() => idField.setId(idField.suggestedId ?? "")}>
78
- {idField.suggestedId}
79
- </button>
80
- </>
81
- ) : null}
82
- </div>
83
- </div>
84
- ) : null}
85
-
86
- <div>
87
- <label htmlFor={titleInputId} className="text-xs text-[color:var(--ck-text-tertiary)]">
88
- Title
89
- </label>
90
- <input
91
- id={titleInputId}
92
- className={inputClass}
93
- value={title}
94
- onChange={(e) => setTitle(e.target.value)}
95
- placeholder={idField ? "Increase trial activation" : "Goal title"}
96
- />
97
- </div>
98
-
99
- <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
100
- <div>
101
- <label htmlFor={statusSelectId} className="text-xs text-[color:var(--ck-text-tertiary)]">
102
- Status
103
- </label>
104
- <select
105
- id={statusSelectId}
106
- className={inputClass}
107
- value={status}
108
- onChange={(e) => setStatus(e.target.value as GoalStatus)}
109
- aria-label="Goal status"
110
- >
111
- <option value="planned">Planned</option>
112
- <option value="active">Active</option>
113
- <option value="done">Done</option>
114
- </select>
115
- </div>
116
- <div>
117
- <label htmlFor={teamsInputId} className="text-xs text-[color:var(--ck-text-tertiary)]">
118
- Teams (comma-separated)
119
- </label>
120
- <input
121
- id={teamsInputId}
122
- className={inputClass}
123
- value={teamsRaw}
124
- onChange={(e) => setTeamsRaw(e.target.value)}
125
- placeholder="development-team, marketing-team"
126
- />
127
- </div>
128
- <div>
129
- <label htmlFor={tagsInputId} className="text-xs text-[color:var(--ck-text-tertiary)]">
130
- Tags (comma-separated)
131
- </label>
132
- <input
133
- id={tagsInputId}
134
- className={inputClass}
135
- value={tagsRaw}
136
- onChange={(e) => setTagsRaw(e.target.value)}
137
- placeholder="onboarding, growth"
138
- />
139
- </div>
140
- </div>
141
-
142
- <div>
143
- <div className="flex items-center justify-between">
144
- <label htmlFor={bodyTextareaId} className="text-xs text-[color:var(--ck-text-tertiary)]">
145
- Body (markdown)
146
- </label>
147
- {updatedAt != null ? (
148
- <div className="text-xs text-[color:var(--ck-text-tertiary)]">
149
- {updatedAt ? `updated ${new Date(updatedAt).toLocaleString()}` : ""}
150
- </div>
151
- ) : null}
152
- </div>
153
- <textarea
154
- id={bodyTextareaId}
155
- className={`mt-1 ${bodyHeight} w-full rounded-[var(--ck-radius-sm)] border border-[color:var(--ck-border-subtle)] bg-transparent px-3 py-2 font-mono text-sm`}
156
- value={body}
157
- onChange={(e) => setBody(e.target.value)}
158
- placeholder="Write the goal here…"
159
- />
160
- </div>
161
- </>
162
- );
163
- }
@@ -1,78 +0,0 @@
1
- "use client";
2
-
3
- import { createPortal } from "react-dom";
4
-
5
- export type ScaffoldOverlayStep = 1 | 2 | 3;
6
-
7
- const stepLabel: Record<ScaffoldOverlayStep, string> = {
8
- 1: "Ordering team…",
9
- 2: "Cooking up agents…",
10
- 3: "Serving them up hot…",
11
- };
12
-
13
- function getStepCircleClass(done: boolean, active: boolean): string {
14
- if (done) return "bg-emerald-400";
15
- if (active) return "bg-[var(--ck-accent-red)] animate-pulse";
16
- return "bg-white/20";
17
- }
18
-
19
- export function ScaffoldOverlay({
20
- open,
21
- step,
22
- onDismiss,
23
- }: {
24
- open: boolean;
25
- step: ScaffoldOverlayStep;
26
- onDismiss?: () => void;
27
- }) {
28
- if (!open) return null;
29
-
30
- return createPortal(
31
- <div className="fixed inset-0 z-[9999]">
32
- {/* Slightly transparent full-screen overlay so we hide the app while still showing a hint of context. */}
33
- <div className="fixed inset-0 bg-white/90 dark:bg-black/90 pointer-events-none" />
34
-
35
- {onDismiss ? (
36
- <button
37
- type="button"
38
- onClick={(e) => {
39
- e.preventDefault();
40
- e.stopPropagation();
41
- onDismiss();
42
- }}
43
- className="fixed right-4 top-4 z-[10000] rounded-full border border-white/10 bg-[color:var(--ck-bg-glass)] px-3 py-2 text-sm font-medium text-[color:var(--ck-text-primary)] shadow-[var(--ck-shadow-1)] hover:bg-[color:var(--ck-bg-glass-strong)]"
44
- aria-label="Dismiss loading overlay"
45
- title="Dismiss"
46
- >
47
- Esc
48
- </button>
49
- ) : null}
50
-
51
- <div className="fixed inset-0 flex items-center justify-center p-6 sm:p-10">
52
- <div className="w-full max-w-2xl rounded-2xl border border-white/10 bg-[color:var(--ck-bg-glass-strong)] p-8 sm:p-10 shadow-[var(--ck-shadow-2)]">
53
- <div className="text-2xl font-semibold text-[color:var(--ck-text-primary)]">Claw Kitchen</div>
54
- <div className="mt-3 text-base text-[color:var(--ck-text-secondary)]">Hang tight — we’re updating your OpenClaw install.</div>
55
-
56
- <div className="mt-8 space-y-4 text-base">
57
- {[1, 2, 3].map((n) => {
58
- const s = n as ScaffoldOverlayStep;
59
- const active = s === step;
60
- const done = s < step;
61
- return (
62
- <div key={s} className="flex items-center gap-4">
63
- <div className={"h-4 w-4 rounded-full " + getStepCircleClass(done, active)} />
64
- <div className={done ? "text-[color:var(--ck-text-secondary)] line-through" : "text-[color:var(--ck-text-primary)]"}>
65
- {stepLabel[s]}
66
- </div>
67
- </div>
68
- );
69
- })}
70
- </div>
71
-
72
- {/* Details removed — avoid noisy/scrolling stderr in the primary UX. */}
73
- </div>
74
- </div>
75
- </div>,
76
- document.body,
77
- );
78
- }
@@ -1,53 +0,0 @@
1
- "use client";
2
-
3
- import { useEffect, useState } from "react";
4
- import { MoonIcon, SunIcon } from "@/components/icons";
5
-
6
- export type Theme = "light" | "dark";
7
-
8
- const STORAGE_KEY = "ck-theme";
9
-
10
- function readInitialTheme(): Theme {
11
- // Default: dark mode.
12
- if (typeof window === "undefined") return "dark";
13
- const saved = window.localStorage.getItem(STORAGE_KEY);
14
- return saved === "light" ? "light" : "dark";
15
- }
16
-
17
- function applyTheme(theme: Theme) {
18
- document.documentElement.dataset.theme = theme;
19
- }
20
-
21
- export function ThemeToggle() {
22
- const [theme, setTheme] = useState<Theme>(readInitialTheme);
23
-
24
- useEffect(() => {
25
- applyTheme(theme);
26
- window.localStorage.setItem(STORAGE_KEY, theme);
27
- }, [theme]);
28
-
29
- function toggle() {
30
- setTheme((t) => (t === "dark" ? "light" : "dark"));
31
- }
32
-
33
- const label = theme === "dark" ? "Switch to light mode" : "Switch to dark mode";
34
-
35
- return (
36
- <button
37
- type="button"
38
- onClick={toggle}
39
- className="grid h-9 w-9 place-items-center rounded-full border border-[color:var(--ck-border-subtle)] bg-[color:var(--ck-bg-glass)] text-[color:var(--ck-text-primary)] shadow-[var(--ck-shadow-1)] transition-colors hover:bg-[color:var(--ck-bg-glass-strong)]"
40
- aria-label={label}
41
- title={label}
42
- >
43
- <span className="sr-only" suppressHydrationWarning>
44
- {label}
45
- </span>
46
- {theme === "dark" ? (
47
- <MoonIcon className="h-4.5 w-4.5" />
48
- ) : (
49
- <SunIcon className="h-4.5 w-4.5" />
50
- )}
51
- </button>
52
- );
53
- }
@@ -1,163 +0,0 @@
1
- "use client";
2
-
3
- import { createContext, useCallback, useContext, useMemo, useState } from "react";
4
-
5
- export type ToastKind = "success" | "error" | "info";
6
-
7
- type ToastInternal = Toast & { state: "enter" | "show" | "leave" };
8
- export type Toast = {
9
- id: string;
10
- kind: ToastKind;
11
- title?: string;
12
- message: string;
13
- timeoutMs?: number;
14
- };
15
-
16
- type ToastContextValue = {
17
- push: (t: Omit<Toast, "id">) => void;
18
- };
19
-
20
- const ToastContext = createContext<ToastContextValue | null>(null);
21
-
22
- function randomHex(bytes: number): string {
23
- const arr = new Uint8Array(bytes);
24
- crypto.getRandomValues(arr);
25
- return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
26
- }
27
-
28
- function getToastMotionClass(state: "enter" | "show" | "leave"): string {
29
- if (state === "enter") return "translate-x-[-16px] opacity-0";
30
- if (state === "leave") return "translate-x-[-16px] opacity-0";
31
- return "translate-x-0 opacity-100";
32
- }
33
-
34
- function ToastIcon({ kind }: { kind: ToastKind }) {
35
- if (kind === "success") {
36
- return (
37
- <svg viewBox="0 0 20 20" fill="currentColor" className="h-5 w-5 text-emerald-400">
38
- <path
39
- fillRule="evenodd"
40
- d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.707a1 1 0 00-1.414-1.414L9 10.172 7.707 8.879a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
41
- clipRule="evenodd"
42
- />
43
- </svg>
44
- );
45
- }
46
- if (kind === "error") {
47
- return (
48
- <svg viewBox="0 0 20 20" fill="currentColor" className="h-5 w-5 text-red-400">
49
- <path
50
- fillRule="evenodd"
51
- d="M10 18a8 8 0 100-16 8 8 0 000 16zm-1-5a1 1 0 112 0 1 1 0 01-2 0zm0-8a1 1 0 012 0v6a1 1 0 11-2 0V5z"
52
- clipRule="evenodd"
53
- />
54
- </svg>
55
- );
56
- }
57
- return (
58
- <svg viewBox="0 0 20 20" fill="currentColor" className="h-5 w-5 text-slate-300">
59
- <path
60
- fillRule="evenodd"
61
- d="M18 10A8 8 0 11 2 10a8 8 0 0116 0zM9 9a1 1 0 112 0v5a1 1 0 11-2 0V9zm0-3a1 1 0 112 0 1 1 0 01-2 0z"
62
- clipRule="evenodd"
63
- />
64
- </svg>
65
- );
66
- }
67
-
68
- export function ToastProvider({ children }: { children: React.ReactNode }) {
69
- const [toasts, setToasts] = useState<ToastInternal[]>([]);
70
-
71
- const removeNow = useCallback((id: string) => {
72
- setToasts((prev) => prev.filter((t) => t.id !== id));
73
- }, []);
74
-
75
- const dismiss = useCallback(
76
- (id: string) => {
77
- // Start leave animation, then remove.
78
- setToasts((prev) => prev.map((t) => (t.id === id ? { ...t, state: "leave" } : t)));
79
- window.setTimeout(() => removeNow(id), 250);
80
- },
81
- [removeNow],
82
- );
83
-
84
- const promoteToShow = useCallback((id: string) => {
85
- setToasts((prev) => prev.map((x) => (x.id === id ? { ...x, state: "show" } : x)));
86
- }, []);
87
-
88
- const push = useCallback(
89
- (t: Omit<Toast, "id">) => {
90
- const id = `${Date.now()}-${randomHex(8)}`;
91
- const toast: ToastInternal = { id, timeoutMs: 5000, state: "enter", ...t };
92
- setToasts((prev) => [toast, ...prev].slice(0, 4));
93
-
94
- window.setTimeout(() => promoteToShow(id), 10);
95
-
96
- const ms = toast.timeoutMs;
97
- if (ms && ms > 0) {
98
- window.setTimeout(() => dismiss(id), ms);
99
- }
100
- },
101
- [dismiss, promoteToShow],
102
- );
103
-
104
- const value = useMemo(() => ({ push }), [push]);
105
-
106
- return (
107
- <ToastContext.Provider value={value}>
108
- {children}
109
-
110
- {/* Tailwind UI-inspired notifications */}
111
- <div
112
- aria-live="assertive"
113
- className="pointer-events-none fixed inset-0 z-[100] flex items-end px-4 py-6 sm:p-6"
114
- >
115
- <div className="flex w-full flex-col items-start space-y-4">
116
- {toasts.map((t) => (
117
- <div
118
- key={t.id}
119
- className={
120
- "pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg border bg-[color:var(--ck-toast-bg)] shadow-[var(--ck-shadow-2)] transition-all duration-200 ease-out border-[color:var(--ck-toast-border)] " +
121
- getToastMotionClass(t.state)
122
- }
123
- >
124
- <div className="p-4">
125
- <div className="flex items-start">
126
- <div className="shrink-0">
127
- <ToastIcon kind={t.kind} />
128
- </div>
129
- <div className="ml-3 w-0 flex-1">
130
- {t.title ? (
131
- <p className="text-sm font-medium text-[color:var(--ck-text-primary)]">{t.title}</p>
132
- ) : null}
133
- <p className="whitespace-pre-wrap text-sm text-[color:var(--ck-text-primary)]">{t.message}</p>
134
- </div>
135
- <div className="ml-4 flex shrink-0">
136
- <button
137
- type="button"
138
- onClick={() => dismiss(t.id)}
139
- className="inline-flex rounded-md bg-transparent text-[color:var(--ck-text-tertiary)] hover:text-[color:var(--ck-text-primary)]"
140
- aria-label="Dismiss"
141
- title="Dismiss"
142
- >
143
- <span className="sr-only">Close</span>
144
- <svg viewBox="0 0 20 20" fill="currentColor" className="h-5 w-5">
145
- <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 10-1.06-1.06L10 8.94 6.28 5.22z" />
146
- </svg>
147
- </button>
148
- </div>
149
- </div>
150
- </div>
151
- </div>
152
- ))}
153
- </div>
154
- </div>
155
- </ToastContext.Provider>
156
- );
157
- }
158
-
159
- export function useToast() {
160
- const ctx = useContext(ToastContext);
161
- if (!ctx) throw new Error("useToast must be used within ToastProvider");
162
- return ctx;
163
- }
@@ -1,109 +0,0 @@
1
- import { describe, expect, it, vi, afterEach } from "vitest";
2
- import { render, screen, fireEvent, cleanup, within } from "@testing-library/react";
3
- import { ConfirmationModal } from "../ConfirmationModal";
4
-
5
- afterEach(cleanup);
6
-
7
- describe("ConfirmationModal", () => {
8
- it("returns null when open is false", () => {
9
- render(
10
- <ConfirmationModal
11
- open={false}
12
- onClose={vi.fn()}
13
- title="Confirm"
14
- confirmLabel="Confirm"
15
- onConfirm={vi.fn()}
16
- >
17
- <p>Body content</p>
18
- </ConfirmationModal>
19
- );
20
- expect(screen.queryByText("Confirm")).toBeNull();
21
- });
22
-
23
- it("renders title, body, Cancel and Confirm when open", () => {
24
- render(
25
- <ConfirmationModal
26
- open={true}
27
- onClose={vi.fn()}
28
- title="Delete item?"
29
- confirmLabel="Delete"
30
- onConfirm={vi.fn()}
31
- >
32
- <p>Are you sure?</p>
33
- </ConfirmationModal>
34
- );
35
- expect(screen.getByText("Delete item?")).toBeTruthy();
36
- expect(screen.getByText("Are you sure?")).toBeTruthy();
37
- expect(screen.getByRole("button", { name: "Cancel" })).toBeTruthy();
38
- expect(screen.getByRole("button", { name: "Delete" })).toBeTruthy();
39
- });
40
-
41
- it("calls onClose when Cancel clicked", () => {
42
- const onClose = vi.fn();
43
- render(
44
- <ConfirmationModal
45
- open={true}
46
- onClose={onClose}
47
- title="Confirm Close"
48
- confirmLabel="OK"
49
- onConfirm={vi.fn()}
50
- >
51
- <p>Body</p>
52
- </ConfirmationModal>
53
- );
54
- const modal = screen.getByText("Confirm Close").closest(".rounded-2xl");
55
- fireEvent.click(within(modal!).getByRole("button", { name: "Cancel" }));
56
- expect(onClose).toHaveBeenCalled();
57
- });
58
-
59
- it("calls onConfirm when Confirm clicked", () => {
60
- const onConfirm = vi.fn();
61
- render(
62
- <ConfirmationModal
63
- open={true}
64
- onClose={vi.fn()}
65
- title="Confirm Submit"
66
- confirmLabel="Submit"
67
- onConfirm={onConfirm}
68
- >
69
- <p>Body</p>
70
- </ConfirmationModal>
71
- );
72
- const modal = screen.getByText("Confirm Submit").closest(".rounded-2xl");
73
- fireEvent.click(within(modal!).getByRole("button", { name: "Submit" }));
74
- expect(onConfirm).toHaveBeenCalled();
75
- });
76
-
77
- it("shows error when provided", () => {
78
- render(
79
- <ConfirmationModal
80
- open={true}
81
- onClose={vi.fn()}
82
- title="Confirm"
83
- confirmLabel="Confirm"
84
- onConfirm={vi.fn()}
85
- error="Something failed"
86
- >
87
- <p>Body</p>
88
- </ConfirmationModal>
89
- );
90
- expect(screen.getByText("Something failed")).toBeTruthy();
91
- });
92
-
93
- it("shows confirmBusyLabel when busy", () => {
94
- render(
95
- <ConfirmationModal
96
- open={true}
97
- onClose={vi.fn()}
98
- title="Confirm"
99
- confirmLabel="Confirm"
100
- confirmBusyLabel="Confirming…"
101
- onConfirm={vi.fn()}
102
- busy={true}
103
- >
104
- <p>Body</p>
105
- </ConfirmationModal>
106
- );
107
- expect(screen.getByRole("button", { name: "Confirming…" })).toBeTruthy();
108
- });
109
- });
@@ -1,39 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { render, screen } from "@testing-library/react";
3
- import { ErrorBoundary } from "../ErrorBoundary";
4
-
5
- function ThrowError() {
6
- throw new Error("Test error");
7
- }
8
-
9
- describe("ErrorBoundary", () => {
10
- it("renders children when no error", () => {
11
- render(
12
- <ErrorBoundary>
13
- <div data-testid="child">Hello</div>
14
- </ErrorBoundary>
15
- );
16
- expect(screen.getByTestId("child").textContent).toBe("Hello");
17
- });
18
-
19
- it("renders fallback UI when child throws", () => {
20
- render(
21
- <ErrorBoundary>
22
- <ThrowError />
23
- </ErrorBoundary>
24
- );
25
- expect(screen.getByText("Something went wrong")).toBeTruthy();
26
- expect(screen.getByText("Test error")).toBeTruthy();
27
- expect(screen.getByRole("button", { name: /refresh page/i })).toBeTruthy();
28
- expect(screen.getByRole("link", { name: /go home/i })).toBeTruthy();
29
- });
30
-
31
- it("renders custom fallback when provided", () => {
32
- render(
33
- <ErrorBoundary fallback={<div data-testid="custom">Custom fallback</div>}>
34
- <ThrowError />
35
- </ErrorBoundary>
36
- );
37
- expect(screen.getByTestId("custom").textContent).toBe("Custom fallback");
38
- });
39
- });