@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,349 +0,0 @@
1
- "use client";
2
-
3
- import { useEffect, useMemo, useState } from "react";
4
- import { errorMessage } from "@/lib/errors";
5
-
6
- type MemoryItem = {
7
- ts: string;
8
- author: string;
9
- type: string;
10
- content: string;
11
- source?: unknown;
12
- _file?: string;
13
- _line?: number;
14
- };
15
-
16
- type PinnedItem = MemoryItem & {
17
- pinnedAt: string;
18
- pinnedBy: string;
19
- _key: string;
20
- };
21
-
22
- function memoryKey(it: { _file?: string; _line?: number }): string {
23
- return `${it._file ?? ""}:${it._line ?? 0}`;
24
- }
25
-
26
- export function TeamMemoryTab({ teamId }: { teamId: string }) {
27
- const [loading, setLoading] = useState(false);
28
- const [error, setError] = useState("");
29
- const [files, setFiles] = useState<string[]>([]);
30
- const [pinnedItems, setPinnedItems] = useState<PinnedItem[]>([]);
31
- const [items, setItems] = useState<MemoryItem[]>([]);
32
-
33
- const [newType, setNewType] = useState("learning");
34
- const [newContent, setNewContent] = useState("");
35
- const [newSource, setNewSource] = useState("");
36
- const [saving, setSaving] = useState(false);
37
- const [pinningKey, setPinningKey] = useState<string | null>(null);
38
-
39
- async function refresh() {
40
- setLoading(true);
41
- setError("");
42
- try {
43
- const res = await fetch(`/api/teams/memory?teamId=${encodeURIComponent(teamId)}`, { cache: "no-store" });
44
- const json = (await res.json()) as {
45
- ok?: boolean;
46
- error?: string;
47
- files?: string[];
48
- pinnedItems?: PinnedItem[];
49
- items?: MemoryItem[];
50
- };
51
- if (!res.ok || !json.ok) throw new Error(json.error || "Failed to load memory");
52
- setFiles(Array.isArray(json.files) ? json.files : []);
53
- setPinnedItems(Array.isArray(json.pinnedItems) ? json.pinnedItems : []);
54
- setItems(Array.isArray(json.items) ? json.items : []);
55
- } catch (e: unknown) {
56
- setError(errorMessage(e));
57
- setFiles([]);
58
- setPinnedItems([]);
59
- setItems([]);
60
- } finally {
61
- setLoading(false);
62
- }
63
- }
64
-
65
- useEffect(() => {
66
- void refresh();
67
- // eslint-disable-next-line react-hooks/exhaustive-deps -- refresh is defined inline; teamId is the only intended trigger.
68
- }, [teamId]);
69
-
70
- const examples = useMemo(
71
- () => [
72
- { label: "decision", value: "decision" },
73
- { label: "learning", value: "learning" },
74
- { label: "bug", value: "bug" },
75
- { label: "customer", value: "customer" },
76
- { label: "release", value: "release" },
77
- ],
78
- []
79
- );
80
-
81
- const pinnedKeySet = useMemo(() => new Set(pinnedItems.map((x) => x._key)), [pinnedItems]);
82
-
83
- async function pin(it: MemoryItem) {
84
- const key = memoryKey(it);
85
- if (!it._file || !it._line) return;
86
-
87
- setPinningKey(key);
88
- setError("");
89
- try {
90
- const payload = {
91
- op: "pin",
92
- ts: new Date().toISOString(),
93
- actor: `${teamId}-lead`,
94
- key: { file: "team.jsonl", line: it._line },
95
- item: { ts: it.ts, author: it.author, type: it.type, content: it.content, source: it.source },
96
- };
97
- const res = await fetch(`/api/teams/memory?teamId=${encodeURIComponent(teamId)}`, {
98
- method: "POST",
99
- headers: { "content-type": "application/json" },
100
- body: JSON.stringify(payload),
101
- });
102
- const json = (await res.json()) as { ok?: boolean; error?: string };
103
- if (!res.ok || !json.ok) throw new Error(json.error || "Failed to pin");
104
- await refresh();
105
- } catch (e: unknown) {
106
- setError(errorMessage(e));
107
- } finally {
108
- setPinningKey(null);
109
- }
110
- }
111
-
112
- async function unpin(it: { _file?: string; _line?: number }) {
113
- const key = memoryKey(it);
114
- if (!it._file || !it._line) return;
115
-
116
- setPinningKey(key);
117
- setError("");
118
- try {
119
- const payload = {
120
- op: "unpin",
121
- ts: new Date().toISOString(),
122
- actor: `${teamId}-lead`,
123
- key: { file: "team.jsonl", line: it._line },
124
- };
125
- const res = await fetch(`/api/teams/memory?teamId=${encodeURIComponent(teamId)}`, {
126
- method: "POST",
127
- headers: { "content-type": "application/json" },
128
- body: JSON.stringify(payload),
129
- });
130
- const json = (await res.json()) as { ok?: boolean; error?: string };
131
- if (!res.ok || !json.ok) throw new Error(json.error || "Failed to unpin");
132
- await refresh();
133
- } catch (e: unknown) {
134
- setError(errorMessage(e));
135
- } finally {
136
- setPinningKey(null);
137
- }
138
- }
139
-
140
- return (
141
- <div className="space-y-4">
142
- <div className="ck-glass p-4">
143
- <div className="flex items-start justify-between gap-3">
144
- <div>
145
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">Team memory (file-first)</div>
146
- <div className="mt-1 text-xs text-[color:var(--ck-text-tertiary)]">
147
- Stored in <span className="font-mono">shared-context/memory/*.jsonl</span>. Items must be attributable.
148
- </div>
149
- </div>
150
- <button
151
- type="button"
152
- onClick={refresh}
153
- 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"
154
- >
155
- Refresh
156
- </button>
157
- </div>
158
-
159
- {error ? (
160
- <div className="mt-3 rounded border border-red-400/30 bg-red-500/10 p-2 text-sm text-red-100">{error}</div>
161
- ) : null}
162
-
163
- <div className="mt-3 text-xs text-[color:var(--ck-text-secondary)]">Files: {files.length ? files.join(", ") : "(none)"}</div>
164
- </div>
165
-
166
- <div className="ck-glass p-4">
167
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">Add memory item</div>
168
- <div className="mt-3 grid grid-cols-1 gap-3 md:grid-cols-2">
169
- <label className="block">
170
- <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">type</div>
171
- <select
172
- value={newType}
173
- onChange={(e) => setNewType(e.target.value)}
174
- className="mt-1 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)]"
175
- >
176
- {examples.map((x) => (
177
- <option key={x.value} value={x.value}>
178
- {x.label}
179
- </option>
180
- ))}
181
- </select>
182
- </label>
183
-
184
- <label className="block">
185
- <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">source (ticket/pr/path)</div>
186
- <input
187
- value={newSource}
188
- onChange={(e) => setNewSource(e.target.value)}
189
- className="mt-1 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)]"
190
- placeholder="e.g. ticket 0088, PR https://..., shared-context/DECISIONS.md"
191
- />
192
- </label>
193
-
194
- <label className="block md:col-span-2">
195
- <div className="text-[10px] uppercase tracking-wide text-[color:var(--ck-text-tertiary)]">content</div>
196
- <textarea
197
- value={newContent}
198
- onChange={(e) => setNewContent(e.target.value)}
199
- className="mt-1 h-[110px] w-full resize-none rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-2 text-sm text-[color:var(--ck-text-primary)]"
200
- placeholder="Write a small, specific memory item…"
201
- />
202
- </label>
203
-
204
- <div className="md:col-span-2">
205
- <button
206
- type="button"
207
- disabled={saving || !newContent.trim()}
208
- onClick={async () => {
209
- setSaving(true);
210
- setError("");
211
- try {
212
- const payload = {
213
- op: "append",
214
- ts: new Date().toISOString(),
215
- author: `${teamId}-lead`,
216
- type: newType,
217
- content: newContent.trim(),
218
- source: newSource.trim() ? { text: newSource.trim() } : undefined,
219
- file: "team.jsonl",
220
- };
221
- const res = await fetch(`/api/teams/memory?teamId=${encodeURIComponent(teamId)}`, {
222
- method: "POST",
223
- headers: { "content-type": "application/json" },
224
- body: JSON.stringify(payload),
225
- });
226
- const json = (await res.json()) as { ok?: boolean; error?: string };
227
- if (!res.ok || !json.ok) throw new Error(json.error || "Failed to append memory");
228
- setNewContent("");
229
- setNewSource("");
230
- await refresh();
231
- } catch (e: unknown) {
232
- setError(errorMessage(e));
233
- } finally {
234
- setSaving(false);
235
- }
236
- }}
237
- className="rounded-[var(--ck-radius-sm)] bg-[var(--ck-accent-red)] px-3 py-2 text-sm font-medium text-white shadow-[var(--ck-shadow-1)] disabled:opacity-50"
238
- >
239
- {saving ? "Saving…" : "Append to team.jsonl"}
240
- </button>
241
- </div>
242
- </div>
243
- </div>
244
-
245
- <div className="ck-glass p-4">
246
- <div className="flex items-center justify-between gap-2">
247
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">Pinned memory</div>
248
- <div className="text-xs text-[color:var(--ck-text-tertiary)]">{pinnedItems.length} pinned</div>
249
- </div>
250
-
251
- {loading ? <div className="mt-3 text-sm text-[color:var(--ck-text-secondary)]">Loading…</div> : null}
252
-
253
- <div className="mt-3 space-y-3">
254
- {pinnedItems.length ? (
255
- pinnedItems.map((it) => (
256
- <div key={it._key} className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-3">
257
- <div className="flex flex-wrap items-center justify-between gap-2">
258
- <div className="text-xs text-[color:var(--ck-text-tertiary)]">
259
- <span className="font-mono">{it.ts}</span>
260
- <span className="mx-2">•</span>
261
- <span className="rounded bg-white/5 px-2 py-0.5 font-mono">{it.type}</span>
262
- <span className="mx-2">•</span>
263
- <span className="font-mono">{it.author}</span>
264
- <span className="mx-2">•</span>
265
- <span className="font-mono">pinned {it.pinnedAt}</span>
266
- </div>
267
- <button
268
- type="button"
269
- onClick={() => void unpin(it)}
270
- disabled={pinningKey === it._key}
271
- className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-xs font-medium text-[color:var(--ck-text-primary)] hover:bg-white/10 disabled:opacity-50"
272
- >
273
- {pinningKey === it._key ? "Unpinning…" : "Unpin"}
274
- </button>
275
- </div>
276
-
277
- <div className="mt-2 whitespace-pre-wrap text-sm text-[color:var(--ck-text-primary)]">{it.content}</div>
278
-
279
- {it.source ? (
280
- <pre className="mt-2 overflow-auto rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/30 p-2 text-[10px] text-[color:var(--ck-text-secondary)]">
281
- {JSON.stringify(it.source, null, 2)}
282
- </pre>
283
- ) : null}
284
- </div>
285
- ))
286
- ) : (
287
- <div className="text-sm text-[color:var(--ck-text-secondary)]">No pinned items yet.</div>
288
- )}
289
- </div>
290
- </div>
291
-
292
- <div className="ck-glass p-4">
293
- <div className="flex items-center justify-between gap-2">
294
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">Recent memory</div>
295
- <div className="text-xs text-[color:var(--ck-text-tertiary)]">Showing {items.length} (max 200)</div>
296
- </div>
297
-
298
- {loading ? <div className="mt-3 text-sm text-[color:var(--ck-text-secondary)]">Loading…</div> : null}
299
-
300
- <div className="mt-3 space-y-3">
301
- {items.length ? (
302
- items.map((it) => {
303
- const k = memoryKey(it);
304
- const isPinned = pinnedKeySet.has(k);
305
- return (
306
- <div key={`${it._file ?? "?"}:${it._line ?? 0}`} className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-3">
307
- <div className="flex flex-wrap items-center justify-between gap-2">
308
- <div className="text-xs text-[color:var(--ck-text-tertiary)]">
309
- <span className="font-mono">{it.ts}</span>
310
- <span className="mx-2">•</span>
311
- <span className="rounded bg-white/5 px-2 py-0.5 font-mono">{it.type}</span>
312
- <span className="mx-2">•</span>
313
- <span className="font-mono">{it.author}</span>
314
- </div>
315
- <div className="flex items-center gap-2">
316
- {it._file ? (
317
- <span className="text-[10px] text-[color:var(--ck-text-tertiary)] font-mono">
318
- {it._file}:{it._line}
319
- </span>
320
- ) : null}
321
- <button
322
- type="button"
323
- onClick={() => void pin(it)}
324
- disabled={isPinned || pinningKey === k || !it._file || !it._line}
325
- className="rounded-[var(--ck-radius-sm)] border border-white/10 bg-white/5 px-2 py-1 text-xs font-medium text-[color:var(--ck-text-primary)] hover:bg-white/10 disabled:opacity-50"
326
- >
327
- {isPinned ? "Pinned" : pinningKey === k ? "Pinning…" : "Pin"}
328
- </button>
329
- </div>
330
- </div>
331
-
332
- <div className="mt-2 whitespace-pre-wrap text-sm text-[color:var(--ck-text-primary)]">{it.content}</div>
333
-
334
- {it.source ? (
335
- <pre className="mt-2 overflow-auto rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/30 p-2 text-[10px] text-[color:var(--ck-text-secondary)]">
336
- {JSON.stringify(it.source, null, 2)}
337
- </pre>
338
- ) : null}
339
- </div>
340
- );
341
- })
342
- ) : (
343
- <div className="text-sm text-[color:var(--ck-text-secondary)]">No memory items yet.</div>
344
- )}
345
- </div>
346
- </div>
347
- </div>
348
- );
349
- }
@@ -1,151 +0,0 @@
1
- "use client";
2
-
3
- import type { RecipeListItem } from "./types";
4
-
5
- type TeamRecipeTabProps = {
6
- loading?: boolean;
7
- fromId: string;
8
- setFromId: (v: string) => void;
9
- toId: string;
10
- setToId: (v: string) => void;
11
- toName: string;
12
- setToName: (v: string) => void;
13
- canEditTargetId: boolean;
14
- teamRecipes: RecipeListItem[];
15
- lockedFromId: string | null;
16
- lockedFromName: string | null;
17
- provenanceMissing: boolean;
18
- saving: boolean;
19
- teamIdValid: boolean;
20
- targetIdValid: boolean;
21
- targetIsBuiltin: boolean;
22
- loadedRecipeHash: string | null;
23
- teamMetaRecipeHash: string | null;
24
- publishing: boolean;
25
- content: string;
26
- setContent: (v: string) => void;
27
- setLoadedRecipeHash: (v: string | null) => void;
28
- recipeLoadError: string;
29
- onSaveCustom: (overwrite: boolean) => void;
30
- onPublishOpen: () => void;
31
- onDeleteOpen: () => void;
32
- };
33
-
34
- export function TeamRecipeTab(props: TeamRecipeTabProps) {
35
- const p = props;
36
- return (
37
- <>
38
- <div className="mt-6 grid grid-cols-1 gap-4 lg:grid-cols-2">
39
- <div className="ck-glass-strong p-4">
40
- <div className="flex items-center justify-between gap-3">
41
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">Custom recipe target</div>
42
- {p.loading ? (
43
- <div className="text-xs text-[color:var(--ck-text-tertiary)]">Loading team…</div>
44
- ) : null}
45
- </div>
46
- <label className="mt-3 block text-xs font-medium text-[color:var(--ck-text-secondary)]">Team id</label>
47
- <input
48
- value={p.toId}
49
- onChange={(e) => p.setToId(e.target.value)}
50
- disabled={!p.canEditTargetId}
51
- className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-3 py-2 text-sm text-[color:var(--ck-text-primary)] disabled:opacity-70"
52
- />
53
- <div className="mt-1 text-xs text-[color:var(--ck-text-tertiary)]">
54
- This is the custom recipe id that will be created when you save.
55
- </div>
56
- <label className="mt-3 block text-xs font-medium text-[color:var(--ck-text-secondary)]">Team name</label>
57
- <input
58
- value={p.toName}
59
- onChange={(e) => p.setToName(e.target.value)}
60
- className="mt-1 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-3 py-2 text-sm text-[color:var(--ck-text-primary)]"
61
- />
62
- <div className="mt-4 grid grid-cols-1 gap-2">
63
- <button
64
- type="button"
65
- disabled={p.saving || !p.teamIdValid || !p.targetIdValid || p.targetIsBuiltin}
66
- onClick={() => p.onSaveCustom(true)}
67
- className="rounded-[var(--ck-radius-sm)] bg-[var(--ck-accent-red)] px-3 py-2 text-sm font-medium text-white shadow-[var(--ck-shadow-1)] disabled:opacity-50"
68
- >
69
- {p.saving ? "Saving" : "Save"}
70
- </button>
71
- <button
72
- type="button"
73
- disabled={
74
- p.saving ||
75
- !p.teamIdValid ||
76
- !p.targetIdValid ||
77
- p.targetIsBuiltin ||
78
- !p.loadedRecipeHash ||
79
- !p.teamMetaRecipeHash ||
80
- p.loadedRecipeHash === p.teamMetaRecipeHash
81
- }
82
- onClick={p.onPublishOpen}
83
- className="rounded-[var(--ck-radius-sm)] bg-emerald-600 px-3 py-2 text-sm font-medium text-white shadow-[var(--ck-shadow-1)] disabled:opacity-50"
84
- >
85
- {p.publishing ? "Publishing" : "Publish changes"}
86
- </button>
87
- <button
88
- type="button"
89
- disabled={p.saving}
90
- onClick={p.onDeleteOpen}
91
- 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)] disabled:opacity-50"
92
- >
93
- Delete Team
94
- </button>
95
- </div>
96
- </div>
97
- <div className="ck-glass-strong p-4">
98
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">Notes</div>
99
- <div className="mt-3 rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/20 p-3">
100
- <div className="text-xs font-medium text-[color:var(--ck-text-secondary)]">Parent recipe (locked)</div>
101
- <select
102
- disabled
103
- className="mt-2 w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-3 py-2 text-sm text-[color:var(--ck-text-primary)] disabled:opacity-70"
104
- value={p.fromId}
105
- onChange={(e) => p.setFromId(e.target.value)}
106
- >
107
- {p.teamRecipes.map((r) => (
108
- <option key={`${r.source}:${r.id}`} value={r.id}>
109
- {r.id} ({r.source})
110
- </option>
111
- ))}
112
- </select>
113
- {p.lockedFromId && (
114
- <div className="mt-2 text-xs text-[color:var(--ck-text-tertiary)]">
115
- <code>{p.lockedFromId}</code>
116
- {p.lockedFromName ? ` (${p.lockedFromName})` : ""}
117
- </div>
118
- )}
119
- {!p.lockedFromId && p.provenanceMissing && (
120
- <div className="mt-2 text-xs text-[color:var(--ck-text-tertiary)]">
121
- Provenance not found for this team.
122
- </div>
123
- )}
124
- </div>
125
- <ul className="mt-4 list-disc space-y-1 pl-5 text-sm text-[color:var(--ck-text-secondary)]">
126
- <li>Save writes the custom recipe file identified by Team id.</li>
127
- <li>Publish changes re-scaffolds this team from your custom recipe.</li>
128
- <li>Delete Team runs openclaw recipes remove-team.</li>
129
- </ul>
130
- </div>
131
- </div>
132
- <div className="mt-6 ck-glass-strong p-4">
133
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">Recipe markdown</div>
134
- {p.recipeLoadError ? (
135
- <div className="mt-3 rounded-[var(--ck-radius-sm)] border border-red-400/30 bg-red-500/10 p-3 text-sm text-red-100">
136
- {p.recipeLoadError}
137
- </div>
138
- ) : null}
139
- <textarea
140
- value={p.content}
141
- onChange={(e) => {
142
- p.setContent(e.target.value);
143
- p.setLoadedRecipeHash(null);
144
- }}
145
- className="mt-2 h-[55vh] w-full resize-none rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 p-3 font-mono text-xs text-[color:var(--ck-text-primary)]"
146
- spellCheck={false}
147
- />
148
- </div>
149
- </>
150
- );
151
- }
@@ -1,68 +0,0 @@
1
- "use client";
2
-
3
- type TeamSkillsTabProps = {
4
- teamId: string;
5
- skillsList: string[];
6
- availableSkills: string[];
7
- skillsLoading: boolean;
8
- selectedSkill: string;
9
- setSelectedSkill: (v: string) => void;
10
- installingSkill: boolean;
11
- teamSkillMsg: string;
12
- teamSkillError: string;
13
- onInstallSkill: () => Promise<void>;
14
- };
15
-
16
- export function TeamSkillsTab(props: TeamSkillsTabProps) {
17
- const p = props;
18
- return (
19
- <div className="mt-6 ck-glass-strong p-4">
20
- <div className="text-sm font-medium text-[color:var(--ck-text-primary)]">Skills</div>
21
- <p className="mt-2 text-sm text-[color:var(--ck-text-secondary)]">
22
- Skills installed in this team workspace. For agent-specific skills, open the agent from the Agents tab.
23
- </p>
24
- <div className="mt-4">
25
- <div className="text-xs font-medium text-[color:var(--ck-text-secondary)]">Installed</div>
26
- <ul className="mt-2 list-disc space-y-1 pl-5 text-sm text-[color:var(--ck-text-secondary)]">
27
- {p.skillsList.length ? p.skillsList.map((s) => <li key={s}>{s}</li>) : <li>None installed.</li>}
28
- </ul>
29
- </div>
30
- <div className="mt-5 rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/15 p-3">
31
- <div className="text-xs font-medium text-[color:var(--ck-text-secondary)]">Add a skill</div>
32
- <div className="mt-2 flex flex-col gap-2 sm:flex-row sm:items-center">
33
- <select
34
- value={p.selectedSkill}
35
- onChange={(e) => p.setSelectedSkill(e.target.value)}
36
- disabled={p.installingSkill || p.skillsLoading || !p.availableSkills.length}
37
- className="w-full rounded-[var(--ck-radius-sm)] border border-white/10 bg-black/25 px-3 py-2 text-sm text-[color:var(--ck-text-primary)]"
38
- >
39
- {p.availableSkills.length
40
- ? p.availableSkills.map((s) => <option key={s} value={s}>{s}</option>)
41
- : <option value="">No skills found</option>}
42
- </select>
43
- <button
44
- type="button"
45
- disabled={p.installingSkill || p.skillsLoading || !p.selectedSkill}
46
- onClick={p.onInstallSkill}
47
- className="rounded-[var(--ck-radius-sm)] bg-[var(--ck-accent-red)] px-3 py-2 text-sm font-medium text-white shadow-[var(--ck-shadow-1)] disabled:opacity-50"
48
- >
49
- {p.installingSkill ? "Adding" : "Add"}
50
- </button>
51
- </div>
52
- {p.teamSkillError && (
53
- <div className="mt-3 rounded-[var(--ck-radius-sm)] border border-red-400/30 bg-red-500/10 p-3 text-sm text-red-100">
54
- {p.teamSkillError}
55
- </div>
56
- )}
57
- {p.teamSkillMsg && (
58
- <div className="mt-3 rounded-[var(--ck-radius-sm)] border border-emerald-400/30 bg-emerald-500/10 p-3 text-sm text-emerald-100">
59
- {p.teamSkillMsg}
60
- </div>
61
- )}
62
- <div className="mt-2 text-xs text-[color:var(--ck-text-tertiary)]">
63
- Uses openclaw recipes install-skill with team-id {p.teamId}.
64
- </div>
65
- </div>
66
- </div>
67
- );
68
- }